This is a somewhat involved refactoring of this class. Here's an overview of the changes: * FileWrapper can now be used as a regular class and instances allocated on the stack. * The type now has support for move semantics and copy isn't allowed. * New public ctor with FILE* that can be used instead of OpenFromFileHandle. * New static Open() method. The intent of this is to allow opening a file and getting back a FileWrapper instance. Using this method instead of Create(), will allow us in the future to make the FILE* member pointer, to be const and simplify threading (get rid of the lock). * Rename the Open() method to is_open() and make it inline. * The FileWrapper interface is no longer a pure virtual interface. There's only one implementation so there's no need to go through a vtable for everything. * Functionality offered by the class, is now reduced. No support for looping (not clear if that was actually useful to users of that flag), no need to implement the 'read_only_' functionality in the class, since file APIs implement that already, no support for *not* managing the file handle (this wasn't used). OpenFromFileHandle always "manages" the file. * Delete the unused WriteText() method and don't support opening files in text mode. Text mode is only different on Windows and on Windows it translates \n to \r\n, which means that files such as log files, could have a slightly different format on Windows than other platforms. Besides, tools on Windows can handle UNIX line endings. * Remove FileName(), change Trace code to manage its own path. * Rename id_ member variable to file_. * Removed the open_ member variable since the same functionality can be gotten from just checking the file pointer. * Don't call CloseFile inside of Write. Write shouldn't be changing the state of the class beyond just attempting to write. * Remove concept of looping from FileWrapper and never close inside of Read() * Changed stream base classes to inherit from a common base class instead of both defining the Rewind method. Ultimately, Id' like to remove these interfaces and just have FileWrapper. * Remove read_only param from OpenFromFileHandle * Renamed size_in_bytes_ to position_, since it gets set to 0 when Rewind() is called (and the size actually does not change). * Switch out rw lock for CriticalSection. The r/w lock was only used for reading when checking the open_ flag. BUG= Review-Url: https://codereview.webrtc.org/2054373002 Cr-Commit-Position: refs/heads/master@{#13155}
2737 lines
83 KiB
C++
2737 lines
83 KiB
C++
/*
|
|
* Copyright (c) 2012 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 <assert.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#if defined(_WIN32)
|
|
#include <conio.h>
|
|
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
|
|
#include <termios.h> // tcgetattr
|
|
#endif
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "webrtc/modules/audio_device/test/func_test_manager.h"
|
|
#include "webrtc/system_wrappers/include/sleep.h"
|
|
#include "webrtc/test/testsupport/fileutils.h"
|
|
|
|
#include "webrtc/modules/audio_device/audio_device_config.h"
|
|
#include "webrtc/modules/audio_device/audio_device_impl.h"
|
|
|
|
#ifndef __GNUC__
|
|
// Disable warning message ('sprintf': name was marked as #pragma deprecated)
|
|
#pragma warning( disable : 4995 )
|
|
// Disable warning message 4996 ('scanf': This function or variable may be unsafe)
|
|
#pragma warning( disable : 4996 )
|
|
#endif
|
|
|
|
const char* RecordedMicrophoneFile = "recorded_microphone_mono_48.pcm";
|
|
const char* RecordedMicrophoneVolumeFile =
|
|
"recorded_microphone_volume_mono_48.pcm";
|
|
const char* RecordedMicrophoneMuteFile = "recorded_microphone_mute_mono_48.pcm";
|
|
const char* RecordedMicrophoneBoostFile =
|
|
"recorded_microphone_boost_mono_48.pcm";
|
|
const char* RecordedMicrophoneAGCFile = "recorded_microphone_AGC_mono_48.pcm";
|
|
const char* RecordedSpeakerFile = "recorded_speaker_48.pcm";
|
|
|
|
#if defined(WEBRTC_IOS) || defined(ANDROID)
|
|
#define USE_SLEEP_AS_PAUSE
|
|
#else
|
|
//#define USE_SLEEP_AS_PAUSE
|
|
#endif
|
|
|
|
// Sets the default pause time if using sleep as pause
|
|
#define DEFAULT_PAUSE_TIME 5000
|
|
|
|
#if defined(USE_SLEEP_AS_PAUSE)
|
|
#define PAUSE(a) SleepMs(a);
|
|
#else
|
|
#define PAUSE(a) WaitForKey();
|
|
#endif
|
|
|
|
// Helper functions
|
|
#if !defined(WEBRTC_IOS)
|
|
char* GetFilename(char* filename)
|
|
{
|
|
return filename;
|
|
}
|
|
const char* GetFilename(const char* filename)
|
|
{
|
|
return filename;
|
|
}
|
|
char* GetResource(char* resource)
|
|
{
|
|
return resource;
|
|
}
|
|
const char* GetResource(const char* resource)
|
|
{
|
|
return resource;
|
|
}
|
|
#endif
|
|
|
|
#if !defined(USE_SLEEP_AS_PAUSE)
|
|
static void WaitForKey() {
|
|
#if defined(_WIN32)
|
|
_getch();
|
|
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
|
|
struct termios oldt, newt;
|
|
|
|
tcgetattr( STDIN_FILENO, &oldt );
|
|
|
|
// we don't want getchar to echo!
|
|
|
|
newt = oldt;
|
|
newt.c_lflag &= ~( ICANON | ECHO );
|
|
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
|
|
|
|
// catch any newline that's hanging around...
|
|
// you'll have to hit enter twice if you
|
|
// choose enter out of all available keys
|
|
|
|
if (getc(stdin) == '\n')
|
|
{
|
|
getc(stdin);
|
|
}
|
|
|
|
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
|
|
#endif // defined(_WIN32)
|
|
}
|
|
#endif // !defined(USE_SLEEP_AS_PAUSE)
|
|
|
|
namespace webrtc
|
|
{
|
|
|
|
AudioEventObserver::AudioEventObserver(AudioDeviceModule* audioDevice)
|
|
{
|
|
}
|
|
|
|
AudioEventObserver::~AudioEventObserver()
|
|
{
|
|
}
|
|
|
|
void AudioEventObserver::OnErrorIsReported(const ErrorCode error)
|
|
{
|
|
TEST_LOG("\n[*** ERROR ***] => OnErrorIsReported(%d)\n \n", error);
|
|
_error = error;
|
|
}
|
|
|
|
|
|
void AudioEventObserver::OnWarningIsReported(const WarningCode warning)
|
|
{
|
|
TEST_LOG("\n[*** WARNING ***] => OnWarningIsReported(%d)\n \n", warning);
|
|
_warning = warning;
|
|
}
|
|
|
|
AudioTransportImpl::AudioTransportImpl(AudioDeviceModule* audioDevice) :
|
|
_audioDevice(audioDevice),
|
|
_playFromFile(false),
|
|
_fullDuplex(false),
|
|
_speakerVolume(false),
|
|
_speakerMute(false),
|
|
_microphoneVolume(false),
|
|
_microphoneMute(false),
|
|
_microphoneBoost(false),
|
|
_microphoneAGC(false),
|
|
_loopBackMeasurements(false),
|
|
_playFile(*FileWrapper::Create()),
|
|
_recCount(0),
|
|
_playCount(0)
|
|
{
|
|
_resampler.Reset(48000, 48000, 2);
|
|
}
|
|
|
|
AudioTransportImpl::~AudioTransportImpl()
|
|
{
|
|
_playFile.Flush();
|
|
_playFile.CloseFile();
|
|
delete &_playFile;
|
|
|
|
for (AudioPacketList::iterator iter = _audioList.begin();
|
|
iter != _audioList.end(); ++iter) {
|
|
delete *iter;
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// AudioTransportImpl::SetFilePlayout
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int32_t AudioTransportImpl::SetFilePlayout(bool enable, const char* fileName)
|
|
{
|
|
_playFromFile = enable;
|
|
if (enable)
|
|
return _playFile.OpenFile(fileName, true) ? 0 : -1;
|
|
_playFile.CloseFile();
|
|
return 0;
|
|
}
|
|
|
|
void AudioTransportImpl::SetFullDuplex(bool enable)
|
|
{
|
|
_fullDuplex = enable;
|
|
|
|
for (AudioPacketList::iterator iter = _audioList.begin();
|
|
iter != _audioList.end(); ++iter) {
|
|
delete *iter;
|
|
}
|
|
_audioList.clear();
|
|
}
|
|
|
|
int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
|
const void* audioSamples,
|
|
const size_t nSamples,
|
|
const size_t nBytesPerSample,
|
|
const size_t nChannels,
|
|
const uint32_t samplesPerSec,
|
|
const uint32_t totalDelayMS,
|
|
const int32_t clockDrift,
|
|
const uint32_t currentMicLevel,
|
|
const bool keyPressed,
|
|
uint32_t& newMicLevel)
|
|
{
|
|
if (_fullDuplex && _audioList.size() < 15)
|
|
{
|
|
AudioPacket* packet = new AudioPacket();
|
|
memcpy(packet->dataBuffer, audioSamples, nSamples * nBytesPerSample);
|
|
packet->nSamples = nSamples;
|
|
packet->nBytesPerSample = nBytesPerSample;
|
|
packet->nChannels = nChannels;
|
|
packet->samplesPerSec = samplesPerSec;
|
|
_audioList.push_back(packet);
|
|
}
|
|
|
|
_recCount++;
|
|
if (_recCount % 100 == 0)
|
|
{
|
|
bool addMarker(true);
|
|
|
|
if (_loopBackMeasurements)
|
|
{
|
|
addMarker = false;
|
|
}
|
|
|
|
if (_microphoneVolume)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
uint32_t minVolume(0);
|
|
uint32_t volume(0);
|
|
uint16_t stepSize(0);
|
|
EXPECT_EQ(0, _audioDevice->MaxMicrophoneVolume(&maxVolume));
|
|
EXPECT_EQ(0, _audioDevice->MinMicrophoneVolume(&minVolume));
|
|
EXPECT_EQ(0, _audioDevice->MicrophoneVolumeStepSize(&stepSize));
|
|
EXPECT_EQ(0, _audioDevice->MicrophoneVolume(&volume));
|
|
if (volume == 0)
|
|
{
|
|
TEST_LOG("[0]");
|
|
addMarker = false;
|
|
}
|
|
int stepScale = (int) ((maxVolume - minVolume) / (stepSize * 10));
|
|
volume += (stepScale * stepSize);
|
|
if (volume > maxVolume)
|
|
{
|
|
TEST_LOG("[MAX]");
|
|
volume = 0;
|
|
addMarker = false;
|
|
}
|
|
EXPECT_EQ(0, _audioDevice->SetMicrophoneVolume(volume));
|
|
}
|
|
|
|
if (_microphoneAGC)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
uint32_t minVolume(0);
|
|
uint16_t stepSize(0);
|
|
EXPECT_EQ(0, _audioDevice->MaxMicrophoneVolume(&maxVolume));
|
|
EXPECT_EQ(0, _audioDevice->MinMicrophoneVolume(&minVolume));
|
|
EXPECT_EQ(0, _audioDevice->MicrophoneVolumeStepSize(&stepSize));
|
|
// emulate real AGC (min->max->min->max etc.)
|
|
if (currentMicLevel <= 1)
|
|
{
|
|
TEST_LOG("[MIN]");
|
|
addMarker = false;
|
|
}
|
|
int stepScale = (int) ((maxVolume - minVolume) / (stepSize * 10));
|
|
newMicLevel = currentMicLevel + (stepScale * stepSize);
|
|
if (newMicLevel > maxVolume)
|
|
{
|
|
TEST_LOG("[MAX]");
|
|
newMicLevel = 1; // set lowest (non-zero) AGC level
|
|
addMarker = false;
|
|
}
|
|
}
|
|
|
|
if (_microphoneMute && (_recCount % 500 == 0))
|
|
{
|
|
bool muted(false);
|
|
EXPECT_EQ(0, _audioDevice->MicrophoneMute(&muted));
|
|
muted = !muted;
|
|
EXPECT_EQ(0, _audioDevice->SetMicrophoneMute(muted));
|
|
if (muted)
|
|
{
|
|
TEST_LOG("[MUTE ON]");
|
|
addMarker = false;
|
|
} else
|
|
{
|
|
TEST_LOG("[MUTE OFF]");
|
|
addMarker = false;
|
|
}
|
|
}
|
|
|
|
if (_microphoneBoost && (_recCount % 500 == 0))
|
|
{
|
|
bool boosted(false);
|
|
EXPECT_EQ(0, _audioDevice->MicrophoneBoost(&boosted));
|
|
boosted = !boosted;
|
|
EXPECT_EQ(0, _audioDevice->SetMicrophoneBoost(boosted));
|
|
if (boosted)
|
|
{
|
|
TEST_LOG("[BOOST ON]");
|
|
addMarker = false;
|
|
} else
|
|
{
|
|
TEST_LOG("[BOOST OFF]");
|
|
addMarker = false;
|
|
}
|
|
}
|
|
|
|
if ((nChannels == 1) && addMarker)
|
|
{
|
|
// mono
|
|
TEST_LOG("-");
|
|
} else if ((nChannels == 2) && (nBytesPerSample == 2) && addMarker)
|
|
{
|
|
AudioDeviceModule::ChannelType
|
|
chType(AudioDeviceModule::kChannelLeft);
|
|
EXPECT_EQ(0, _audioDevice->RecordingChannel(&chType));
|
|
if (chType == AudioDeviceModule::kChannelLeft)
|
|
TEST_LOG("-|");
|
|
else
|
|
TEST_LOG("|-");
|
|
} else if (addMarker)
|
|
{
|
|
// stereo
|
|
TEST_LOG("--");
|
|
}
|
|
|
|
if (nChannels == 2 && nBytesPerSample == 2)
|
|
{
|
|
// TEST_LOG("=> emulated mono (one channel exctracted from stereo input)\n");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int32_t AudioTransportImpl::NeedMorePlayData(
|
|
const size_t nSamples,
|
|
const size_t nBytesPerSample,
|
|
const size_t nChannels,
|
|
const uint32_t samplesPerSec,
|
|
void* audioSamples,
|
|
size_t& nSamplesOut,
|
|
int64_t* elapsed_time_ms,
|
|
int64_t* ntp_time_ms)
|
|
{
|
|
if (_fullDuplex)
|
|
{
|
|
if (_audioList.empty())
|
|
{
|
|
// use zero stuffing when not enough data
|
|
memset(audioSamples, 0, nBytesPerSample * nSamples);
|
|
} else
|
|
{
|
|
AudioPacket* packet = _audioList.front();
|
|
_audioList.pop_front();
|
|
if (packet)
|
|
{
|
|
int ret(0);
|
|
size_t lenOut(0);
|
|
int16_t tmpBuf_96kHz[80 * 12];
|
|
int16_t* ptr16In = NULL;
|
|
int16_t* ptr16Out = NULL;
|
|
|
|
const size_t nSamplesIn = packet->nSamples;
|
|
const size_t nChannelsIn = packet->nChannels;
|
|
const uint32_t samplesPerSecIn = packet->samplesPerSec;
|
|
const size_t nBytesPerSampleIn = packet->nBytesPerSample;
|
|
|
|
int32_t fsInHz(samplesPerSecIn);
|
|
int32_t fsOutHz(samplesPerSec);
|
|
|
|
if (fsInHz == 44100)
|
|
fsInHz = 44000;
|
|
|
|
if (fsOutHz == 44100)
|
|
fsOutHz = 44000;
|
|
|
|
if (nChannelsIn == 2 && nBytesPerSampleIn == 4)
|
|
{
|
|
// input is stereo => we will resample in stereo
|
|
ret = _resampler.ResetIfNeeded(fsInHz, fsOutHz, 2);
|
|
if (ret == 0)
|
|
{
|
|
if (nChannels == 2)
|
|
{
|
|
_resampler.Push(
|
|
(const int16_t*) packet->dataBuffer,
|
|
2 * nSamplesIn, (int16_t*) audioSamples,
|
|
2 * nSamples, lenOut);
|
|
} else
|
|
{
|
|
_resampler.Push(
|
|
(const int16_t*) packet->dataBuffer,
|
|
2 * nSamplesIn, tmpBuf_96kHz, 2 * nSamples,
|
|
lenOut);
|
|
|
|
ptr16In = &tmpBuf_96kHz[0];
|
|
ptr16Out = (int16_t*) audioSamples;
|
|
|
|
// do stereo -> mono
|
|
for (size_t i = 0; i < nSamples; i++)
|
|
{
|
|
*ptr16Out = *ptr16In; // use left channel
|
|
ptr16Out++;
|
|
ptr16In++;
|
|
ptr16In++;
|
|
}
|
|
}
|
|
assert(2*nSamples == lenOut);
|
|
} else
|
|
{
|
|
if (_playCount % 100 == 0)
|
|
TEST_LOG(
|
|
"ERROR: unable to resample from %d to %d\n",
|
|
samplesPerSecIn, samplesPerSec);
|
|
}
|
|
} else
|
|
{
|
|
// input is mono (can be "reduced from stereo" as well) =>
|
|
// we will resample in mono
|
|
ret = _resampler.ResetIfNeeded(fsInHz, fsOutHz, 1);
|
|
if (ret == 0)
|
|
{
|
|
if (nChannels == 1)
|
|
{
|
|
_resampler.Push(
|
|
(const int16_t*) packet->dataBuffer, nSamplesIn,
|
|
(int16_t*) audioSamples, nSamples, lenOut);
|
|
} else
|
|
{
|
|
_resampler.Push(
|
|
(const int16_t*) packet->dataBuffer, nSamplesIn,
|
|
tmpBuf_96kHz, nSamples, lenOut);
|
|
|
|
ptr16In = &tmpBuf_96kHz[0];
|
|
ptr16Out = (int16_t*) audioSamples;
|
|
|
|
// do mono -> stereo
|
|
for (size_t i = 0; i < nSamples; i++)
|
|
{
|
|
*ptr16Out = *ptr16In; // left
|
|
ptr16Out++;
|
|
*ptr16Out = *ptr16In; // right (same as left sample)
|
|
ptr16Out++;
|
|
ptr16In++;
|
|
}
|
|
}
|
|
assert(nSamples == lenOut);
|
|
} else
|
|
{
|
|
if (_playCount % 100 == 0)
|
|
TEST_LOG("ERROR: unable to resample from %d to %d\n",
|
|
samplesPerSecIn, samplesPerSec);
|
|
}
|
|
}
|
|
nSamplesOut = nSamples;
|
|
delete packet;
|
|
}
|
|
}
|
|
} // if (_fullDuplex)
|
|
|
|
if (_playFromFile && _playFile.is_open()) {
|
|
int16_t fileBuf[480];
|
|
|
|
// read mono-file
|
|
int32_t len = _playFile.Read((int8_t*)fileBuf, 2 * nSamples);
|
|
if (len != 2 * (int32_t)nSamples) {
|
|
_playFile.Rewind();
|
|
_playFile.Read((int8_t*)fileBuf, 2 * nSamples);
|
|
}
|
|
|
|
// convert to stero if required
|
|
if (nChannels == 1) {
|
|
memcpy(audioSamples, fileBuf, 2 * nSamples);
|
|
} else {
|
|
// mono sample from file is duplicated and sent to left and right
|
|
// channels
|
|
int16_t* audio16 = (int16_t*)audioSamples;
|
|
for (size_t i = 0; i < nSamples; i++) {
|
|
(*audio16) = fileBuf[i]; // left
|
|
audio16++;
|
|
(*audio16) = fileBuf[i]; // right
|
|
audio16++;
|
|
}
|
|
}
|
|
} // if (_playFromFile && _playFile.is_open())
|
|
|
|
_playCount++;
|
|
|
|
if (_playCount % 100 == 0)
|
|
{
|
|
bool addMarker(true);
|
|
|
|
if (_speakerVolume)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
uint32_t minVolume(0);
|
|
uint32_t volume(0);
|
|
uint16_t stepSize(0);
|
|
EXPECT_EQ(0, _audioDevice->MaxSpeakerVolume(&maxVolume));
|
|
EXPECT_EQ(0, _audioDevice->MinSpeakerVolume(&minVolume));
|
|
EXPECT_EQ(0, _audioDevice->SpeakerVolumeStepSize(&stepSize));
|
|
EXPECT_EQ(0, _audioDevice->SpeakerVolume(&volume));
|
|
if (volume == 0)
|
|
{
|
|
TEST_LOG("[0]");
|
|
addMarker = false;
|
|
}
|
|
uint32_t step = (maxVolume - minVolume) / 10;
|
|
step = (step < stepSize ? stepSize : step);
|
|
volume += step;
|
|
if (volume > maxVolume)
|
|
{
|
|
TEST_LOG("[MAX]");
|
|
volume = 0;
|
|
addMarker = false;
|
|
}
|
|
EXPECT_EQ(0, _audioDevice->SetSpeakerVolume(volume));
|
|
}
|
|
|
|
if (_speakerMute && (_playCount % 500 == 0))
|
|
{
|
|
bool muted(false);
|
|
EXPECT_EQ(0, _audioDevice->SpeakerMute(&muted));
|
|
muted = !muted;
|
|
EXPECT_EQ(0, _audioDevice->SetSpeakerMute(muted));
|
|
if (muted)
|
|
{
|
|
TEST_LOG("[MUTE ON]");
|
|
addMarker = false;
|
|
} else
|
|
{
|
|
TEST_LOG("[MUTE OFF]");
|
|
addMarker = false;
|
|
}
|
|
}
|
|
|
|
if (_loopBackMeasurements)
|
|
{
|
|
uint16_t recDelayMS(0);
|
|
uint16_t playDelayMS(0);
|
|
size_t nItemsInList(0);
|
|
|
|
nItemsInList = _audioList.size();
|
|
EXPECT_EQ(0, _audioDevice->RecordingDelay(&recDelayMS));
|
|
EXPECT_EQ(0, _audioDevice->PlayoutDelay(&playDelayMS));
|
|
TEST_LOG("Delay (rec+play)+buf: %3zu (%3u+%3u)+%3zu [ms]\n",
|
|
recDelayMS + playDelayMS + 10 * (nItemsInList + 1),
|
|
recDelayMS, playDelayMS, 10 * (nItemsInList + 1));
|
|
|
|
addMarker = false;
|
|
}
|
|
|
|
if ((nChannels == 1) && addMarker)
|
|
{
|
|
TEST_LOG("+");
|
|
} else if ((nChannels == 2) && addMarker)
|
|
{
|
|
TEST_LOG("++");
|
|
}
|
|
} // if (_playCount % 100 == 0)
|
|
|
|
nSamplesOut = nSamples;
|
|
|
|
return 0;
|
|
}
|
|
|
|
FuncTestManager::FuncTestManager() :
|
|
_audioDevice(NULL),
|
|
_audioEventObserver(NULL),
|
|
_audioTransport(NULL)
|
|
{
|
|
_playoutFile48 = webrtc::test::ResourcePath("audio_device\\audio_short48",
|
|
"pcm");
|
|
_playoutFile44 = webrtc::test::ResourcePath("audio_device\\audio_short44",
|
|
"pcm");
|
|
_playoutFile16 = webrtc::test::ResourcePath("audio_device\\audio_short16",
|
|
"pcm");
|
|
_playoutFile8 = webrtc::test::ResourcePath("audio_device\\audio_short8",
|
|
"pcm");
|
|
}
|
|
|
|
FuncTestManager::~FuncTestManager()
|
|
{
|
|
}
|
|
|
|
int32_t FuncTestManager::Init()
|
|
{
|
|
EXPECT_TRUE((_processThread = ProcessThread::Create("ProcessThread")) !=
|
|
NULL);
|
|
if (_processThread == NULL) {
|
|
return -1;
|
|
}
|
|
_processThread->Start();
|
|
|
|
// create the Audio Device module
|
|
EXPECT_TRUE((_audioDevice = AudioDeviceModule::Create(
|
|
555, ADM_AUDIO_LAYER)) != NULL);
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
EXPECT_EQ(1, _audioDevice->AddRef());
|
|
|
|
// register the Audio Device module
|
|
_processThread->RegisterModule(_audioDevice);
|
|
|
|
// register event observer
|
|
_audioEventObserver = new AudioEventObserver(_audioDevice);
|
|
EXPECT_EQ(0, _audioDevice->RegisterEventObserver(_audioEventObserver));
|
|
|
|
// register audio transport
|
|
_audioTransport = new AudioTransportImpl(_audioDevice);
|
|
EXPECT_EQ(0, _audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::Close()
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->RegisterEventObserver(NULL));
|
|
EXPECT_EQ(0, _audioDevice->RegisterAudioCallback(NULL));
|
|
EXPECT_EQ(0, _audioDevice->Terminate());
|
|
|
|
// release the ProcessThread object
|
|
if (_processThread)
|
|
{
|
|
_processThread->DeRegisterModule(_audioDevice);
|
|
_processThread->Stop();
|
|
_processThread.reset();
|
|
}
|
|
|
|
// delete the audio observer
|
|
if (_audioEventObserver)
|
|
{
|
|
delete _audioEventObserver;
|
|
_audioEventObserver = NULL;
|
|
}
|
|
|
|
// delete the audio transport
|
|
if (_audioTransport)
|
|
{
|
|
delete _audioTransport;
|
|
_audioTransport = NULL;
|
|
}
|
|
|
|
// release the AudioDeviceModule object
|
|
if (_audioDevice)
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->Release());
|
|
_audioDevice = NULL;
|
|
}
|
|
|
|
// return the PlatformThread (singleton)
|
|
Trace::ReturnTrace();
|
|
|
|
// PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::DoTest(const TestType testType)
|
|
{
|
|
switch (testType)
|
|
{
|
|
case TTAll:
|
|
TestAudioLayerSelection();
|
|
TestDeviceEnumeration();
|
|
TestDeviceSelection();
|
|
TestAudioTransport();
|
|
TestSpeakerVolume();
|
|
TestMicrophoneVolume();
|
|
TestLoopback();
|
|
FALLTHROUGH();
|
|
case TTAudioLayerSelection:
|
|
TestAudioLayerSelection();
|
|
break;
|
|
case TTDeviceEnumeration:
|
|
TestDeviceEnumeration();
|
|
break;
|
|
case TTDeviceSelection:
|
|
TestDeviceSelection();
|
|
break;
|
|
case TTAudioTransport:
|
|
TestAudioTransport();
|
|
break;
|
|
case TTSpeakerVolume:
|
|
TestSpeakerVolume();
|
|
break;
|
|
case TTMicrophoneVolume:
|
|
TestMicrophoneVolume();
|
|
break;
|
|
case TTSpeakerMute:
|
|
TestSpeakerMute();
|
|
break;
|
|
case TTMicrophoneMute:
|
|
TestMicrophoneMute();
|
|
break;
|
|
case TTMicrophoneBoost:
|
|
TestMicrophoneBoost();
|
|
break;
|
|
case TTMicrophoneAGC:
|
|
TestMicrophoneAGC();
|
|
break;
|
|
case TTLoopback:
|
|
TestLoopback();
|
|
break;
|
|
case TTDeviceRemoval:
|
|
TestDeviceRemoval();
|
|
break;
|
|
case TTMobileAPI:
|
|
TestAdvancedMBAPI();
|
|
FALLTHROUGH();
|
|
case TTTest:
|
|
TestExtra();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestAudioLayerSelection()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Audio Layer test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
AudioDeviceModule::AudioLayer audioLayer;
|
|
EXPECT_EQ(0, audioDevice->ActiveAudioLayer(&audioLayer));
|
|
|
|
if (audioLayer == AudioDeviceModule::kWindowsWaveAudio)
|
|
{
|
|
TEST_LOG("\nActiveAudioLayer: kWindowsWaveAudio\n \n");
|
|
} else if (audioLayer == AudioDeviceModule::kWindowsCoreAudio)
|
|
{
|
|
TEST_LOG("\nActiveAudioLayer: kWindowsCoreAudio\n \n");
|
|
} else if (audioLayer == AudioDeviceModule::kLinuxAlsaAudio)
|
|
{
|
|
TEST_LOG("\nActiveAudioLayer: kLinuxAlsaAudio\n \n");
|
|
} else if (audioLayer == AudioDeviceModule::kLinuxPulseAudio)
|
|
{
|
|
TEST_LOG("\nActiveAudioLayer: kLinuxPulseAudio\n \n");
|
|
} else
|
|
{
|
|
TEST_LOG("\nActiveAudioLayer: INVALID\n \n");
|
|
}
|
|
|
|
char ch;
|
|
bool tryWinWave(false);
|
|
bool tryWinCore(false);
|
|
|
|
if (audioLayer == AudioDeviceModule::kWindowsWaveAudio)
|
|
{
|
|
TEST_LOG("Would you like to try kWindowsCoreAudio instead "
|
|
"[requires Win Vista or Win 7] (Y/N)?\n: ");
|
|
EXPECT_TRUE(scanf(" %c", &ch) > 0);
|
|
ch = toupper(ch);
|
|
if (ch == 'Y')
|
|
{
|
|
tryWinCore = true;
|
|
}
|
|
} else if (audioLayer == AudioDeviceModule::kWindowsCoreAudio)
|
|
{
|
|
TEST_LOG("Would you like to try kWindowsWaveAudio instead (Y/N)?\n: ");
|
|
EXPECT_TRUE(scanf(" %c", &ch) > 0);
|
|
ch = toupper(ch);
|
|
if (ch == 'Y')
|
|
{
|
|
tryWinWave = true;
|
|
}
|
|
}
|
|
|
|
if (tryWinWave || tryWinCore)
|
|
{
|
|
// =======================================
|
|
// First, close down what we have started
|
|
|
|
// terminate
|
|
EXPECT_EQ(0, _audioDevice->RegisterEventObserver(NULL));
|
|
EXPECT_EQ(0, _audioDevice->RegisterAudioCallback(NULL));
|
|
EXPECT_EQ(0, _audioDevice->Terminate());
|
|
|
|
// release the ProcessThread object
|
|
if (_processThread)
|
|
{
|
|
_processThread->DeRegisterModule(_audioDevice);
|
|
_processThread->Stop();
|
|
_processThread.reset();
|
|
}
|
|
|
|
// delete the audio observer
|
|
if (_audioEventObserver)
|
|
{
|
|
delete _audioEventObserver;
|
|
_audioEventObserver = NULL;
|
|
}
|
|
|
|
// delete the audio transport
|
|
if (_audioTransport)
|
|
{
|
|
delete _audioTransport;
|
|
_audioTransport = NULL;
|
|
}
|
|
|
|
// release the AudioDeviceModule object
|
|
if (_audioDevice)
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->Release());
|
|
_audioDevice = NULL;
|
|
}
|
|
|
|
// ==================================================
|
|
// Next, try to make fresh start with new audio layer
|
|
|
|
EXPECT_TRUE((_processThread = ProcessThread::Create("ProcessThread")) !=
|
|
NULL);
|
|
if (_processThread == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
_processThread->Start();
|
|
|
|
// create the Audio Device module based on selected audio layer
|
|
if (tryWinWave)
|
|
{
|
|
_audioDevice = AudioDeviceModule::Create(
|
|
555,
|
|
AudioDeviceModule::kWindowsWaveAudio);
|
|
} else if (tryWinCore)
|
|
{
|
|
_audioDevice = AudioDeviceModule::Create(
|
|
555,
|
|
AudioDeviceModule::kWindowsCoreAudio);
|
|
}
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
TEST_LOG("\nERROR: Switch of audio layer failed!\n");
|
|
// restore default audio layer instead
|
|
EXPECT_TRUE((_audioDevice = AudioDeviceModule::Create(
|
|
555, AudioDeviceModule::kPlatformDefaultAudio)) != NULL);
|
|
}
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
TEST_LOG("\nERROR: Failed to revert back to default audio layer!\n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(1, _audioDevice->AddRef());
|
|
|
|
// register the Audio Device module
|
|
_processThread->RegisterModule(_audioDevice);
|
|
|
|
// register event observer
|
|
_audioEventObserver = new AudioEventObserver(_audioDevice);
|
|
EXPECT_EQ(0, _audioDevice->RegisterEventObserver(_audioEventObserver));
|
|
|
|
// register audio transport
|
|
_audioTransport = new AudioTransportImpl(_audioDevice);
|
|
EXPECT_EQ(0, _audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
EXPECT_EQ(0, _audioDevice->ActiveAudioLayer(&audioLayer));
|
|
|
|
if (audioLayer == AudioDeviceModule::kWindowsWaveAudio)
|
|
{
|
|
if (tryWinCore)
|
|
TEST_LOG("\nActiveAudioLayer: kWindowsWaveAudio <=> "
|
|
"switch was *not* possible\n \n");
|
|
else
|
|
TEST_LOG("\nActiveAudioLayer: kWindowsWaveAudio <=> "
|
|
"switch was possible\n \n");
|
|
} else if (audioLayer == AudioDeviceModule::kWindowsCoreAudio)
|
|
{
|
|
if (tryWinWave)
|
|
TEST_LOG("\nActiveAudioLayer: kWindowsCoreAudio <=> "
|
|
"switch was *not* possible\n \n");
|
|
else
|
|
TEST_LOG("\nActiveAudioLayer: kWindowsCoreAudio <=> "
|
|
"switch was possible\n \n");
|
|
}
|
|
} // if (tryWinWave || tryWinCore)
|
|
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestDeviceEnumeration()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Device Enumeration test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
char name[kAdmMaxDeviceNameSize];
|
|
char guid[kAdmMaxGuidSize];
|
|
|
|
const int16_t nPlayoutDevices(audioDevice->PlayoutDevices());
|
|
EXPECT_TRUE(nPlayoutDevices >= 0);
|
|
TEST_LOG("\nPlayoutDevices: %u\n \n", nPlayoutDevices);
|
|
for (int n = 0; n < nPlayoutDevices; n++)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->PlayoutDeviceName(n, name, guid));
|
|
TEST_LOG(
|
|
"PlayoutDeviceName(%d) : name=%s \n \
|
|
guid=%s\n",
|
|
n, name, guid);
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
// default (-1)
|
|
// TODO(henrika): fix below test.
|
|
#if 0
|
|
EXPECT_EQ(0, audioDevice->PlayoutDeviceName(-1, name, guid));
|
|
TEST_LOG("PlayoutDeviceName(%d): default name=%s \n \
|
|
default guid=%s\n", -1, name, guid);
|
|
#endif // 0
|
|
#else
|
|
// should fail
|
|
EXPECT_EQ(-1, audioDevice->PlayoutDeviceName(-1, name, guid));
|
|
#endif
|
|
|
|
const int16_t nRecordingDevices(audioDevice->RecordingDevices());
|
|
EXPECT_TRUE(nRecordingDevices >= 0);
|
|
TEST_LOG("\nRecordingDevices: %u\n \n", nRecordingDevices);
|
|
for (int n = 0; n < nRecordingDevices; n++)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->RecordingDeviceName(n, name, guid));
|
|
TEST_LOG(
|
|
"RecordingDeviceName(%d) : name=%s \n \
|
|
guid=%s\n",
|
|
n, name, guid);
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
// default (-1)
|
|
// TODO(henrika): fix below test.
|
|
#if 0
|
|
EXPECT_EQ(0, audioDevice->RecordingDeviceName(-1, name, guid));
|
|
TEST_LOG("RecordingDeviceName(%d): default name=%s \n \
|
|
default guid=%s\n", -1, name, guid);
|
|
#endif
|
|
#else
|
|
// should fail
|
|
EXPECT_EQ(-1, audioDevice->PlayoutDeviceName(-1, name, guid));
|
|
#endif
|
|
|
|
EXPECT_EQ(0, audioDevice->Terminate());
|
|
EXPECT_FALSE(audioDevice->Initialized());
|
|
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestDeviceSelection()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Device Selection test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
#define PRINT_HEADING(a, b) \
|
|
{ \
|
|
TEST_LOG("Set" #a "Device(" #b ") => \n"); \
|
|
} \
|
|
|
|
#define PRINT_HEADING_IDX(a, b,c ) \
|
|
{ \
|
|
TEST_LOG("Set" #a "Device(%d) (%s) => \n", b, c); \
|
|
} \
|
|
|
|
#define PRINT_STR(a, b) \
|
|
{ \
|
|
char str[128]; \
|
|
(b == true) ? (sprintf(str, " %-17s: available\n", #a)) : (sprintf(str, " %-17s: NA\n", #a)); \
|
|
TEST_LOG("%s", str); \
|
|
} \
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
bool available(false);
|
|
int16_t nDevices(-1);
|
|
char name[kAdmMaxDeviceNameSize];
|
|
char guid[kAdmMaxGuidSize];
|
|
|
|
// =======
|
|
// Playout
|
|
|
|
nDevices = audioDevice->PlayoutDevices();
|
|
EXPECT_TRUE(nDevices >= 0);
|
|
|
|
TEST_LOG("\n");
|
|
#ifdef _WIN32
|
|
EXPECT_TRUE(audioDevice->SetPlayoutDevice(
|
|
AudioDeviceModule::kDefaultCommunicationDevice) == 0);
|
|
PRINT_HEADING(Playout, kDefaultCommunicationDevice);
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
PRINT_STR(Playout, available);
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StereoPlayoutIsAvailable(&available));
|
|
PRINT_STR(Stereo Playout, available);
|
|
}
|
|
else
|
|
{
|
|
PRINT_STR(Stereo Playout, false);
|
|
}
|
|
EXPECT_EQ(0, audioDevice->SpeakerVolumeIsAvailable(&available));
|
|
PRINT_STR(Speaker Volume, available);
|
|
EXPECT_EQ(0, audioDevice->SpeakerMuteIsAvailable(&available));
|
|
PRINT_STR(Speaker Mute, available);
|
|
|
|
EXPECT_EQ(0, audioDevice->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice));
|
|
PRINT_HEADING(Playout, kDefaultDevice);
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
PRINT_STR(Playout, available);
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StereoPlayoutIsAvailable(&available));
|
|
PRINT_STR(Stereo Playout, available);
|
|
}
|
|
else
|
|
{
|
|
PRINT_STR(Stereo Playout, false);
|
|
}
|
|
EXPECT_EQ(0, audioDevice->SpeakerVolumeIsAvailable(&available));
|
|
PRINT_STR(Speaker Volume, available);
|
|
EXPECT_EQ(0, audioDevice->SpeakerMuteIsAvailable(&available));
|
|
PRINT_STR(Speaker Mute, available);
|
|
#else
|
|
EXPECT_TRUE(audioDevice->SetPlayoutDevice(
|
|
AudioDeviceModule::kDefaultCommunicationDevice) == -1);
|
|
EXPECT_EQ(-1, audioDevice->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice));
|
|
#endif
|
|
|
|
for (int i = 0; i < nDevices; i++)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetPlayoutDevice(i));
|
|
EXPECT_EQ(0, audioDevice->PlayoutDeviceName(i, name, guid));
|
|
PRINT_HEADING_IDX(Playout, i, name);
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
PRINT_STR(Playout, available);
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StereoPlayoutIsAvailable(&available));
|
|
PRINT_STR(Stereo Playout, available);
|
|
} else
|
|
{
|
|
PRINT_STR(Stereo Playout, false);
|
|
}
|
|
EXPECT_EQ(0, audioDevice->SpeakerVolumeIsAvailable(&available));
|
|
PRINT_STR(Speaker Volume, available);
|
|
EXPECT_EQ(0, audioDevice->SpeakerMuteIsAvailable(&available));
|
|
PRINT_STR(Speaker Mute, available);
|
|
}
|
|
|
|
// =========
|
|
// Recording
|
|
|
|
nDevices = audioDevice->RecordingDevices();
|
|
EXPECT_TRUE(nDevices >= 0);
|
|
|
|
TEST_LOG("\n");
|
|
#ifdef _WIN32
|
|
EXPECT_TRUE(audioDevice->SetRecordingDevice(
|
|
AudioDeviceModule::kDefaultCommunicationDevice) == 0);
|
|
PRINT_HEADING(Recording, kDefaultCommunicationDevice);
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
PRINT_STR(Recording, available);
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
PRINT_STR(Stereo Recording, available);
|
|
}
|
|
else
|
|
{
|
|
// special fix to ensure that we don't log 'available' when recording is not OK
|
|
PRINT_STR(Stereo Recording, false);
|
|
}
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
PRINT_STR(Microphone Volume, available);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneMuteIsAvailable(&available));
|
|
PRINT_STR(Microphone Mute, available);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneBoostIsAvailable(&available));
|
|
PRINT_STR(Microphone Boost, available);
|
|
|
|
EXPECT_EQ(0, audioDevice->SetRecordingDevice(AudioDeviceModule::kDefaultDevice));
|
|
PRINT_HEADING(Recording, kDefaultDevice);
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
PRINT_STR(Recording, available);
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
PRINT_STR(Stereo Recording, available);
|
|
}
|
|
else
|
|
{
|
|
// special fix to ensure that we don't log 'available' when recording is not OK
|
|
PRINT_STR(Stereo Recording, false);
|
|
}
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
PRINT_STR(Microphone Volume, available);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneMuteIsAvailable(&available));
|
|
PRINT_STR(Microphone Mute, available);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneBoostIsAvailable(&available));
|
|
PRINT_STR(Microphone Boost, available);
|
|
#else
|
|
EXPECT_TRUE(audioDevice->SetRecordingDevice(
|
|
AudioDeviceModule::kDefaultCommunicationDevice) == -1);
|
|
EXPECT_EQ(-1, audioDevice->SetRecordingDevice(AudioDeviceModule::kDefaultDevice));
|
|
#endif
|
|
|
|
for (int i = 0; i < nDevices; i++)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetRecordingDevice(i));
|
|
EXPECT_EQ(0, audioDevice->RecordingDeviceName(i, name, guid));
|
|
PRINT_HEADING_IDX(Recording, i, name);
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
PRINT_STR(Recording, available);
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
PRINT_STR(Stereo Recording, available);
|
|
} else
|
|
{
|
|
// special fix to ensure that we don't log 'available' when recording
|
|
// is not OK
|
|
PRINT_STR(Stereo Recording, false);
|
|
}
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
PRINT_STR(Microphone Volume, available);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneMuteIsAvailable(&available));
|
|
PRINT_STR(Microphone Mute, available);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneBoostIsAvailable(&available));
|
|
PRINT_STR(Microphone Boost, available);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->Terminate());
|
|
EXPECT_FALSE(audioDevice->Initialized());
|
|
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestAudioTransport()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Audio Transport test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
bool recIsAvailable(false);
|
|
bool playIsAvailable(false);
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&recIsAvailable));
|
|
if (!recIsAvailable)
|
|
{
|
|
TEST_LOG(
|
|
"\nWARNING: Recording is not available for the selected device!\n \n");
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&playIsAvailable));
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
} else if (!playIsAvailable)
|
|
{
|
|
TEST_LOG(
|
|
"\nWARNING: Playout is not available for the selected device!\n \n");
|
|
}
|
|
|
|
bool available(false);
|
|
uint32_t samplesPerSec(0);
|
|
|
|
if (playIsAvailable)
|
|
{
|
|
// =========================================
|
|
// Start by playing out an existing PCM file
|
|
|
|
EXPECT_EQ(0, audioDevice->SpeakerVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
EXPECT_EQ(0, audioDevice->MaxSpeakerVolume(&maxVolume));
|
|
EXPECT_EQ(0, audioDevice->SetSpeakerVolume(maxVolume/2));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->PlayoutSampleRate(&samplesPerSec));
|
|
if (samplesPerSec == 48000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile48.c_str()));
|
|
} else if (samplesPerSec == 44100 || samplesPerSec == 44000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile44.c_str()));
|
|
} else if (samplesPerSec == 16000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile16.c_str()));
|
|
} else if (samplesPerSec == 8000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile8.c_str()));
|
|
} else {
|
|
TEST_LOG("\nERROR: Sample rate (%u) is not supported!\n \n",
|
|
samplesPerSec);
|
|
return -1;
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
|
|
if (audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Listen to the file being played (fs=%d) out "
|
|
"and verify that the audio quality is OK.\n"
|
|
"> Press any key to stop playing...\n \n",
|
|
samplesPerSec);
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetFilePlayout(false);
|
|
}
|
|
|
|
bool enabled(false);
|
|
if (recIsAvailable)
|
|
{
|
|
// ====================================
|
|
// Next, record from microphone to file
|
|
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
EXPECT_EQ(0, audioDevice->MaxMicrophoneVolume(&maxVolume));
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(maxVolume));
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->StartRawInputFileRecording(
|
|
GetFilename(RecordedMicrophoneFile)) == 0);
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
if (enabled)
|
|
{
|
|
// ensure file recording in mono
|
|
EXPECT_EQ(0, audioDevice->SetRecordingChannel(AudioDeviceModule::kChannelLeft));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
SleepMs(100);
|
|
|
|
EXPECT_TRUE(audioDevice->Recording());
|
|
if (audioDevice->Recording())
|
|
{
|
|
TEST_LOG("\n \n> The microphone input signal is now being recorded "
|
|
"to a PCM file.\n"
|
|
"> Speak into the microphone to ensure that your voice is"
|
|
" recorded.\n> Press any key to stop recording...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
if (enabled)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetRecordingChannel(AudioDeviceModule::kChannelBoth));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
EXPECT_EQ(0, audioDevice->StopRawInputFileRecording());
|
|
}
|
|
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
// ==========================
|
|
// Play out the recorded file
|
|
|
|
_audioTransport->SetFilePlayout(true,
|
|
GetFilename(RecordedMicrophoneFile));
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
SleepMs(100);
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n \n> Listen to the recorded file and verify that the "
|
|
"audio quality is OK.\n"
|
|
"> Press any key to stop listening...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetFilePlayout(false);
|
|
}
|
|
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
// ==============================
|
|
// Finally, make full duplex test
|
|
|
|
uint32_t playSamplesPerSec(0);
|
|
uint32_t recSamplesPerSecRec(0);
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
_audioTransport->SetFullDuplex(true);
|
|
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
EXPECT_EQ(0, audioDevice->MaxMicrophoneVolume(&maxVolume));
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(maxVolume));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->PlayoutSampleRate(&playSamplesPerSec));
|
|
EXPECT_EQ(0, audioDevice->RecordingSampleRate(&recSamplesPerSecRec));
|
|
if (playSamplesPerSec != recSamplesPerSecRec)
|
|
{
|
|
TEST_LOG("\nERROR: sample rates does not match (fs_play=%u, fs_rec=%u)",
|
|
playSamplesPerSec, recSamplesPerSecRec);
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
_audioTransport->SetFullDuplex(false);
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
SleepMs(100);
|
|
|
|
if (audioDevice->Playing() && audioDevice->Recording())
|
|
{
|
|
TEST_LOG("\n \n> Full duplex audio (fs=%u) is now active.\n"
|
|
"> Speak into the microphone and verify that your voice is "
|
|
"played out in loopback.\n> Press any key to stop...\n \n",
|
|
playSamplesPerSec);
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetFullDuplex(false);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->Terminate());
|
|
EXPECT_FALSE(audioDevice->Initialized());
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestSpeakerVolume()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Speaker Volume test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
uint32_t startVolume(0);
|
|
uint32_t samplesPerSec(0);
|
|
|
|
EXPECT_EQ(0, audioDevice->SpeakerVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetSpeakerVolume(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Volume control is not available for the selected "
|
|
"device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
// store initial volume setting
|
|
EXPECT_EQ(0, audioDevice->InitSpeaker());
|
|
EXPECT_EQ(0, audioDevice->SpeakerVolume(&startVolume));
|
|
|
|
// start at volume 0
|
|
EXPECT_EQ(0, audioDevice->SetSpeakerVolume(0));
|
|
|
|
// ======================================
|
|
// Start playing out an existing PCM file
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->PlayoutSampleRate(&samplesPerSec));
|
|
if (48000 == samplesPerSec) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile48.c_str()));
|
|
} else if (44100 == samplesPerSec || samplesPerSec == 44000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile44.c_str()));
|
|
} else if (samplesPerSec == 16000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile16.c_str()));
|
|
} else if (samplesPerSec == 8000) {
|
|
_audioTransport->SetFilePlayout(
|
|
true, GetResource(_playoutFile8.c_str()));
|
|
} else {
|
|
TEST_LOG("\nERROR: Sample rate (%d) is not supported!\n \n",
|
|
samplesPerSec);
|
|
return -1;
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Listen to the file being played out and verify that the "
|
|
"selected speaker volume is varied between [~0] and [~MAX].\n"
|
|
"> The file shall be played out with an increasing volume level "
|
|
"correlated to the speaker volume.\n"
|
|
"> Press any key to stop playing...\n \n");
|
|
PAUSE(10000);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetSpeakerVolume(false);
|
|
_audioTransport->SetFilePlayout(false);
|
|
|
|
// restore volume setting
|
|
EXPECT_EQ(0, audioDevice->SetSpeakerVolume(startVolume));
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestSpeakerMute()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Speaker Mute test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
bool startMute(false);
|
|
uint32_t samplesPerSec(0);
|
|
|
|
EXPECT_EQ(0, audioDevice->SpeakerMuteIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetSpeakerMute(true);
|
|
} else
|
|
{
|
|
TEST_LOG(
|
|
"\nERROR: Mute control is not available for the selected"
|
|
" device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
// store initial mute setting
|
|
EXPECT_EQ(0, audioDevice->InitSpeaker());
|
|
EXPECT_EQ(0, audioDevice->SpeakerMute(&startMute));
|
|
|
|
// start with no mute
|
|
EXPECT_EQ(0, audioDevice->SetSpeakerMute(false));
|
|
|
|
// ======================================
|
|
// Start playing out an existing PCM file
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->PlayoutSampleRate(&samplesPerSec));
|
|
if (48000 == samplesPerSec)
|
|
_audioTransport->SetFilePlayout(true, _playoutFile48.c_str());
|
|
else if (44100 == samplesPerSec || 44000 == samplesPerSec)
|
|
_audioTransport->SetFilePlayout(true, _playoutFile44.c_str());
|
|
else
|
|
{
|
|
TEST_LOG("\nERROR: Sample rate (%d) is not supported!\n \n",
|
|
samplesPerSec);
|
|
return -1;
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Listen to the file being played out and verify that the"
|
|
" selected speaker mute control is toggled between [MUTE ON] and"
|
|
" [MUTE OFF].\n> You should only hear the file during the"
|
|
" 'MUTE OFF' periods.\n"
|
|
"> Press any key to stop playing...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetSpeakerMute(false);
|
|
_audioTransport->SetFilePlayout(false);
|
|
|
|
// restore mute setting
|
|
EXPECT_EQ(0, audioDevice->SetSpeakerMute(startMute));
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestMicrophoneVolume()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Microphone Volume test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetMicrophoneVolume(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Volume control is not available for the selected "
|
|
"device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Playout is not available for the selected "
|
|
"device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
TEST_LOG("\nEnable recording of microphone input to file (%s) during this"
|
|
" test (Y/N)?\n: ",
|
|
RecordedMicrophoneVolumeFile);
|
|
char ch;
|
|
bool fileRecording(false);
|
|
EXPECT_TRUE(scanf(" %c", &ch) > 0);
|
|
ch = toupper(ch);
|
|
if (ch == 'Y')
|
|
{
|
|
fileRecording = true;
|
|
}
|
|
|
|
uint32_t startVolume(0);
|
|
bool enabled(false);
|
|
|
|
// store initial volume setting
|
|
EXPECT_EQ(0, audioDevice->InitMicrophone());
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolume(&startVolume));
|
|
|
|
// start at volume 0
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(0));
|
|
|
|
// ======================================================================
|
|
// Start recording from the microphone while the mic volume is changed
|
|
// continuously.
|
|
// Also, start playing out the input to enable real-time verification.
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StartRawInputFileRecording(RecordedMicrophoneVolumeFile));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
if (enabled)
|
|
{
|
|
// ensures a mono file
|
|
EXPECT_EQ(0, audioDevice->SetRecordingChannel(AudioDeviceModule::kChannelRight));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->Recording());
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Recording() && audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Speak into the microphone and verify that the selected "
|
|
"microphone volume is varied between [~0] and [~MAX].\n"
|
|
"> You should hear your own voice with an increasing volume level"
|
|
" correlated to the microphone volume.\n"
|
|
"> After a finalized test (and if file recording was enabled) "
|
|
"verify the recorded result off line.\n"
|
|
"> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StopRawInputFileRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
|
|
_audioTransport->SetMicrophoneVolume(false);
|
|
_audioTransport->SetFullDuplex(false);
|
|
|
|
// restore volume setting
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(startVolume));
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestMicrophoneMute()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Microphone Mute test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneMuteIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetMicrophoneMute(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Mute control is not available for the selected"
|
|
" device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Playout is not available for the selected "
|
|
"device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
TEST_LOG("\nEnable recording of microphone input to file (%s) during this "
|
|
"test (Y/N)?\n: ",
|
|
RecordedMicrophoneMuteFile);
|
|
char ch;
|
|
bool fileRecording(false);
|
|
EXPECT_TRUE(scanf(" %c", &ch) > 0);
|
|
ch = toupper(ch);
|
|
if (ch == 'Y')
|
|
{
|
|
fileRecording = true;
|
|
}
|
|
|
|
bool startMute(false);
|
|
bool enabled(false);
|
|
|
|
// store initial volume setting
|
|
EXPECT_EQ(0, audioDevice->InitMicrophone());
|
|
EXPECT_EQ(0, audioDevice->MicrophoneMute(&startMute));
|
|
|
|
// start at no mute
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneMute(false));
|
|
|
|
// ==================================================================
|
|
// Start recording from the microphone while the mic mute is toggled
|
|
// continuously.
|
|
// Also, start playing out the input to enable real-time verification.
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StartRawInputFileRecording(RecordedMicrophoneMuteFile));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
if (enabled)
|
|
{
|
|
// ensure file recording in mono
|
|
EXPECT_EQ(0, audioDevice->SetRecordingChannel(AudioDeviceModule::kChannelLeft));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->Recording());
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Recording() && audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Speak into the microphone and verify that the selected "
|
|
"microphone mute control is toggled between [MUTE ON] and [MUTE OFF]."
|
|
"\n> You should only hear your own voice in loopback during the"
|
|
" 'MUTE OFF' periods.\n> After a finalized test (and if file "
|
|
"recording was enabled) verify the recorded result off line.\n"
|
|
"> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StopRawInputFileRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetMicrophoneMute(false);
|
|
_audioTransport->SetFullDuplex(false);
|
|
|
|
// restore volume setting
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneMute(startMute));
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestMicrophoneBoost()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Microphone Boost test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneBoostIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetMicrophoneBoost(true);
|
|
} else
|
|
{
|
|
TEST_LOG(
|
|
"\nERROR: Boost control is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Playout is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
TEST_LOG("\nEnable recording of microphone input to file (%s) during this "
|
|
"test (Y/N)?\n: ",
|
|
RecordedMicrophoneBoostFile);
|
|
char ch;
|
|
bool fileRecording(false);
|
|
EXPECT_TRUE(scanf(" %c", &ch) > 0);
|
|
ch = toupper(ch);
|
|
if (ch == 'Y')
|
|
{
|
|
fileRecording = true;
|
|
}
|
|
|
|
bool startBoost(false);
|
|
bool enabled(false);
|
|
|
|
// store initial volume setting
|
|
EXPECT_EQ(0, audioDevice->InitMicrophone());
|
|
EXPECT_EQ(0, audioDevice->MicrophoneBoost(&startBoost));
|
|
|
|
// start at no boost
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneBoost(false));
|
|
|
|
// ==================================================================
|
|
// Start recording from the microphone while the mic boost is toggled
|
|
// continuously.
|
|
// Also, start playing out the input to enable real-time verification.
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StartRawInputFileRecording(RecordedMicrophoneBoostFile));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
if (enabled)
|
|
{
|
|
// ensure file recording in mono
|
|
EXPECT_EQ(0, audioDevice->SetRecordingChannel(AudioDeviceModule::kChannelLeft));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->Recording());
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Recording() && audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Speak into the microphone and verify that the selected "
|
|
"microphone boost control is toggled between [BOOST ON] and [BOOST OFF].\n"
|
|
"> You should hear your own voice with an increased volume level "
|
|
"during the 'BOOST ON' periods.\n \n"
|
|
"> After a finalized test (and if file recording was enabled) verify"
|
|
" the recorded result off line.\n"
|
|
"> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StopRawInputFileRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetMicrophoneBoost(false);
|
|
_audioTransport->SetFullDuplex(false);
|
|
|
|
// restore boost setting
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneBoost(startBoost));
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestMicrophoneAGC()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Microphone AGC test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetMicrophoneAGC(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: It is not possible to control the microphone volume"
|
|
" for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
} else
|
|
{
|
|
TEST_LOG("\nERROR: Playout is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
TEST_LOG("\nEnable recording of microphone input to file (%s) during "
|
|
"this test (Y/N)?\n: ",
|
|
RecordedMicrophoneAGCFile);
|
|
char ch;
|
|
bool fileRecording(false);
|
|
EXPECT_TRUE(scanf(" %c", &ch) > 0);
|
|
ch = toupper(ch);
|
|
if (ch == 'Y')
|
|
{
|
|
fileRecording = true;
|
|
}
|
|
|
|
uint32_t startVolume(0);
|
|
bool enabled(false);
|
|
|
|
// store initial volume setting
|
|
EXPECT_EQ(0, audioDevice->InitMicrophone());
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolume(&startVolume));
|
|
|
|
// ====================================================================
|
|
// Start recording from the microphone while the mic volume is changed
|
|
// continuously
|
|
// by the emulated AGC (implemented by our audio transport).
|
|
// Also, start playing out the input to enable real-time verification.
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StartRawInputFileRecording(RecordedMicrophoneAGCFile));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetAGC(true));
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
if (enabled)
|
|
{
|
|
// ensures a mono file
|
|
EXPECT_EQ(0, audioDevice->SetRecordingChannel(AudioDeviceModule::kChannelRight));
|
|
}
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
}
|
|
|
|
EXPECT_TRUE(audioDevice->AGC());
|
|
EXPECT_TRUE(audioDevice->Recording());
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
if (audioDevice->Recording() && audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Speak into the microphone and verify that the volume of"
|
|
" the selected microphone is varied between [~0] and [~MAX].\n"
|
|
"> You should hear your own voice with an increasing volume level"
|
|
" correlated to an emulated AGC setting.\n"
|
|
"> After a finalized test (and if file recording was enabled) verify"
|
|
" the recorded result off line.\n"
|
|
"> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
if (fileRecording)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->StopRawInputFileRecording());
|
|
}
|
|
EXPECT_EQ(0, audioDevice->SetAGC(false));
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
|
|
_audioTransport->SetMicrophoneAGC(false);
|
|
_audioTransport->SetFullDuplex(false);
|
|
|
|
// restore volume setting
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(startVolume));
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestLoopback()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Loopback measurement test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
bool recIsAvailable(false);
|
|
bool playIsAvailable(false);
|
|
uint8_t nPlayChannels(0);
|
|
uint8_t nRecChannels(0);
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&recIsAvailable));
|
|
if (!recIsAvailable)
|
|
{
|
|
TEST_LOG("\nERROR: Recording is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&playIsAvailable));
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
_audioTransport->SetLoopbackMeasurements(true);
|
|
} else if (!playIsAvailable)
|
|
{
|
|
TEST_LOG("\nERROR: Playout is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool enabled(false);
|
|
bool available(false);
|
|
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
uint32_t playSamplesPerSec(0);
|
|
uint32_t recSamplesPerSecRec(0);
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
_audioTransport->SetFullDuplex(true);
|
|
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetStereoRecording(true));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StereoPlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetStereoPlayout(true));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
EXPECT_EQ(0, audioDevice->MaxMicrophoneVolume(&maxVolume));
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(maxVolume));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->PlayoutSampleRate(&playSamplesPerSec));
|
|
EXPECT_EQ(0, audioDevice->RecordingSampleRate(&recSamplesPerSecRec));
|
|
EXPECT_EQ(0, audioDevice->StereoPlayout(&enabled));
|
|
enabled ? nPlayChannels = 2 : nPlayChannels = 1;
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
enabled ? nRecChannels = 2 : nRecChannels = 1;
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
|
|
if (audioDevice->Playing() && audioDevice->Recording())
|
|
{
|
|
TEST_LOG("\n \n> Loopback audio is now active.\n"
|
|
"> Rec : fs=%u, #channels=%u.\n"
|
|
"> Play: fs=%u, #channels=%u.\n"
|
|
"> Speak into the microphone and verify that your voice is"
|
|
" played out in loopback.\n"
|
|
"> Press any key to stop...\n \n",
|
|
recSamplesPerSecRec, nRecChannels, playSamplesPerSec,
|
|
nPlayChannels);
|
|
PAUSE(30000);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetFullDuplex(false);
|
|
_audioTransport->SetLoopbackMeasurements(false);
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->Terminate());
|
|
EXPECT_FALSE(audioDevice->Initialized());
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestDeviceRemoval()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Device removal test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
bool recIsAvailable(false);
|
|
bool playIsAvailable(false);
|
|
uint8_t nPlayChannels(0);
|
|
uint8_t nRecChannels(0);
|
|
uint8_t loopCount(0);
|
|
|
|
while (loopCount < 2)
|
|
{
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->RecordingIsAvailable(&recIsAvailable));
|
|
if (!recIsAvailable)
|
|
{
|
|
TEST_LOG("\nERROR: Recording is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->PlayoutIsAvailable(&playIsAvailable));
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
_audioTransport->SetFullDuplex(true);
|
|
} else if (!playIsAvailable)
|
|
{
|
|
TEST_LOG("\nERROR: Playout is not available for the selected device!\n \n");
|
|
return -1;
|
|
}
|
|
|
|
bool available(false);
|
|
bool enabled(false);
|
|
|
|
if (recIsAvailable && playIsAvailable)
|
|
{
|
|
uint32_t playSamplesPerSec(0);
|
|
uint32_t recSamplesPerSecRec(0);
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
|
|
_audioTransport->SetFullDuplex(true);
|
|
|
|
EXPECT_EQ(0, audioDevice->StereoRecordingIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetStereoRecording(true));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StereoPlayoutIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->SetStereoPlayout(true));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->MicrophoneVolumeIsAvailable(&available));
|
|
if (available)
|
|
{
|
|
uint32_t maxVolume(0);
|
|
EXPECT_EQ(0, audioDevice->MaxMicrophoneVolume(&maxVolume));
|
|
EXPECT_EQ(0, audioDevice->SetMicrophoneVolume(maxVolume));
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->PlayoutSampleRate(&playSamplesPerSec));
|
|
EXPECT_EQ(0, audioDevice->RecordingSampleRate(&recSamplesPerSecRec));
|
|
EXPECT_EQ(0, audioDevice->StereoPlayout(&enabled));
|
|
enabled ? nPlayChannels = 2 : nPlayChannels = 1;
|
|
EXPECT_EQ(0, audioDevice->StereoRecording(&enabled));
|
|
enabled ? nRecChannels = 2 : nRecChannels = 1;
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
|
|
AudioDeviceModule::AudioLayer audioLayer;
|
|
EXPECT_EQ(0, audioDevice->ActiveAudioLayer(&audioLayer));
|
|
|
|
if (audioLayer == AudioDeviceModule::kLinuxPulseAudio)
|
|
{
|
|
TEST_LOG("\n \n> PulseAudio loopback audio is now active.\n"
|
|
"> Rec : fs=%u, #channels=%u.\n"
|
|
"> Play: fs=%u, #channels=%u.\n"
|
|
"> Speak into the microphone and verify that your voice is"
|
|
" played out in loopback.\n"
|
|
"> Unplug the device and make sure that your voice is played"
|
|
" out in loop back on the built-in soundcard.\n"
|
|
"> Then press any key...\n",
|
|
recSamplesPerSecRec, nRecChannels, playSamplesPerSec,
|
|
nPlayChannels);
|
|
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
} else if (audioDevice->Playing() && audioDevice->Recording())
|
|
{
|
|
if (loopCount < 1)
|
|
{
|
|
TEST_LOG("\n \n> Loopback audio is now active.\n"
|
|
"> Rec : fs=%u, #channels=%u.\n"
|
|
"> Play: fs=%u, #channels=%u.\n"
|
|
"> Speak into the microphone and verify that your voice"
|
|
" is played out in loopback.\n"
|
|
"> Unplug the device and wait for the error message...\n",
|
|
recSamplesPerSecRec, nRecChannels,
|
|
playSamplesPerSec, nPlayChannels);
|
|
|
|
_audioEventObserver->_error
|
|
= (AudioDeviceObserver::ErrorCode) (-1);
|
|
while (_audioEventObserver->_error
|
|
== (AudioDeviceObserver::ErrorCode) (-1))
|
|
{
|
|
SleepMs(500);
|
|
}
|
|
} else
|
|
{
|
|
TEST_LOG("\n \n> Loopback audio is now active.\n"
|
|
"> Rec : fs=%u, #channels=%u.\n"
|
|
"> Play: fs=%u, #channels=%u.\n"
|
|
"> Speak into the microphone and verify that your voice"
|
|
" is played out in loopback.\n"
|
|
"> Press any key to stop...\n",
|
|
recSamplesPerSecRec, nRecChannels,
|
|
playSamplesPerSec, nPlayChannels);
|
|
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
}
|
|
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetFullDuplex(false);
|
|
|
|
if (loopCount < 1)
|
|
{
|
|
TEST_LOG("\n \n> Stopped!\n");
|
|
TEST_LOG("> Now reinsert device if you want to enumerate it.\n");
|
|
TEST_LOG("> Press any key when done.\n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
loopCount++;
|
|
}
|
|
} // loopCount
|
|
|
|
EXPECT_EQ(0, audioDevice->Terminate());
|
|
EXPECT_FALSE(audioDevice->Initialized());
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestExtra()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Extra test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
EXPECT_EQ(0, audioDevice->Terminate());
|
|
EXPECT_FALSE(audioDevice->Initialized());
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t FuncTestManager::SelectRecordingDevice()
|
|
{
|
|
int16_t nDevices = _audioDevice->RecordingDevices();
|
|
char name[kAdmMaxDeviceNameSize];
|
|
char guid[kAdmMaxGuidSize];
|
|
int32_t ret(-1);
|
|
|
|
#ifdef _WIN32
|
|
TEST_LOG("\nSelect Recording Device\n \n");
|
|
TEST_LOG(" (%d) Default\n", 0);
|
|
TEST_LOG(" (%d) Default Communication [Win 7]\n", 1);
|
|
TEST_LOG("- - - - - - - - - - - - - - - - - - - -\n");
|
|
for (int i = 0; i < nDevices; i++)
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->RecordingDeviceName(i, name, guid));
|
|
TEST_LOG(" (%d) Device %d (%s)\n", i+10, i, name);
|
|
}
|
|
TEST_LOG("\n: ");
|
|
|
|
int sel(0);
|
|
|
|
scanf("%u", &sel);
|
|
|
|
if (sel == 0)
|
|
{
|
|
EXPECT_EQ(0, (ret = _audioDevice->SetRecordingDevice(AudioDeviceModule::kDefaultDevice)));
|
|
}
|
|
else if (sel == 1)
|
|
{
|
|
EXPECT_TRUE((ret = _audioDevice->SetRecordingDevice(
|
|
AudioDeviceModule::kDefaultCommunicationDevice)) == 0);
|
|
}
|
|
else if (sel < (nDevices+10))
|
|
{
|
|
EXPECT_EQ(0, (ret = _audioDevice->SetRecordingDevice(sel-10)));
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
#else
|
|
TEST_LOG("\nSelect Recording Device\n \n");
|
|
for (int i = 0; i < nDevices; i++)
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->RecordingDeviceName(i, name, guid));
|
|
TEST_LOG(" (%d) Device %d (%s)\n", i, i, name);
|
|
}
|
|
TEST_LOG("\n: ");
|
|
int sel(0);
|
|
EXPECT_TRUE(scanf("%u", &sel) > 0);
|
|
if (sel < (nDevices))
|
|
{
|
|
EXPECT_EQ(0, (ret = _audioDevice->SetRecordingDevice(sel)));
|
|
} else
|
|
{
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
int32_t FuncTestManager::SelectPlayoutDevice()
|
|
{
|
|
int16_t nDevices = _audioDevice->PlayoutDevices();
|
|
char name[kAdmMaxDeviceNameSize];
|
|
char guid[kAdmMaxGuidSize];
|
|
|
|
#ifdef _WIN32
|
|
TEST_LOG("\nSelect Playout Device\n \n");
|
|
TEST_LOG(" (%d) Default\n", 0);
|
|
TEST_LOG(" (%d) Default Communication [Win 7]\n", 1);
|
|
TEST_LOG("- - - - - - - - - - - - - - - - - - - -\n");
|
|
for (int i = 0; i < nDevices; i++)
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->PlayoutDeviceName(i, name, guid));
|
|
TEST_LOG(" (%d) Device %d (%s)\n", i+10, i, name);
|
|
}
|
|
TEST_LOG("\n: ");
|
|
|
|
int sel(0);
|
|
|
|
scanf("%u", &sel);
|
|
|
|
int32_t ret(0);
|
|
|
|
if (sel == 0)
|
|
{
|
|
EXPECT_TRUE((ret = _audioDevice->SetPlayoutDevice(
|
|
AudioDeviceModule::kDefaultDevice)) == 0);
|
|
}
|
|
else if (sel == 1)
|
|
{
|
|
EXPECT_TRUE((ret = _audioDevice->SetPlayoutDevice(
|
|
AudioDeviceModule::kDefaultCommunicationDevice)) == 0);
|
|
}
|
|
else if (sel < (nDevices+10))
|
|
{
|
|
EXPECT_EQ(0, (ret = _audioDevice->SetPlayoutDevice(sel-10)));
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
#else
|
|
TEST_LOG("\nSelect Playout Device\n \n");
|
|
for (int i = 0; i < nDevices; i++)
|
|
{
|
|
EXPECT_EQ(0, _audioDevice->PlayoutDeviceName(i, name, guid));
|
|
TEST_LOG(" (%d) Device %d (%s)\n", i, i, name);
|
|
}
|
|
TEST_LOG("\n: ");
|
|
int sel(0);
|
|
EXPECT_TRUE(scanf("%u", &sel) > 0);
|
|
int32_t ret(0);
|
|
if (sel < (nDevices))
|
|
{
|
|
EXPECT_EQ(0, (ret = _audioDevice->SetPlayoutDevice(sel)));
|
|
} else
|
|
{
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
int32_t FuncTestManager::TestAdvancedMBAPI()
|
|
{
|
|
TEST_LOG("\n=======================================\n");
|
|
TEST_LOG(" Advanced mobile device API test:\n");
|
|
TEST_LOG("=======================================\n");
|
|
|
|
if (_audioDevice == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
RESET_TEST;
|
|
|
|
AudioDeviceModule* audioDevice = _audioDevice;
|
|
|
|
EXPECT_EQ(0, audioDevice->Init());
|
|
EXPECT_TRUE(audioDevice->Initialized());
|
|
|
|
if (SelectRecordingDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
if (SelectPlayoutDevice() == -1)
|
|
{
|
|
TEST_LOG("\nERROR: Device selection failed!\n \n");
|
|
return -1;
|
|
}
|
|
_audioTransport->SetFullDuplex(true);
|
|
_audioTransport->SetLoopbackMeasurements(true);
|
|
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(_audioTransport));
|
|
// Start recording
|
|
EXPECT_EQ(0, audioDevice->InitRecording());
|
|
EXPECT_EQ(0, audioDevice->StartRecording());
|
|
// Start playout
|
|
EXPECT_EQ(0, audioDevice->InitPlayout());
|
|
EXPECT_EQ(0, audioDevice->StartPlayout());
|
|
|
|
EXPECT_TRUE(audioDevice->Recording());
|
|
EXPECT_TRUE(audioDevice->Playing());
|
|
|
|
#if defined(_WIN32_WCE) || defined(WEBRTC_IOS)
|
|
TEST_LOG("\nResetAudioDevice\n \n");
|
|
if (audioDevice->Recording() && audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Speak into the microphone and verify that the audio is good.\n\
|
|
> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
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)
|
|
{
|
|
EXPECT_EQ(0, audioDevice->ResetAudioDevice());
|
|
SleepMs(p);
|
|
}
|
|
TEST_LOG("\n> Speak into the microphone and verify that the audio is good.\n");
|
|
SleepMs(2000);
|
|
}
|
|
#endif
|
|
|
|
#if defined(WEBRTC_IOS)
|
|
bool loudspeakerOn(false);
|
|
TEST_LOG("\nSet playout spaker\n \n");
|
|
if (audioDevice->Recording() && audioDevice->Playing())
|
|
{
|
|
TEST_LOG("\n> Speak into the microphone and verify that the audio is good.\n\
|
|
> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
}
|
|
|
|
TEST_LOG("Set to use speaker\n");
|
|
EXPECT_EQ(0, audioDevice->SetLoudspeakerStatus(true));
|
|
TEST_LOG("\n> Speak into the microphone and verify that the audio is"
|
|
" from the loudspeaker.\n\
|
|
> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
EXPECT_EQ(0, audioDevice->GetLoudspeakerStatus(&loudspeakerOn));
|
|
EXPECT_TRUE(loudspeakerOn);
|
|
|
|
TEST_LOG("Set to not use speaker\n");
|
|
EXPECT_EQ(0, audioDevice->SetLoudspeakerStatus(false));
|
|
TEST_LOG("\n> Speak into the microphone and verify that the audio is not"
|
|
" from the loudspeaker.\n\
|
|
> Press any key to stop...\n \n");
|
|
PAUSE(DEFAULT_PAUSE_TIME);
|
|
EXPECT_EQ(0, audioDevice->GetLoudspeakerStatus(&loudspeakerOn));
|
|
EXPECT_FALSE(loudspeakerOn);
|
|
#endif
|
|
|
|
EXPECT_EQ(0, audioDevice->StopRecording());
|
|
EXPECT_EQ(0, audioDevice->StopPlayout());
|
|
EXPECT_EQ(0, audioDevice->RegisterAudioCallback(NULL));
|
|
|
|
_audioTransport->SetFullDuplex(false);
|
|
|
|
TEST_LOG("\n");
|
|
PRINT_TEST_RESULTS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
} // namespace webrtc
|
|
|
|
// EOF
|