blob: df9578cc4f8993b31b18d719883fff2f24d78a01 [file] [log] [blame]
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdio.h>
#include <string.h>
#include <vector>
#include "critical_section_wrapper.h"
#include "event_wrapper.h"
#include "thread_wrapper.h"
#include "voe_extended_test.h"
#include "../../source/voice_engine_defines.h" // defines build macros
#include "system_wrappers/interface/ref_count.h"
#if defined(_WIN32)
#include <conio.h>
#include <winsock2.h>
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
#include <netdb.h>
#endif
using namespace webrtc;
namespace voetest {
// Set this flag to ensure that test packets are transmitted to
// RemoteIP::RemotePort during tests of SetSendToS and SetSendGQos. Requires
// receiver at the remote side and Wireshark with a proper ip.src filter.
#define _SEND_TO_REMOTE_IP_
#ifdef _SEND_TO_REMOTE_IP_
const int RemotePort = 12345; // transmit to this UDP port
const char* RemoteIP = "192.168.200.1"; // transmit to this IP address
#endif
#ifdef MAC_IPHONE
#define SLEEP_IF_IPHONE(x) SLEEP(x)
#else
#define SLEEP_IF_IPHONE(x)
#endif
#ifdef WEBRTC_ANDROID
// Global pointers
extern void* globalJavaVM;
extern void* globalContext;
#endif
extern char* GetFilename(char* filename);
extern const char* GetFilename(const char* filename);
extern int GetResource(char* resource, char* dest, int destLen);
extern char* GetResource(char* resource);
extern const char* GetResource(const char* resource);
// ----------------------------------------------------------------------------
// External AudioDeviceModule implementation
// ----------------------------------------------------------------------------
// static
AudioDeviceModuleImpl* AudioDeviceModuleImpl::Create() {
AudioDeviceModuleImpl* xADM = new AudioDeviceModuleImpl();
if (xADM)
xADM->AddRef();
return xADM;
}
// static
bool AudioDeviceModuleImpl::Destroy(AudioDeviceModuleImpl* adm) {
if (!adm)
return false;
int32_t count = adm->Release();
if (count != 0) {
return false;
} else {
delete adm;
return true;
}
}
AudioDeviceModuleImpl::AudioDeviceModuleImpl() :
_ref_count(0) {
}
AudioDeviceModuleImpl::~AudioDeviceModuleImpl() {
}
int32_t AudioDeviceModuleImpl::AddRef() {
return ++_ref_count;
}
int32_t AudioDeviceModuleImpl::Release() {
// Avoid self destruction in this mock implementation.
// Ensures that we can always check the reference counter while alive.
return --_ref_count;
}
// ----------------------------------------------------------------------------
// External transport (Transport) implementations:
// ----------------------------------------------------------------------------
ExtendedTestTransport::ExtendedTestTransport(VoENetwork* ptr) :
myNetw(ptr), _thread(NULL), _lock(NULL), _event(NULL), _length(0), _channel(0) {
const char* threadName = "voe_extended_test_external_thread";
_lock = CriticalSectionWrapper::CreateCriticalSection();
_event = EventWrapper::Create();
_thread = ThreadWrapper::CreateThread(Run, this, kHighPriority, threadName);
if (_thread) {
unsigned int id;
_thread->Start(id);
}
}
ExtendedTestTransport::~ExtendedTestTransport() {
if (_thread) {
_thread->SetNotAlive();
_event->Set();
if (_thread->Stop()) {
delete _thread;
_thread = NULL;
delete _event;
_event = NULL;
delete _lock;
_lock = NULL;
}
}
}
bool ExtendedTestTransport::Run(void* ptr) {
return static_cast<ExtendedTestTransport*> (ptr)->Process();
}
bool ExtendedTestTransport::Process() {
switch (_event->Wait(500)) {
case kEventSignaled:
_lock->Enter();
myNetw->ReceivedRTPPacket(_channel, _packetBuffer, _length);
_lock->Leave();
return true;
case kEventTimeout:
return true;
case kEventError:
break;
}
return true;
}
int ExtendedTestTransport::SendPacket(int channel, const void *data, int len) {
_lock->Enter();
if (len < 1612) {
memcpy(_packetBuffer, (const unsigned char*) data, len);
_length = len;
_channel = channel;
}
_lock->Leave();
_event->Set(); // triggers ReceivedRTPPacket() from worker thread
return len;
}
int ExtendedTestTransport::SendRTCPPacket(int channel, const void *data, int len) {
myNetw->ReceivedRTCPPacket(channel, data, len);
return len;
}
XTransport::XTransport(VoENetwork* netw, VoEFile* file) :
_netw(netw), _file(file) {
}
int XTransport::SendPacket(int channel, const void *data, int len) {
// loopback
// _netw->ReceivedRTPPacket(channel, data, len);
return 0;
}
int XTransport::SendRTCPPacket(int, const void *, int) {
return 0;
}
// ----------------------------------------------------------------------------
// VoERTPObserver
// ----------------------------------------------------------------------------
XRTPObserver::XRTPObserver() :
_SSRC(0) {
}
XRTPObserver::~XRTPObserver() {
}
void XRTPObserver::OnIncomingCSRCChanged(const int /*channel*/, const unsigned int /*CSRC*/,
const bool /*added*/) {
}
void XRTPObserver::OnIncomingSSRCChanged(const int /*channel*/, const unsigned int SSRC) {
// char msg[128];
// sprintf(msg, "OnIncomingSSRCChanged(channel=%d, SSRC=%lu)\n",
// channel, SSRC);
// TEST_LOG(msg);
_SSRC = SSRC; // skip channel dependency for simplicty
}
// ----------------------------------------------------------------------------
// VoEExtendedTest
// ----------------------------------------------------------------------------
int VoEExtendedTest::PrepareTest(const char* str) const {
TEST_LOG("\n\n================================================\n");
TEST_LOG("\tExtended *%s* Test\n", str);
TEST_LOG("================================================\n\n");
return 0;
}
int VoEExtendedTest::TestPassed(const char* str) const {
TEST_LOG("\n\n------------------------------------------------\n");
TEST_LOG("\tExtended *%s* test passed!\n", str);
TEST_LOG("------------------------------------------------\n\n");
return 0;
}
void VoEExtendedTest::OnPeriodicDeadOrAlive(const int /*channel*/, const bool alive) {
_alive = alive;
if (alive) {
TEST_LOG("=> ALIVE ");
} else {
TEST_LOG("=> DEAD ");
}
fflush(NULL);
}
void VoEExtendedTest::CallbackOnError(const int errCode, int) {
_errCode = errCode;
TEST_LOG("\n************************\n");
TEST_LOG(" RUNTIME ERROR: %d \n", errCode);
TEST_LOG("************************\n");
}
VoEExtendedTest::VoEExtendedTest(VoETestManager& mgr) :
_mgr(mgr) {
for (int i = 0; i < 32; i++) {
_listening[i] = false;
_playing[i] = false;
_sending[i] = false;
}
}
VoEExtendedTest::~VoEExtendedTest() {
}
void VoEExtendedTest::StartMedia(int channel, int rtpPort, bool listen,
bool playout, bool send) {
VoEBase* voe_base_ = _mgr.BasePtr();
_listening[channel] = false;
_playing[channel] = false;
_sending[channel] = false;
voe_base_->SetLocalReceiver(channel, rtpPort);
voe_base_->SetSendDestination(channel, rtpPort, "127.0.0.1");
if (listen) {
_listening[channel] = true;
voe_base_->StartReceive(channel);
}
if (playout) {
_playing[channel] = true;
voe_base_->StartPlayout(channel);
}
if (send) {
_sending[channel] = true;
voe_base_->StartSend(channel);
}
}
void VoEExtendedTest::StopMedia(int channel) {
VoEBase* voe_base_ = _mgr.BasePtr();
if (_listening[channel]) {
_listening[channel] = false;
voe_base_->StopReceive(channel);
}
if (_playing[channel]) {
_playing[channel] = false;
voe_base_->StopPlayout(channel);
}
if (_sending[channel]) {
_sending[channel] = false;
voe_base_->StopSend(channel);
}
}
void VoEExtendedTest::Play(int channel, unsigned int timeMillisec, bool addFileAsMicrophone,
bool addTimeMarker) {
VoEBase* voe_base_ = _mgr.BasePtr();
VoEFile* file = _mgr.FilePtr();
voe_base_->StartPlayout(channel);
TEST_LOG("[playing]");
fflush(NULL);
if (addFileAsMicrophone) {
file->StartPlayingFileAsMicrophone(channel, _mgr.AudioFilename(), true, true);
TEST_LOG("[file as mic]");
fflush(NULL);
}
if (addTimeMarker) {
float dtSec = (float) ((float) timeMillisec / 1000.0);
TEST_LOG("[dT=%.1f]", dtSec);
fflush(NULL); // print sleep time in seconds
}
SLEEP(timeMillisec);
voe_base_->StopPlayout(channel);
file->StopPlayingFileAsMicrophone(channel);
}
void VoEExtendedTest::Sleep(unsigned int timeMillisec, bool addMarker) {
if (addMarker) {
float dtSec = (float) ((float) timeMillisec / 1000.0);
TEST_LOG("[dT=%.1f]", dtSec); // print sleep time in seconds
}
::Sleep(timeMillisec);
}
int VoEExtendedTest::TestBase() {
#ifndef _WIN32
// Sleep a bit instead when pause not supported
#undef PAUSE
#define PAUSE SLEEP(2000);
#endif
PrepareTest("Base");
// TODO(qhogpat): make this an actual instance variable. I think the
// macro black magic will make more sense then. This is named like an
// instance variable since it is required in order to appease the
// gods of darkness.
VoEBase* voe_base_ = _mgr.BasePtr();
VoENetwork* netw = _mgr.NetworkPtr();
#ifdef _TEST_RTP_RTCP_
VoERTP_RTCP* rtp = _mgr.RTP_RTCPPtr();
#endif
//////////////////////////
// SetTraceFileName
#ifdef _USE_EXTENDED_TRACE_
TEST(SetTraceFileName - SetDebugTraceFileName); ANL();
TEST_MUSTPASS(VoiceEngine::SetTraceFile(NULL)); MARK();
// don't use these files
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(""
"VoEBase_trace_dont_use.txt"))); MARK();
// use these instead
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(""
"VoEBase_trace.txt"))); MARK();
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStream |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo)); MARK();
ANL(); AOK(); ANL(); ANL();
#endif
///////////////////////////////////////
// RegisterVoiceEngineObserver
// DeRegisterVoiceEngineObserver
TEST(SetObserver);
ANL();
TEST_MUSTPASS(voe_base_->RegisterVoiceEngineObserver(*this));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->DeRegisterVoiceEngineObserver());
MARK();
ANL();
AOK();
ANL();
ANL();
/////////////////////
// GetVersion
TEST(GetVersion);
ANL();
char version[1024];
// audio device module and AudioProcessing fail to getversion when they
// are not initiliazed
TEST_MUSTPASS(voe_base_->GetVersion(version));
MARK();
TEST_LOG("\n-----\n%s\n-----\n", version);
ANL();
AOK();
ANL();
ANL();
///////////////
// Init
TEST(Init);
ANL();
TEST_MUSTPASS(voe_base_->Init());
MARK();
TEST_MUSTPASS(voe_base_->Terminate());
TEST_MUSTPASS(voe_base_->Init());
MARK();
// ensure that no new memory is allocated at the second call (check
// trace file)
TEST_MUSTPASS(voe_base_->Init());
MARK();
TEST_MUSTPASS(voe_base_->Terminate());
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
// verify AEC recording
TEST_MUSTPASS(voe_base_->Init());
MARK(); // verify output dat-files
TEST_MUSTPASS(voe_base_->Terminate());
#endif
ANL();
AOK();
ANL();
ANL();
////////////////////
// Terminate
TEST(Terminate);
ANL();
TEST_MUSTPASS(voe_base_->Terminate());
MARK(); // should be ignored
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->Terminate());
MARK(); // should terminate
ANL();
AOK();
ANL();
ANL();
// ------------------------------------------------------------------------
// >> Init(AudioDeviceModule)
//
// Note that our mock implementation of the ADM also mocks the
// reference counting part. This approach enables us to keep track
// of the internal reference counter without checking return values
// from the ADM and we also avoid the built-in self destruction.
//
// TODO(henrika): this test does not verify that external ADM methods
// are called by the VoiceEngine once registered. We could extend
// the mock implementation and add counters for each ADM API to ensure
// that they are called in the correct sequence and the correct number
// of times.
TEST_LOG("\nTesting: Init in combination with an external ADM\n");
// Create the ADM and call AddRef within the factory method.
AudioDeviceModuleImpl* xADM = AudioDeviceModuleImpl::Create();
ASSERT_FALSE(xADM == NULL);
ASSERT_TRUE(xADM->ReferenceCounter() == 1);
// Verify default usage case for external ADM.
TEST_MUSTPASS(voe_base_->Init(xADM));MARK();
ASSERT_TRUE(xADM->ReferenceCounter() == 2);
TEST_MUSTPASS(voe_base_->Terminate());
ASSERT_TRUE(xADM->ReferenceCounter() == 1);
// Our reference-count implementation does not self destruct.
// We do it manually here instead by calling Release followed by delete.
ASSERT_TRUE(AudioDeviceModuleImpl::Destroy(xADM));
ANL();
AOK();ANL();
// >> end of Init(AudioDeviceModule)
// ------------------------------------------------------------------------
///////////////////////////
// MaxNumOfChannels
TEST(MaxNumOfChannels);
ANL();
TEST_MUSTPASS(voe_base_->MaxNumOfChannels() < 0);
MARK();
ANL();
AOK();
ANL();
ANL();
////////////////////////
// CreateChannel
// DeleteChannel
int i;
int channel;
int nChannels(voe_base_->MaxNumOfChannels());
TEST(CreateChannel);
ANL();
TEST(DeleteChannel);
ANL();
TEST_MUSTPASS(voe_base_->Init());
channel = voe_base_->CreateChannel();
MARK();
TEST_MUSTPASS(channel != 0);
channel = voe_base_->CreateChannel();
MARK();
TEST_MUSTPASS(channel != 1);
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
MARK();
TEST_MUSTPASS(voe_base_->DeleteChannel(1));
MARK();
// create and delete one channel many times
for (i = 0; i < 10; i++) {
channel = voe_base_->CreateChannel();
MARK();
TEST_MUSTPASS(channel != 0); // should be 0 each time
TEST_MUSTPASS(voe_base_->DeleteChannel(channel));
MARK();
}
// create max number of channels
for (i = 0; i < nChannels; i++) {
channel = voe_base_->CreateChannel();
MARK();
TEST_MUSTPASS(channel != i);
}
channel = voe_base_->CreateChannel();
MARK(); // should fail since no more channels can now be created
TEST_MUSTPASS(channel != -1);
int aChannel = (((nChannels - 17) > 0) ? (nChannels - 17) : 0);
TEST_MUSTPASS(voe_base_->DeleteChannel(aChannel));
MARK();
channel = voe_base_->CreateChannel();
MARK(); // should reuse channel
TEST_MUSTPASS(channel != aChannel);
// delete all created channels
for (i = 0; i < nChannels; i++) {
TEST_MUSTPASS(voe_base_->DeleteChannel(i));
MARK();
}
// try to delete a non-existing channel
TEST_MUSTPASS(-1 != voe_base_->DeleteChannel(aChannel));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
ANL();
AOK();
ANL();
ANL();
// ------------------------------------------------------------------------
// >> SetLocalReceiver
//
// State: VE not initialized, no existing channels
TEST_MUSTPASS(voe_base_->Init());
int ch;
TEST(SetLocalReceiver);
ANL();
// no channel created yet => should fail
TEST_MUSTPASS(!voe_base_->SetLocalReceiver(0, 100));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
ch = voe_base_->CreateChannel();
#ifdef MAC_IPHONE
printf("\nNOTE: Local IP must be set in source code (line %d) \n",
__LINE__ + 1);
char* localIp = "127.0.0.1";
#else
char localIp[64] = { 0 };
TEST_MUSTPASS(netw->GetLocalIP(localIp));
MARK();
// NOTE: This API is supported on Win, Mac and Linux and may fail or not
// return local IP for other platforms.
#endif
// trivial invalid function calls
TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch+1, 12345));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch, -1));
MARK();
TEST_ERROR(VE_INVALID_PORT_NMBR);
// check conflict with ongoing receiving
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
MARK();
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch, 12345));
MARK();
TEST_ERROR(VE_ALREADY_LISTENING);
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// check conflict with ongoing transmission
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch, 12345));
MARK();
TEST_ERROR(VE_ALREADY_SENDING);
TEST_MUSTPASS(voe_base_->StopSend(ch));
// valid function calls
// Need to sleep between, otherwise it may fail for unknown reason
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, localIp));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, NULL,
"230.1.2.3"));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, localIp,
"230.1.2.3"));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, 5555, NULL));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
MARK();
SLEEP(100);
// STATE: no media but sockets exists and are binded to 12345 and 12346
// respectively
// Add some dynamic tests as well:
// ensure that last setting is used (cancels old settings)
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 44444));
MARK();
SLEEP(100);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 54321));
MARK();
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 54321, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
Play(ch, 1000, true, true);
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
ANL();
AOK();
ANL();
ANL();
// >> end of SetLocalReceiver
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> GetLocalReceiver
//
// State: VE initialized, no existing channels
TEST(GetLocalReceiver);
ANL();
int port;
char ipaddr[64];
int RTCPport;
ch = voe_base_->CreateChannel();
// verify non-configured (blank) local receiver
TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
MARK();
TEST_MUSTPASS(port != 0);
TEST_MUSTPASS(RTCPport != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
// check some trivial set/get combinations
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345))
TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
MARK();
TEST_MUSTPASS(port != 12345);
TEST_MUSTPASS(RTCPport != 12346);
TEST_MUSTPASS(strcmp(ipaddr, "0.0.0.0") != 0); // now binded to "any" IP
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, 55555))
TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
MARK();
TEST_MUSTPASS(port != 12345);
TEST_MUSTPASS(RTCPport != 55555);
TEST_MUSTPASS(strcmp(ipaddr, "0.0.0.0") != 0);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, localIp))
TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
MARK();
TEST_MUSTPASS(port != 12345);
TEST_MUSTPASS(RTCPport != 12346);
TEST_MUSTPASS(strcmp(ipaddr, localIp) != 0);
TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
ANL();
AOK();
ANL();
ANL();
// >> end of GetLocalReceiver
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetSendDestination
//
// State: VE initialized, no existing channels
TEST(SetSendDestination);
ANL();
// call without existing channel
TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
ch = voe_base_->CreateChannel();
// trivial fail tests
TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 65536, "127.0.0.1"));
MARK();
TEST_ERROR(VE_INVALID_PORT_NMBR); // invalid RTP port
TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", 65536));
MARK();
TEST_ERROR(VE_INVALID_PORT_NMBR); // invalid source port
TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", kVoEDefault,
65536));
MARK();
TEST_ERROR(VE_INVALID_PORT_NMBR); // invalid RTCP port
TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 12345, "127.0.0.300"));
MARK();
TEST_ERROR(VE_INVALID_IP_ADDRESS); // invalid IP address
// sockets must be created first to support multi-cast (not required
// otherwise)
TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 55555, "230.0.0.1"));
MARK();
TEST_ERROR(VE_SOCKET_ERROR);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555)); // create sockets
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 55555, "230.0.0.1"));
MARK(); // should work now
voe_base_->DeleteChannel(0);
ch = voe_base_->CreateChannel();
// STATE: one channel created, no sockets exist
// valid function calls
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1"));
MARK();
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", 44444));
MARK();
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", kVoEDefault,
55555));
MARK();
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", 44444,
55555));
MARK();
voe_base_->DeleteChannel(0);
ch = voe_base_->CreateChannel();
// create receive sockets first and then an extra pair of send sockets
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 44444));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 44444, "127.0.0.1", 11111));
MARK(); // binds to 11111
TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
ANL();
AOK();
ANL();
ANL();
// >> end of SetSendDestination
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> GetSendDestination
//
// State: VE initialized, no existing channels
TEST(GetSendDestination);
ANL();
int sourcePort;
ch = voe_base_->CreateChannel();
// verify non-configured (blank) local receiver
TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, ipaddr, sourcePort,
RTCPport));
MARK();
TEST_MUSTPASS(port != 0);
TEST_MUSTPASS(sourcePort != 0);
TEST_MUSTPASS(RTCPport != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
// check some trivial set/get combinations
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 44444, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, ipaddr, sourcePort,
RTCPport));
MARK();
TEST_MUSTPASS(port != 44444);
TEST_MUSTPASS(sourcePort != 0); // should be 0 since no local receiver has
// NOT been defined yet
TEST_MUSTPASS(RTCPport != 44445);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555));
TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, ipaddr, sourcePort,
RTCPport));
MARK();
TEST_MUSTPASS(port != 44444);
TEST_MUSTPASS(sourcePort != 55555); // should be equal to local port
TEST_MUSTPASS(RTCPport != 44445);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
voe_base_->DeleteChannel(0);
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 44444, "127.0.0.1"));
// NULL as IP-address input should work as well
TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, NULL, sourcePort,
RTCPport));
MARK();
TEST_MUSTPASS(port != 44444);
TEST_MUSTPASS(sourcePort != 0);
TEST_MUSTPASS(RTCPport != 44445);
TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
ANL();
AOK();
ANL();
ANL();
// >> end of GetLocalReceiver
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> StartReceive
// >> StopReceive
//
// State: VE initialized, no existing channels
TEST(StartReceive);
ANL();
TEST(StopReceive);
ANL();
// call without existing channel
TEST_MUSTPASS(!voe_base_->StartReceive(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!voe_base_->StopReceive(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
ch = voe_base_->CreateChannel();
// sockets must be created first
TEST_MUSTPASS(!voe_base_->StartReceive(0));
MARK();
TEST_ERROR(VE_SOCKETS_NOT_INITED);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555));
TEST_MUSTPASS(voe_base_->StartReceive(0));
MARK(); // should work this time
// enable again (should work)
TEST_MUSTPASS(voe_base_->StartReceive(0));
MARK();
// Stop/Start (should work)
TEST_MUSTPASS(voe_base_->StopReceive(0));
MARK();
TEST_MUSTPASS(voe_base_->StartReceive(0));
MARK();
// Verify in loopback
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 55555, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
Play(ch, 1000, true, true);
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopReceive(0));
MARK();
voe_base_->DeleteChannel(0);
ch = voe_base_->CreateChannel();
// Ensure that it is OK to add delay between SetLocalReceiver and StarListen
TEST_LOG("\nspeak after 2 seconds and ensure that no delay is added:\n");
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555));
Sleep(2000, true); // adding emulated delay here
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 55555, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
Play(ch, 2000, true, true);
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
ANL();
// Multi-channel tests
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 11111+2*i));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
MARK();
}
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
TEST_MUSTPASS(voe_base_->StopReceive(i));
MARK();
voe_base_->DeleteChannel(i);
}
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 11111+2*i));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
MARK();
TEST_MUSTPASS(voe_base_->StopReceive(ch));
MARK();
voe_base_->DeleteChannel(ch);
}
ANL();
AOK();
ANL();
ANL();
// >> end of StartReceive/StopReceive
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> StartPlayout
// >> StopPlayout
//
// State: VE initialized, no existing channels
TEST(StartPlayout);
ANL();
TEST(StopPlayout);
ANL();
// call without existing channel
TEST_MUSTPASS(!voe_base_->StartPlayout(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!voe_base_->StopPlayout(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
MARK();
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
MARK();
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
MARK();
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
MARK();
voe_base_->DeleteChannel(ch);
// Multi-channel tests
const int MaxNumberOfPlayingChannels(kVoiceEngineMaxNumOfActiveChannels);
for (i = 0; i < MaxNumberOfPlayingChannels; i++) {
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
MARK();
}
for (i = 0; i < MaxNumberOfPlayingChannels; i++) {
TEST_MUSTPASS(voe_base_->StopPlayout(i));
MARK();
voe_base_->DeleteChannel(i);
}
for (i = 0; i < MaxNumberOfPlayingChannels; i++) {
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
MARK();
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
MARK();
voe_base_->DeleteChannel(ch);
}
ANL();
AOK();
ANL();
ANL();
// >> end of StartPlayout/StopPlayout
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> StartSend
// >> StopSend
//
// State: VE initialized, no existing channels
TEST(StartSend);
ANL();
TEST(StopSend);
ANL();
// call without existing channel
TEST_MUSTPASS(!voe_base_->StartSend(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!voe_base_->StopSend(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
ch = voe_base_->CreateChannel();
// call without initialized destination
TEST_MUSTPASS(!voe_base_->StartSend(ch));
MARK();
TEST_ERROR(VE_DESTINATION_NOT_INITED);
// initialize destination and try again (should work even without existing
// sockets)
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
MARK();
SLEEP(100);
// STATE: sockets should now have been created automatically at the first
// transmitted packet should be binded to 33333 and "0.0.0.0"
TEST_MUSTPASS(voe_base_->StopSend(ch));
MARK();
voe_base_->DeleteChannel(ch);
ch = voe_base_->CreateChannel();
// try loopback with unique send sockets (closed when channel is deleted or
// new source is set)
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 33333));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", 44444));
TEST_MUSTPASS(voe_base_->StartSend(ch));
MARK();
TEST_MUSTPASS(voe_base_->StartReceive(ch));
Play(ch, 2000, true, true);
TEST_MUSTPASS(voe_base_->StopSend(ch));
MARK();
TEST_MUSTPASS(voe_base_->StopReceive(ch));
voe_base_->DeleteChannel(ch);
ANL();
// Multi-channel tests
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 33333 + 2*i));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333 + 2*i, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
MARK();
}
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
TEST_MUSTPASS(voe_base_->StopSend(i));
MARK();
voe_base_->DeleteChannel(i);
}
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 45633 + 2*i));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 45633 + 2*i, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
MARK();
TEST_MUSTPASS(voe_base_->StopSend(ch));
MARK();
voe_base_->DeleteChannel(ch);
}
ANL();
AOK();
ANL();
ANL();
// >> end of StartSend/StopSend
// ------------------------------------------------------------------------
//////////////////////////////
// SetNetEQPlayoutMode
// GetNetEQPlayoutMode
TEST(SetNetEQPlayoutMode);
ANL();
TEST(GetNetEQPlayoutMode);
ANL();
NetEqModes mode;
ch = voe_base_->CreateChannel();
// invalid function calls (should fail)
TEST_MUSTPASS(!voe_base_->GetNetEQPlayoutMode(ch+1, mode));
MARK();
TEST_MUSTPASS(!voe_base_->SetNetEQPlayoutMode(ch+1, kNetEqDefault));
MARK();
// verify default mode (should be kNetEqDefault)
TEST_MUSTPASS(voe_base_->GetNetEQPlayoutMode(ch, mode));
MARK();
TEST_MUSTPASS(mode != kNetEqDefault);
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(ch, kNetEqStreaming));
MARK();
voe_base_->DeleteChannel(ch);
// ensure that default mode is set as soon as new channel is created
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->GetNetEQPlayoutMode(ch, mode));
MARK();
TEST_MUSTPASS(mode != kNetEqDefault);
voe_base_->DeleteChannel(ch);
// verify Set/Get for all supported modes and max number of channels
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
ch = voe_base_->CreateChannel();
// verify Set/Get for all supported modes
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(i, kNetEqDefault));
MARK();
TEST_MUSTPASS(voe_base_->GetNetEQPlayoutMode(i, mode));
MARK();
TEST_MUSTPASS(mode != kNetEqDefault);
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(i, kNetEqStreaming));
MARK();
TEST_MUSTPASS(voe_base_->GetNetEQPlayoutMode(i, mode));
MARK();
TEST_MUSTPASS(mode != kNetEqStreaming);
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(i, kNetEqFax));
MARK();
TEST_MUSTPASS(voe_base_->GetNetEQPlayoutMode(i, mode));
MARK();
TEST_MUSTPASS(mode != kNetEqFax);
SLEEP(50);
}
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
voe_base_->DeleteChannel(i);
}
ANL();
AOK();
ANL();
ANL();
//////////////////////////////
// SetNetEQBGNMode
// GetNetEQBGNMode
TEST(SetNetEQBGNMode);
ANL();
TEST(GetNetEQBGNMode);
ANL();
NetEqBgnModes bgnMode;
ch = voe_base_->CreateChannel();
// invalid function calls (should fail)
TEST_MUSTPASS(!voe_base_->GetNetEQBGNMode(ch+1, bgnMode));
MARK();
TEST_MUSTPASS(!voe_base_->SetNetEQBGNMode(ch+1, kBgnOn));
MARK();
// verify default mode (should be kBgnOn)
TEST_MUSTPASS(voe_base_->GetNetEQBGNMode(ch, bgnMode));
MARK();
TEST_MUSTPASS(bgnMode != kBgnOn);
voe_base_->DeleteChannel(ch);
// ensure that default mode is set as soon as new channel is created
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->GetNetEQBGNMode(ch, bgnMode));
MARK();
TEST_MUSTPASS(bgnMode != kBgnOn);
voe_base_->DeleteChannel(ch);
// verify Set/Get for all supported modes and max number of channels
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
ch = voe_base_->CreateChannel();
// verify Set/Get for all supported modes
TEST_MUSTPASS(voe_base_->SetNetEQBGNMode(i, kBgnOn));
MARK();
TEST_MUSTPASS(voe_base_->GetNetEQBGNMode(i, bgnMode));
MARK();
TEST_MUSTPASS(bgnMode != kBgnOn);
TEST_MUSTPASS(voe_base_->SetNetEQBGNMode(i, kBgnFade));
MARK();
TEST_MUSTPASS(voe_base_->GetNetEQBGNMode(i, bgnMode));
MARK();
TEST_MUSTPASS(bgnMode != kBgnFade);
TEST_MUSTPASS(voe_base_->SetNetEQBGNMode(i, kBgnOff));
MARK();
TEST_MUSTPASS(voe_base_->GetNetEQBGNMode(i, bgnMode));
MARK();
TEST_MUSTPASS(bgnMode != kBgnOff);
SLEEP(50);
}
for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
voe_base_->DeleteChannel(i);
}
// Verify real-time performance for all playout modes in full duplex
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(ch, kNetEqDefault));
MARK();
TEST_LOG("\nenjoy full duplex using kNetEqDefault playout mode...\n");
PAUSE
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(ch, kNetEqStreaming));
MARK();
TEST_LOG("\nenjoy full duplex using kNetEqStreaming playout mode...\n");
PAUSE
TEST_MUSTPASS(voe_base_->SetNetEQPlayoutMode(ch, kNetEqFax));
MARK();
TEST_LOG("\nenjoy full duplex using kNetEqFax playout mode...\n");
PAUSE
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
voe_base_->DeleteChannel(ch);
ANL();
AOK();
ANL();
ANL();
/////////////////////
// Full duplex tests
ch = voe_base_->CreateChannel(); // We must delete this channel first to be able
// to reuse port 12345
// start with default case, also test non-default RTCP port
#ifdef _TEST_RTP_RTCP_
TEST_MUSTPASS(rtp->SetRTCP_CNAME(ch, "Johnny"));
#endif
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, 12349));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", kVoEDefault,
12349));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_LOG("full duplex is now activated (1)\n");
TEST_LOG("waiting for RTCP packet...\n");
SLEEP(7000); // Make sure we get RTCP packet
PAUSE;
// Verify that we got RTCP packet from correct source port
#ifdef _TEST_RTP_RTCP_
char tmpStr[64] = { 0 };
TEST_MUSTPASS(rtp->GetRemoteRTCP_CNAME(ch, tmpStr));
TEST_MUSTPASS(_stricmp("Johnny", tmpStr));
#endif
int rtpPort(0), rtcpPort(0);
char ipAddr[64] = { 0 };
TEST_MUSTPASS(netw->GetSourceInfo(ch, rtpPort, rtcpPort, ipAddr));
TEST_MUSTPASS(12349 != rtcpPort);
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// Call StartSend before StartReceive
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_LOG("\nfull duplex is now activated (2)\n");
PAUSE
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// Try again using same ports
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_LOG("\nfull duplex is now activated (3)\n");
TEST_LOG("waiting for RTCP packet...\n");
SLEEP(7000); // Make sure we get RTCP packet
PAUSE
// Verify correct RTCP source port
TEST_MUSTPASS(netw->GetSourceInfo(ch, rtpPort, rtcpPort, ipAddr));
TEST_MUSTPASS(12345+1 != rtcpPort);
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
voe_base_->DeleteChannel(ch);
ch = voe_base_->CreateChannel();
// Try with extra send socket
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 22222));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 22222, "127.0.0.1", 11111));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_LOG("\nfull duplex is now activated (4)\n");
PAUSE
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// repeat default case starting with a fresh channel
voe_base_->DeleteChannel(ch);
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_LOG("\nfull duplex is now activated (5)\n");
PAUSE
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// restart call again
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_LOG("\nfull duplex is now activated (6)\n");
PAUSE
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// force sending from new socket
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", 12350,
12359));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_LOG("\nfull duplex is now activated (7)\n");
PAUSE
// Test getting send settings
TEST_MUSTPASS(voe_base_->GetSendDestination(ch, rtpPort, ipAddr, sourcePort,
rtcpPort));
TEST_MUSTPASS(12345 != rtpPort);
TEST_MUSTPASS(_stricmp("127.0.0.1", ipAddr));
TEST_MUSTPASS(12350 != sourcePort);
TEST_MUSTPASS(12359 != rtcpPort);
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
// new channel and new port
ch = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 33221));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33221, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_LOG("\nfull duplex is now activated (8)\n");
PAUSE
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
voe_base_->DeleteChannel(ch);
ch = voe_base_->CreateChannel();
#ifndef MAC_IPHONE
// bind to local IP and try again
strcpy(localIp, "127.0.0.1");
#else
localIp = "127.0.0.1";
#endif
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 33221, 12349, localIp));
TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33221, localIp));
TEST_MUSTPASS(voe_base_->StartReceive(ch));
TEST_MUSTPASS(voe_base_->StartPlayout(ch));
TEST_MUSTPASS(voe_base_->StartSend(ch));
TEST_LOG("\nfull duplex is now activated (9)\n");
PAUSE
TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, rtpPort, rtcpPort, ipAddr));
TEST_MUSTPASS(33221 != rtpPort);
TEST_MUSTPASS(_stricmp(localIp, ipAddr));
TEST_MUSTPASS(12349 != rtcpPort);
ANL();
AOK();
ANL();
ANL();
//////////////////////
// Trace filter tests
#ifdef _USE_EXTENDED_TRACE_
TEST(SetTraceFilter); ANL();
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(""
"VoEBase_trace_filter.txt"))); MARK();
SLEEP(100);
// Test a few different filters, verify in trace file
// Each SetTraceFilter calls should be seen once, no more, no less
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceNone)); MARK();
SLEEP(300);
// API call and info should NOT be seen in log
TEST_MUSTPASS(voe_base_->SetOnHoldStatus(0, true)); MARK();
// API call and error should NOT be seen in log
TEST_MUSTPASS(!voe_base_->SetOnHoldStatus(999, true)); MARK();
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceApiCall |
kTraceCritical |
kTraceError |
kTraceWarning)); MARK();
SLEEP(300);
// API call should and info should NOT be seen in log
TEST_MUSTPASS(voe_base_->SetOnHoldStatus(0, false)); MARK();
// API call and error should be seen in log
TEST_MUSTPASS(!voe_base_->SetOnHoldStatus(999, true)); MARK();
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceApiCall | kTraceInfo));
MARK();
SLEEP(300);
// API call and info should be seen in log
TEST_MUSTPASS(voe_base_->SetOnHoldStatus(0, true)); MARK();
// API call should and error should NOT be seen in log
TEST_MUSTPASS(!voe_base_->SetOnHoldStatus(999, true)); MARK();
// Back to default
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceAll)); MARK();
SLEEP(300);
AOK(); ANL();
#endif
// ------------------------------------------------------------------------
// >> Multiple instance testing
//
// We should support 8 instances simultaneously
// and at least one should be able to have a call running
// One instance is already created
VoiceEngine* instVE[7];
VoEBase* baseVE[7];
for (int instNum = 0; instNum < 7; instNum++) {
instVE[instNum] = VoiceEngine::Create();
baseVE[instNum] = VoEBase::GetInterface(instVE[instNum]);
TEST_MUSTPASS(baseVE[instNum]->Init());
TEST_MUSTPASS(baseVE[instNum]->CreateChannel());
}
TEST_LOG("Created 7 more instances of VE, make sure audio is ok...\n\n");
PAUSE
for (int instNum = 0; instNum < 7; instNum++) {
TEST_MUSTPASS(baseVE[instNum]->DeleteChannel(0));
TEST_MUSTPASS(baseVE[instNum]->Terminate());
TEST_MUSTPASS(baseVE[instNum]->Release());
VoiceEngine::Delete(instVE[instNum]);
}
AOK();
ANL();
//////////////
// Close down
TEST_MUSTPASS(voe_base_->StopSend(ch));
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
TEST_MUSTPASS(voe_base_->StopReceive(ch));
TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
voe_base_->DeleteChannel(0);
TEST_MUSTPASS(voe_base_->Terminate());
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestCallReport
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestCallReport() {
// Get required sub-API pointers
VoEBase* voe_base_ = _mgr.BasePtr();
VoECallReport* report = _mgr.CallReportPtr();
VoEFile* file = _mgr.FilePtr();
VoEAudioProcessing* apm = _mgr.APMPtr();
VoENetwork* netw = _mgr.NetworkPtr();
PrepareTest("CallReport");
// check if this interface is supported
if (!report) {
TEST_LOG("VoECallReport is not supported!");
return -1;
}
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename("VoECallReport_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
///////////////////////////
// Actual test starts here
TEST(ResetCallReportStatistics);
ANL();
TEST_MUSTPASS(!report->ResetCallReportStatistics(-2));
MARK(); // not OK
TEST_MUSTPASS(!report->ResetCallReportStatistics(1));
MARK(); // not OK
TEST_MUSTPASS(report->ResetCallReportStatistics(0));
MARK(); // OK
TEST_MUSTPASS(report->ResetCallReportStatistics(-1));
MARK(); // OK
AOK();
ANL();
bool enabled = false;
EchoStatistics echo;
TEST(GetEchoMetricSummary);
ANL();
TEST_MUSTPASS(apm->GetEcMetricsStatus(enabled));
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(apm->SetEcMetricsStatus(true));
TEST_MUSTPASS(report->GetEchoMetricSummary(echo)); // all outputs will be
// -100 in loopback (skip further tests)
AOK();
ANL();
// TODO(xians): investigate the cause of test failure before enabling.
/*
StatVal delays;
TEST(GetRoundTripTimeSummary);
ANL();
// All values should be >=0 since RTCP is now on
TEST_MUSTPASS(report->GetRoundTripTimeSummary(0, delays));
MARK();
TEST_MUSTPASS(delays.min == -1);
TEST_MUSTPASS(delays.max == -1);
TEST_MUSTPASS(delays.average == -1);
rtp_rtcp->SetRTCPStatus(0, false);
// All values should be -1 since RTCP is off
TEST_MUSTPASS(report->GetRoundTripTimeSummary(0, delays));
MARK();
TEST_MUSTPASS(delays.min != -1);
TEST_MUSTPASS(delays.max != -1);
TEST_MUSTPASS(delays.average != -1);
rtp_rtcp->SetRTCPStatus(0, true);
AOK();
ANL();
*/
int nDead = 0;
int nAlive = 0;
TEST(GetDeadOrAliveSummary);
ANL();
// All results should be -1 since dead-or-alive is not active
TEST_MUSTPASS(report->GetDeadOrAliveSummary(0, nDead, nAlive) != -1);
MARK();
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 1));
SLEEP(2000);
// All results should be >= 0 since dead-or-alive is active
TEST_MUSTPASS(report->GetDeadOrAliveSummary(0, nDead, nAlive));
MARK();
TEST_MUSTPASS(nDead == -1);
TEST_MUSTPASS(nAlive == -1)
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
AOK();
ANL();
TEST(WriteReportToFile);
ANL();
// Greek and Coptic (see http://www.utf8-chartable.de/unicode-utf8-table.pl)
char fileNameUTF8[64];
fileNameUTF8[0] = (char) 0xce;
fileNameUTF8[1] = (char) 0xba;
fileNameUTF8[2] = (char) 0xce;
fileNameUTF8[3] = (char) 0xbb;
fileNameUTF8[4] = (char) 0xce;
fileNameUTF8[5] = (char) 0xbd;
fileNameUTF8[6] = (char) 0xce;
fileNameUTF8[7] = (char) 0xbe;
fileNameUTF8[8] = '.';
fileNameUTF8[9] = 't';
fileNameUTF8[10] = 'x';
fileNameUTF8[11] = 't';
fileNameUTF8[12] = 0;
TEST_MUSTPASS(!report->WriteReportToFile(NULL));
MARK();
TEST_MUSTPASS(report->WriteReportToFile("call_report.txt"));
MARK();
TEST_MUSTPASS(report->WriteReportToFile(fileNameUTF8));
MARK(); // should work with UTF-8 as well (κλνξ.txt)
AOK();
ANL();
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestCodec
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestCodec() {
PrepareTest("Codec");
VoEBase* voe_base_ = _mgr.BasePtr();
VoECodec* codec = _mgr.CodecPtr();
VoEFile* file = _mgr.FilePtr();
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename("VoECodec_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
#ifdef WEBRTC_EXTERNAL_TRANSPORT
ExtendedTestTransport* ptrTransport(NULL);
ptrTransport = new ExtendedTestTransport(netw);
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
#else
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
#endif
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
///////////////////////////
// Actual test starts here
int i;
int err;
CodecInst cinst;
/////////////////////////
// GetNumOfCodecs
int nCodecs;
TEST(GetNumOfCodecs);
ANL();
// validate #codecs
nCodecs = codec->NumOfCodecs();
MARK();
TEST_MUSTPASS(nCodecs < 0);
AOK();
ANL();
///////////////////
// GetCodec
TEST(GetCodec);
ANL();
// scan all supported codecs
nCodecs = codec->NumOfCodecs();
for (int index = 0; index < nCodecs; index++) {
TEST_MUSTPASS(codec->GetCodec(index, cinst));
TEST_LOG("[%2d] %16s: fs=%6d, pt=%4d, rate=%7d, ch=%2d, size=%5d", index, cinst.plname,
cinst.plfreq, cinst.pltype, cinst.rate, cinst.channels, cinst.pacsize);
if (cinst.pltype == -1) {
TEST_LOG(" <= NOTE pt=-1\n");
} else {
ANL();
}
}
// ensure that an invalid index parameter is detected
TEST_MUSTPASS(-1 != codec->GetCodec(-1, cinst));
nCodecs = codec->NumOfCodecs();
TEST_MUSTPASS(-1 != codec->GetCodec(nCodecs, cinst));
MARK();
// ensure that error code is VE_INVALID_LISTNR
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_LISTNR);
AOK();
ANL();
///////////////////////
// GetSendCodec
TEST(GetSendCodec);
ANL();
CodecInst defaultCodec;
// check the channel parameter
int nMaxChannels(voe_base_->MaxNumOfChannels());
TEST_MUSTPASS(-1 != codec->GetSendCodec(nMaxChannels-1, cinst));
MARK(); // not created
TEST_MUSTPASS(-1 != codec->GetSendCodec(nMaxChannels, cinst));
MARK(); // out of range
TEST_MUSTPASS(-1 != codec->GetSendCodec(-1, cinst));
MARK(); // out of range
TEST_MUSTPASS(codec->GetSendCodec(0, cinst));
MARK(); // OK
nCodecs = codec->NumOfCodecs();
for (int index = 0; index < nCodecs; index++) {
TEST_MUSTPASS(codec->GetCodec(index, defaultCodec));
if (codec->SetSendCodec(0, defaultCodec) == 0) {
TEST_MUSTPASS(codec->GetSendCodec(0, cinst));
MARK();
//TEST_LOG("[%2d] %s: fs=%d, pt=%d, rate=%d, ch=%d, size=%d\n",
// index, cinst.plname, cinst.plfreq, cinst.pltype, cinst.rate,
// cinst.channels, cinst.pacsize);
TEST_MUSTPASS(cinst.pacsize != defaultCodec.pacsize);
TEST_MUSTPASS(cinst.plfreq != defaultCodec.plfreq);
TEST_MUSTPASS(cinst.pltype != defaultCodec.pltype);
TEST_MUSTPASS(cinst.rate != defaultCodec.rate);
TEST_MUSTPASS(cinst.channels != defaultCodec.channels);
}
}
ANL();
AOK();
ANL();
///////////////////////
// SetSendCodec
TEST(SetSendCodec);
ANL();
// --- Scan all supported codecs and set default parameters
nCodecs = codec->NumOfCodecs();
for (int index = 0; index < nCodecs; index++) {
// Get default (ACM) settings
TEST_MUSTPASS(codec->GetCodec(index, cinst));
defaultCodec = cinst;
TEST_LOG("[%2d] %s (default): fs=%d, pt=%d, rate=%d, ch=%d, size=%d\n",
index, cinst.plname, cinst.plfreq, cinst.pltype, cinst.rate,
cinst.channels, cinst.pacsize);
// Verify invalid codec names
if (!_stricmp("CN", cinst.plname) || !_stricmp("telephone-event",
cinst.plname)
|| !_stricmp("red", cinst.plname)) {
// default settings for invalid payload names (should give
// VE_INVALID_PLNAME)
TEST_MUSTPASS(!codec->SetSendCodec(0, cinst));
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
continue;
}
// If we build the ACM with more codecs than we have payload types,
// some codecs will be given -1 as default payload type. This is a fix
// to ensure that we can complete these tests also for this case.
if (cinst.pltype == -1) {
cinst.pltype = 97;
}
// --- Default settings
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
// --- Packet size
TEST_LOG("\npacsize : ");
for (int pacsize = 80; pacsize < 1440; pacsize += 80) {
cinst.pacsize = pacsize;
if (-1 != codec->SetSendCodec(0, cinst)) {
// log valid packet size
TEST_LOG("%d ", pacsize);
} else {
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
}
cinst.pacsize = defaultCodec.pacsize;
// --- Audio channels (1/mono or 2/stereo)
TEST_LOG("\nchannels: ");
for (int channels = 1; channels < 4; channels++) {
cinst.channels = channels;
if (-1 != codec->SetSendCodec(0, cinst)) {
// valid channels (only 1 should be OK)
TEST_LOG("%d ", channels);
} else {
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
}
cinst.channels = defaultCodec.channels;
// --- Payload frequency
TEST_LOG("\nplfreq : ");
cinst.plfreq = defaultCodec.plfreq;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.plfreq);
// --- Payload name
strcpy(cinst.plname, "INVALID");
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst))
{
// ensure that error code is VE_INVALID_PLNAME
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
// restore default plname
strcpy(cinst.plname, defaultCodec.plname);
// --- Payload type (dynamic range is 96-127)
TEST_LOG("\npltype : ");
// All PT should be OK, test a few different
cinst.pltype = defaultCodec.pltype;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.pltype);
cinst.pltype = defaultCodec.pltype + 1;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.pltype);
const int valid_pltypes[4] = { 0, 96, 117, 127 };
for (i = 0; i < static_cast<int> (sizeof(valid_pltypes) / sizeof(int)); i++) {
cinst.pltype = valid_pltypes[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.pltype);
}
// Restore default
cinst.pltype = defaultCodec.pltype;
// --- Codec rate
TEST_LOG("\nrate : ");
if (_stricmp("isac", cinst.plname) == 0) {
// ISAC
if (cinst.plfreq == 16000) {
int valid_rates[3] = { -1, 10000, 32000 };
// failed in RegisterPayload when rate is 32000
for (i = 0; i < static_cast<int> (sizeof(valid_rates) / sizeof(int)); i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
cinst.rate = 0; // invalid
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst))
{
// ensure that error code is VE_CANNOT_SET_SEND_CODEC
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
ANL();
} else //ISACSWB
{
// rate changing fails in RegisterPayload
int valid_rates[8] = { -1, 10000, 25000, 32000, 35000, 45000, 50000, 52000 };
for (i = 0; i < static_cast<int> (sizeof(valid_rates) / sizeof(int)); i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
int invalid_rates[3] = { 0, 5000, 57000 }; // invalid
for (i = 0; i < static_cast<int> (sizeof(invalid_rates) / sizeof(int)); i++) {
cinst.rate = invalid_rates[i];
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst))
{
// ensure that error code is VE_CANNOT_SET_SEND_CODEC
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
}
ANL();
}
} else if (_stricmp("amr", cinst.plname) == 0) {
int valid_rates[8] = { 4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200 };
for (i = 0;
i < static_cast<int> (sizeof(valid_rates) / sizeof(int));
i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
ANL();
} else if (_stricmp("g7291", cinst.plname) == 0) {
int valid_rates[12] = { 8000, 12000, 14000, 16000, 18000, 20000, 22000,
24000, 26000, 28000, 30000, 32000 };
for (i = 0;
i < static_cast<int> (sizeof(valid_rates) / sizeof(int));
i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
ANL();
} else if (_stricmp("amr-wb", cinst.plname) == 0) {
int valid_rates[9] = { 7000, 9000, 12000, 14000, 16000, 18000, 20000,
23000, 24000 };
for (i = 0;
i < static_cast<int> (sizeof(valid_rates) / sizeof(int));
i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
TEST_LOG(" <=> ");
ANL();
} else if (_stricmp("speex", cinst.plname) == 0) {
// Valid speex rates are > 2000, testing some of them here
int valid_rates[9] = { 2001, 4000, 7000, 11000, 15000, 20000, 25000,
33000, 46000 };
for (i = 0;
i < static_cast<int> (sizeof(valid_rates) / sizeof(int));
i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
cinst.rate = 2000; // invalid
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst))
{
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
ANL();
} else if (_stricmp("silk", cinst.plname) == 0) {
// Valid Silk rates are 6000 - 40000, listing some of them here
int valid_rates[7] = { 6000, 10000, 15000, 20000, 25000, 32000, 40000 };
for (i = 0;
i < static_cast<int> (sizeof(valid_rates) / sizeof(int));
i++) {
cinst.rate = valid_rates[i];
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
}
cinst.rate = 5999; // invalid
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst))
{
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
cinst.rate = 40001; // invalid
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst))
{
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
ANL();
} else {
// Use default rate for all other codecs.
cinst.rate = defaultCodec.rate;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_LOG("%d ", cinst.rate);
cinst.rate = defaultCodec.rate + 17;
TEST_MUSTPASS(!codec->SetSendCodec(0, cinst));
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
ANL();
}
cinst.rate = defaultCodec.rate;
// run some extra tests for L16
if (_stricmp("l16", cinst.plname) == 0) {
if (8000 == cinst.plfreq) {
// valid pacsizes: 80, 160, 240, 320
cinst.pacsize = 480; // only supported in combination with 16kHz
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst));
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
cinst.pacsize = 640; // only supported in combination with 16kHz
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst));
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
} else {
// valid pacsizes: 160, 320, 480, 640
cinst.pacsize = 80; // only supported in combination with 8kHz
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst));
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
cinst.pacsize = 240; // only supported in combination with 8kHz
TEST_MUSTPASS(-1 != codec->SetSendCodec(0, cinst));
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
}
}
ANL();
} // for (int index = 0; index < nCodecs; index++)
// restore PCMU
const CodecInst tmp = { 0, "PCMU", 8000, 160, 1, 64000 };
TEST_MUSTPASS(codec->SetSendCodec(0, tmp));
ANL();
AOK();
ANL();
///////
// VAD
const int VADSleep = 0;
bool disabledDTX;
VadModes mode;
bool enabled;
// verify default settings (should be OFF, kVadConventional and DTX enabled)
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(mode != kVadConventional);
TEST_MUSTPASS(disabledDTX != true);
// enable default VAD settings
TEST_MUSTPASS(codec->SetVADStatus(0, true));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(mode != kVadConventional);
TEST_MUSTPASS(disabledDTX != false);
SLEEP(VADSleep);
// set kVadConventional mode
TEST_MUSTPASS(codec->SetVADStatus(0, true, kVadConventional));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(mode != kVadConventional);
SLEEP(VADSleep);
// set kVadAggressiveLow mode
TEST_MUSTPASS(codec->SetVADStatus(0, true, kVadAggressiveLow));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(mode != kVadAggressiveLow);
SLEEP(VADSleep);
// set kVadAggressiveMid mode
TEST_MUSTPASS(codec->SetVADStatus(0, true, kVadAggressiveMid));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(mode != kVadAggressiveMid);
SLEEP(VADSleep);
// set kVadAggressiveMid mode
TEST_MUSTPASS(codec->SetVADStatus(0, true, kVadAggressiveHigh));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(mode != kVadAggressiveHigh);
SLEEP(VADSleep);
// turn DTX OFF (audio should not be affected by VAD decisions)
TEST_MUSTPASS(codec->SetVADStatus(0, true, kVadConventional, true));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(disabledDTX != true);
SLEEP(VADSleep);
// try to enable DTX again (should fail since VAD is disabled)
TEST_MUSTPASS(codec->SetVADStatus(0, false, kVadConventional, false));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(disabledDTX == false);
SLEEP(VADSleep);
// disable VAD
TEST_MUSTPASS(codec->SetVADStatus(0, false));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(enabled != false);
SLEEP(VADSleep);
// restore default VAD
TEST_MUSTPASS(codec->SetVADStatus(0, true));
TEST_MUSTPASS(codec->SetVADStatus(0, false));
TEST_MUSTPASS(codec->GetVADStatus(0, enabled, mode, disabledDTX));
TEST_LOG("VAD: enabled=%d, mode=%d, disabledDTX=%d\n", enabled, mode,
disabledDTX);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(mode != kVadConventional);
TEST_MUSTPASS(disabledDTX != true);
SLEEP(VADSleep);
AOK();
ANL();
ANL();
//////////////////////
// GetRecCodec
TEST(GetRecCodec);
ANL();
// stop all streaming first
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
// start loopback streaming (PCMU is default)
#ifndef WEBRTC_EXTERNAL_TRANSPORT
TEST_MUSTPASS(voe_base_->SetSendDestination(0,8000,"127.0.0.1"));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0,8000));
#endif
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(100); // ensure that at least one packets is received
// scan all supported and valid codecs
CodecInst newCodec;
for (i = 0; i < codec->NumOfCodecs(); i++) {
TEST_MUSTPASS(codec->GetCodec(i, newCodec));
// test all valid send codecs
if (!_stricmp("red", newCodec.plname) || !_stricmp("cn", newCodec.plname)
|| !_stricmp("telephone-event", newCodec.plname)) {
continue; // Ignore these
}
if (-1 != codec->SetSendCodec(0, newCodec)) {
SLEEP(150);
// verify correct detection
TEST_MUSTPASS(codec->GetRecCodec(0, cinst));
TEST_LOG("%s %s ", newCodec.plname, cinst.plname);
TEST_MUSTPASS(_stricmp(newCodec.plname, cinst.plname) != 0);
TEST_MUSTPASS(cinst.pltype != newCodec.pltype);
TEST_MUSTPASS(cinst.plfreq != newCodec.plfreq);
}
}
// stop streaming
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
ANL();
AOK();
ANL();
ANL();
#ifdef WEBRTC_CODEC_GSMAMR
//////////////////////////
// SetAMREncFormat
// Fresh channel
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST(SetAMREncFormat); ANL();
//set another codec which is not AMR
TEST_MUSTPASS(codec->GetCodec(0, cinst));
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
//try to change the encode format, tests should fail
TEST_MUSTPASS(-1 != codec->SetAMREncFormat(0)); MARK();
TEST_MUSTPASS(-1 != codec->SetAMREncFormat(0, kRfc3267BwEfficient));
MARK();
TEST_MUSTPASS(-1 != codec->SetAMREncFormat(0, kRfc3267OctetAligned));
MARK();
TEST_MUSTPASS(-1 != codec->SetAMREncFormat(0, kRfc3267FileStorage));
MARK();
//set AMR as encoder
strcpy(cinst.plname,"AMR");
cinst.channels=1; cinst.plfreq=8000; cinst.rate=12200; cinst.pltype=112;
cinst.pacsize=160;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
//try to change the encode format, tests should pass
TEST_MUSTPASS(codec->SetAMREncFormat(0)); MARK();
TEST_MUSTPASS(codec->SetAMREncFormat(0, kRfc3267BwEfficient)); MARK();
TEST_MUSTPASS(codec->SetAMREncFormat(0, kRfc3267OctetAligned)); MARK();
TEST_MUSTPASS(codec->SetAMREncFormat(0, kRfc3267FileStorage)); MARK();
TEST_MUSTPASS(-1 != codec->SetAMREncFormat(-1)); MARK();
TEST_MUSTPASS(codec->SetAMREncFormat(0)); MARK(); // restore default
ANL();
AOK();
ANL();
//////////////////////////
// SetAMRDecFormat
TEST(SetAMRDecFormat); ANL();
// It should not be possible to set AMR dec format before valid AMR decoder
// is registered
TEST_MUSTPASS(!codec->SetAMRDecFormat(0)); MARK();
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_AUDIO_CODING_MODULE_ERROR);
// Ensure that ACM::RegisterReceiveCodec(AMR) is called
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
// All these tests should now pass
TEST_MUSTPASS(codec->SetAMRDecFormat(0)); MARK();
TEST_MUSTPASS(codec->SetAMRDecFormat(0, kRfc3267BwEfficient)); MARK();
TEST_MUSTPASS(codec->SetAMRDecFormat(0, kRfc3267OctetAligned)); MARK();
TEST_MUSTPASS(codec->SetAMRDecFormat(0, kRfc3267FileStorage)); MARK();
TEST_MUSTPASS(-1 != codec->SetAMRDecFormat(-1)); MARK();
TEST_MUSTPASS(codec->SetAMRDecFormat(0)); MARK(); // restore default
ANL();
AOK();
ANL();
#endif // #ifdef WEBRTC_CODEC_GSMAMR
#ifdef WEBRTC_CODEC_GSMAMRWB
//////////////////////////
// SetAMRWbEncFormat
// Fresh channel
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST(SetAMRWbEncFormat); ANL();
//set another codec which is not AMR-wb
TEST_MUSTPASS(codec->GetCodec(0, cinst));
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
//try to change the encode format, tests should fail
TEST_MUSTPASS(-1 != codec->SetAMRWbEncFormat(0)); MARK();
TEST_MUSTPASS(-1 != codec->SetAMRWbEncFormat(0, kRfc3267BwEfficient));
MARK();
TEST_MUSTPASS(-1 != codec->SetAMRWbEncFormat(0, kRfc3267OctetAligned));
MARK();
TEST_MUSTPASS(-1 != codec->SetAMRWbEncFormat(0, kRfc3267FileStorage));
MARK();
//set AMR-wb as encoder
strcpy(cinst.plname,"AMR-WB");
cinst.channels=1; cinst.plfreq=16000; cinst.rate=20000;
cinst.pltype=112; cinst.pacsize=320;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
//try to change the encode format, tests should pass
TEST_MUSTPASS(codec->SetAMRWbEncFormat(0)); MARK();
TEST_MUSTPASS(codec->SetAMRWbEncFormat(0, kRfc3267BwEfficient)); MARK();
TEST_MUSTPASS(codec->SetAMRWbEncFormat(0, kRfc3267OctetAligned)); MARK();
TEST_MUSTPASS(codec->SetAMRWbEncFormat(0, kRfc3267FileStorage)); MARK();
TEST_MUSTPASS(-1 != codec->SetAMRWbEncFormat(-1)); MARK();
TEST_MUSTPASS(codec->SetAMRWbEncFormat(0)); MARK(); // restore default
ANL();
AOK();
ANL();
//////////////////////////
// SetAMRDecFormat
TEST(SetAMRWbDecFormat); ANL();
// It should not be possible to set AMR dec format before valid AMR decoder
// is registered
TEST_MUSTPASS(!codec->SetAMRWbDecFormat(0)); MARK();
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_AUDIO_CODING_MODULE_ERROR);
// Ensure that ACM::RegisterReceiveCodec(AMR) is called
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
// All these tests should now pass
TEST_MUSTPASS(codec->SetAMRWbDecFormat(0)); MARK();
TEST_MUSTPASS(codec->SetAMRWbDecFormat(0, kRfc3267BwEfficient)); MARK();
TEST_MUSTPASS(codec->SetAMRWbDecFormat(0, kRfc3267OctetAligned)); MARK();
TEST_MUSTPASS(codec->SetAMRWbDecFormat(0, kRfc3267FileStorage)); MARK();
TEST_MUSTPASS(-1 != codec->SetAMRWbDecFormat(-1)); MARK();
TEST_MUSTPASS(codec->SetAMRWbDecFormat(0)); MARK(); // restore default
ANL();
AOK();
ANL();
#endif // #ifdef WEBRTC_CODEC_GSMAMRWB
///////////////////////////////
// SetSendCNPayloadType
TEST(SetSendCNPayloadType);
ANL();
TEST_MUSTPASS(-1 != codec->SetSendCNPayloadType(-1, 0));
MARK(); // invalid channel
// Invalid payload range (only dynamic range [96,127]
TEST_MUSTPASS(-1 != codec->SetSendCNPayloadType(0, 0));
MARK(); // invalid PT
TEST_MUSTPASS(-1 != codec->SetSendCNPayloadType(0, 95));
MARK(); // invalid PT
TEST_MUSTPASS(-1 != codec->SetSendCNPayloadType(0, 128));
MARK(); // invalid PT
TEST_MUSTPASS(-1 != codec->SetSendCNPayloadType(0, -1));
MARK(); // invalid PT
// Not possible to change PT for 8000
TEST_MUSTPASS(!codec->SetSendCNPayloadType(0, 96, kFreq8000Hz));
MARK();
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_PLFREQ);
// Try some dynamic for 16000 and 32000 as well
TEST_MUSTPASS(codec->SetSendCNPayloadType(0, 96, kFreq16000Hz));
MARK();
TEST_MUSTPASS(codec->SetSendCNPayloadType(0, 96, kFreq32000Hz));
MARK(); // same should work
TEST_MUSTPASS(codec->SetSendCNPayloadType(0, 127, kFreq16000Hz));
MARK();
TEST_MUSTPASS(codec->SetSendCNPayloadType(0, 127, kFreq32000Hz));
MARK();
TEST_MUSTPASS(codec->SetSendCNPayloadType(0, 100, kFreq32000Hz));
MARK();
ANL();
AOK();
ANL();
/////////////////////////////
// SetRecPayloadType
TEST(SetRecPayloadType);
ANL();
// scan all supported and valid codecs without changing payloads
nCodecs = codec->NumOfCodecs();
for (i = 0; i < nCodecs; i++) {
TEST_MUSTPASS(codec->GetCodec(i, newCodec));
// If no default payload type is defined, we use 127
if (-1 == newCodec.pltype) {
newCodec.pltype = 127;
}
TEST_MUSTPASS(codec->SetRecPayloadType(0, newCodec));
MARK(); // use default
newCodec.pltype = 99;
TEST_MUSTPASS(codec->SetRecPayloadType(0, newCodec));
MARK(); // use same PT on all
newCodec.pltype = -1;
TEST_MUSTPASS(codec->SetRecPayloadType(0, newCodec));
MARK(); // deregister all PTs
}
ANL();
AOK();
ANL();
/////////////////////////////
// GetRecPayloadType
TEST(GetRecPayloadType);
ANL();
CodecInst extraCodec;
for (i = 0; i < nCodecs; i++) {
// Set defaults
TEST_MUSTPASS(codec->GetCodec(i, newCodec));
// If no default payload type is defined, we use 127
if (-1 == newCodec.pltype) {
newCodec.pltype = 127;
}
TEST_MUSTPASS(codec->SetRecPayloadType(0, newCodec));
//TEST_LOG("[%2d] %s (SetRec): fs=%d, pt=%d, rate=%d, ch=%d, size=%d\n",
// i, newCodec.plname, newCodec.plfreq, newCodec.pltype, newCodec.rate,
// newCodec.channels, newCodec.pacsize);
extraCodec.pltype = -1; // don't know this yet
extraCodec.plfreq = newCodec.plfreq;
extraCodec.rate = newCodec.rate;
extraCodec.channels = newCodec.channels;
strcpy(extraCodec.plname, newCodec.plname);
// Verfify that setting is OK
TEST_MUSTPASS(codec->GetRecPayloadType(0, extraCodec));
//TEST_LOG("[%2d] %s (GetRec): fs=%d, pt=%d, rate=%d, ch=%d, size=%d\n",
// i, extraCodec.plname, extraCodec.plfreq, extraCodec.pltype,
// extraCodec.rate, extraCodec.channels, extraCodec.pacsize);
TEST_MUSTPASS(newCodec.pltype != extraCodec.pltype);
TEST_MUSTPASS(newCodec.plfreq != extraCodec.plfreq);
TEST_MUSTPASS(newCodec.channels != extraCodec.channels);
}
AOK();
ANL();
////////////////////////////////////////////////////
// SetRecPayloadType - remove receive codecs
TEST(SetRecPayloadType - removing receive codecs);
ANL();
#ifndef WEBRTC_EXTERNAL_TRANSPORT
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
#endif
TEST_MUSTPASS(voe_base_->StartSend(0));
if (file) {
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0,
_mgr.AudioFilename(),
true,
true));
}
// Scan all supported and valid codecs and remove from receiving db, then
// restore
nCodecs = codec->NumOfCodecs();
for (i = 0; i < nCodecs; i++) {
TEST_MUSTPASS(codec->GetCodec(i, cinst));
if (!_stricmp("red", cinst.plname) || !_stricmp("cn", cinst.plname)
|| !_stricmp("telephone-event", cinst.plname)) {
continue; // Ignore these
}
TEST_LOG("Testing codec: %s", cinst.plname);
fflush(NULL);
if (-1 == cinst.pltype) {
// If no default payload type is defined, we use 127,
// codec is not registered for receiving
cinst.pltype = 127;
} else {
// Remove codec
memcpy(&extraCodec, &cinst, sizeof(CodecInst));
extraCodec.pltype = -1;
TEST_MUSTPASS(codec->SetRecPayloadType(0, extraCodec));
}
// Set send codec
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
// Verify no audio
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_LOG(" silence");
fflush(NULL);
SLEEP(800);
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
// Restore codec
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
// Verify audio
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_LOG(" audio");
fflush(NULL);
SLEEP(800);
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
if (127 == cinst.pltype) {
// If no default payload type is defined, i.e. we have set pt to
//127 above,
// make sure we remove codec from receiving
cinst.pltype = -1;
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
}
ANL();
}
// Remove certain codecs
TEST_LOG("Removing receive codecs:");
for (i = 0; i < nCodecs; i++) {
TEST_MUSTPASS(codec->GetCodec(i, cinst));
if (!_stricmp("ipcmwb", cinst.plname) || !_stricmp("pcmu", cinst.plname)
|| !_stricmp("eg711a", cinst.plname)) {
TEST_LOG(" %s", cinst.plname);
memcpy(&extraCodec, &cinst, sizeof(CodecInst));
extraCodec.pltype = -1;
TEST_MUSTPASS(codec->SetRecPayloadType(0, extraCodec));
}
}
ANL();
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
// Test sending all codecs - verify audio/no audio depending on codec
TEST_LOG("Looping through send codecs \n");
TEST_LOG("Verify that removed codecs are not audible and the other are \n");
for (i = 0; i < nCodecs; i++) {
TEST_MUSTPASS(codec->GetCodec(i, cinst));
if (!_stricmp("red", cinst.plname) || !_stricmp("cn", cinst.plname)
|| !_stricmp("telephone-event", cinst.plname)) {
continue; // Ignore these
}
TEST_LOG("Testing codec: %s \n", cinst.plname);
// If no default payload type is defined, we use 127 and set receive
// payload type
if (-1 == cinst.pltype) {
cinst.pltype = 127;
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
}
// Set send codec
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
// Verify audio/no audio
SLEEP(800);
}
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
// Restore codecs
TEST_LOG("Restoring receive codecs:");
for (i = 0; i < nCodecs; i++) {
TEST_MUSTPASS(codec->GetCodec(i, cinst));
if (!_stricmp("ipcmwb", cinst.plname) || !_stricmp("pcmu", cinst.plname)
|| !_stricmp("eg711a", cinst.plname)) {
TEST_LOG(" %s", cinst.plname);
memcpy(&extraCodec, &cinst, sizeof(CodecInst));
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
}
}
ANL();
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
// Test sending all codecs - verify audio
TEST_LOG("Looping through send codecs \n");
TEST_LOG("Verify that all codecs are audible \n");
for (i = 0; i < nCodecs; i++) {
TEST_MUSTPASS(codec->GetCodec(i, cinst));
if (!_stricmp("red", cinst.plname) || !_stricmp("cn", cinst.plname)
|| !_stricmp("telephone-event", cinst.plname)) {
continue; // Ignore these
}
TEST_LOG("Testing codec: %s \n", cinst.plname);
// If no default payload type is defined, we use 127 and set receive
// payload type
if (-1 == cinst.pltype) {
cinst.pltype = 127;
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
}
// Set send codec
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
// Verify audio/no audio
SLEEP(800);
}
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
// Fresh channel
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
#if defined(WEBRTC_CODEC_ISAC)
/////////////////////////////////////
// SetISACInitTargetRate - wb
TEST(SetISACInitTargetRate);
ANL();
// set PCMU as sending codec
cinst.channels = 1;
cinst.pacsize = 160;
cinst.plfreq = 8000;
strcpy(cinst.plname, "PCMU");
cinst.pltype = 0;
cinst.rate = 64000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, 10000));
MARK(); // should fail since iSAC is not active
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_CODEC_ERROR);
// set iSAC as sending codec (16kHz)
cinst.channels = 1;
cinst.plfreq = 16000;
strcpy(cinst.plname, "ISAC");
cinst.pltype = 103;
cinst.rate = -1; // adaptive rate
cinst.pacsize = 480; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACInitTargetRate(1, 10000));
MARK(); // invalid channel
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, 500));
MARK(); // invalid target rates (too small)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, 33000));
MARK(); // invalid target rates (too large)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 10000));
MARK(); // life is good now
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 0));
MARK(); // 0 is a valid rate
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 32000));
MARK(); // try max as well
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 32000, true));
MARK();
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 32000, false));
MARK();
cinst.pacsize = 960; // 60ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 32000, false));
MARK();
cinst.rate = 20000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, 32000));
MARK(); // only works in adaptive mode
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_AUDIO_CODING_MODULE_ERROR);
cinst.rate = -1;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 32000));
MARK(); // back to adaptive mode
ANL();
AOK();
ANL();
/////////////////////////////////////
// SetISACInitTargetRate - swb
TEST(ISACSWB SetISACInitTargetRate);
ANL();
// set iSAC as sending codec
cinst.channels = 1;
cinst.plfreq = 32000;
strcpy(cinst.plname, "ISAC");
cinst.pltype = 104;
cinst.rate = -1; // default rate
cinst.pacsize = 960; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACInitTargetRate(1, 10000));
MARK(); // invalid channel
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, -1));
MARK(); // invalid target rates (too small)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, -1));
MARK(); // invalid target rates (too small)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, 500));
MARK(); // invalid target rates (too small)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACInitTargetRate(0, 57000));
MARK(); // invalid target rates (valid range is [10000, 56000])
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 10000));
MARK();
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 0));
MARK();
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 56000));
MARK(); // try max as well
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 56000, true));
MARK();
TEST_MUSTPASS(codec->SetISACInitTargetRate(0, 56000, false));
MARK();
ANL();
AOK();
ANL();
////////////////////////////////
// SetISACMaxRate
TEST(SetISACMaxRate);
ANL();
// set PCMU as sending codec
cinst.channels = 1;
cinst.pacsize = 160;
cinst.plfreq = 8000;
strcpy(cinst.plname, "PCMU");
cinst.pltype = 0;
cinst.rate = 64000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 48000));
MARK(); // should fail since iSAC is not active
TEST_MUSTPASS(voe_base_->LastError() != VE_CODEC_ERROR);
// set iSAC as sending codec
cinst.channels = 1;
cinst.plfreq = 16000;
strcpy(cinst.plname, "ISAC");
cinst.pltype = 103;
cinst.rate = -1; // adaptive rate
cinst.pacsize = 480; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxRate(1, 48000));
MARK(); // invalid channel
TEST_MUSTPASS(voe_base_->LastError() != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 31900));
MARK(); // invalid target rates (too small)
TEST_MUSTPASS(voe_base_->LastError() != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 53500));
MARK(); // invalid target rates (too large)
TEST_MUSTPASS(voe_base_->LastError() != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACMaxRate(0, 32000));
MARK(); // life is good now
TEST_MUSTPASS(codec->SetISACMaxRate(0, 40000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 48000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 53400));
MARK(); // try max as well (default)
cinst.pacsize = 960; // 60ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(codec->SetISACMaxRate(0, 48000));
MARK();
cinst.rate = 20000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(codec->SetISACMaxRate(0, 40000));
MARK(); // also works in non-adaptive mode
ANL();
AOK();
ANL();
TEST(ISACSWB SetISACMaxRate);
ANL();
// set iSAC as sending codec
cinst.channels = 1;
cinst.plfreq = 32000;
strcpy(cinst.plname, "ISAC");
cinst.pltype = 104;
cinst.rate = 45000; // instantaneous mode
cinst.pacsize = 960; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxRate(1, 48000));
MARK(); // invalid channel
TEST_MUSTPASS(voe_base_->LastError() != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 31900));
MARK(); // invalid target rates (too small)
TEST_MUSTPASS(voe_base_->LastError() != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 107500));
MARK(); // invalid target rates (too large)
TEST_MUSTPASS(voe_base_->LastError() != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACMaxRate(0, 32000));
MARK(); // life is good now
TEST_MUSTPASS(codec->SetISACMaxRate(0, 40000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 55000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 80000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 107000));
MARK(); // try max as well (default)
cinst.rate = -1; // adaptive mode
cinst.pacsize = 960; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxRate(1, 48000));
MARK(); // invalid channel
TEST_MUSTPASS(voe_base_->LastError() != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 31900));
MARK(); // invalid target rates (too small)
TEST_MUSTPASS(voe_base_->LastError() != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACMaxRate(0, 107500));
MARK(); // invalid target rates (too large)
TEST_MUSTPASS(voe_base_->LastError() != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACMaxRate(0, 32000));
MARK(); // life is good now
TEST_MUSTPASS(codec->SetISACMaxRate(0, 40000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 55000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 80000));
MARK();
TEST_MUSTPASS(codec->SetISACMaxRate(0, 107000));
MARK(); // try max as well (default)
ANL();
AOK();
ANL();
////////////////////////////////
// SetISACMaxPayloadSize
TEST(SetISACMaxPayloadSize);
ANL();
// set PCMU as sending codec
cinst.channels = 1;
cinst.pacsize = 160;
cinst.plfreq = 8000;
strcpy(cinst.plname, "PCMU");
cinst.pltype = 0;
cinst.rate = 64000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(0, 120));
MARK(); // should fail since iSAC is not active
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_CODEC_ERROR);
// set iSAC as sending codec
cinst.channels = 1;
cinst.plfreq = 16000;
strcpy(cinst.plname, "ISAC");
cinst.pltype = 103;
cinst.rate = -1; // adaptive rate
cinst.pacsize = 480; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(1, 120));
MARK(); // invalid channel
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(0, 100));
MARK(); // invalid size (too small)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(0, 410));
MARK(); // invalid size (too large)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACMaxPayloadSize(0, 200));
MARK(); // life is good now
TEST_MUSTPASS(codec->SetISACMaxPayloadSize(0, 120));
MARK();
TEST_MUSTPASS(codec->SetISACMaxPayloadSize(0, 400));
MARK();
ANL();
AOK();
ANL();
TEST(ISACSWB SetISACMaxPayloadSize);
ANL();
// set iSAC as sending codec
cinst.channels = 1;
cinst.plfreq = 32000;
strcpy(cinst.plname, "ISAC");
cinst.pltype = 104;
cinst.rate = 45000; // default rate
cinst.pacsize = 960; // 30ms
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(1, 100));
MARK(); // invalid channel
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(0, 100));
MARK(); // invalid size (too small)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!codec->SetISACMaxPayloadSize(0, 610));
MARK(); // invalid size (too large)
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_INVALID_ARGUMENT);
TEST_MUSTPASS(codec->SetISACMaxPayloadSize(0, 200));
MARK(); // life is good now
TEST_MUSTPASS(codec->SetISACMaxPayloadSize(0, 120));
MARK();
TEST_MUSTPASS(codec->SetISACMaxPayloadSize(0, 600));
MARK();
ANL();
AOK();
ANL();
// set iSAC as sending codec
// set iSAC-wb as sending codec
#ifdef WEBRTC_EXTERNAL_TRANSPORT
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
#else
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8001, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8001));
#endif
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
0, GetFilename("audio_long16.pcm"), true , true));
cinst.channels = 1;
TEST_LOG("Testing codec: Switch between iSAC-wb and iSAC-swb \n");
TEST_LOG("Testing codec: iSAC wideband \n");
strcpy(cinst.plname, "ISAC");
cinst.pltype = 103;
cinst.rate = -1; // default rate
cinst.pacsize = 480; // 30ms
cinst.plfreq = 16000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
SLEEP(2000);
TEST_LOG(" : iSAC superwideband \n");
cinst.pltype = 104;
cinst.rate = -1; // default rate
cinst.pacsize = 960; // 30ms
cinst.plfreq = 32000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
SLEEP(2000);
TEST_LOG(" : iSAC wideband \n");
strcpy(cinst.plname, "ISAC");
cinst.pltype = 103;
cinst.rate = -1; // default rate
cinst.pacsize = 480; // 30ms
cinst.plfreq = 16000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
SLEEP(2000);
TEST_LOG(" : iSAC superwideband \n");
cinst.pltype = 104;
cinst.rate = -1; // default rate
cinst.pacsize = 960; // 30ms
cinst.plfreq = 32000;
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
SLEEP(2000);
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
#else
TEST_LOG("Skipping extended iSAC API tests - "
"WEBRTC_CODEC_ISAC not defined\n");
#endif // #if defined(WEBRTC_CODEC_ISAC)
#ifdef WEBRTC_EXTERNAL_TRANSPORT
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
delete ptrTransport;
#endif
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestDtmf
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestDtmf() {
PrepareTest("Dtmf");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEDtmf* dtmf = _mgr.DtmfPtr();
VoECodec* codec = _mgr.CodecPtr();
VoEVolumeControl* volume = _mgr.VolumeControlPtr();
//#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename("VoEDtmf_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
//#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
///////////////////////////
// Actual test starts here
// SetDtmfFeedbackStatus
TEST(SetDtmfFeedbackStatus & GetDtmfFeedbackStatus);
ANL();
bool dtmfFeedback = false, dtmfDirectFeedback = true;
TEST_MUSTPASS(dtmf->GetDtmfFeedbackStatus(dtmfFeedback,
dtmfDirectFeedback));
TEST_MUSTPASS(!dtmfFeedback);
TEST_MUSTPASS(dtmfDirectFeedback);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(false, false));
TEST_MUSTPASS(dtmf->GetDtmfFeedbackStatus(dtmfFeedback,
dtmfDirectFeedback));
TEST_MUSTPASS(dtmfFeedback);
TEST_MUSTPASS(dtmfDirectFeedback);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(false, true));
TEST_MUSTPASS(dtmf->GetDtmfFeedbackStatus(dtmfFeedback,
dtmfDirectFeedback));
TEST_MUSTPASS(dtmfFeedback);
TEST_MUSTPASS(!dtmfDirectFeedback);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(true, false));
TEST_MUSTPASS(dtmf->GetDtmfFeedbackStatus(dtmfFeedback,
dtmfDirectFeedback));
TEST_MUSTPASS(!dtmfFeedback);
TEST_MUSTPASS(dtmfDirectFeedback);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(true, true));
TEST_MUSTPASS(dtmf->GetDtmfFeedbackStatus(dtmfFeedback,
dtmfDirectFeedback));
TEST_MUSTPASS(!dtmfFeedback);
TEST_MUSTPASS(!dtmfDirectFeedback);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(false, false));
AOK();
ANL();
// SendDtmf
TEST(SendDtmf);
ANL();
// Fail tests
// Event
// the eventcode is changed to unsigned char, so -1 will be interpreted as
// 255, 256->0
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, -1, false, 160, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 16, false, 160, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
// Length
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 0, true, 99, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 0, true, 60001, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 20, true, -1, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
// Volume
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 0, true, 160, -1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 0, true, 160, 37));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
// Without sending
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(!dtmf->SendTelephoneEvent(0, 0, true));
MARK();
TEST_MUSTPASS(VE_NOT_SENDING != voe_base_->LastError());
TEST_MUSTPASS(voe_base_->StartSend(0));
// Testing Dtmf out-of-band: event, length and volume
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 16, true));
MARK();
SLEEP(500); // Flash, not audible
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 100, 10));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 400, 10));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 160, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 160, 36));
MARK();
SLEEP(500);
// Testing Dtmf inband: event, length and volume
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, false));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 15, false));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, false, 100, 10));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, false, 400, 10));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, false, 160, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, false, 160, 36));
MARK();
SLEEP(500);
// Testing other events out-of-band: event and length
// These are not audible
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 17, true, 100, 10));
MARK();
SLEEP(200);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 32, true, 100, 10));
MARK();
SLEEP(200);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 78, true, 100, 10));
MARK();
SLEEP(200);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 255, true, 100, 10));
MARK();
SLEEP(200);
// the minimum length is 100 for the telephoneevent
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 32, true, 100, 10));
MARK();
SLEEP(200);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 32, true, 1000, 10));
MARK();
SLEEP(1200);
AOK();
ANL();
// PlayDtmfTone
TEST(PlayDtmfTone);
ANL();
TEST_MUSTPASS(!dtmf->PlayDtmfTone(-1, 200, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->PlayDtmfTone(16, 200, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->PlayDtmfTone(0, 9, 10));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->PlayDtmfTone(0, 200, -1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!dtmf->PlayDtmfTone(0, 200, 37));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(dtmf->PlayDtmfTone(0));
MARK();
SLEEP(500);
// the minimum length fo the DtmfTone is 100
TEST_MUSTPASS(dtmf->PlayDtmfTone(0, 100, 10));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->PlayDtmfTone(0, 2000, 10));
MARK();
SLEEP(2300);
TEST_MUSTPASS(dtmf->PlayDtmfTone(0, 200, 0));
MARK();
SLEEP(500);
TEST_MUSTPASS(dtmf->PlayDtmfTone(0, 200, 36));
MARK();
SLEEP(500);
AOK();
ANL();
// SetTelephoneEventDetection
TEST(SetTelephoneEventDetection);
ANL();
AOK();
ANL();
// Testing sending Dtmf under VAD/CN
TEST(SendDtmf - with VAD enabled);
ANL();
// Mute mic
TEST_MUSTPASS(volume->SetInputMute(0, true));
MARK();
// Enable VAD
TEST_MUSTPASS(codec->SetVADStatus(0, true));
MARK();
// Send Dtmf
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 400));
MARK();
SLEEP(1000);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 9, true, 400));
MARK();
SLEEP(1000);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 400));
MARK();
SLEEP(1000);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 9, true, 400));
MARK();
SLEEP(1000);
// Switch codec
CodecInst ci;
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
ci.channels = 1;
ci.pacsize = 480;
ci.plfreq = 16000;
strcpy(ci.plname, "ISAC");
ci.pltype = 103;
ci.rate = -1;
#else
ci.pltype = 119;
strcpy(ci.plname, "isaclc");
ci.plfreq = 16000;
ci.pacsize = 320;
ci.channels = 1;
ci.rate = 40000;
#endif
TEST_MUSTPASS(codec->SetSendCodec(0, ci));
MARK();
// Send Dtmf
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 400));
MARK();
SLEEP(1000);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 9, true, 400));
MARK();
SLEEP(1000);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 0, true, 400));
MARK();
SLEEP(1000);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, 9, true, 400));
MARK();
SLEEP(1000);
SLEEP(4000);
// Disable VAD
TEST_MUSTPASS(codec->SetVADStatus(0, false));
MARK();
// Unmute
TEST_MUSTPASS(volume->SetInputMute(0, false));
MARK();
AOK();
ANL();
// SetSendTelephoneEventPayloadType
TEST(SetSendTelephoneEventPayloadType);
ANL();
TEST_MUSTPASS(!dtmf->SetSendTelephoneEventPayloadType(0, 128));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(dtmf->SetSendTelephoneEventPayloadType(0, 96));
MARK();
TEST_MUSTPASS(dtmf->SetSendTelephoneEventPayloadType(0, 127));
MARK();
TEST_MUSTPASS(dtmf->SetSendTelephoneEventPayloadType(0, 106));
MARK(); // restore default
AOK();
ANL();
#ifdef WEBRTC_DTMF_DETECTION
TEST(RegisterTelephoneEventDetection - several channels); ANL();
ci.channels = 1;
ci.pacsize = 160;
ci.plfreq = 8000;
ci.pltype = 0;
ci.rate = 64000;
strcpy(ci.plname, "PCMU");
TEST_MUSTPASS(codec->SetSendCodec(0, ci));
int ch2 = voe_base_->CreateChannel();
TEST_MUSTPASS(voe_base_->SetSendDestination(ch2, 8002, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch2, 8002));
TEST_MUSTPASS(voe_base_->StartReceive(ch2));
TEST_MUSTPASS(codec->SetSendCodec(ch2, ci));
TEST_MUSTPASS(voe_base_->StartPlayout(ch2));
TEST_MUSTPASS(voe_base_->StartSend(ch2));
MARK();
DtmfCallback *d = new DtmfCallback();
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(false));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
// In-band
TEST_MUSTPASS(dtmf->RegisterTelephoneEventDetection(0, kInBand, *d));
TEST_MUSTPASS(dtmf->RegisterTelephoneEventDetection(ch2, kInBand, *d));
TEST_LOG("\nSending in-band telephone events:");
for(int i = 0; i < 16; i++)
{
TEST_LOG("\n %d ", i); fflush(NULL);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, i, false, 160, 10));
TEST_MUSTPASS(dtmf->SendTelephoneEvent(ch2, i, false, 160, 10));
SLEEP(500);
}
TEST_LOG("\nDetected %d events \n", d->counter);
TEST_MUSTPASS(d->counter != 32);
TEST_MUSTPASS(dtmf->DeRegisterTelephoneEventDetection(0));
TEST_MUSTPASS(dtmf->DeRegisterTelephoneEventDetection(ch2));
// Out-of-band
d->counter = 0;
TEST_MUSTPASS(dtmf->RegisterTelephoneEventDetection(0, kOutOfBand, *d));
TEST_MUSTPASS(dtmf->RegisterTelephoneEventDetection(ch2, kOutOfBand, *d));
TEST_LOG("\nSending out-band telephone events:");
for(int i = 0; i < 16; i++)
{
TEST_LOG("\n %d ", i); fflush(NULL);
TEST_MUSTPASS(dtmf->SendTelephoneEvent(0, i, true, 160, 10));
TEST_MUSTPASS(dtmf->SendTelephoneEvent(ch2, i, true, 160, 10));
SLEEP(500);
}
TEST_LOG("\nDetected %d events \n", d->counter);
TEST_MUSTPASS(d->counter != 32);
TEST_MUSTPASS(dtmf->DeRegisterTelephoneEventDetection(0));
TEST_MUSTPASS(dtmf->DeRegisterTelephoneEventDetection(ch2));
delete d;
AOK(); ANL();
#endif
TEST_MUSTPASS(dtmf->SetDtmfFeedbackStatus(true, false));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestEncryption
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestEncryption() {
PrepareTest("Encryption");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEFile* file = _mgr.FilePtr();
VoEEncryption* encrypt = _mgr.EncryptionPtr();
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(
GetFilename("VoEEncryption_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
///////////////////////////
// Actual test starts here
unsigned char key1[30] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
#ifdef WEBRTC_SRTP
unsigned char key2[30]; // Different than key1 in first position
memcpy(key2, key1, 30);
key2[0] = 99;
unsigned char key3[30]; // Different than key1 in last position
memcpy(key3, key1, 30);
key3[29] = 99;
unsigned char key4[29]; // Same as key1 but shorter
memcpy(key4, key1, 29);
TEST(SRTP - Fail tests); ANL();
// Send
// Incorrect parameters when not all protection is enabled
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kNoProtection, key1));
TEST_MUSTPASS(VE_SRTP_ERROR != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kEncryption key1));
TEST_MUSTPASS(VE_SRTP_ERROR != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kAuthentication, key1));
TEST_MUSTPASS(VE_SRTP_ERROR != voe_base_->LastError());
MARK();
// Incorrect cipher key length
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 15,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 257,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherNull, 15, kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherNull, 257, kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// Incorrect auth key length
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 21, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthNull, 257, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// Incorrect auth tag length
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 21,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthNull, 20, 13,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// key NULL pointer
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, NULL));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// Same for receive
// Incorrect parameters when not all protection is enabled
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kNoProtection, key1));
TEST_MUSTPASS(VE_SRTP_ERROR != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kEncryption key1));
TEST_MUSTPASS(VE_SRTP_ERROR != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kAuthentication, key1));
TEST_MUSTPASS(VE_SRTP_ERROR != voe_base_->LastError());
MARK();
// Incorrect cipher key length
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 15,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 257,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherNull, 15,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherNull, 257,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// Incorrect auth key length
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode,
30, kAuthHmacSha1, 21, 4,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// it crashed the application
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthNull, 257, 4,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// Incorrect auth tag length
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 21,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// it crashed the application
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthNull, 20, 13,
kEncryptionAndAuthentication,
key1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// key NULL pointer
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
NULL));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
ANL();
TEST(SRTP - Should hear audio at all time); ANL();
// Authentication only
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherNull, 0, kAuthHmacSha1, 20,
4, kAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherNull, 0, kAuthHmacSha1,
20, 4, kAuthentication, key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
ANL();
// No protection
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherNull, 0, kAuthNull, 0, 0,
kNoProtection, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherNull, 0, kAuthNull, 0, 0,
kNoProtection, key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
// Encryption only
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0, kEncryption key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0,
kEncryption key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
// Authentication only
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherNull, 0, kAuthHmacSha1, 20,
4, kAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherNull, 0, kAuthHmacSha1,
20, 4, kAuthentication, key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
ANL();
// Switching between keys
TEST(SRTP - Different keys - should hear audio at all time); ANL();
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key2));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key2));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key2));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key2));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
ANL();
// Testing different keys that should be silent
TEST(SRTP - Should be silent or garbage); ANL();
// key1 and key2
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key2));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key2));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0, kEncryption key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0,
kEncryption key2));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherNull, 0, kAuthHmacSha1,
20, 4, kAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherNull, 0, kAuthHmacSha1,
20, 4, kAuthentication, key2));
MARK(); SLEEP(2000);
// key1 and key3
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key3));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key3));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0, kEncryption key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0,
kEncryption key3));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherNull, 0, kAuthHmacSha1, 20,
4, kAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherNull, 0, kAuthHmacSha1,
20, 4, kAuthentication, key3));
MARK(); SLEEP(2000);
// key1 and key4
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key4));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication, key4));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1, 20, 4,
kEncryptionAndAuthentication,
key1));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0, kEncryption key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthNull, 0, 0,
kEncryption key4));
MARK(); SLEEP(2000);
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherNull, 0, kAuthHmacSha1, 20,
4, kAuthentication, key1));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherNull, 0, kAuthHmacSha1,
20, 4, kAuthentication, key4));
MARK(); SLEEP(2000);
ANL();
// Back to normal
TEST(SRTP - Back to normal - should hear audio); ANL();
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
MARK(); SLEEP(2000);
ANL();
// SRTCP tests
TEST(SRTCP - Ignore voice or not); ANL();
VoERTP_RTCP* rtp_rtcp = _mgr.RTP_RTCPPtr();
char tmpStr[32];
// First test that RTCP packet is received and OK without encryption
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik1"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik1", tmpStr));
// Enable SRTP and SRTCP send and receive
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1, true));
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1, true));
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik2"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik2", tmpStr));
// Disable SRTP and SRTCP send
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik3"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik2", tmpStr)); // Should not have changed
// Enable SRTP send, but disable SRTCP send
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik4"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik2", tmpStr)); // Should not have changed
// Enable SRTP and SRTCP send, disable SRTP and SRTCP receive
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->EnableSRTPSend(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1, true));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik5"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik2", tmpStr)); // Should not have changed
// Enable SRTP receive, but disable SRTCP receive
TEST_MUSTPASS(encrypt->EnableSRTPReceive(0, kCipherAes128CounterMode, 30,
kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik6"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik2", tmpStr)); // Should not have changed
// Disable all
TEST_MUSTPASS(encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(rtp_rtcp->SetRTCP_CNAME(0, "Henrik7"));
MARK(); SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCP_CNAME(0, tmpStr));
TEST_MUSTPASS(_stricmp("Henrik7", tmpStr));
ANL();
#else
TEST(SRTP disabled - Fail tests);
ANL();
TEST_MUSTPASS(!encrypt->EnableSRTPSend(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
TEST_MUSTPASS(!encrypt->EnableSRTPReceive(0, kCipherNull, 30, kAuthHmacSha1,
20, 4, kEncryptionAndAuthentication, key1));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
TEST_MUSTPASS(!encrypt->DisableSRTPSend(0));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
TEST_MUSTPASS(!encrypt->DisableSRTPReceive(0));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
ANL();
#endif
AOK();
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestExternalMedia
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestExternalMedia() {
PrepareTest("VoEExternalMedia");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEExternalMedia* xmedia = _mgr.ExternalMediaPtr();
// check if this interface is supported
if (!xmedia) {
TEST_LOG("VoEExternalMedia is not supported!");
return -1;
}
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(
GetFilename("VoEExternalMedia_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(
kTraceStateInfo | kTraceStateInfo | kTraceWarning |
kTraceError | kTraceCritical | kTraceApiCall |
kTraceMemory | kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
int getLen = 0;
WebRtc_Word16 vector[32000];
memset(vector, 0, 32000 * sizeof(short));
#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
// ExternalPlayoutGetData
TEST(ExternalPlayoutGetData);
ANL();
TEST_MUSTPASS(!xmedia->SetExternalPlayoutStatus(true));
TEST_MUSTPASS(VE_ALREADY_SENDING != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalPlayoutGetData(vector, 16000, 100, getLen));
TEST_MUSTPASS(VE_INVALID_OPERATION != voe_base_->LastError());
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(xmedia->SetExternalPlayoutStatus(true));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(xmedia->ExternalPlayoutGetData(vector, 48000, 0, getLen));
TEST_MUSTPASS(480 != getLen);
SLEEP(10);
TEST_MUSTPASS(xmedia->ExternalPlayoutGetData(vector, 16000, 3000, getLen));
TEST_MUSTPASS(160 != getLen);
SLEEP(10);
TEST_MUSTPASS(!xmedia->ExternalPlayoutGetData(vector, 8000, 100, getLen));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalPlayoutGetData(vector, 16000, -1, getLen));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(xmedia->SetExternalPlayoutStatus(false));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
// SetExternalRecording
TEST(SetExternalRecording);
ANL();
TEST_MUSTPASS(!xmedia->SetExternalRecordingStatus(true));
TEST_MUSTPASS(VE_ALREADY_SENDING != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 160, 16000, 20));
TEST_MUSTPASS(VE_INVALID_OPERATION != voe_base_->LastError());
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(xmedia->SetExternalRecordingStatus(true));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(xmedia->ExternalRecordingInsertData(vector, 480, 48000, 0));
SLEEP(10);
TEST_MUSTPASS(xmedia->ExternalRecordingInsertData(vector, 640, 16000, 0));
SLEEP(40);
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 160, 16000, -1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 80, 8000, 20));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 0, 16000, 20));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 80, 16000, 20));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 500, 16000, 20));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(xmedia->SetExternalRecordingStatus(false));
TEST_MUSTPASS(voe_base_->StartSend(0));
#else // #ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
TEST_MUSTPASS(!xmedia->SetExternalPlayoutStatus(true));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalPlayoutGetData(vector, 16000, 100, getLen));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->SetExternalRecordingStatus(true));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
TEST_MUSTPASS(!xmedia->ExternalRecordingInsertData(vector, 160, 16000, 20));
TEST_MUSTPASS(VE_FUNC_NOT_SUPPORTED != voe_base_->LastError());
#endif // #ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
ANL();
AOK();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestFile
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestFile() {
PrepareTest("File");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEFile* file = _mgr.FilePtr();
VoECodec* codec = _mgr.CodecPtr();
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(
GetFilename("VoEFile_trace.txt"))); MARK();
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
///////////////////////////
// Actual test starts here
const int dT(100);
TEST(StartPlayingFileLocally);
ANL();
TEST(StopPlayingFileLocally);
ANL();
voe_base_->StopPlayout(0);
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm")));MARK();
voe_base_->StartPlayout(0);
MARK(); // file should be mixed in and played out
SLEEP(dT);
TEST_MUSTPASS(!file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm")));
MARK(); // should fail (must stop first)
TEST_MUSTPASS(voe_base_->LastError() != VE_ALREADY_PLAYING);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm")));
MARK(); // should work again (restarts file)
SLEEP(dT);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm"), false, kFileFormatPcm16kHzFile));
MARK();
SLEEP(dT);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long8.pcm"), false, kFileFormatPcm8kHzFile));
MARK();
SLEEP(dT);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.wav"), false, kFileFormatPcm8kHzFile));
MARK();
SLEEP(dT);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long8mulaw.wav"), false,
kFileFormatPcm8kHzFile));
MARK();
SLEEP(dT);
// add compressed tests here...
// TEST_MUSTPASS(file->StopPlayingFileLocally(0)); MARK();
// TEST_MUSTPASS(file->StartPlayingFileLocally(
// 0, GetResource("audio_short16.pcm"), true,
// kFileFormatPcm16kHzFile)); MARK(); // loop
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_short16.pcm"), false,
kFileFormatPcm16kHzFile, 1.0, 0, 2000));
MARK(); // play segment
SLEEP(2500);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(!file->StartPlayingFileLocally(
0, GetResource("audio_short16.pcm"), false,
kFileFormatPcm16kHzFile, 1.0, 2000, 1000));
MARK(); // invalid segment
TEST_MUSTPASS(voe_base_->LastError() != VE_BAD_FILE);
TEST_MUSTPASS(!file->StartPlayingFileLocally(
0, GetResource("audio_short16.pcm"), false,
kFileFormatPcm16kHzFile, 1.0, 21000, 30000));
MARK(); // start > file size
TEST_MUSTPASS(voe_base_->LastError() != VE_BAD_FILE);
TEST_MUSTPASS(!file->StartPlayingFileLocally(
0, GetResource("audio_short16.pcm"), false,
kFileFormatPcm16kHzFile, 1.0, 100, 100));
MARK(); // invalid segment
TEST_MUSTPASS(voe_base_->LastError() != VE_BAD_FILE);
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm")));
MARK(); // should work again (restarts file)
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
TEST_MUSTPASS(!file->StartPlayingFileLocally(0, (InStream*)NULL));
MARK(); // just do it
TEST_MUSTPASS(voe_base_->LastError() != VE_BAD_FILE);
AOK();
ANL();
TEST(IsPlayingFileLocally);
ANL();
TEST_MUSTPASS(0 != file->IsPlayingFileLocally(0));
MARK(); // inactive
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm")));
MARK();
TEST_MUSTPASS(1 != file->IsPlayingFileLocally(0));
MARK(); // active
AOK();
ANL();
TEST(ScaleLocalFilePlayout);
ANL();
TEST_MUSTPASS(file->ScaleLocalFilePlayout(0, 1.0));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->ScaleLocalFilePlayout(0, 0.0));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->ScaleLocalFilePlayout(0, 0.5));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->ScaleLocalFilePlayout(0, 0.25));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
MARK();
AOK();
ANL();
// Replace microphone with file and play out on remote side
// All channels, per channel
// Different mixing frequencies
TEST(StartPlayingFileAsMicrophone);
ANL();
TEST(IsPlayingFileAsMicrophone);
ANL();
TEST(ScaleFileAsMicrophonePlayout);
ANL();
CodecInst tempCodec;
for (int ch = -1; ch < 1; ++ch) // Channel -1 and 0
{
TEST_LOG("Testing channel = %d \n", ch);
for (int fs = 1; fs < 4; ++fs) // nb, wb and swb codecs
{
switch (fs) {
case 1: // nb
TEST_LOG("Testing with nb codec \n");
tempCodec.channels = 1;
tempCodec.pacsize = 160;
tempCodec.plfreq = 8000;
strcpy(tempCodec.plname, "PCMU");
tempCodec.pltype = 0;
tempCodec.rate = 64000;
break;
case 2: // wb
#ifdef WEBRTC_CODEC_ISAC
TEST_LOG("Testing with wb codec \n");
tempCodec.channels = 1;
tempCodec.pacsize = 480;
tempCodec.plfreq = 16000;
strcpy(tempCodec.plname, "ISAC");
tempCodec.pltype = 103;
tempCodec.rate = 32000;
break;
#else
TEST_LOG("NOT testing with wb codec - "
"WEBRTC_CODEC_ISAC not defined \n");
continue;
#endif
case 3: // swb
#ifdef WEBRTC_CODEC_PCM16
TEST_LOG("Testing with swb codec \n");
tempCodec.channels = 1;
tempCodec.pacsize = 640;
tempCodec.plfreq = 32000;
strcpy(tempCodec.plname, "L16");
tempCodec.pltype = 125;
tempCodec.rate = 512000;
break;
#else
TEST_LOG("NOT testing with swb codec -"
" WEBRTC_CODEC_PCM16 not defined \n");
continue;
#endif
}
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(codec->SetRecPayloadType(0, tempCodec));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(codec->SetSendCodec(0, tempCodec));
TEST_LOG("File 1 in 16 kHz no mix, 2 in 16 kHz mix,"
" 3 in 8 kHz no mix, 4 in 8 kHz mix \n");
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
ch, GetResource("audio_long16.pcm")));
MARK(); // don't mix
SLEEP(2000);
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(ch));
MARK();
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
ch, GetResource("audio_long16.wav"), false, true,
kFileFormatWavFile));
MARK(); // mix
SLEEP(2000);
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(ch));
MARK();
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
ch, GetResource("audio_long8.pcm"), false, false,
kFileFormatPcm8kHzFile));
MARK(); // don't mix
SLEEP(2000);
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(ch));
MARK();
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
ch, GetResource("audio_long8.pcm"), false, true,
kFileFormatPcm8kHzFile));
MARK(); // mix
SLEEP(2000);
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(ch));
MARK();
TEST_MUSTPASS(!file->StartPlayingFileAsMicrophone(
ch, (InStream*)NULL));
MARK(); // force error
AOK();
ANL();
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
ch, GetResource("audio_long16.pcm")));
TEST_MUSTPASS(1 != file->IsPlayingFileAsMicrophone(ch));
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(ch));
TEST_MUSTPASS(0 != file->IsPlayingFileAsMicrophone(ch));
AOK();
ANL();
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
ch, GetResource("audio_long16.pcm")));
TEST_MUSTPASS(file->ScaleFileAsMicrophonePlayout(ch, 1.0));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->ScaleFileAsMicrophonePlayout(ch, 0.5));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->ScaleFileAsMicrophonePlayout(ch, 0.25));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->ScaleFileAsMicrophonePlayout(ch, 0.0));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(ch));
MARK();
AOK();
ANL();
}
}
// Record speaker signal to file
CodecInst fcomp = { 0, "L16", 8000, 80, 1, 128000 };
TEST(StartRecordingPlayout);
ANL();
TEST(StopRecordingPlayout);
ANL();
TEST_MUSTPASS(file->StartRecordingPlayout(0,
GetFilename("rec_play16.pcm")));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(0));
MARK();
fcomp.plfreq = 8000;
strcpy(fcomp.plname, "L16");
TEST_MUSTPASS(file->StartRecordingPlayout(0, GetFilename("rec_play8.wav"),
&fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(0));
MARK();
fcomp.plfreq = 16000;
strcpy(fcomp.plname, "L16");
TEST_MUSTPASS(file->StartRecordingPlayout(0, GetFilename("rec_play16.wav"),
&fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(0));
MARK();
fcomp.pltype = 0;
fcomp.plfreq = 8000;
strcpy(fcomp.plname, "PCMU");
fcomp.rate = 64000;
fcomp.pacsize = 160;
fcomp.channels = 1;
TEST_MUSTPASS(file->StartRecordingPlayout(0,
GetFilename("rec_play_pcmu.wav"),
&fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(0));
MARK();
fcomp.pltype = 8;
fcomp.plfreq = 8000;
strcpy(fcomp.plname, "PCMA");
TEST_MUSTPASS(file->StartRecordingPlayout(0,
GetFilename("rec_play_pcma.wav"),
&fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(0));
MARK();
fcomp.pltype = 97;
fcomp.pacsize = 240;
fcomp.rate = 13300;
fcomp.plfreq = 8000;
strcpy(fcomp.plname, "ILBC");
TEST_MUSTPASS(file->StartRecordingPlayout(0,
GetFilename("rec_play.ilbc"),
&fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(0));
MARK();
TEST_MUSTPASS(file->StartRecordingPlayout(
-1, GetFilename("rec_play16_mixed.pcm")));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingPlayout(-1));
MARK();
// TEST_MUSTPASS(file->StopPlayingFileLocally(0)); // Why should this work?
TEST_LOG("\nplaying out...\n");
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetFilename("rec_play.ilbc"), false, kFileFormatCompressedFile));
MARK();
SLEEP(2000);
AOK();
ANL();
// Record microphone signal to file
TEST(StartRecordingMicrophone);
ANL();
TEST(StopRecordingMicrophone);
ANL();
TEST_MUSTPASS(file->StartRecordingMicrophone(GetFilename("rec_mic16.pcm")));
MARK();
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
voe_base_->StopSend(0);
TEST_MUSTPASS(file->StartRecordingMicrophone(GetFilename("rec_mic16.pcm")));
MARK(); // record without sending as well
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
voe_base_->StartSend(0); // restore sending
fcomp.plfreq = 8000;
strcpy(fcomp.plname, "L16");
TEST_MUSTPASS(file->StartRecordingMicrophone(
GetFilename("rec_play8.wav"), &fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
fcomp.plfreq = 16000;
strcpy(fcomp.plname, "L16");
TEST_MUSTPASS(file->StartRecordingMicrophone(
GetFilename("rec_play16.wav"), &fcomp));
SLEEP(1000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
// FT#1810, the following test is to make sure StartRecordingCall will
// record both mic and file
TEST_LOG("StartRecordingCall, record both mic and file in specific"
" channels \n");
TEST_LOG("Create maxnumofchannels \n");
for (int i = 1; i < voe_base_->MaxNumOfChannels(); i++) {
int ch = voe_base_->CreateChannel();
TEST_MUSTPASS(ch == -1);
TEST_MUSTPASS(voe_base_->StopPlayout(ch));
}
TEST_MUSTPASS(voe_base_->SetSendDestination(1, 12356, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(1, 12356));
TEST_MUSTPASS(voe_base_->StartReceive(1));
TEST_MUSTPASS(voe_base_->StopPlayout(1));
TEST_MUSTPASS(voe_base_->StartSend(1));
TEST_MUSTPASS(voe_base_->StartPlayout(1));
TEST_LOG("ALways playing audio_long16.pcm for "
"channel 0 in background \n");
fcomp.plfreq = 16000;
strcpy(fcomp.plname, "L16");
TEST_LOG("Recording microphone to L16, please speak \n");
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
0, GetResource("audio_long16.pcm"), true , true));
TEST_MUSTPASS(file->StartRecordingMicrophone(
GetFilename("rec_play_ch.wav"), &fcomp));
MARK();
SLEEP(3000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
TEST_LOG("Playing recording file, you should only hear what you said \n");
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetFilename("rec_play_ch.wav"), false, kFileFormatWavFile));
SLEEP(2500);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
TEST_LOG("Recording microphone 0 to L16, please speak \n");
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
-1, GetResource("audio_long16.pcm"), true , true));
TEST_MUSTPASS(file->StartRecordingMicrophone(
GetFilename("rec_play_ch_0.wav"), &fcomp));
MARK();
SLEEP(3000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(-1));
TEST_LOG("Playing recording file, you should hear what you said and"
" audio_long16.pcm \n");
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetFilename("rec_play_ch_0.wav"), false, kFileFormatWavFile));
SLEEP(2500);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
TEST_LOG("Recording microphone to ilbc, please speak \n");
strcpy(fcomp.plname, "ilbc");
fcomp.plfreq = 8000;
fcomp.pacsize = 160;
fcomp.rate = 15200;
fcomp.channels = 1;
fcomp.pltype = 97;
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(
0, GetResource("audio_long16.pcm"), true , true));
TEST_MUSTPASS(file->StartRecordingMicrophone(
GetFilename("rec_play_ch_0.ilbc"), &fcomp));
MARK();
SLEEP(3000);
TEST_MUSTPASS(file->StopRecordingMicrophone());
MARK();
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
TEST_LOG("Playing recording file, you should only hear what you said \n");
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetFilename("rec_play_ch_0.ilbc"), false,
kFileFormatCompressedFile));
SLEEP(2500);
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
for (int i = 1; i < voe_base_->MaxNumOfChannels(); i++) {
TEST_MUSTPASS(voe_base_->DeleteChannel(i));
}
AOK();
ANL();
// Record mixed (speaker + microphone) signal to file
#if !defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID)
TEST(StartRecordingSpeakerStereo);
ANL();
TEST(StopRecordingSpeakerStereo);
ANL();
VoEHardware* hardware = _mgr.HardwarePtr();
TEST_MUSTPASS(NULL == hardware);
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
#if defined(_WIN32)
TEST_MUSTPASS(hardware->SetRecordingDevice(-1));
TEST_MUSTPASS(hardware->SetPlayoutDevice(-1));
#else
TEST_MUSTPASS(hardware->SetRecordingDevice(0));
TEST_MUSTPASS(hardware->SetPlayoutDevice(0));
#endif
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
MARK();
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
#if defined(_WIN32)
TEST_MUSTPASS(hardware->SetRecordingDevice(-1));
TEST_MUSTPASS(hardware->SetPlayoutDevice(-1));
#else
TEST_MUSTPASS(hardware->SetRecordingDevice(0));
TEST_MUSTPASS(hardware->SetPlayoutDevice(0));
#endif
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
AOK();
ANL();
#else
TEST_LOG("Skipping stereo record tests -"
" MAC_IPHONE or WEBRTC_ANDROID is defined \n");
#endif // #if !defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID)
// Conversion between different file formats
#if defined(MAC_IPHONE) || defined(WEBRTC_ANDROID)
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
#endif
TEST(ConvertPCMToWAV);
ANL();
TEST_MUSTPASS(file->ConvertPCMToWAV(
GetResource("audio_long16.pcm"),
GetFilename("singleUserDemoConv.wav")));
MARK();
TEST_MUSTPASS(!file->ConvertPCMToWAV((InStream*)NULL,
(OutStream*)NULL));MARK(); // invalid stream handles
AOK();
ANL();
TEST(ConvertWAVToPCM);
ANL();
TEST_MUSTPASS(file->ConvertWAVToPCM(
GetResource("audio_long16.wav"),
GetFilename("singleUserDemoConv.pcm")));
MARK();
TEST_MUSTPASS(!file->ConvertWAVToPCM((InStream*)NULL, (OutStream*)NULL));
MARK(); // invalid stream handles
AOK();
ANL();
TEST(ConvertPCMToCompressed);
ANL();
fcomp.plfreq = 16000;
strcpy(fcomp.plname, "L16");
TEST_MUSTPASS(!file->ConvertPCMToCompressed(
GetResource("audio_long16.pcm"),
GetFilename("singleUserDemoConv16_dummy.wav"), &fcomp));
MARK(); // should not be supported
fcomp.plfreq = 8000;
strcpy(fcomp.plname, "ilbc");
fcomp.pacsize = 160;
fcomp.rate = 15200;
fcomp.pltype = 97;
fcomp.channels = 1;
TEST_MUSTPASS(file->ConvertPCMToCompressed(
GetResource("audio_long16.pcm"),
GetFilename("singleUserDemoConv.ilbc"), &fcomp));MARK();
AOK();ANL();
TEST(ConvertCompressedToPCM);
ANL();
TEST_MUSTPASS(file->ConvertCompressedToPCM(
GetFilename("singleUserDemoConv.ilbc"),
GetFilename("singleUserDemoConv_ilbc.pcm")));MARK();
TEST_MUSTPASS(!file->ConvertCompressedToPCM(
GetResource("audio_long16.pcm"),
GetFilename("singleUserDemoConv_dummy.pcm")));MARK();
AOK();ANL();
#if defined(MAC_IPHONE) || defined(WEBRTC_ANDROID)
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
#endif
// Misc file functions
TEST(GetFileDuration);
ANL();
int dur;
TEST_MUSTPASS(file->GetFileDuration(
GetResource("audio_long16.pcm"), dur));
TEST_MUSTPASS(file->GetFileDuration(
GetResource("audio_long8.pcm"), dur, kFileFormatPcm8kHzFile));
TEST_MUSTPASS(file->GetFileDuration(
GetResource("audio_long16.pcm"), dur, kFileFormatPcm16kHzFile));
TEST_MUSTPASS(file->GetFileDuration(
GetResource("audio_long16.wav"), dur, kFileFormatPcm8kHzFile));
TEST_MUSTPASS(file->GetFileDuration(
GetFilename("singleUserDemoConv.ilbc"), dur,
kFileFormatCompressedFile));
AOK();
ANL();
TEST(GetPlaybackPosition);
ANL();
int pos;
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource("audio_long16.pcm")));
SLEEP(1000);
TEST_MUSTPASS(file->GetPlaybackPosition(0, pos));
MARK(); // position should be ~1000
SLEEP(1000);
TEST_MUSTPASS(file->GetPlaybackPosition(0, pos));
MARK(); // position should be ~2000
// SLEEP(70*1000);
// file is no longer playing
// TEST_MUSTPASS(file->GetPlaybackPosition(0, pos)); MARK();
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
AOK();
ANL();
// These tests are related to defect 5136
// They play .wav files with different sample freq for 5s
char localFiles[7][50] = { "audio_tiny8.wav", "audio_tiny11.wav",
"audio_tiny16.wav", "audio_tiny22.wav", "audio_tiny32.wav",
"audio_tiny44.wav", "audio_tiny48.wav" };
char freq[7][5] = { "8", "11", "16", "22", "32", "44.1", "48" };
TEST_MUSTPASS(voe_base_->StopReceive(0));
for (int i = 0; i < 7; i++) {
TEST_LOG("Playing file %s, in %s KHz \n", localFiles[i], freq[i]);
TEST_MUSTPASS(file->StartPlayingFileLocally(
0, GetResource(localFiles[i]),false, kFileFormatWavFile, 1));
SLEEP(4500); // The file should not end
TEST_MUSTPASS(file->StopPlayingFileLocally(0));
}
// TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0)); // Should not work
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
AOK();
ANL();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestMixing
// ----------------------------------------------------------------------------
// Creates and mixes |num_channels| with a constant amplitude of |input_value|.
// The mixed output is verified to always fall between |max_output_value| and
// |min_output_value|, after a startup phase.
int VoEExtendedTest::RunMixingTest(int num_channels,
int16_t input_value,
int16_t max_output_value,
int16_t min_output_value) {
VoEBase* voe_base_ = _mgr.BasePtr();
VoEFile* file = _mgr.FilePtr();
VoECodec* codec = _mgr.CodecPtr();
VoEAudioProcessing* apm = _mgr.APMPtr();
// Use L16 at 16kHz to minimize distortion (file recording is 16kHz
// and resampling will cause large distortions).
CodecInst codec_inst;
strcpy(codec_inst.plname, "L16");
codec_inst.channels = 1;
codec_inst.rate = 256000;
codec_inst.plfreq = 16000;
codec_inst.pltype = 105;
codec_inst.pacsize = 160;
apm->SetNsStatus(false);
apm->SetAgcStatus(false);
apm->SetEcStatus(false);
const char file_to_generate_name[] = "dc_file.pcm";
const char* input_filename = file_to_generate_name;
FILE* file_to_generate = fopen(file_to_generate_name, "wb");
ASSERT_TRUE(file_to_generate != NULL);
for (int i = 0; i < 160 * 100 * 5; i++) {
fwrite(&input_value, sizeof(input_value), 1, file_to_generate);
}
fclose(file_to_generate);
TEST_MUSTPASS(voe_base_->Init());
std::vector<int> channels(num_channels);
for (int channel_index = 0; channel_index < num_channels; ++channel_index) {
const int channel = voe_base_->CreateChannel();
channels[channel_index] = channel;
ASSERT_TRUE(channel != -1);
TEST_MUSTPASS(codec->SetRecPayloadType(channel, codec_inst));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(channel,
1234 + 2 * channel_index));
TEST_MUSTPASS(voe_base_->SetSendDestination(channel,
1234 + 2 * channel_index,
"127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(channel));
TEST_MUSTPASS(voe_base_->StartPlayout(channel));
TEST_MUSTPASS(codec->SetSendCodec(channel, codec_inst));
TEST_MUSTPASS(voe_base_->StartSend(channel));
}
for (int channel_index = 0; channel_index < num_channels; ++channel_index) {
const int channel = channels[channel_index];
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(channel,
input_filename,
true));
}
const char mix_result[] = "mix_result.pcm";
TEST_MUSTPASS(file->StartRecordingPlayout(-1/*record meeting*/,
mix_result));
TEST_LOG("Playing %d channels\n", num_channels);
SLEEP(5000);
TEST_MUSTPASS(file->StopRecordingPlayout(-1));
TEST_LOG("Stopping\n");
for (int channel_index = 0; channel_index < num_channels; ++channel_index) {
const int channel = channels[channel_index];
channels[channel_index] = channel;
TEST_MUSTPASS(voe_base_->StopSend(channel));
TEST_MUSTPASS(voe_base_->StopPlayout(channel));
TEST_MUSTPASS(voe_base_->StopReceive(channel));
TEST_MUSTPASS(voe_base_->DeleteChannel(channel));
}
FILE* verification_file = fopen(mix_result, "rb");
ASSERT_TRUE(verification_file != NULL);
int16_t mix_value = 0;
// Skip the first 100 ms to avoid initialization and ramping-in effects.
ASSERT_TRUE(fseek(verification_file, sizeof(int16_t) * 1600, SEEK_SET) == 0);
while (fread(&mix_value, sizeof(mix_value), 1, verification_file)) {
ASSERT_TRUE(mix_value <= max_output_value)
ASSERT_TRUE(mix_value >= min_output_value);
}
fclose(verification_file);
return 0;
}
// TODO(andrew): move or copy these to the mixer module test when possible.
int VoEExtendedTest::TestMixing() {
// These tests assume a maxmium of three mixed participants. We allow a
// +/- 10% range around the expected output level to accout for distortion
// from coding and processing in the loopback chain.
// Create four channels and make sure that only three are mixed.
TEST_LOG("Test max-three-participant mixing.\n");
int16_t input_value = 1000;
int16_t expected_output = input_value * 3;
if (RunMixingTest(4, input_value, 1.1 * expected_output,
0.9 * expected_output) != 0) {
return -1;
}
// Ensure the mixing saturation protection is working. We can do this because
// the mixing limiter is given some headroom, so the expected output is less
// than full scale.
TEST_LOG("Test mixing saturation protection.\n");
input_value = 20000;
expected_output = 29204; // = -1 dBFS, the limiter headroom.
// If this isn't satisfied, we're not testing anything.
assert(input_value * 3 > 32767);
assert(1.1 * expected_output < 32767);
if (RunMixingTest(3, input_value, 1.1 * expected_output,
0.9 * expected_output) != 0) {
return -1;
}
// Ensure the mixing saturation protection is not applied when only using a
// single channel.
TEST_LOG("Test saturation protection has no effect on one channel.\n");
input_value = 32767;
expected_output = 32767;
// If this isn't satisfied, we're not testing anything.
assert(0.95 * expected_output > 29204); // = -1 dBFS, the limiter headroom.
if (RunMixingTest(1, input_value, expected_output,
0.95 * expected_output) != 0) {
return -1;
}
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestHardware
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestHardware() {
PrepareTest("Hardware");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEHardware* hardware = _mgr.HardwarePtr();
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(
"VoEHardware_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
// Set/GetAudioDeviceLayer
TEST(Set/GetAudioDeviceLayer);
ANL();
AudioLayers wantedLayer = kAudioPlatformDefault;
AudioLayers givenLayer;
#if defined(_WIN32)
wantedLayer = kAudioWindowsCore;
hardware->SetAudioDeviceLayer(wantedLayer);
TEST_LOG("If you run on XP or below, CoreAudio "
"should not be able to set.\n");
TEST_LOG("If you run on Vista or above, CoreAudio "
"should be able to set.\n");
TEST_LOG("Verify that this is the case.\n");
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(hardware->GetAudioDeviceLayer(givenLayer));
if(givenLayer == kAudioWindowsCore)
{
TEST_LOG("CoreAudio was set\n");
}
else
{
TEST_LOG("CoreAudio was *not* set\n");
}
TEST_MUSTPASS(voe_base_->Terminate());
wantedLayer = kAudioWindowsWave;
TEST_MUSTPASS(hardware->SetAudioDeviceLayer(wantedLayer));
TEST_LOG("Wave audio should always be able to set.\n");
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(hardware->GetAudioDeviceLayer(givenLayer));
if(givenLayer == kAudioWindowsWave)
{
TEST_LOG("Wave audio was set\n");
}
else
{
TEST_LOG("Wave audio was not set\n");
}
TEST_MUSTPASS(voe_base_->Terminate());
// end _WIN32
#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
wantedLayer = kAudioLinuxPulse;
TEST_MUSTPASS(hardware->SetAudioDeviceLayer(wantedLayer));
TEST_LOG("If you run on Linux with no/unsupported PA version, PulseAudio "
"7should not be able to set.\n");
TEST_LOG("If you run on Linux with supported PA version running, PulseAudio"
" should be able to set.\n");
TEST_LOG("Verify that this is the case.\n");
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(hardware->GetAudioDeviceLayer(givenLayer));
if(givenLayer == kAudioLinuxPulse)
{
TEST_LOG("\nPulseAudio was set\n");
}
else
{
TEST_LOG("\nPulseAudio was not set\n");
}
TEST_MUSTPASS(voe_base_->Terminate());
wantedLayer = kAudioLinuxAlsa;
TEST_MUSTPASS(hardware->SetAudioDeviceLayer(wantedLayer));
TEST_LOG("ALSA audio should always be able to set.\n");
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(hardware->GetAudioDeviceLayer(givenLayer));
if(givenLayer == kAudioLinuxAlsa)
{
TEST_LOG("\nALSA audio was set\n");
}
else
{
TEST_LOG("\nALSA audio was not set\n");
}
TEST_MUSTPASS(voe_base_->Terminate());
#endif // defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
// Invalid arguments
wantedLayer = (AudioLayers) 17;
TEST_MUSTPASS(-1 != hardware->SetAudioDeviceLayer(wantedLayer));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
// Basic usage
wantedLayer = kAudioPlatformDefault;
TEST_MUSTPASS(hardware->SetAudioDeviceLayer(wantedLayer));
TEST_MUSTPASS(hardware->GetAudioDeviceLayer(givenLayer));
TEST_MUSTPASS(givenLayer != wantedLayer);
MARK();
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
wantedLayer = kAudioPlatformDefault;
TEST_MUSTPASS(-1 != hardware->SetAudioDeviceLayer(wantedLayer));
TEST_MUSTPASS(VE_ALREADY_INITED != voe_base_->LastError());
MARK();
TEST_MUSTPASS(hardware->GetAudioDeviceLayer(givenLayer));
MARK();
switch (givenLayer) {
case kAudioPlatformDefault:
// already set above
break;
case kAudioWindowsCore:
TEST_LOG("\nRunning kAudioWindowsCore\n");
break;
case kAudioWindowsWave:
TEST_LOG("\nRunning kAudioWindowsWave\n");
break;
case kAudioLinuxAlsa:
TEST_LOG("\nRunning kAudioLinuxAlsa\n");
break;
case kAudioLinuxPulse:
TEST_LOG("\nRunning kAudioLinuxPulse\n");
break;
default:
TEST_LOG("\nERROR: Running unknown audio layer!!\n");
return -1;
}
ANL();
#if !defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID)
// GetRecording/PlayoutDeviceStatus
TEST(Getrecording/PlayoutDeviceStatus);
ANL();
bool isRecAvailable = false;
bool isPlayAvailable = false;
TEST_MUSTPASS(hardware->GetRecordingDeviceStatus(isRecAvailable));
TEST_MUSTPASS(!isRecAvailable);
MARK();
TEST_MUSTPASS(hardware->GetPlayoutDeviceStatus(isPlayAvailable));
TEST_MUSTPASS(!isPlayAvailable);
MARK();
ANL();
int nRec = 0, nPlay = 0;
char devName[128];
char guidName[128];
int idx;
TEST_MUSTPASS(hardware->GetNumOfPlayoutDevices(nPlay));
// GetPlayoutDeviceName
TEST(GetPlayoutDeviceName);
ANL();
TEST_MUSTPASS(-1 != hardware->GetPlayoutDeviceName(nPlay, devName,
guidName));
TEST_MUSTPASS(VE_CANNOT_RETRIEVE_DEVICE_NAME != voe_base_->LastError());
MARK();
TEST_MUSTPASS(-1 != hardware->GetPlayoutDeviceName(-2, devName, guidName));
TEST_MUSTPASS(VE_CANNOT_RETRIEVE_DEVICE_NAME != voe_base_->LastError());
MARK();
TEST_MUSTPASS(-1 != hardware->GetPlayoutDeviceName(nPlay+1, devName,
guidName));
TEST_MUSTPASS(VE_CANNOT_RETRIEVE_DEVICE_NAME != voe_base_->LastError());
MARK();
TEST_MUSTPASS(-1 != hardware->GetPlayoutDeviceName(0, NULL, guidName));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(hardware->GetPlayoutDeviceName(0, devName, NULL));
// default tests
for (idx = 0; idx < nPlay; idx++) {
TEST_MUSTPASS(hardware->GetPlayoutDeviceName(idx, devName, guidName));
MARK();
TEST_MUSTPASS(hardware->SetPlayoutDevice(idx));
}
ANL();
TEST_MUSTPASS(hardware->GetNumOfRecordingDevices(nRec));
// GetRecordingDeviceName
TEST(GetRecordingDeviceName);
ANL();
TEST_MUSTPASS(-1 != hardware->GetRecordingDeviceName(nRec, devName,
guidName));
TEST_MUSTPASS(VE_CANNOT_RETRIEVE_DEVICE_NAME != voe_base_->LastError());
MARK();
TEST_MUSTPASS(-1 != hardware->GetRecordingDeviceName(-2, devName, guidName));
TEST_MUSTPASS(VE_CANNOT_RETRIEVE_DEVICE_NAME != voe_base_->LastError());
MARK();
TEST_MUSTPASS(-1 != hardware->GetRecordingDeviceName(nRec+1, devName,
guidName));
TEST_MUSTPASS(VE_CANNOT_RETRIEVE_DEVICE_NAME != voe_base_->LastError());
MARK();
TEST_MUSTPASS(-1 != hardware->GetRecordingDeviceName(0, NULL, guidName));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(hardware->GetRecordingDeviceName(0, devName, NULL));
// default tests
for (idx = 0; idx < nRec; idx++) {
TEST_MUSTPASS(hardware->GetRecordingDeviceName(idx, devName, guidName));
MARK();
TEST_MUSTPASS(hardware->SetRecordingDevice(idx));
}
ANL();
// // SetRecordingDevice
TEST(SetRecordingDevice);
ANL();
TEST_MUSTPASS(hardware->SetRecordingDevice(0));
MARK();
TEST_MUSTPASS(hardware->SetRecordingDevice(0, kStereoLeft));
MARK();
TEST_MUSTPASS(hardware->SetRecordingDevice(0, kStereoRight));
MARK();
ANL();
// SetPlayoutDevice
TEST(SetPlayoutDevice);
ANL();
#if defined(_WIN32)
TEST_MUSTPASS(hardware->SetPlayoutDevice(-1)); MARK();
#else
TEST_MUSTPASS(hardware->SetPlayoutDevice(0));
MARK();
#endif
ANL();
#endif // #if !defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID)
#if defined(MAC_IPHONE)
TEST(ResetSoundDevice); ANL();
for (int p=0; p<=60; p+=20)
{
TEST_LOG("Resetting sound device several times with pause %d ms\n", p);
for (int l=0; l<50; ++l)
{
TEST_MUSTPASS(hardware->ResetAudioDevice()); MARK();
SLEEP(p);
}
ANL();
}
TEST_LOG("Start streaming - verify the audio after each batch of resets \n");
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0,8000));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(2000);
SLEEP(2000);
for (int p=0; p<=60; p+=20)
{
TEST_LOG("Resetting sound device several time with pause %d ms\n", p);
for (int l=0; l<20; ++l)
{
TEST_MUSTPASS(hardware->ResetAudioDevice()); MARK();
SLEEP(p);
}
ANL();
SLEEP(2000);
}
TEST_LOG("Stop streaming \n");
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartReceive(0));
#endif // defined(MAC_IPHONE))
#ifdef MAC_IPHONE
TEST_LOG("\nNOTE: Always run hardware tests also without extended tests "
"enabled,\nsince the extended tests are pre-streaming tests only.\n");
#endif
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
ANL();
AOK();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestNetEqStats
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestNetEqStats() {
PrepareTest("NetEqStats (!EMPTY!)");
AOK();
ANL();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestNetwork
//
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestNetwork() {
PrepareTest("Network");
#ifdef WEBRTC_ANDROID
int sleepTime = 200;
int sleepTime2 = 250;
#elif defined(MAC_IPHONE) // MAC_IPHONE needs more delay for getSourceInfo()
int sleepTime = 150;
int sleepTime2 = 200;
#else
int sleepTime = 100;
int sleepTime2 = 200;
#endif
VoEBase* voe_base_ = _mgr.BasePtr();
VoEFile* file = _mgr.FilePtr();
VoENetwork* netw = _mgr.NetworkPtr();
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(
"VoENetwork_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
// ------------------------------------------------------------------------
// >> GetLocalIP
//
// State: VE initialized, no existing channels
TEST(GetLocalIP);
ANL();
#ifdef MAC_IPHONE
// Should fail
TEST_MUSTPASS(!netw->GetLocalIP(NULL, 0)); MARK();
TEST_ERROR(VE_FUNC_NOT_SUPPORTED);
ANL();
printf("NOTE: Local IP must be set in source code (line %d) \n",
__LINE__ + 1);
const char* localIP = "192.168.1.4";
#else
char localIP[64];
// invalid parameter
TEST_MUSTPASS(!netw->GetLocalIP(NULL));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
// default function calls (IPv4)
TEST_MUSTPASS(netw->GetLocalIP(localIP));
MARK();
TEST_LOG("[local IPv4: %s]\n", localIP);
TEST_MUSTPASS(netw->GetLocalIP(localIP));
MARK();
#if !defined(WEBRTC_MAC) && !defined(WEBRTC_ANDROID)
// default function calls (IPv6)
TEST_MUSTPASS(netw->GetLocalIP(localIP, true));
MARK();
TEST_LOG("[local IPv6: %s]\n", localIP);
TEST_MUSTPASS(netw->GetLocalIP(localIP, true));
MARK();
#endif
// one last call to ensure that local
TEST_MUSTPASS(netw->GetLocalIP(localIP));
MARK();
#endif
ANL();
AOK();
ANL();
ANL();
// >> end of GetLocalIP
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> GetSourceInfo
//
// - VE initialized
// - no existing channels
TEST(GetSourceInfo);
ANL();
int rtpPort(0);
int rtcpPort(0);
char ipaddr[64] = { 0 };
ExtendedTestTransport* ptrTransport(NULL);
// call without valid channel
TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// NULL as input string
TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, NULL));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
// call when external transport is enabled
ptrTransport = new ExtendedTestTransport(netw);
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
delete ptrTransport;
// call when external transport is disabled (no packet received yet)
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 0);
TEST_MUSTPASS(rtcpPort != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
// send and receive packets with default settings for a while
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime2); // does not guarantee RTCP
// verify remote parameters (exclude RTCP)
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 8000);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// ensure that valid results are maintained after StopListen
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 8000);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// verify that results are maintained after new call to SetLocalReceiver
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 8000);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// STATE: not listening, not sending
// send and receive packets with other settings for a while
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 9005));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// STATE: listening, sending
// verify new remote parameters
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 9005);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// restart sending to and from local IP
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 9005, kVoEDefault, localIP));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// verify new remote parameters
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 9005);
TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0); // should not be "127.0.0.1"
// use non-default source port in outgoing packets
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 9005));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, "127.0.0.1", 9010));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// verify new remote parameters
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 9010);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// STATE: listening and sending using an extra local socket
// stop/start sending
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// verify that the unique source port is maintained for the extra socket
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 9010);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// set new source port for outgoing packets (9010 -> 9020)
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, "127.0.0.1", 9020));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
#ifdef MAC_IPHONE
SLEEP(500); // Need extra pause for some reason
#endif
// verify that the unique source port is set for the new extra socket
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 9020);
// STATE: listening and sending using an extra local socket
// remove extra send socket and restart call again
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0)); // delete channel => destroys the
// extra socket
TEST_MUSTPASS(voe_base_->CreateChannel()); // new channel uses one socket only
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000)); // use new port as well
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// verify that remote info is correct
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 8000);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// STATE: listening and sending using shared socket
// use non-default source port in outgoing packets to create extra send
// socket
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 7000));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 7000, "127.0.0.1", 7010));
// RTP src is 7010 => RTCP src = 7011
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// verify new remote parameters
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 7010);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
// check RTCP port as well (should be 7010 + 1 = 7011)
Sleep(8000, true);
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 7010);
TEST_MUSTPASS(rtcpPort != 7011);
TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL();
AOK();
ANL();
ANL();
// >> end of GetSourceInfo
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetExternalTransport
//
// - VE initialized
// - no existing channels
// - no media
//
TEST(SetExternalTransport);
ANL();
ptrTransport = new ExtendedTestTransport(netw);
// call without valid channel
TEST_MUSTPASS(!netw->DeRegisterExternalTransport(0));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// different valid call combinations
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
MARK();
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
MARK();
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
MARK(); // must deregister first
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
MARK();
// STATE: external transport is disabled
// initialize sending and ensure that external transport can't be enabled
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 1234, "127.0.0.2"));
TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
TEST_ERROR(VE_SEND_SOCKETS_CONFLICT);
// restart channel to ensure that "initialized sender" state is cleared
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
// initialize receiving and ensure that external transport can't be enabled
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 5678));
TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
TEST_ERROR(VE_RECEIVE_SOCKETS_CONFLICT);
// restart channel to ensure that "initialized receiver" state is cleared
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
// enable external transport and verify that "emulated loopback" works
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
TEST_MUSTPASS(voe_base_->StartSend(0)); // should only start recording
TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
MARK(); // should fail
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
MARK();
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
Play(0, 2000, true, true); // play file as mic and verify loopback audio
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
MARK();
// STATE: external transport is disabled
#if defined(WEBRTC_ANDROID) || defined(MAC_IPHONE)
int testError = VE_FUNC_NOT_SUPPORTED;
#else
int testError = VE_EXTERNAL_TRANSPORT_ENABLED;
#endif
// check all APIs that should fail when external transport is enabled
int DSCP, priority, serviceType, overrideDSCP, nBytes(0);
bool useSetSockopt, enabled;
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
MARK();
TEST_MUSTPASS(!voe_base_->SetLocalReceiver(0, 12345));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!voe_base_->GetLocalReceiver(0, rtpPort, rtcpPort, ipaddr));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!voe_base_->GetSendDestination(0, rtpPort, ipaddr, rtpPort,
rtcpPort));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!netw->EnableIPv6(0))
TEST_ERROR(testError);
TEST_MUSTPASS(netw->IPv6IsEnabled(0) != false)
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345, 12346));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(!netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
// modified i VoE 3.4 (can be called also for external transport)
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
#if (!defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_MAC)) || \
defined(WEBRTC_EXTERNAL_TRANSPORT)
testError = VE_FUNC_NOT_SUPPORTED;
#else
testError = VE_EXTERNAL_TRANSPORT_ENABLED;
#endif
TEST_MUSTPASS(!netw->SetSendTOS(0, 0));
TEST_ERROR(testError);
TEST_MUSTPASS(!netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_ERROR(testError);
#if !defined(_WIN32) || defined(WEBRTC_EXTERNAL_TRANSPORT)
testError = VE_FUNC_NOT_SUPPORTED;
#else
testError = VE_EXTERNAL_TRANSPORT_ENABLED;
#endif
TEST_MUSTPASS(!netw->SetSendGQoS(0, false, 0));
TEST_ERROR(testError);
TEST_MUSTPASS(!netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_ERROR(testError);
char dummy[1] = { 'a' };
TEST_MUSTPASS(!netw->SendUDPPacket(0, dummy, 1, nBytes));
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
// always disable external transport before deleting the Transport object;
// will lead to crash for RTCP transmission otherwise
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
MARK();
delete ptrTransport;
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL();
AOK();
ANL();
ANL();
// >> end of SetExternalTransport
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> EnableIPv6
//
// - VE initialized
// - no existing channels
// - no media
// - NOTE: set _ENABLE_IPV6_TESTS_ to include these tests
// - http://www.microsoft.com/resources/documentation/windows/xp/all/
// proddocs/en-us/sag_ip_v6_pro_rt_enable.mspx?mfr=true
// >> ipv6 install
// >> ipv6 [-v] if [IfIndex]
// >> ping6 ::1
// >> ping6 fe80::1
#ifdef _ENABLE_IPV6_TESTS_
TEST(EnableIPv6); ANL();
// call without valid channel
TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// call with enabled external transport
ptrTransport = new ExtendedTestTransport(netw);
TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK();
TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
delete ptrTransport;
// Test "locking" to IPv4
TEST_MUSTPASS(netw->IPv6IsEnabled(0)); MARK(); // After this call we cannot
// enable IPv6
TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK(); // Should fail
// Check that IPv6 address is invalid
TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 8000, "::1")); MARK(); // fail
// New channel
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
// valid default call
TEST_MUSTPASS(netw->EnableIPv6(0)); MARK();
TEST_MUSTPASS(netw->GetLocalIP(localIP)); MARK(); // should still read IPv4
TEST_LOG("[local IPv4: %s]", localIP);
// ensure that Ipv6 is enabled
TEST_MUSTPASS(netw->IPv6IsEnabled(0) != true);
// check that IPv4 address is invalid
TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_ERROR(VE_INVALID_IP_ADDRESS);
// verify usage of IPv6 loopback address
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
// IPv6 loopback address is 0:0:0:0:0:0:0:1
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "::1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK(); // Should fail
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true);
ANL();
// Restart channel
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(netw->EnableIPv6(0)); MARK();
// ensure that Ipv6 is enabled
TEST_MUSTPASS(netw->IPv6IsEnabled(0) != true);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
TEST_MUSTPASS(voe_base_->StartReceive(0));
// IPv6 loopback address is 0:0:0:0:0:0:0:1
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "::1"));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(), true,
true);
SLEEP(500); // ensure that we receieve some packets
// SetSourceFilter and GetSourceFilter
TEST(SetSourceFilter and GetSourceFilter for IPv6); ANL();
char sourceIp[64] =
{ 0};
char filterIp[64] =
{ 0};
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, sourceIp));
TEST_LOG("Source port: %d \n", rtpPort);
TEST_LOG("Source RTCP port: %d \n", rtcpPort);
TEST_LOG("Source IP: %s \n", sourceIp);
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
TEST_LOG("Filter port RTP: %d \n", rtpPort);
TEST_LOG("Filter port RTCP: %d \n", rtcpPort);
TEST_LOG("Filter IP: %s \n", filterIp);
TEST_MUSTPASS(0 != rtpPort);
TEST_MUSTPASS(0 != rtcpPort);
TEST_MUSTPASS(filterIp[0] != '\0');
TEST_LOG("Set filter IP to %s => should hear audio\n", sourceIp);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, sourceIp));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
TEST_MUSTPASS(0 != rtpPort);
TEST_MUSTPASS(0 != rtcpPort);
TEST_MUSTPASS(_stricmp(filterIp, sourceIp));
SLEEP(1500);
TEST_LOG("Set filter IP to ::10:10:10 => should *not* hear audio\n");
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::10:10:10"));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
TEST_MUSTPASS(_stricmp(filterIp, "::10:10:10"));
SLEEP(1500);
TEST_LOG("Disable IP filter => should hear audio again\n");
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::0"));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
TEST_MUSTPASS(_stricmp(filterIp, "::"));
SLEEP(1500);
TEST_LOG("Set filter IP to ::10:10:10 => should *not* hear audio\n");
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::10:10:10"));
SLEEP(1500);
TEST_LOG("Disable IP filter => should hear audio again\n");
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
TEST_MUSTPASS(filterIp[0] != '\0');
SLEEP(1500);
TEST_LOG("Set filter IP to ::10:10:10 => should *not* hear audio\n");
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::10:10:10"));
SLEEP(1500);
TEST_LOG("Disable IP filter => should hear audio again\n");
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::"));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
TEST_MUSTPASS(_stricmp(filterIp, "::"));
SLEEP(1500);
file->StopPlayingFileAsMicrophone(0);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
#endif // #ifdef _ENABLE_IPV6_TESTS_
// >> end of EnableIPv6
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetSourceFilter
//
// - VE initialized
// - no existing channels
// - no media
TEST(SetSourceFilter);
ANL();
// call without valid channel
TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// invalid parameters
TEST_MUSTPASS(!netw->SetSourceFilter(0, 65536));
MARK();
TEST_ERROR(VE_INVALID_PORT_NMBR);
TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345, 65536));
MARK();
TEST_ERROR(VE_INVALID_PORT_NMBR);
TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345, 12346, "300.300.300.300"));
MARK();
TEST_ERROR(VE_INVALID_IP_ADDRESS);
// STATE: RTP filter port is 12345, RTCP filter port is 12346
// disable all filters and ensure that media is received
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
MARK();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000, kVoEDefault, localIP));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
TEST_MUSTPASS(rtpPort != 2000);
TEST_MUSTPASS(rtcpPort != 2001);
TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0);
// clear states and restart loopback session
TEST_MUSTPASS(voe_base_->DeleteChannel(0)); // clear source info state
TEST_MUSTPASS(voe_base_->CreateChannel());
// set RTP filter to port 2002 and verify that source 2000 is blocked
TEST_MUSTPASS(netw->SetSourceFilter(0, 2002, 0, NULL));;
MARK();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000, kVoEDefault, localIP));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
TEST_MUSTPASS(rtpPort != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
// ensure that received packets originates from 2002 and that they now pass
// the filter
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
// RTP source is 2002
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2002, kVoEDefault, localIP));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2002, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
TEST_MUSTPASS(rtpPort != 2002);
TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0);
// clear states and restart loopback session
TEST_MUSTPASS(voe_base_->DeleteChannel(0)); // clear source info state
TEST_MUSTPASS(voe_base_->CreateChannel());
// set IP filter to local IP and verify that default loopback stream is
// blocked
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, localIP));;
MARK();
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
TEST_MUSTPASS(rtpPort != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
// ensure that received packets originates from the local IP and that they
// now pass the filter
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
// should pass the filter
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000, kVoEDefault, localIP));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
TEST_MUSTPASS(rtpPort != 2000);
TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0);
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
// STATE: no active media, IP filter is active
// disable all filters
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));;
MARK();
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
TEST_MUSTPASS(rtpPort != 0);
TEST_MUSTPASS(rtcpPort != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL();
AOK();
ANL();
ANL();
// >> end of SetSourceFilter
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> GetSourceFilter
//
// - VE initialized
// - no existing channels
// - no media
TEST(GetSourceFilter);
ANL();
// call without valid channel
TEST_MUSTPASS(!netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// invalid input parameters
TEST_MUSTPASS(!netw->GetSourceFilter(0, rtpPort, rtcpPort, NULL));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
// valid call without any filter set
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 0);
TEST_MUSTPASS(rtcpPort != 0);
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
// STATE: no active media and no enabled filters
// set different filters and verify that they "bite"
TEST_MUSTPASS(netw->SetSourceFilter(0, 54321, 0, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 54321);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtpPort != 0);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 15425, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtcpPort != 15425);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(rtcpPort != 0);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "192.168.199.19"));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(strcmp(ipaddr, "192.168.199.19") != 0);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "0.0.0.0"));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(strcmp(ipaddr, "0.0.0.0") != 0);
TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
MARK();
TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL();
AOK();
ANL();
ANL();
// >> end of GetSourceFilter
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> RegisterDeadOrAliveObserver
// >> DeRegisterDeadOrAliveObserver
//
// - VE initialized
// - no existing channels
// - no media
TEST(RegisterDeadOrAliveObserver);
ANL();
TEST(DeRegisterDeadOrAliveObserver);
ANL();
// call without valid channel
TEST_MUSTPASS(!netw->RegisterDeadOrAliveObserver(0, *this));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(netw->RegisterDeadOrAliveObserver(0, *this));
MARK();
TEST_MUSTPASS(!netw->RegisterDeadOrAliveObserver(0, *this));
MARK(); // already registered
TEST_ERROR(VE_INVALID_OPERATION);
TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
MARK();
TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
MARK(); // OK to do it again
TEST_MUSTPASS(netw->RegisterDeadOrAliveObserver(0, *this));
MARK();
TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
MARK();
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
// STATE: dead-or-alive observer is disabled
// >> end of RegisterDeadOrAliveObserver
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetPeriodicDeadOrAliveStatus
// >> GetPeriodicDeadOrAliveStatus
//
// - VE initialized
// - no existing channels
// - no media
// call without valid channel
TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(0, false));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// Invalid paramters
TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(0, true, 0));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(0, true, 151));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(1, true, 10));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
int sampleTime(0);
// Valid parameters
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 1));
MARK();
TEST_MUSTPASS(netw->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(sampleTime != 1);
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 150));
MARK();
TEST_MUSTPASS(netw->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(sampleTime != 150);
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
MARK();
TEST_MUSTPASS(netw->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(sampleTime != 150); // ensure last set time isnt modified
StartMedia(0, 2000, true, true, true);
// STATE: full duplex media is active
// test the dead-or-alive mechanism
TEST_MUSTPASS(netw->RegisterDeadOrAliveObserver(0, *this));
MARK();
TEST_LOG("\nVerify that Alive callbacks are received (dT=2sec): ");
fflush(NULL);
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 2));
SLEEP(6000);
TEST_LOG("\nChange dT to 1 second: ");
fflush(NULL);
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 1));
SLEEP(6000);
TEST_LOG("\nDisable dead-or-alive callbacks: ");
fflush(NULL);
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
SLEEP(6000);
TEST_LOG("\nStop sending and enable callbacks again.\n");
TEST_LOG("Verify that Dead callbacks are received (dT=2sec): ");
fflush(NULL);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 2));
SLEEP(6000);
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_LOG("\nRestart sending.\n");
TEST_LOG("Verify that Alive callbacks are received again (dT=2sec): ");
fflush(NULL);
SLEEP(6000);
TEST_LOG("\nDisable dead-or-alive callbacks.");
fflush(NULL);
TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
MARK();
StopMedia(0);
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL();
AOK();
ANL();
ANL();
// >> end of SetPeriodicDeadOrAliveStatus
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetPacketTimeoutNotification
// >> GetPacketTimeoutNotification
//
// - VE initialized
// - no existing channels
// - no media
// - NOTE: dynamic tests are performed in standard test
int timeOut(0);
TEST(SetPacketTimeoutNotification);
ANL();
TEST(GetPacketTimeoutNotification);
ANL();
// call without existing valid channel
TEST_MUSTPASS(!netw->SetPacketTimeoutNotification(0, false));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// invalid function calls
TEST_MUSTPASS(!netw->SetPacketTimeoutNotification(0, true, 0));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetPacketTimeoutNotification(0, true, 151));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
// valid function calls (no active media)
TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, true, 2));
MARK();
TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(timeOut != 2);
TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, false));
MARK();
TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
MARK();
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, true, 10));
MARK();
TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(timeOut != 10);
TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, true, 2));
MARK();
TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(timeOut != 2);
TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, false));
MARK();
TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
MARK();
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL();
AOK();
ANL();
ANL();
// >> end of SetPacketTimeoutNotification
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SendUDPPacket
//
// - VE initialized
// - no existing channels
// - no media
// >> end of SendUDPPacket
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetSendTOS
//
// - VE initialized
// - no existing channels
// - no media
TEST(SetSendTOS);
ANL();
#if defined(_WIN32) || defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
// call without existing valid channel
TEST_MUSTPASS(!netw->SetSendTOS(0, 0)); MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// trivial invalid function calls
TEST_MUSTPASS(!netw->SetSendTOS(0, -1)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendTOS(0, 64)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendTOS(0, 1, -2)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendTOS(0, 1, 8)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendTOS(0, 1)); MARK();
TEST_ERROR(VE_SOCKET_ERROR); // must create sockets first
#ifdef _WIN32
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 3000));
// enable ToS using SetSockopt (should work without local binding)
TEST_MUSTPASS(netw->SetSendTOS(0, 1, -1, true)); MARK();
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
TEST_MUSTPASS(DSCP != 1);
TEST_MUSTPASS(priority != 0);
TEST_MUSTPASS(useSetSockopt != true);
// try to disable SetSockopt while ToS is enabled (should fail)
TEST_MUSTPASS(!netw->SetSendTOS(0, 1, -1, false)); MARK();
TEST_ERROR(VE_TOS_INVALID); // must disable ToS before enabling SetSockopt
// disable ToS to be able to stop using SetSockopt
TEST_MUSTPASS(netw->SetSendTOS(0, 0, -1, true)); MARK(); // disable ToS
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
TEST_MUSTPASS(DSCP != 0);
TEST_MUSTPASS(priority != 0);
TEST_MUSTPASS(useSetSockopt != true);
// to use the "non-SetSockopt" method, local binding is required,
// trying without it should fail
TEST_MUSTPASS(!netw->SetSendTOS(0, 1, -1, false)); MARK();
TEST_ERROR(VE_TOS_ERROR); // must bind to local IP first
// bind to local IP and try again (should work this time)
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345, kVoEDefault, localIP));
TEST_LOG("\nThis test needs to be run as administrator\n");
TEST_MUSTPASS(netw->SetSendTOS(0, 1, -1, false)); MARK();
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
TEST_MUSTPASS(DSCP != 1);
TEST_MUSTPASS(priority != 0);
TEST_MUSTPASS(useSetSockopt != false);
// STATE: binded to local IP, local port is 12345 and DSCP is 1 (not using
// SetSockopt)
// verify loopback audio with the current settings
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true); // file should be played out here...
#ifdef _SEND_TO_REMOTE_IP_
// Send to remote destination and verify the DSCP using Wireshark.
// Use filter ip.src == "RemoteIP".
TEST_LOG("\nUse Wireshark and verify a correctly received DSCP at the "
"remote side!\n");
TEST_LOG("Sending approx. 5 packets to %s:%d for each DSCP below:\n",
RemoteIP, RemotePort);
TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
TEST_LOG(" DSCP is set to 0x%02x\n", 1);
SLEEP(100);
// Change the DSCP while sending is active and verify on remote side.
TEST_MUSTPASS(netw->SetSendTOS(0, 2));
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x\n", DSCP);
SLEEP(100);
// Change the DSCP while sending is active and verify on remote side.
TEST_MUSTPASS(netw->SetSendTOS(0, 63));
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x\n", DSCP);
SLEEP(100);
// stop and resume sending
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x\n", DSCP);
SLEEP(100);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(netw->SetSendTOS(0, 0));
#endif // _SEND_TO_REMOTE_IP_
// Windows priority tests (priority cannot be set using setsockopt on Win)
TEST_LOG("Testing priority\n");
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(!netw->SetSendTOS(0, 0, 3, true)); // Should fail
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(netw->SetSendTOS(0, 0, 3, false));
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(netw->SetSendTOS(0, 1, 3, false));
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->CreateChannel());
#endif // _WIN32
// STATE: no media, disabled ToS, no defined receiver
// Repeat tests above but using setsockopt() this time.
// Binding to local IP should not be required.
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345, kVoEDefault));
TEST_MUSTPASS(netw->SetSendTOS(0, 10, -1, true)); MARK();
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
TEST_MUSTPASS(DSCP != 10);
TEST_MUSTPASS(priority != 0);
TEST_MUSTPASS(useSetSockopt != true);
// STATE: *not* binded to local IP, local port is 12345 and DSCP is 10
// (using SetSockopt)
// verify loopback audio with the current settings
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true); // file should be played out here...
#ifdef _SEND_TO_REMOTE_IP_
// Send to remote destination and verify the DSCP using Wireshark.
// Use filter ip.src == "RemoteIP".
TEST_LOG("\nUse Wireshark and verify a correctly received DSCP at the"
" remote side!\n");
TEST_LOG("Sending approx. 5 packets to %s:%d for each DSCP below:\n",
RemoteIP, RemotePort);
TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x (setsockopt)\n", DSCP);
SLEEP(100);
// Change the DSCP while sending is active and verify on remote side.
TEST_MUSTPASS(netw->SetSendTOS(0, 20, -1, true)); // use setsockopt()
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x (setsockopt)\n", DSCP);
SLEEP(100);
// Change the DSCP while sending is active and verify on remote side.
TEST_MUSTPASS(netw->SetSendTOS(0, 61, -1, true)); // use setsockopt()
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x (setsockopt)\n", DSCP);
SLEEP(100);
// stop and resume sending
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
TEST_LOG(" DSCP is set to 0x%02x (setsockopt)\n", DSCP);
SLEEP(100);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(netw->SetSendTOS(0, 0, -1, true));
#endif // _SEND_TO_REMOTE_IP_
#if defined(WEBRTC_LINUX)
// Linux priority tests (using setsockopt)
TEST_LOG("Testing priority\n");
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(netw->SetSendTOS(0, 0, 3, true));
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(netw->SetSendTOS(0, 1, 3, true));
TEST_MUSTPASS(voe_base_->StartSend(0));
Play(0, 2000, true, true); // file should be played out here...
#endif // #if defined(WEBRTC_LINUX)
#if !defined(_WIN32) && !defined(WEBRTC_LINUX)
// Fail tests for other than Wind and Linux
TEST_MUSTPASS(!netw->SetSendTOS(0, 0, 3, false)); // Should fail
TEST_ERROR(VE_INVALID_ARGUMENT);
#endif // #if !defined(_WIN32) && !defined(WEBRTC_LINUX)
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL(); AOK(); ANL(); ANL();
// END #if defined(_WIN32) || defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
#else
TEST_LOG("Skipping ToS tests - _WIN32, LINUX, MAC is not defined or "
"WEBRTC_ANDROID is defined");
#endif
// >> end of SetSendTOS
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// >> SetSendGQoS (Windows only)
//
// - VE initialized
// - no existing channels
// - no media
//
// From qos.h:
//
// #define SERVICETYPE_NOTRAFFIC 0x00000000
// #define SERVICETYPE_BESTEFFORT 0x00000001 (*)
// #define SERVICETYPE_CONTROLLEDLOAD 0x00000002 (*)
// #define SERVICETYPE_GUARANTEED 0x00000003 (*)
// #define SERVICETYPE_NETWORK_UNAVAILABLE 0x00000004
// #define SERVICETYPE_GENERAL_INFORMATION 0x00000005
// #define SERVICETYPE_NOCHANGE 0x00000006
// #define SERVICETYPE_NONCONFORMING 0x00000009
// #define SERVICETYPE_NETWORK_CONTROL 0x0000000A
// #define SERVICETYPE_QUALITATIVE 0x0000000D (*)
//
// #define SERVICE_BESTEFFORT 0x80010000
// #define SERVICE_CONTROLLEDLOAD 0x80020000
// #define SERVICE_GUARANTEED 0x80040000
// #define SERVICE_QUALITATIVE 0x80200000
//
// (*) supported in WEBRTC VoE
TEST(SetSendGQoS);
ANL();
#ifdef _WIN32
// call without existing valid channel
TEST_MUSTPASS(!netw->SetSendGQoS(0, false, 0)); MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(voe_base_->CreateChannel());
// supported service type but no sockets
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
TEST_ERROR(VE_SOCKETS_NOT_INITED);
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
// supported service type but sender is not initialized
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
TEST_ERROR(VE_DESTINATION_NOT_INITED);
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
// invalid service types
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NOTRAFFIC)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NETWORK_UNAVAILABLE));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_GENERAL_INFORMATION));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NOCHANGE)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NONCONFORMING));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NETWORK_CONTROL));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_BESTEFFORT)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_CONTROLLEDLOAD)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_GUARANTEED)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_QUALITATIVE)); MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
// Is ToS enabled here?
// Settings which don't require binding to local IP
// set SERVICETYPE_BESTEFFORT
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(serviceType != SERVICETYPE_BESTEFFORT);
TEST_MUSTPASS(overrideDSCP != false);
// set SERVICETYPE_CONTROLLEDLOAD
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_CONTROLLEDLOAD));
MARK();
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(serviceType != SERVICETYPE_CONTROLLEDLOAD);
TEST_MUSTPASS(overrideDSCP != false);
// set SERVICETYPE_GUARANTEED
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_GUARANTEED)); MARK();
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(serviceType != SERVICETYPE_GUARANTEED);
TEST_MUSTPASS(overrideDSCP != false);
// set SERVICETYPE_QUALITATIVE
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_QUALITATIVE)); MARK();
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(serviceType != SERVICETYPE_QUALITATIVE);
TEST_MUSTPASS(overrideDSCP != false);
// disable GQoS
TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0)); MARK();
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
MARK();
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(serviceType != SERVICETYPE_QUALITATIVE);
TEST_MUSTPASS(overrideDSCP != false);
// STATE: diabled QGoS, sockets exists, sending side is initialized, no media
// Loopback tests using the four different GQoS settings
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
ANL();
TEST_LOG("[SERVICETYPE_BESTEFFORT]");
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_CONTROLLEDLOAD)); MARK();
ANL();
TEST_LOG("[SERVICETYPE_CONTROLLEDLOAD]");
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_GUARANTEED)); MARK();
ANL();
TEST_LOG("[SERVICETYPE_GUARANTEED]");
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_QUALITATIVE)); MARK();
ANL();
TEST_LOG("[SERVICETYPE_QUALITATIVE]");
Play(0, 2000, true, true); // file should be played out here...
#ifdef _SEND_TO_REMOTE_IP_
// Send to remote destination and verify the DSCP mapping using Wireshark.
// Use filter ip.src == "RemoteIP".
// Modify the send destination on the fly
TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
TEST_LOG("\nUse Wireshark and verify a correctly received DSCP mapping at"
" the remote side!\n");
TEST_LOG("Sending approx. 5 packets to %s:%d for each GQoS setting below:\n",
RemoteIP, RemotePort);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_BESTEFFORT (0x%02x), should "
"be mapped to DSCP = 0x00\n", serviceType);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_CONTROLLEDLOAD));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_CONTROLLEDLOAD (0x%02x), "
"should be mapped to DSCP = 0x18\n", serviceType);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
TEST_LOG(" QoS is disabled, should give DSCP = 0x%02x\n", 0);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_GUARANTEED));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_GUARANTEED (0x%02x), should "
"be mapped to DSCP = 0x28\n", serviceType);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_QUALITATIVE));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_QUALITATIVE (0x%02x), should"
" be mapped to DSCP = 0x00\n", serviceType);
SLEEP(100);
#endif // _SEND_TO_REMOTE_IP_
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
// STATE: sockets exists, sending side is initialized, no media
// Repeat test above but this time using overrideDSCP.
// Some initial loopack tests.
// NOTE - override DSCP requres binding to local IP.
// should not work since QoS is enabled
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 3));
MARK();
TEST_ERROR(VE_TOS_GQOS_CONFLICT);
// disble QoS and try to override again (should fail again since local
// binding is not done yet)
TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 3));
MARK();
TEST_ERROR(VE_GQOS_ERROR);
// make proper settings and try again (should work this time)
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345, kVoEDefault, localIP));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 3));
MARK();
// Now, let's try some loopback tests using override DSCP
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
ANL();
TEST_LOG("[overrideDSCP=3]");
Play(0, 2000, true, true); // file should be played out here...
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 17));
MARK();
ANL();
TEST_LOG("[overrideDSCP=17]");
Play(0, 2000, true, true); // file should be played out here...
// And finally, send to remote side as well to verify that the new mapping
// works as it should.
#ifdef _SEND_TO_REMOTE_IP_
// Modify the send destination on the fly
TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
TEST_LOG("\nUse Wireshark and verify a correctly received DSCP mapping at"
" the remote side!\n");
TEST_LOG("Sending approx. 5 packets to %s:%d for each GQoS setting below:\n",
RemoteIP, RemotePort);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 18));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_BESTEFFORT, should be "
"overrided to DSCP = 0x%02x\n", overrideDSCP);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 62));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_BESTEFFORT, should be "
"overrided to DSCP = 0x%02x\n", overrideDSCP);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 32));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_BESTEFFORT, should be "
"overrided to DSCP = 0x%02x\n", overrideDSCP);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 1));
TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
TEST_LOG(" serviceType is set to SERVICETYPE_BESTEFFORT, should be "
"overrided to DSCP = 0x%02x\n", overrideDSCP);
SLEEP(100);
TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
TEST_LOG(" QoS is disabled, should give DSCP = 0x%02x\n", 0);
SLEEP(100);
#endif // _SEND_TO_REMOTE_IP_
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
ANL(); AOK(); ANL(); ANL();
#else
TEST_LOG("Skipping GQoS tests - _WIN32 is not defined");
#endif // #ifdef _WIN32
// >> end of SetSendGQoS
// ------------------------------------------------------------------------
if (file) {
file->StopPlayingFileAsMicrophone(0);
}
voe_base_->StopSend(0);
voe_base_->StopPlayout(0);
voe_base_->StopReceive(0);
voe_base_->DeleteChannel(0);
voe_base_->Terminate();
ANL();
AOK();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestRTP_RTCP
// ----------------------------------------------------------------------------
// Used to validate packets during the RTP audio level indication test.
class RTPAudioTransport: public Transport {
public:
RTPAudioTransport() :
mute_(false) {
}
virtual ~RTPAudioTransport() {
}
void set_mute(bool mute) {
mute_ = mute;
}
bool mute() const {
return mute_;
}
// TODO(andrew): use proper error checks here rather than asserts.
virtual int SendPacket(int channel, const void* data, int length) {
const uint8_t* packet = static_cast<const uint8_t*> (data);
// Extension bit.
assert(packet[0] & 0x10);
int index = 12; // Assume standard RTP header.
// Header extension ID
assert(packet[index++] == 0xBE);
assert(packet[index++] == 0xDE);
// Header extension length
assert(packet[index++] == 0x00);
assert(packet[index++] == 0x01);
// User-defined ID.
assert(((packet[index] & 0xf0) >> 4) == 1);
// Length
assert((packet[index++] & 0x0f) == 0);
int vad = packet[index] >> 7;
int level = packet[index] & 0x7f;
if (channel == 0) {
printf("%d -%d\n", vad, level);
} else if (channel == 1) {
printf(" %d -%d\n", vad, level);
} else {
assert(false);
}
if (mute_) {
assert(vad == 0);
assert(level == 127);
} else {
assert(vad == 0 || vad == 1);
assert(level >= 0 && level <= 127);
}
return 0;
}
virtual int SendRTCPPacket(int /*channel*/, const void* /*data*/,
int /*length*/) {
return 0;
}
private:
bool mute_;
};
int VoEExtendedTest::TestRTP_RTCP() {
PrepareTest("RTP_RTCP");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEFile* file = _mgr.FilePtr();
VoERTP_RTCP* rtp_rtcp = _mgr.RTP_RTCPPtr();
VoENetwork* network = _mgr.NetworkPtr();
VoEVolumeControl* volume = _mgr.VolumeControlPtr();
VoECodec* codec = _mgr.CodecPtr();
XRTPObserver rtpObserver;
#ifdef WEBRTC_ANDROID
int sleepTime = 200;
#else
int sleepTime = 100;
#endif
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(
"VoERTP_RTCP_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
///////////////////////////
// Actual test starts here
// ------------------------------------------------------------------------
// >> Set/GetRTPAudioLevelIndicationStatus
TEST(SetRTPAudioLevelIndicationStatus);
ANL();
TEST(GetRTPAudioLevelIndicationStatus);
// test invalid input parameters
TEST_MUSTPASS(-1 != rtp_rtcp->SetRTPAudioLevelIndicationStatus(0, true, 0));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(-1 != rtp_rtcp->SetRTPAudioLevelIndicationStatus(0, true, 15));
MARK();
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(-1 != rtp_rtcp->SetRTPAudioLevelIndicationStatus(0, false, 15));
MARK();
TEST_MUSTPASS(-1 != rtp_rtcp->SetRTPAudioLevelIndicationStatus(1, true, 5));
MARK();
TEST_ERROR(VE_CHANNEL_NOT_VALID);
// test complete valid input range [1,14]
bool audioLevelEnabled(false);
unsigned char ID(0);
for (int id = 1; id < 15; id++) {
TEST_MUSTPASS(rtp_rtcp->SetRTPAudioLevelIndicationStatus(0, true, id));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTPAudioLevelIndicationStatus(
0, audioLevelEnabled, ID));
MARK();
TEST_MUSTPASS(audioLevelEnabled != true);
TEST_MUSTPASS(rtp_rtcp->SetRTPAudioLevelIndicationStatus(0, false, id));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTPAudioLevelIndicationStatus(
0, audioLevelEnabled, ID));
MARK();
TEST_MUSTPASS(audioLevelEnabled != false);
TEST_MUSTPASS(ID != id);
}
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
RTPAudioTransport rtpAudioTransport;
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(network->RegisterExternalTransport(0, rtpAudioTransport));
TEST_MUSTPASS(rtp_rtcp->SetRTPAudioLevelIndicationStatus(0, true));
TEST_MUSTPASS(codec->SetVADStatus(0, true));
printf("\n\nReceving muted packets (expect VAD = 0, Level = -127)...\n");
printf("VAD Level [dbFS]\n");
SLEEP(2000);
rtpAudioTransport.set_mute(true);
TEST_MUSTPASS(volume->SetInputMute(0, true));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(5000);
TEST_MUSTPASS(voe_base_->StopSend(0));
rtpAudioTransport.set_mute(false);
TEST_MUSTPASS(volume->SetInputMute(0, false));
printf("\nReceiving packets from mic (should respond to mic level)...\n");
printf("VAD Level [dbFS]\n");
SLEEP(2000);
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(5000);
TEST_MUSTPASS(voe_base_->StopSend(0));
printf("\nReceiving packets from file (expect mostly VAD = 1)...\n");
printf("VAD Level [dbFS]\n");
SLEEP(2000);
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(5000);
TEST_MUSTPASS(voe_base_->StopSend(0));
printf("\nMuted and mic on independent channels...\n");
printf("Muted Mic\n");
SLEEP(2000);
ASSERT_TRUE(1 == voe_base_->CreateChannel());
TEST_MUSTPASS(network->RegisterExternalTransport(1, rtpAudioTransport));
TEST_MUSTPASS(rtp_rtcp->SetRTPAudioLevelIndicationStatus(1, true));
TEST_MUSTPASS(codec->SetVADStatus(1, true));
TEST_MUSTPASS(volume->SetInputMute(0, true));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartSend(1));
SLEEP(5000);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopSend(1));
TEST_MUSTPASS(network->DeRegisterExternalTransport(0));
TEST_MUSTPASS(network->DeRegisterExternalTransport(1));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(1));
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
MARK();
ANL();
// ------------------------------------------------------------------------
// >> InsertExtraRTPPacket
int i(0);
TEST(SetLocalSSRC);
TEST_MUSTPASS(!rtp_rtcp->SetLocalSSRC(0, 5678));
MARK();
TEST_MUSTPASS(VE_ALREADY_SENDING != voe_base_->LastError());
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(rtp_rtcp->SetLocalSSRC(0, 5678)); // force send SSRC to 5678
TEST_MUSTPASS(voe_base_->StartSend(0));
MARK();
ANL();
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
// ------------------------------------------------------------------------
// >> InsertExtraRTPPacket
TEST(InsertExtraRTPPacket);
ANL();
const char payloadData[8] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(-1, 0, false,
payloadData, 8));
MARK(); // invalid channel
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, -1, false,
payloadData, 8));
MARK(); // invalid payload type
TEST_ERROR(VE_INVALID_PLTYPE);
TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 128, false,
payloadData, 8));
MARK(); // invalid payload type
TEST_ERROR(VE_INVALID_PLTYPE);
TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 99, false,
NULL, 8));
MARK(); // invalid pointer
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 99, false,
payloadData, 1500-28+1));
MARK(); // invalid size
TEST_ERROR(VE_INVALID_ARGUMENT);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 99, false,
payloadData, 8));
MARK(); // not sending
TEST_ERROR(VE_NOT_SENDING);
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
SLEEP(1000);
for (int p = 0; p < 128; p++) {
TEST_MUSTPASS(rtp_rtcp->InsertExtraRTPPacket(0, p, false,
payloadData, 8));
MARK();
TEST_MUSTPASS(rtp_rtcp->InsertExtraRTPPacket(0, p, true,
payloadData, 8));
MARK();
}
// Ensure we have sent all extra packets before we move forward to avoid
//incorrect error code
SLEEP(1000);
ANL();
// ------------------------------------------------------------------------
// >> RTP dump APIs
TEST(Start/StopRtpDump);
ANL();
TEST(Start/RTPDumpIsActive);
TEST_MUSTPASS(-1 != rtp_rtcp->RTPDumpIsActive(-1, kRtpIncoming));
MARK(); // invalid channel
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(false != rtp_rtcp->RTPDumpIsActive(0, kRtpIncoming));
MARK(); // should be off by default
TEST_MUSTPASS(false != rtp_rtcp->RTPDumpIsActive(0, kRtpOutgoing));
MARK(); // should be off by default
TEST_MUSTPASS(-1 != rtp_rtcp->StartRTPDump(-1, NULL));
MARK(); // invalid channel
TEST_ERROR(VE_CHANNEL_NOT_VALID);
TEST_MUSTPASS(-1 != rtp_rtcp->StartRTPDump(0, NULL));
MARK(); // invalid file name
TEST_ERROR(VE_BAD_FILE);
// Create two RTP dump files:
// - dump_in_1sec.rtp <=> ~1 sec recording of input side
// - dump_in_2sec.rtp <=> ~2 sec recording of output side
//
TEST_MUSTPASS(rtp_rtcp->StopRTPDump(0));
MARK();
TEST_MUSTPASS(rtp_rtcp->StopRTPDump(0, kRtpIncoming));
MARK();
TEST_MUSTPASS(rtp_rtcp->StopRTPDump(0, kRtpOutgoing));
MARK();
TEST_MUSTPASS(rtp_rtcp->StartRTPDump(0, GetFilename("dump_in_1sec.rtp"),
kRtpIncoming));
MARK();
TEST_MUSTPASS(rtp_rtcp->StartRTPDump(0, GetFilename("dump_out_2sec.rtp"),
kRtpOutgoing));
MARK();
SLEEP(1000);
TEST_MUSTPASS(rtp_rtcp->StopRTPDump(0, kRtpIncoming));
MARK();
SLEEP(1000);
TEST_MUSTPASS(rtp_rtcp->StopRTPDump(0, kRtpOutgoing));
MARK();
// Start/Stop tests:
//
// - only one file (called dump_in_200ms.rtp) should exist after this test
//
for (i = 0; i < 10; i++) {
TEST_MUSTPASS(rtp_rtcp->StartRTPDump(0,
GetFilename("dump_in_200ms.rtp")));
MARK();
SLEEP(200);
TEST_MUSTPASS(rtp_rtcp->StopRTPDump(0));
MARK();
}
// >> end of RTP dump APIs
// ------------------------------------------------------------------------
ANL();
TEST(GetRTCPStatus);
bool enabled;
TEST_MUSTPASS(!rtp_rtcp->GetRTCPStatus(-1, enabled));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatus(0, enabled));
MARK(); // should be on by default
TEST_MUSTPASS(enabled != true);
ANL();
TEST(SetRTCPStatus);
TEST_MUSTPASS(rtp_rtcp->SetRTCPStatus(0, false));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatus(0, enabled));
TEST_MUSTPASS(enabled != false);
MARK();
SLEEP(2000);
TEST_MUSTPASS(rtp_rtcp->SetRTCPStatus(0, true));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatus(0, enabled));
TEST_MUSTPASS(enabled != true);
MARK();
SLEEP(6000); // Make sure we get an RTCP packet
ANL();
TEST(CNAME);
TEST_MUSTPASS(!rtp_rtcp->SetRTCP_CNAME(0, NULL));
MARK();
TEST_MUSTPASS(VE_RTP_RTCP_MODULE_ERROR != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!rtp_rtcp->GetRemoteRTCP_CNAME(0, NULL));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
ANL();
TEST(GetRemoteSSRC);
unsigned int ssrc(0);
TEST_MUSTPASS(rtp_rtcp->GetRemoteSSRC(0, ssrc));
MARK();
TEST_MUSTPASS(ssrc != 5678);
ANL();
TEST(GetRemoteCSRC); // only trivial tests added
unsigned int csrcs[2];
int n(0);
TEST_MUSTPASS(!rtp_rtcp->GetRemoteCSRCs(1, csrcs));
MARK();
n = rtp_rtcp->GetRemoteCSRCs(0, csrcs);
MARK();
TEST_MUSTPASS(n != 0); // should be empty
ANL();
TEST(SetRTPObserver);
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(rtp_rtcp->RegisterRTPObserver(0, rtpObserver));
TEST_MUSTPASS(rtp_rtcp->DeRegisterRTPObserver(0));
TEST_MUSTPASS(rtp_rtcp->RegisterRTPObserver(0, rtpObserver));
TEST_MUSTPASS(rtp_rtcp->SetLocalSSRC(0, 7777)); // force send SSRC to 7777
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(sleepTime);
// verify that the new SSRC has been detected by the observer
TEST_MUSTPASS(rtpObserver._SSRC != 7777);
TEST_MUSTPASS(rtp_rtcp->DeRegisterRTPObserver(0));
ANL();
TEST(GetRTPKeepaliveStatus);
unsigned char pt;
int dT;
TEST_MUSTPASS(!rtp_rtcp->GetRTPKeepaliveStatus(-1, enabled, pt, dT));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTPKeepaliveStatus(0, enabled, pt, dT));
MARK(); // should be off by default
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(pt != 255);
TEST_MUSTPASS(dT != 0);
ANL();
TEST(SetRTPKeepaliveStatus);
// stop send before changing the settings
TEST_MUSTPASS(voe_base_->StopSend(0));
// verify invalid input parameters
TEST_MUSTPASS(!rtp_rtcp->SetRTPKeepaliveStatus(-1, true, 0, 15));
MARK();
TEST_MUSTPASS(!rtp_rtcp->SetRTPKeepaliveStatus(0, true, -1, 15));
MARK();
TEST_MUSTPASS(!rtp_rtcp->SetRTPKeepaliveStatus(0, true, 0, 61));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTPKeepaliveStatus(0, enabled, pt, dT));
MARK(); // should still be off
TEST_MUSTPASS(enabled != false);
// try valid settings
TEST_MUSTPASS(rtp_rtcp->SetRTPKeepaliveStatus(0, true, 117));
MARK();
TEST_MUSTPASS(rtp_rtcp->GetRTPKeepaliveStatus(0, enabled, pt, dT));
MARK(); // should be on now
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(pt != 117);
TEST_MUSTPASS(dT != 15);
// change from PT 99 to 121, as 99 is occupied
TEST_MUSTPASS(rtp_rtcp->SetRTPKeepaliveStatus(0, true, 121, 3));
MARK(); // on, PT=99, dT=3
TEST_MUSTPASS(rtp_rtcp->GetRTPKeepaliveStatus(0, enabled, pt, dT));
MARK();
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(pt != 121);
TEST_MUSTPASS(dT != 3);
ANL();
// Make fresh restart (ensures that SSRC is randomized)
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
SLEEP(100);
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
SLEEP(8000);
TEST(GetRemoteRTCPData);
// Statistics based on received RTCP reports (i.e. statistics on the remote
// side sent to us).
unsigned int NTPHigh(0), NTPLow(0), timestamp(0), playoutTimestamp(0),
jitter(0);
unsigned short fractionLost(0);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCPData(0, NTPHigh, NTPLow,
timestamp, playoutTimestamp));
TEST_LOG("\n NTPHigh = %u \n NTPLow = %u \n timestamp = %u \n "
" playoutTimestamp = %u \n jitter = %u \n fractionLost = %hu \n",
NTPHigh, NTPLow, timestamp, playoutTimestamp, jitter, fractionLost);
unsigned int NTPHigh2(0), NTPLow2(0), timestamp2(0);
unsigned int playoutTimestamp2(0), jitter2(0);
unsigned short fractionLost2(0);
TEST_LOG("take a new sample and ensure that the playout timestamp is "
"maintained");
SLEEP(100);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCPData(0, NTPHigh2, NTPLow2, timestamp2,
playoutTimestamp2, &jitter2,
&fractionLost2));
TEST_LOG("\n NTPHigh = %u \n NTPLow = %u \n timestamp = %u \n "
" playoutTimestamp = %u \n jitter = %u \n fractionLost = %hu \n",
NTPHigh2, NTPLow2, timestamp2, playoutTimestamp2, jitter2, fractionLost2);
TEST_MUSTPASS(playoutTimestamp != playoutTimestamp2);
TEST_LOG("wait for 8 seconds and ensure that the RTCP statistics is"
" updated...");
SLEEP(8000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCPData(0, NTPHigh2, NTPLow2,
timestamp2, playoutTimestamp2,
&jitter2, &fractionLost2));
TEST_LOG("\n NTPHigh = %u \n NTPLow = %u \n timestamp = %u \n "
" playoutTimestamp = %u \n jitter = %u \n fractionLost = %hu \n",
NTPHigh2, NTPLow2, timestamp2, playoutTimestamp2, jitter2, fractionLost2);
TEST_MUSTPASS((NTPHigh == NTPHigh2) && (NTPLow == NTPLow2));
TEST_MUSTPASS(timestamp == timestamp2);
TEST_MUSTPASS(playoutTimestamp == playoutTimestamp2);
#ifdef WEBRTC_CODEC_RED
//The following test is related to defect 4985 and 4986
TEST_LOG("Turn FEC and VAD on and wait for 4 seconds and ensure that "
"the jitter is still small...");
CodecInst cinst;
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
cinst.pltype = 104;
strcpy(cinst.plname, "isac");
cinst.plfreq = 32000;
cinst.pacsize = 960;
cinst.channels = 1;
cinst.rate = 45000;
#else
cinst.pltype = 119;
strcpy(cinst.plname, "isaclc");
cinst.plfreq = 16000;
cinst.pacsize = 320;
cinst.channels = 1;
cinst.rate = 40000;
#endif
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
TEST_MUSTPASS(codec->SetSendCodec(0, cinst));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(rtp_rtcp->SetFECStatus(0, true, -1));
MARK();
TEST_MUSTPASS(codec->SetVADStatus(0,true));
SLEEP(4000);
TEST_MUSTPASS(rtp_rtcp->GetRemoteRTCPData(0, NTPHigh2, NTPLow2, timestamp2,
playoutTimestamp2, &jitter2,
&fractionLost2));
TEST_LOG("\n NTPHigh = %u \n NTPLow = %u \n timestamp = %u \n "
" playoutTimestamp = %u \n jitter = %u \n fractionLost = %hu \n",
NTPHigh2, NTPLow2, timestamp2, playoutTimestamp2, jitter2, fractionLost2);
TEST_MUSTPASS(jitter2 > 1000)
TEST_MUSTPASS(rtp_rtcp->SetFECStatus(0, false));
MARK();
//4985 and 4986 end
#endif // #ifdef WEBRTC_CODEC_RED
TEST(GetRTPStatistics);
ANL();
// Statistics summarized on local side based on received RTP packets.
CallStatistics stats;
// Call GetRTPStatistics over a longer period than 7.5 seconds
// (=dT RTCP transmissions).
unsigned int averageJitterMs, maxJitterMs, discardedPackets;
SLEEP(1000);
for (i = 0; i < 8; i++) {
TEST_MUSTPASS(rtp_rtcp->GetRTPStatistics(0, averageJitterMs,
maxJitterMs,
discardedPackets));
TEST_LOG(" %i) averageJitterMs = %u \n maxJitterMs = %u \n "
" discardedPackets = %u \n", i, averageJitterMs, maxJitterMs,
discardedPackets);
SLEEP(1000);
}
TEST(RTCPStatistics #1);
ANL();
unsigned int packetsSent(0);
unsigned int packetsReceived(0);
for (i = 0; i < 8; i++)
{
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatistics(0, stats));
TEST_LOG(" %i) fractionLost = %hu \n cumulativeLost = %u \n "
" extendedMax = %u \n jitterSamples = %u \n rttMs = %d \n",
i, stats.fractionLost, stats.cumulativeLost,
stats.extendedMax, stats.jitterSamples, stats.rttMs);
TEST_LOG( " bytesSent = %d \n packetsSent = %d \n "
" bytesReceived = %d \n packetsReceived = %d \n",
stats.bytesSent, stats.packetsSent, stats.bytesReceived,
stats.packetsReceived);
if (i > 0)
{
TEST_LOG(" diff sent packets : %u (~50)\n",
stats.packetsSent - packetsSent);
TEST_LOG(" diff received packets: %u (~50)\n",
stats.packetsReceived - packetsReceived);
}
packetsSent = stats.packetsSent;
packetsReceived = stats.packetsReceived;
SLEEP(1000);
}
TEST(RTCPStatistics #2);
ANL();
TEST_LOG("restart sending and ensure that the statistics is reset");
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
SLEEP(50); // ensures approx. two received packets
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatistics(0, stats));
TEST_LOG("\n fractionLost = %hu \n cumulativeLost = %u \n "
" extendedMax = %u \n jitterSamples = %u \n rttMs = %d \n",
stats.fractionLost, stats.cumulativeLost,
stats.extendedMax, stats.jitterSamples, stats.rttMs);
TEST_LOG( " bytesSent = %d \n packetsSent = %d \n "
" bytesReceived = %d \n packetsReceived = %d \n",
stats.bytesSent, stats.packetsSent, stats.bytesReceived,
stats.packetsReceived);
TEST(RTCPStatistics #3);
ANL();
TEST_LOG("disable RTCP and verify that statistics is not corrupt");
TEST_MUSTPASS(rtp_rtcp->SetRTCPStatus(0, false));
SLEEP(250);
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatistics(0, stats));
TEST_LOG("\n fractionLost = %hu \n cumulativeLost = %u \n "
" extendedMax = %u \n jitterSamples = %u \n rttMs = %d \n",
stats.fractionLost, stats.cumulativeLost,
stats.extendedMax, stats.jitterSamples, stats.rttMs);
TEST_LOG(" bytesSent = %d \n packetsSent = %d \n "
"bytesReceived = %d \n packetsReceived = %d \n",
stats.bytesSent, stats.packetsSent,
stats.bytesReceived, stats.packetsReceived);
TEST_MUSTPASS(rtp_rtcp->SetRTCPStatus(0, true));
TEST(RTCPStatistics #4);
ANL();
TEST_LOG("restart receiving and check RX statistics");
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->StartReceive(0));
SLEEP(50); // ensures approx. two received packets
TEST_MUSTPASS(rtp_rtcp->GetRTCPStatistics(0, stats));
TEST_LOG("\n fractionLost = %hu \n cumulativeLost = %u \n "
" extendedMax = %u \n jitterSamples = %u \n rttMs = %d \n",
stats.fractionLost, stats.cumulativeLost,
stats.extendedMax, stats.jitterSamples,
stats.rttMs);
TEST_LOG(" bytesSent = %d \n packetsSent = %d \n "
" bytesReceived = %d \n packetsReceived = %d \n",
stats.bytesSent, stats.packetsSent,
stats.bytesReceived, stats.packetsReceived);
TEST(SendApplicationDefinedRTCPPacket);
// just do some fail tests here
TEST_MUSTPASS(voe_base_->StopSend(0));
// should fail since sending is off
TEST_MUSTPASS(!rtp_rtcp->SendApplicationDefinedRTCPPacket(
0, 0, 0, "abcdabcdabcdabcdabcdabcdabcdabcd", 32));
MARK();
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_MUSTPASS(rtp_rtcp->SendApplicationDefinedRTCPPacket(
0, 0, 0, "abcdabcdabcdabcdabcdabcdabcdabcd", 32));
MARK();
TEST_MUSTPASS(rtp_rtcp->SetRTCPStatus(0, false));
// should fail since RTCP is off
TEST_MUSTPASS(!rtp_rtcp->SendApplicationDefinedRTCPPacket(
0, 0, 0, "abcdabcdabcdabcdabcdabcdabcdabcd", 32));
MARK();
TEST_MUSTPASS(rtp_rtcp->SetRTCPStatus(0, true));
TEST_MUSTPASS(rtp_rtcp->SendApplicationDefinedRTCPPacket(
0, 0, 0, "abcdabcdabcdabcdabcdabcdabcdabcd", 32));
MARK();
// invalid data length
TEST_MUSTPASS(!rtp_rtcp->SendApplicationDefinedRTCPPacket(
0, 0, 0, "abcdabcdabcdabcdabcdabcdabcdabc", 31));
MARK();
// invalid data vector
TEST_MUSTPASS(!rtp_rtcp->SendApplicationDefinedRTCPPacket(0, 0, 0, NULL, 0));
MARK();
ANL();
#ifdef WEBRTC_CODEC_RED
TEST(SetFECStatus);
ANL();
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
cinst.pltype = 126;
strcpy(cinst.plname, "red");
cinst.plfreq = 8000;
cinst.pacsize = 0;
cinst.channels = 1;
cinst.rate = 0;
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
cinst.pltype = 104;
strcpy(cinst.plname, "isac");
cinst.plfreq = 32000;
cinst.pacsize = 960;
cinst.channels = 1;
cinst.rate = 45000;
#else
cinst.pltype = 119;
strcpy(cinst.plname, "isaclc");
cinst.plfreq = 16000;
cinst.pacsize = 320;
cinst.channels = 1;
cinst.rate = 40000;
#endif
// We have to re-register the audio codec payload type as stopReceive will
// clean the database
TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
TEST_LOG("Start playing a file as microphone again \n");
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
TEST_MUSTPASS(rtp_rtcp->SetFECStatus(0, true, 126));
MARK();
TEST_LOG("Should sound OK with FEC enabled\n");
SLEEP(4000);
TEST_MUSTPASS(rtp_rtcp->SetFECStatus(0, false));
MARK();
#endif // #ifdef WEBRTC_CODEC_RED
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
ANL();
AOK();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestVideoSync
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestVideoSync()
{
PrepareTest("VideoSync");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEVideoSync* vsync = _mgr.VideoSyncPtr();
// check if this interface is supported
if (!vsync)
{
TEST_LOG("VoEVideoSync is not supported!");
return -1;
}
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename(
"VoEVideoSync_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
///////////////////////////
// Actual test starts here
TEST(SetInitTimestamp);
ANL();
TEST_MUSTPASS(!vsync->SetInitTimestamp(0, 12345));
TEST_MUSTPASS(voe_base_->StopSend(0));
MARK();
SLEEP(1000);
TEST_MUSTPASS(vsync->SetInitTimestamp(0, 12345));
TEST_MUSTPASS(voe_base_->StartSend(0));
MARK();
SLEEP(1000);
AOK();
ANL();
TEST(SetInitSequenceNumber);
ANL();
TEST_MUSTPASS(!vsync->SetInitSequenceNumber(0, 123));
TEST_MUSTPASS(voe_base_->StopSend(0));
MARK();
SLEEP(1000);
TEST_MUSTPASS(vsync->SetInitSequenceNumber(0, 123));
TEST_MUSTPASS(voe_base_->StartSend(0));
MARK();
SLEEP(1000);
AOK();
ANL();
unsigned int timeStamp;
TEST(GetPlayoutTimestamp);
ANL();
TEST_MUSTPASS(vsync->GetPlayoutTimestamp(0, timeStamp));
TEST_LOG("GetPlayoutTimestamp: %u", timeStamp);
SLEEP(1000);
TEST_MUSTPASS(vsync->GetPlayoutTimestamp(0, timeStamp));
TEST_LOG(" %u", timeStamp);
SLEEP(1000);
TEST_MUSTPASS(vsync->GetPlayoutTimestamp(0, timeStamp));
TEST_LOG(" %u\n", timeStamp);
AOK();
ANL();
TEST(SetMinimumPlayoutDelay);
ANL();
TEST_MUSTPASS(!vsync->SetMinimumPlayoutDelay(0, -1));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(!vsync->SetMinimumPlayoutDelay(0, 5000));
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
MARK();
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
AOK();
ANL();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestVolumeControl
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestVolumeControl()
{
PrepareTest("TestVolumeControl");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEVolumeControl* volume = _mgr.VolumeControlPtr();
#ifdef _TEST_FILE_
VoEFile* file = _mgr.FilePtr();
#endif
#ifdef _TEST_HARDWARE_
VoEHardware* hardware = _mgr.HardwarePtr();
#endif
#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(
GetFilename("VoEVolumeControl_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
#if (defined _TEST_HARDWARE_ && (!defined(MAC_IPHONE) && \
!defined(WEBRTC_ANDROID)))
#if defined(_WIN32)
TEST_MUSTPASS(hardware->SetRecordingDevice(-1));
TEST_MUSTPASS(hardware->SetPlayoutDevice(-1));
#else
TEST_MUSTPASS(hardware->SetRecordingDevice(0));
TEST_MUSTPASS(hardware->SetPlayoutDevice(0));
#endif
#endif
TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
TEST_MUSTPASS(voe_base_->StartReceive(0));
TEST_MUSTPASS(voe_base_->StartPlayout(0));
TEST_MUSTPASS(voe_base_->StartSend(0));
#ifdef _TEST_FILE_
TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
true, true));
#endif
////////////////////////////
// Actual test starts here
#if !defined(MAC_IPHONE)
TEST(SetSpeakerVolume);
ANL();
TEST_MUSTPASS(-1 != volume->SetSpeakerVolume(256));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
ANL();
#endif // #if !defined(MAC_IPHONE)
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
TEST(SetMicVolume); ANL();
TEST_MUSTPASS(-1 != volume->SetMicVolume(256)); MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
ANL();
#endif // #if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
#if !defined(MAC_IPHONE)
TEST(SetChannelOutputVolumeScaling);
ANL();
TEST_MUSTPASS(-1 != volume->SetChannelOutputVolumeScaling(0, (float)-0.1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetChannelOutputVolumeScaling(0, (float)10.1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
ANL();
#endif // #if !defined(MAC_IPHONE)
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
TEST(SetOutputVolumePan);
ANL();
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(-1, (float)-0.1,
(float)1.0));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(-1, (float)1.1,
(float)1.0));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(-1, (float)1.0,
(float)-0.1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(-1, (float)1.0,
(float)1.1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
ANL();
TEST(SetChannelOutputVolumePan);
ANL();
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(0, (float)-0.1,
(float)1.0));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(0, (float)1.1,
(float)1.0));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(0, (float)1.0,
(float)-0.1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
TEST_MUSTPASS(-1 != volume->SetOutputVolumePan(0, (float)1.0,
(float)1.1));
MARK();
TEST_MUSTPASS(VE_INVALID_ARGUMENT != voe_base_->LastError());
ANL();
#endif // #if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
#ifdef _TEST_FILE_
TEST_MUSTPASS(file->StopPlayingFileAsMicrophone(0));
#endif
TEST_MUSTPASS(voe_base_->StopSend(0));
TEST_MUSTPASS(voe_base_->StopPlayout(0));
TEST_MUSTPASS(voe_base_->StopReceive(0));
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
AOK();
ANL();
return 0;
}
// ----------------------------------------------------------------------------
// VoEExtendedTest::TestAPM
// ----------------------------------------------------------------------------
int VoEExtendedTest::TestAPM() {
PrepareTest("AudioProcessing");
VoEBase* voe_base_ = _mgr.BasePtr();
VoEAudioProcessing* apm = _mgr.APMPtr();
//#ifdef _USE_EXTENDED_TRACE_
TEST_MUSTPASS(VoiceEngine::SetTraceFile(GetFilename("apm_trace.txt")));
TEST_MUSTPASS(VoiceEngine::SetTraceFilter(kTraceStateInfo |
kTraceStateInfo |
kTraceWarning |
kTraceError |
kTraceCritical |
kTraceApiCall |
kTraceMemory |
kTraceInfo));
//#endif
TEST_MUSTPASS(voe_base_->Init());
TEST_MUSTPASS(voe_base_->CreateChannel());
///////////////////////////
// Actual test starts here
int i;
bool enabled;
//////
// EC
const int ECSleep = 0;
const int ECIterations = 10;
EcModes ECmode(kEcAec);
AecmModes AECMmode(kAecmSpeakerphone);
bool enabledCNG(false);
#if (defined(MAC_IPHONE) || defined(WEBRTC_ANDROID))
const EcModes ECmodeDefault(kEcAecm);
#else
const EcModes ECmodeDefault(kEcAec);
#endif
// verify default settings (should be OFF and mode as above)
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(ECmode != ECmodeDefault);
// set EC defaults
TEST_MUSTPASS(apm->SetEcStatus(false, kEcDefault));
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(ECmode != ECmodeDefault);
SLEEP(ECSleep);
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
// set kEcAec mode
TEST_MUSTPASS(apm->SetEcStatus(true, kEcAec));
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(ECmode != kEcAec);
SLEEP(ECSleep);
// set kEcConference mode
TEST_MUSTPASS(apm->SetEcStatus(true, kEcConference));
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(ECmode != kEcAec);
SLEEP(ECSleep);
#endif // #if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
// get default AECM mode, should the kAecmSpeakerphone as default
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_MUSTPASS(AECMmode != kAecmSpeakerphone);
TEST_MUSTPASS(enabledCNG != true);
TEST_MUSTPASS(apm->SetAecmMode(kAecmQuietEarpieceOrHeadset, false));
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_LOG("AECM: mode=%d, CNG: mode=%d\n", AECMmode,
enabledCNG);
TEST_MUSTPASS(AECMmode != kAecmQuietEarpieceOrHeadset);
TEST_MUSTPASS(enabledCNG != false);
// set kEcAecm mode
TEST_MUSTPASS(apm->SetEcStatus(true, kEcAecm));
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != true);
TEST_MUSTPASS(ECmode != kEcAecm);
SLEEP(ECSleep);
// AECM mode, get and set
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_MUSTPASS(AECMmode != kAecmQuietEarpieceOrHeadset);
TEST_MUSTPASS(enabledCNG != false);
TEST_MUSTPASS(apm->SetAecmMode(kAecmEarpiece, true));
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_LOG("AECM: mode=%d, CNG: mode=%d\n", AECMmode,
enabledCNG);
TEST_MUSTPASS(AECMmode != kAecmEarpiece);
TEST_MUSTPASS(enabledCNG != true);
TEST_MUSTPASS(apm->SetAecmMode(kAecmEarpiece, false));
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_LOG("AECM: mode=%d, CNG: mode=%d\n", AECMmode,
enabledCNG);
TEST_MUSTPASS(AECMmode != kAecmEarpiece);
TEST_MUSTPASS(enabledCNG != false);
TEST_MUSTPASS(apm->SetAecmMode(kAecmLoudEarpiece, true));
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_LOG("AECM: mode=%d, CNG: mode=%d\n", AECMmode,
enabledCNG);
TEST_MUSTPASS(AECMmode != kAecmLoudEarpiece);
TEST_MUSTPASS(enabledCNG != true);
TEST_MUSTPASS(apm->SetAecmMode(kAecmSpeakerphone, false));
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_LOG("AECM: mode=%d, CNG: mode=%d\n", AECMmode,
enabledCNG);
TEST_MUSTPASS(AECMmode != kAecmSpeakerphone);
TEST_MUSTPASS(enabledCNG != false);
TEST_MUSTPASS(apm->SetAecmMode(kAecmLoudSpeakerphone, true));
TEST_MUSTPASS(apm->GetAecmMode(AECMmode, enabledCNG));
TEST_LOG("AECM: mode=%d, CNG: mode=%d\n", AECMmode,
enabledCNG);
TEST_MUSTPASS(AECMmode != kAecmLoudSpeakerphone);
TEST_MUSTPASS(enabledCNG != true);
// verify that all modes are maintained when EC is disabled
TEST_MUSTPASS(apm->SetEcStatus(false));
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(ECmode != kEcAecm);
SLEEP(ECSleep);
// restore defaults
TEST_MUSTPASS(apm->SetEcStatus(true, kEcDefault));
TEST_MUSTPASS(apm->SetEcStatus(false, kEcUnchanged));
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(ECmode != ECmodeDefault);
SLEEP(ECSleep);
// enable/disable many times in a row
for (i = 0; i < ECIterations; i++) {
TEST_MUSTPASS(apm->SetEcStatus(true));
TEST_MUSTPASS(apm->SetEcStatus(false));
}
TEST_MUSTPASS(apm->GetEcStatus(enabled, ECmode));
TEST_LOG("EC: enabled=%d, ECmode=%d\n", enabled, ECmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(ECmode != ECmodeDefault);
SLEEP(ECSleep);
///////
// AGC
const int AGCSleep = 0;
const int AGCIterations = 10;
AgcModes AGCmode(kAgcAdaptiveAnalog);
#if (defined(MAC_IPHONE) || defined(WEBRTC_ANDROID))
bool enabledDefault = false;
AgcModes AGCmodeDefault(kAgcAdaptiveDigital);
#else
bool enabledDefault = true;
AgcModes AGCmodeDefault(kAgcAdaptiveAnalog);
#endif
// verify default settings (should be as above)
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(enabled != enabledDefault);
TEST_MUSTPASS(AGCmode != AGCmodeDefault);
// set default AGC mode
TEST_MUSTPASS(apm->SetAgcStatus(false, kAgcDefault));
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(AGCmode != AGCmodeDefault);
SLEEP(AGCSleep);
// set kAgcFixedDigital mode
TEST_MUSTPASS(apm->SetAgcStatus(true, kAgcFixedDigital));
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(AGCmode != kAgcFixedDigital);
SLEEP(AGCSleep);
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
// set kAgcAdaptiveAnalog mode
TEST_MUSTPASS(apm->SetAgcStatus(true, kAgcAdaptiveAnalog));
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(AGCmode != kAgcAdaptiveAnalog);
SLEEP(AGCSleep);
#endif // #if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
// set kAgcAdaptiveDigital mode
TEST_MUSTPASS(apm->SetAgcStatus(true, kAgcAdaptiveDigital));
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(AGCmode != kAgcAdaptiveDigital);
SLEEP(AGCSleep);
// verify that mode is maintained when AGC is disabled
TEST_MUSTPASS(apm->SetAgcStatus(false));
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(AGCmode != kAgcAdaptiveDigital);
SLEEP(AGCSleep);
// restore default AGC
TEST_MUSTPASS(apm->SetAgcStatus(enabledDefault, kAgcDefault));
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(enabled != enabledDefault);
TEST_MUSTPASS(AGCmode != AGCmodeDefault);
SLEEP(AGCSleep);
// enable/disable many times in a row
for (i = 0; i < AGCIterations; i++)
{
TEST_MUSTPASS(apm->SetAgcStatus(true));
TEST_MUSTPASS(apm->SetAgcStatus(false));
}
TEST_MUSTPASS(apm->GetAgcStatus(enabled, AGCmode));
TEST_LOG("AGC: enabled=%d, AGCmode=%d\n", enabled, AGCmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(AGCmode != AGCmodeDefault);
// --- Set/AGCConfig --
//
// targetLeveldBOv : [0, 31] (default 3)
// digitalCompressionGaindB: [0, 90] (default 9)
// limiterEnable : 0: Off, 1: On (default)
AgcConfig agcConfig;
AgcConfig agcConfigDefault;
const unsigned short targetLeveldBOvDefault = 3;
const unsigned short digitalCompressionGaindBDefault = 9;
const bool limiterEnableDefault = true;
const unsigned short targetLeveldBOvMax = 31;
const unsigned short digitalCompressionGaindBMax = 90;
// verify default configuration
TEST_MUSTPASS(apm->GetAgcConfig(agcConfigDefault));
TEST_LOG("AGC: targetLeveldBOv=%d, digitalCompressionGaindB=%d, "
"limiterEnable=%d\n",
agcConfigDefault.targetLeveldBOv,
agcConfigDefault.digitalCompressionGaindB,
agcConfigDefault.limiterEnable);
TEST_MUSTPASS(agcConfigDefault.targetLeveldBOv != targetLeveldBOvDefault);
TEST_MUSTPASS(agcConfigDefault.digitalCompressionGaindB !=
digitalCompressionGaindBDefault);
TEST_MUSTPASS(agcConfigDefault.limiterEnable != limiterEnableDefault);
// verify that invalid (out-of-range) parameters are detected
agcConfig = agcConfigDefault;
agcConfig.targetLeveldBOv = targetLeveldBOvMax + 1;
TEST_MUSTPASS(!apm->SetAgcConfig(agcConfig));
int err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_APM_ERROR);
agcConfig = agcConfigDefault;
agcConfig.digitalCompressionGaindB
= digitalCompressionGaindBMax + 1;
TEST_MUSTPASS(!apm->SetAgcConfig(agcConfig));
AgcConfig agcConfigSet;
agcConfigSet.digitalCompressionGaindB = 17;
agcConfigSet.targetLeveldBOv = 11;
agcConfigSet.limiterEnable = false;
// try some set/get operations using valid settings
TEST_MUSTPASS(apm->SetAgcConfig(agcConfigDefault));
TEST_MUSTPASS(apm->GetAgcConfig(agcConfig));
TEST_MUSTPASS(agcConfig.targetLeveldBOv != targetLeveldBOvDefault);
TEST_MUSTPASS(agcConfig.digitalCompressionGaindB !=
digitalCompressionGaindBDefault);
TEST_MUSTPASS(agcConfig.limiterEnable != limiterEnableDefault);
TEST_MUSTPASS(apm->SetAgcConfig(agcConfigSet));
TEST_MUSTPASS(apm->GetAgcConfig(agcConfig));
TEST_MUSTPASS(agcConfig.targetLeveldBOv != agcConfigSet.targetLeveldBOv);
TEST_MUSTPASS(agcConfig.digitalCompressionGaindB !=
agcConfigSet.digitalCompressionGaindB);
TEST_MUSTPASS(agcConfig.limiterEnable != agcConfigSet.limiterEnable);
// restore default AGC config
TEST_MUSTPASS(apm->SetAgcConfig(agcConfigDefault));
SLEEP(AGCSleep);
//////
// NS
const int NSSleep = 0;
const int NSIterations = 10;
NsModes NSmode(kNsHighSuppression);
NsModes NSmodeDefault(kNsModerateSuppression);
// verify default settings (should be OFF and mode as above)
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(NSmode != NSmodeDefault);
// enable default NS settings
// must set a value first time!
TEST_MUSTPASS(apm->SetNsStatus(false, kNsDefault));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(NSmode != NSmodeDefault);
SLEEP(NSSleep);
// set kNsLowSuppression mode
TEST_MUSTPASS(apm->SetNsStatus(true, kNsLowSuppression));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(NSmode != kNsLowSuppression);
SLEEP(NSSleep);
// set kNsModerateSuppression mode
TEST_MUSTPASS(apm->SetNsStatus(true, kNsModerateSuppression));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(NSmode != kNsModerateSuppression);
SLEEP(NSSleep);
// set kNsHighSuppression mode
TEST_MUSTPASS(apm->SetNsStatus(true, kNsHighSuppression));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(NSmode != kNsHighSuppression);
SLEEP(NSSleep);
// set kNsVeryHighSuppression mode
TEST_MUSTPASS(apm->SetNsStatus(true, kNsVeryHighSuppression));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(NSmode != kNsVeryHighSuppression);
SLEEP(NSSleep);
// set kNsVeryHighSuppression mode
TEST_MUSTPASS(apm->SetNsStatus(true, kNsConference));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(NSmode != kNsHighSuppression);
SLEEP(NSSleep);
// verify that mode is maintained when NS is disabled
TEST_MUSTPASS(apm->SetNsStatus(false));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(NSmode != kNsHighSuppression);
SLEEP(NSSleep);
// restore default NS
TEST_MUSTPASS(apm->SetNsStatus(true, kNsDefault));
TEST_MUSTPASS(apm->SetNsStatus(false));
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(NSmode != NSmodeDefault);
SLEEP(NSSleep);
// enable/disable many times in a row
for (i = 0; i < NSIterations; i++) {
TEST_MUSTPASS(apm->SetNsStatus(true));
TEST_MUSTPASS(apm->SetNsStatus(false));
}
TEST_MUSTPASS(apm->GetNsStatus(enabled, NSmode));
TEST_LOG("NS: enabled=%d, NSmode=%d\n", enabled, NSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(NSmode != NSmodeDefault);
SLEEP(NSSleep);
//////////////////////////////////
// Ec Metrics
#if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
TEST(GetEcMetricsStatus);
ANL();
TEST(SetEcMetricsStatus);
ANL();
TEST_MUSTPASS(apm->GetEcMetricsStatus(enabled));
MARK();
TEST_MUSTPASS(enabled != false);
MARK(); // should be OFF by default
TEST_MUSTPASS(apm->SetEcMetricsStatus(true));
MARK();
TEST_MUSTPASS(apm->GetEcMetricsStatus(enabled));
MARK();
TEST_MUSTPASS(enabled != true);
MARK();
TEST_MUSTPASS(apm->SetEcMetricsStatus(false));
MARK();
TEST_MUSTPASS(apm->GetEcMetricsStatus(enabled));
MARK();
TEST_MUSTPASS(enabled != false);
MARK();
AOK();
ANL();
TEST(GetEchoMetrics);
ANL();
int ERL, ERLE, RERL, A_NLP;
TEST_MUSTPASS(-1 != apm->GetEchoMetrics(ERL, ERLE, RERL, A_NLP));
MARK(); // Should fail since not activated.
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_APM_ERROR);
TEST_MUSTPASS(apm->SetEcMetricsStatus(true));
TEST_MUSTPASS(-1 != apm->GetEchoMetrics(ERL, ERLE, RERL, A_NLP));
MARK(); // Should fail since AEC is off.
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_APM_ERROR);
TEST_MUSTPASS(apm->SetEcStatus(true));
TEST_MUSTPASS(apm->GetEchoMetrics(ERL, ERLE, RERL, A_NLP));
MARK(); // Should work now.
TEST_LOG("\nEcho: ERL=%d, ERLE=%d, RERL=%d, A_NLP=%d [dB]\n",
ERL, ERLE, RERL, A_NLP);
TEST_MUSTPASS(apm->SetEcMetricsStatus(false));
TEST_MUSTPASS(apm->SetEcStatus(false));
AOK();
ANL();
TEST(GetEcDelayMetrics);
ANL();
int delay_median = 0;
int delay_std = 0;
TEST_MUSTPASS(-1 != apm->GetEcDelayMetrics(delay_median, delay_std));
MARK(); // Should fail since not activated.
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_APM_ERROR);
TEST_MUSTPASS(apm->SetEcMetricsStatus(true));
TEST_MUSTPASS(-1 != apm->GetEcDelayMetrics(delay_median, delay_std));
MARK(); // Should fail since AEC is off.
err = voe_base_->LastError();
TEST_MUSTPASS(err != VE_APM_ERROR);
TEST_MUSTPASS(apm->SetEcStatus(true));
TEST_MUSTPASS(apm->GetEcDelayMetrics(delay_median, delay_std));
MARK(); // Should work now.
TEST_LOG("\nEC Delay: median=%d, std=%d [ms]\n", delay_median, delay_std);
TEST_MUSTPASS(apm->SetEcMetricsStatus(false));
TEST_MUSTPASS(apm->SetEcStatus(false));
AOK();
ANL();
#endif // #if (!defined(MAC_IPHONE) && !defined(WEBRTC_ANDROID))
// far-end AudioProcessing
///////
// AGC
AgcModes rxAGCmode(kAgcAdaptiveDigital);
AgcModes rxAGCmodeDefault(kAgcAdaptiveDigital);
bool rxEnabledDefault = false;
// verify default settings (should be as above)
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(enabled != rxEnabledDefault);
TEST_MUSTPASS(rxAGCmode != rxAGCmodeDefault);
// set default AGC mode
TEST_MUSTPASS(apm->SetRxAgcStatus(0, false, kAgcDefault));
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxAGCmode != rxAGCmodeDefault);
SLEEP(AGCSleep);
// set kAgcAdaptiveAnalog mode, should fail
TEST_MUSTPASS(!apm->SetRxAgcStatus(0, true, kAgcAdaptiveAnalog));
// set kAgcFixedDigital mode
TEST_MUSTPASS(apm->SetRxAgcStatus(0, true, kAgcFixedDigital));
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(rxAGCmode != kAgcFixedDigital);
SLEEP(AGCSleep);
// set kAgcAdaptiveDigital mode
TEST_MUSTPASS(apm->SetRxAgcStatus(0, true, kAgcAdaptiveDigital));
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(rxAGCmode != kAgcAdaptiveDigital);
SLEEP(AGCSleep);
// verify that mode is maintained when AGC is disabled
TEST_MUSTPASS(apm->SetRxAgcStatus(0, false));
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxAGCmode != kAgcAdaptiveDigital);
SLEEP(AGCSleep);
// restore default AGC
TEST_MUSTPASS(apm->SetRxAgcStatus(0, enabledDefault, kAgcDefault));
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(enabled != enabledDefault);
TEST_MUSTPASS(rxAGCmode != rxAGCmodeDefault);
SLEEP(AGCSleep);
// enable/disable many times in a row
for (i = 0; i < AGCIterations; i++) {
TEST_MUSTPASS(apm->SetRxAgcStatus(0, true));
TEST_MUSTPASS(apm->SetRxAgcStatus(0, false));
}
TEST_MUSTPASS(apm->GetRxAgcStatus(0, enabled, rxAGCmode));
TEST_LOG("rxAGC: enabled=%d, AGCmode=%d\n", enabled,
rxAGCmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxAGCmode != rxAGCmodeDefault);
// --- Set/GetAgcConfig --
// targetLeveldBOv : [0, 31] (default 3)
// digitalCompressionGaindB: [0, 90] (default 9)
// limiterEnable : 0: Off, 1: On (default)
AgcConfig rxAGCConfig;
AgcConfig rxAGCConfigDefault;
const unsigned short rxTargetLeveldBOvDefault = 3;
const unsigned short rxDigitalCompressionGaindBDefault = 9;
const bool rxLimiterEnableDefault = true;
const unsigned short rxTargetLeveldBOvMax = 31;
const unsigned short rxDigitalCompressionGaindBMax = 90;
// verify default configuration
TEST_MUSTPASS(apm->GetRxAgcConfig(0, rxAGCConfigDefault));
TEST_LOG(
"rxAGC: targetLeveldBOv=%u, digitalCompressionGaindB=%u, "
"limiterEnable=%d\n",
rxAGCConfigDefault.targetLeveldBOv,
rxAGCConfigDefault.digitalCompressionGaindB,
rxAGCConfigDefault.limiterEnable);
TEST_MUSTPASS(rxAGCConfigDefault.targetLeveldBOv !=
rxTargetLeveldBOvDefault);
TEST_MUSTPASS(rxAGCConfigDefault.digitalCompressionGaindB !=
rxDigitalCompressionGaindBDefault);
TEST_MUSTPASS(rxAGCConfigDefault.limiterEnable != rxLimiterEnableDefault);
// verify that invalid (out-of-range) parameters are detected
rxAGCConfig = rxAGCConfigDefault;
rxAGCConfig.targetLeveldBOv = rxTargetLeveldBOvMax + 1;
TEST_MUSTPASS(!apm->SetRxAgcConfig(0, rxAGCConfig));
int rxErr = voe_base_->LastError();
TEST_MUSTPASS(rxErr != VE_APM_ERROR);
rxAGCConfig = rxAGCConfigDefault;
rxAGCConfig.digitalCompressionGaindB
= rxDigitalCompressionGaindBMax + 1;
TEST_MUSTPASS(!apm->SetRxAgcConfig(0, rxAGCConfig));
AgcConfig rxAGCConfigSet;
rxAGCConfigSet.digitalCompressionGaindB = 17;
rxAGCConfigSet.targetLeveldBOv = 11;
rxAGCConfigSet.limiterEnable = false;
// try some set/get operations using valid settings
TEST_MUSTPASS(apm->SetRxAgcConfig(0, rxAGCConfigDefault));
TEST_MUSTPASS(apm->GetRxAgcConfig(0, rxAGCConfig));
TEST_MUSTPASS(rxAGCConfig.targetLeveldBOv != rxTargetLeveldBOvDefault);
TEST_MUSTPASS(rxAGCConfig.digitalCompressionGaindB !=
rxDigitalCompressionGaindBDefault);
TEST_MUSTPASS(rxAGCConfig.limiterEnable != rxLimiterEnableDefault);
TEST_MUSTPASS(apm->SetRxAgcConfig(0, rxAGCConfigSet));
TEST_MUSTPASS(apm->GetRxAgcConfig(0, rxAGCConfig));
TEST_MUSTPASS(rxAGCConfig.targetLeveldBOv !=
rxAGCConfigSet.targetLeveldBOv);
TEST_MUSTPASS(rxAGCConfig.digitalCompressionGaindB !=
rxAGCConfigSet.digitalCompressionGaindB);
TEST_MUSTPASS(rxAGCConfig.limiterEnable != rxAGCConfigSet.limiterEnable);
// restore default AGC config
TEST_MUSTPASS(apm->SetRxAgcConfig(0, rxAGCConfigDefault));
SLEEP(AGCSleep);
//////
// NS
NsModes rxNSmode(kNsHighSuppression);
NsModes rxNSmodeDefault(kNsModerateSuppression);
// verify default settings (should be OFF and mode as above)
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxNSmode != rxNSmodeDefault);
// enable default NS settings
// must set a value first time!
TEST_MUSTPASS(apm->SetRxNsStatus(0, false, kNsDefault));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxNSmode != rxNSmodeDefault);
SLEEP(NSSleep);
// set kNsLowSuppression mode
TEST_MUSTPASS(apm->SetRxNsStatus(0, true, kNsLowSuppression));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(rxNSmode != kNsLowSuppression);
SLEEP(NSSleep);
// set kNsModerateSuppression mode
TEST_MUSTPASS(apm->SetRxNsStatus(0, true, kNsModerateSuppression));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(rxNSmode != kNsModerateSuppression);
SLEEP(NSSleep);
// set kNsHighSuppression mode
TEST_MUSTPASS(apm->SetRxNsStatus(0, true, kNsHighSuppression));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(rxNSmode != kNsHighSuppression);
SLEEP(NSSleep);
// set kNsVeryHighSuppression mode
TEST_MUSTPASS(apm->SetRxNsStatus(0, true, kNsVeryHighSuppression));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(rxNSmode != kNsVeryHighSuppression);
SLEEP(NSSleep);
// set kNsVeryHighSuppression mode
TEST_MUSTPASS(apm->SetRxNsStatus(0, true, kNsConference));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(rxNSmode != kNsHighSuppression);
SLEEP(NSSleep);
// verify that mode is maintained when NS is disabled
TEST_MUSTPASS(apm->SetRxNsStatus(0, false));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxNSmode != kNsHighSuppression);
SLEEP(NSSleep);
// restore default NS
TEST_MUSTPASS(apm->SetRxNsStatus(0, true, kNsDefault));
TEST_MUSTPASS(apm->SetRxNsStatus(0, false));
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxNSmode != NSmodeDefault);
SLEEP(NSSleep);
// enable/disable many times in a row
for (i = 0; i < NSIterations; i++)
{
TEST_MUSTPASS(apm->SetRxNsStatus(0, true));
TEST_MUSTPASS(apm->SetRxNsStatus(0, false));
}
TEST_MUSTPASS(apm->GetRxNsStatus(0, enabled, rxNSmode));
TEST_LOG("rxNS: enabled=%d, NSmode=%d\n", enabled, rxNSmode);
TEST_MUSTPASS(enabled != false);
TEST_MUSTPASS(rxNSmode != NSmodeDefault);
SLEEP(NSSleep);
/////////////////////////////
// StartDebugRecording
////////////////////////////
// StopDebugRecording
TEST_LOG("StartDebugRecording");
TEST_MUSTPASS(apm->StartDebugRecording(GetFilename("apm_debug.txt")));
SLEEP(1000);
TEST_LOG("StopDebugRecording");
TEST_MUSTPASS(apm->StopDebugRecording());
TEST_MUSTPASS(voe_base_->DeleteChannel(0));
TEST_MUSTPASS(voe_base_->Terminate());
return 0;
}
} // namespace voetest