Add file-playing channels to voe_cmd_test.

Fix file reading and writing.

TEST=voe_cmd_test

Review URL: http://webrtc-codereview.appspot.com/279001

git-svn-id: http://webrtc.googlecode.com/svn/trunk@938 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org 2011-11-13 01:34:05 +00:00
parent cd8243807e
commit 0db7dc6e18
8 changed files with 179 additions and 99 deletions

View File

@ -569,7 +569,7 @@ WebRtc_Word32 AudioTransportImpl::NeedMorePlayData(
;
FuncTestManager::FuncTestManager() :
_resourcePath(webrtc::test::GetProjectRootPath() +
_resourcePath(webrtc::test::ProjectRootPath() +
"test/data/audio_device/"),
_processThread(NULL),
_audioDevice(NULL),

View File

@ -73,7 +73,7 @@ class ApmTest : public ::testing::Test {
};
ApmTest::ApmTest()
: kResourcePath(webrtc::test::GetProjectRootPath() +
: kResourcePath(webrtc::test::ProjectRootPath() +
"test/data/audio_processing/"),
#if defined(WEBRTC_APM_UNIT_TEST_FIXED_PROFILE)
kOutputFileName(kResourcePath + "output_data_fixed.pb"),

View File

@ -622,7 +622,7 @@ bool VoETestManager::Init()
#if defined(WEBRTC_ANDROID)
resourcePath_ = "/sdcard/";
#else
resourcePath_ = webrtc::test::GetProjectRootPath();
resourcePath_ = webrtc::test::ProjectRootPath();
if (resourcePath_ == webrtc::test::kCannotFindProjectRootDir)
{
TEST_LOG("Failed to get project root directory\n");

View File

@ -15,7 +15,10 @@
#include <unistd.h>
#endif
#include <vector>
#include "gtest/gtest.h"
#include "test/testsupport/fileutils.h"
#include "voe_errors.h"
#include "voe_base.h"
@ -65,7 +68,7 @@ VoEHardware* hardware = NULL;
VoEExternalMedia* xmedia = NULL;
VoENetEqStats* neteqst = NULL;
void run_test();
void RunTest(std::string out_path);
#ifdef EXTERNAL_TRANSPORT
@ -88,28 +91,6 @@ int my_transportation::SendRTCPPacket(int channel, const void *data, int len)
}
my_transportation my_transport;
#endif
// TODO(amyfong): we should share this with autotest in a common place.
#if defined(MAC_IPHONE)
char micFile[256] = {0}; // Filename copied to buffer in code
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_MAC_INTEL)
const char* micFile = "audio_long16bigendian.pcm";
#elif defined(WEBRTC_ANDROID)
const char* micFile = "/sdcard/audio_long16.pcm";
#elif defined(_WIN32)
// File path is relative to the location of 'voice_engine.gyp'.
const char* micFile = "../../test/data/voice_engine/audio_long16.pcm";
#elif defined(WEBRTC_LINUX)
// Assumes launch from command line:
// $ ./out/<Debug><Release>/audio_device_test_func
const char* micFile = "./test/data/voice_engine/audio_long16.pcm";
#elif (defined(WEBRTC_MAC_INTEL) || defined(WEBRTC_MAC))
// Assumes that the working directory in Xcode
// is set to <path-to-src>/xcodebuild/<Debug><Release>.
const char* micFile = "../../test/data/voice_engine/audio_long16.pcm";
#else
const char* micFile = "audio_long16.pcm";
#endif
class MyObserver : public VoiceEngineObserver {
@ -163,9 +144,16 @@ int main() {
MyObserver my_observer;
#if defined(WEBRTC_ANDROID)
const std::string out_path = "/sdcard/";
#else
const std::string out_path = webrtc::test::OutputPath();
#endif
const std::string trace_filename = out_path + "webrtc_trace.txt";
printf("Set trace filenames (enable trace)\n");
VoiceEngine::SetTraceFilter(kTraceAll);
res = VoiceEngine::SetTraceFile("webrtc_trace.txt");
res = VoiceEngine::SetTraceFile(trace_filename.c_str());
VALIDATE;
res = VoiceEngine::SetTraceCallback(NULL);
@ -190,7 +178,7 @@ int main() {
cnt++;
printf("%s\n", tmp);
run_test();
RunTest(out_path);
printf("Terminate \n");
@ -243,7 +231,7 @@ int main() {
return 0;
}
void run_test() {
void RunTest(std::string out_path) {
int chan, cnt, res;
CodecInst cinst;
cnt = 0;
@ -259,6 +247,24 @@ void run_test() {
bool muted = false;
bool on_hold = false;
#if defined(WEBRTC_ANDROID)
std::string resource_path = "/sdcard/";
#else
std::string resource_path = webrtc::test::ProjectRootPath();
if (resource_path == webrtc::test::kCannotFindProjectRootDir) {
printf("*** Unable to get project root directory. "
"File playing may fail. ***\n");
// Fall back to the current directory.
resource_path = "./";
} else {
resource_path += "test/data/voice_engine/";
}
#endif
const std::string audio_filename = resource_path + "audio_long16.pcm";
const std::string play_filename = out_path + "recorded_playout.pcm";
const std::string mic_filename = out_path + "recorded_mic.pcm";
chan = base1->CreateChannel();
if (chan < 0) {
printf("Error at position %i\n", cnt);
@ -356,6 +362,20 @@ void run_test() {
res = codec->SetSendCodec(chan, cinst);
VALIDATE;
const int kMaxNumChannels = 8;
int channel_index = 0;
std::vector<int> channels(kMaxNumChannels);
for (i = 0; i < kMaxNumChannels; ++i) {
channels[i] = base1->CreateChannel();
int port = rPort + (i + 1) * 2;
res = base1->SetSendDestination(channels[i], port, ip);
VALIDATE;
res = base1->SetLocalReceiver(channels[i], port);
VALIDATE;
res = codec->SetSendCodec(channels[i], cinst);
VALIDATE;
}
// Call loop
bool newcall = true;
while (newcall) {
@ -486,13 +506,13 @@ void run_test() {
i++;
printf("\t%i. Play local file (audio_long16.pcm) \n", i);
i++;
printf("\t%i. Change Playout Device \n", i);
printf("\t%i. Change playout device \n", i);
i++;
printf("\t%i. Change Recording Device \n", i);
printf("\t%i. Change recording device \n", i);
i++;
printf("\t%i. Toggle Remote AGC \n", i);
printf("\t%i. Toggle receive-side AGC \n", i);
i++;
printf("\t%i. Toggle Remote NS \n", i);
printf("\t%i. Toggle receive-side NS \n", i);
i++;
printf("\t%i. AGC status \n", i);
i++;
@ -502,7 +522,7 @@ void run_test() {
i++;
printf("\t%i. Get last error code \n", i);
i++;
printf("\t%i. Toggle typing detection(for Mac/Windows only) \n", i);
printf("\t%i. Toggle typing detection (for Mac/Windows only) \n", i);
i++;
printf("\t%i. Record a PCM file \n", i);
i++;
@ -510,7 +530,10 @@ void run_test() {
i++;
printf("\t%i. Play a previously recorded PCM file as microphone \n", i);
i++;
printf("\t%i. Stop call \n", i);
printf("\t%i. Add an additional file-playing channel \n", i);
i++;
printf("\t%i. Remove a file-playing channel \n", i);
i++;
printf("Select action or %i to stop the call: ", i);
ASSERT_EQ(1, scanf("%i", &codecinput));
@ -602,7 +625,8 @@ void run_test() {
VALIDATE;
}
else if (codecinput == (noCodecs + 11)) {
file->StartPlayingFileLocally(0, micFile);
res = file->StartPlayingFileLocally(0, audio_filename.c_str());
VALIDATE;
}
else if (codecinput == (noCodecs + 12)) {
// change the playout device with current call
@ -655,9 +679,9 @@ void run_test() {
res = apm->SetRxAgcStatus(chan, AGC1);
VALIDATE;
if (AGC1)
printf("\n Remote AGC is now on! \n");
printf("\n Receive-side AGC is now on! \n");
else
printf("\n Remote AGC is now off! \n");
printf("\n Receive-side AGC is now off! \n");
}
else if (codecinput == (noCodecs + 15)) {
// Remote NS
@ -665,16 +689,16 @@ void run_test() {
res = apm->SetRxNsStatus(chan, NS);
VALIDATE;
if (NS1)
printf("\n Remote NS is now on! \n");
printf("\n Receive-side NS is now on! \n");
else
printf("\n Remote NS is now off! \n");
printf("\n Receive-side NS is now off! \n");
}
else if (codecinput == (noCodecs + 16)) {
AgcModes agcmode;
bool enable;
res = apm->GetAgcStatus(enable, agcmode);
VALIDATE
printf("\n AGC enable is %d , mode is %d \n", enable, agcmode);
printf("\n AGC enable is %d, mode is %d \n", enable, agcmode);
}
else if (codecinput == (noCodecs + 17)) {
// Toggle Mute on Microphone
@ -729,15 +753,16 @@ void run_test() {
printf("\n Enter your selection: \n");
ASSERT_EQ(1, scanf("%i", &file_source));
if (file_source == 1) {
printf("\n Start recording microphone as recordedmic.pcm \n");
res = file->StartRecordingMicrophone("recordedmic.pcm");
printf("\n Start recording microphone as %s \n",
mic_filename.c_str());
res = file->StartRecordingMicrophone(mic_filename.c_str());
VALIDATE;
}
}
else {
printf("\n Start recording playout as recordedplayout.pcm \n");
res = file->StartRecordingPlayout(chan, "recordedplayout.pcm");
printf("\n Start recording playout as %s \n", play_filename.c_str());
res = file->StartRecordingPlayout(chan, play_filename.c_str());
VALIDATE;
}
}
while (stop_record != 0) {
printf("\n Type 0 to stop recording file \n");
ASSERT_EQ(1, scanf("%i", &stop_record));
@ -745,7 +770,7 @@ void run_test() {
if (file_source == 1) {
res = file->StopRecordingMicrophone();
VALIDATE;
}
}
else {
res = file->StopRecordingPlayout(chan);
VALIDATE;
@ -756,20 +781,21 @@ void run_test() {
int file_type = 1;
int stop_play = 1;
printf("\n Select a file to play locally in a loop.");
printf("\n 1. Play recordedmic.pcm");
printf("\n 2. Play recordedplayout.pcm");
printf("\n 1. Play %s", mic_filename.c_str());
printf("\n 2. Play %s", play_filename.c_str());
printf("\n Enter your selection\n");
ASSERT_EQ(1, scanf("%i", &file_type));
if (file_type == 1) {
printf("\n Start playing recordedmic.pcm locally in a loop\n");
res = file->StartPlayingFileLocally(chan,
"recordedmic.pcm", true);
printf("\n Start playing %s locally in a loop\n",
mic_filename.c_str());
res = file->StartPlayingFileLocally(chan, mic_filename.c_str(), true);
VALIDATE;
}
else {
printf("\n Start playing recordedplayout.pcm locally in a loop\n");
res = file->StartPlayingFileLocally(chan,
"recordedplayout.pcm", true);
else {
printf("\n Start playing %s locally in a loop\n",
play_filename.c_str());
res = file->StartPlayingFileLocally(chan, play_filename.c_str(),
true);
VALIDATE;
}
while (stop_play != 0) {
@ -783,20 +809,22 @@ void run_test() {
int file_type = 1;
int stop_play = 1;
printf("\n Select a file to play as microphone in a loop.");
printf("\n 1. Play recordedmic.pcm");
printf("\n 2. Play recordedplayout.pcm");
printf("\n 1. Play %s", mic_filename.c_str());
printf("\n 2. Play %s", play_filename.c_str());
printf("\n Enter your selection\n");
ASSERT_EQ(1, scanf("%i", &file_type));
if (file_type == 1) {
printf("\n Start playing recordedmic.pcm as mic in a loop\n");
res = file->StartPlayingFileAsMicrophone(chan,
"recordedmic.pcm", true);
printf("\n Start playing %s as mic in a loop\n",
mic_filename.c_str());
res = file->StartPlayingFileAsMicrophone(chan, mic_filename.c_str(),
true);
VALIDATE;
}
else {
printf("\n Start playing recordedplayout.pcm as mic in a loop\n");
res = file->StartPlayingFileAsMicrophone(chan,
"recordedplayout.pcm", true);
printf("\n Start playing %s as mic in a loop\n",
play_filename.c_str());
res = file->StartPlayingFileAsMicrophone(chan, play_filename.c_str(),
true);
VALIDATE;
}
while (stop_play != 0) {
@ -806,6 +834,41 @@ void run_test() {
res = file->StopPlayingFileAsMicrophone(chan);
VALIDATE;
}
else if (codecinput == (noCodecs + 24)) {
if (channel_index < kMaxNumChannels) {
res = base1->StartReceive(channels[channel_index]);
VALIDATE;
res = base1->StartPlayout(channels[channel_index]);
VALIDATE;
res = base1->StartSend(channels[channel_index]);
VALIDATE;
res = file->StartPlayingFileAsMicrophone(channels[channel_index],
audio_filename.c_str(),
true,
false);
VALIDATE;
channel_index++;
printf("Using %d additional channels\n", channel_index);
} else {
printf("Max number of channels reached\n");
}
}
else if (codecinput == (noCodecs + 25)) {
if (channel_index > 0) {
channel_index--;
res = file->StopPlayingFileAsMicrophone(channels[channel_index]);
VALIDATE;
res = base1->StopSend(channels[channel_index]);
VALIDATE;
res = base1->StopPlayout(channels[channel_index]);
VALIDATE;
res = base1->StopReceive(channels[channel_index]);
VALIDATE;
printf("Using %d additional channels\n", channel_index);
} else {
printf("All additional channels stopped\n");
}
}
else
break;
}
@ -828,6 +891,18 @@ void run_test() {
#endif
}
while (channel_index > 0) {
--channel_index;
res = file->StopPlayingFileAsMicrophone(channels[channel_index]);
VALIDATE;
res = base1->StopSend(channels[channel_index]);
VALIDATE;
res = base1->StopPlayout(channels[channel_index]);
VALIDATE;
res = base1->StopReceive(channels[channel_index]);
VALIDATE;
}
printf("\n1. New call \n");
printf("2. Quit \n");
printf("Select action: ");
@ -836,7 +911,12 @@ void run_test() {
// Call loop
}
printf("Delete Channel \n");
printf("Delete channels \n");
res = base1->DeleteChannel(chan);
VALIDATE;
for (i = 0; i < kMaxNumChannels; ++i) {
channels[i] = base1->DeleteChannel(channels[i]);
VALIDATE;
}
}

View File

@ -45,6 +45,7 @@
'target_name': 'voe_cmd_test',
'type': 'executable',
'dependencies': [
'<(webrtc_root)/../test/test.gyp:test_support',
'<(webrtc_root)/../testing/gtest.gyp:gtest',
'voice_engine_core',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',

View File

@ -36,9 +36,10 @@ static const char* kPathDelimiter = "/";
// The file we're looking for to identify the project root dir.
static const char* kProjectRootFileName = "DEPS";
static const char* kOutputDirName = "out";
static const char* kOutputFallbackPath = "./";
const char* kCannotFindProjectRootDir = "ERROR_CANNOT_FIND_PROJECT_ROOT_DIR";
std::string GetProjectRootPath() {
std::string ProjectRootPath() {
char path_buffer[FILENAME_MAX];
if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) {
fprintf(stderr, "Cannot get current directory!\n");
@ -67,10 +68,10 @@ std::string GetProjectRootPath() {
return kCannotFindProjectRootDir;
}
std::string GetOutputDir() {
std::string path = GetProjectRootPath();
std::string OutputPath() {
std::string path = ProjectRootPath();
if (path == kCannotFindProjectRootDir) {
return kCannotFindProjectRootDir;
return kOutputFallbackPath;
}
path += kOutputDirName;
struct stat path_info = {0};
@ -79,7 +80,7 @@ std::string GetOutputDir() {
if (!S_ISDIR(path_info.st_mode)) {
fprintf(stderr, "Path %s exists but is not a directory! Remove this file "
"and re-run to create the output folder.\n", path.c_str());
return kCannotFindProjectRootDir;
return kOutputFallbackPath;
}
} else {
#ifdef WIN32

View File

@ -9,7 +9,7 @@
*/
// File utilities for testing purposes.
// The GetProjectRootPath() method is a convenient way of getting an absolute
// The ProjectRootPath() method is a convenient way of getting an absolute
// path to the project source tree root directory. Using this, it is easy to
// refer to test resource files in a portable way.
//
@ -19,7 +19,7 @@
//
// Example use:
// Assume we have the following code being used in a test source file:
// const std::string kInputFile = webrtc::test::GetProjectRootPath() +
// const std::string kInputFile = webrtc::test::ProjectRootPath() +
// "test/data/voice_engine/audio_long16.wav";
// // Use the kInputFile for the tests...
//
@ -29,7 +29,7 @@
// * Test project located in /home/user/webrtc/trunk/src/testproject
// * Test binary compiled as:
// /home/user/webrtc/trunk/out/Debug/testproject_unittests
// Then GetProjectRootPath() will return /home/user/webrtc/trunk/ no matter if
// Then ProjectRootPath() will return /home/user/webrtc/trunk/ no matter if
// the test binary is executed from standing in either of:
// /home/user/webrtc/trunk
// or
@ -41,7 +41,7 @@
// * Test project located in C:\Users\user\webrtc\trunk\src\testproject
// * Test binary compiled as:
// C:\Users\user\webrtc\trunk\src\testproject\Debug\testproject_unittests.exe
// Then GetProjectRootPath() will return C:\Users\user\webrtc\trunk\ when the
// Then ProjectRootPath() will return C:\Users\user\webrtc\trunk\ when the
// test binary is executed from inside Visual Studio.
// It will also return the same path if the test is executed from a command
// prompt standing in C:\Users\user\webrtc\trunk\src\testproject\Debug
@ -51,7 +51,7 @@
// * Test project located in /Users/user/webrtc/trunk/src/testproject
// * Test binary compiled as:
// /Users/user/webrtc/trunk/xcodebuild/Debug/testproject_unittests
// Then GetProjectRootPath() will return /Users/user/webrtc/trunk/ no matter if
// Then ProjectRootPath() will return /Users/user/webrtc/trunk/ no matter if
// the test binary is executed from standing in either of:
// /Users/user/webrtc/trunk
// or
@ -66,7 +66,7 @@
namespace webrtc {
namespace test {
// This is the "directory" returned if the GetProjectPath() function fails
// This is the "directory" returned if the ProjectPath() function fails
// to find the project root.
extern const char* kCannotFindProjectRootDir;
@ -86,20 +86,18 @@ extern const char* kCannotFindProjectRootDir;
// WITH a trailing path delimiter.
// If the project root is not found, the string specified by
// kCannotFindProjectRootDir is returned.
std::string GetProjectRootPath();
std::string ProjectRootPath();
// Creates and returns the absolute path to the output directory where log files
// and other test artifacts should be put. The output directory is always a
// directory named "out" at the top-level of the project, i.e. a subfolder to
// the path returned by GetProjectRootPath().
// the path returned by ProjectRootPath().
//
// Details described for GetProjectRootPath() apply here too.
// Details described for ProjectRootPath() apply here too.
//
// Returns the absolute path to the output directory (named "out") below the
// project root dir WITH a trailing path delimiter.
// If the project root is not found, the string specified by
// kCannotFindProjectRootDir is returned.
std::string GetOutputDir();
// Returns the path WITH a trailing path delimiter. If the project root is not
// found, the current working directory ("./") is returned as a fallback.
std::string OutputPath();
} // namespace test
} // namespace webrtc

View File

@ -53,16 +53,16 @@ class FileUtilsTest: public testing::Test {
// The test is not fully testing the implementation, since we cannot be sure
// of where the executable was launched from.
// The test will fail if the top level directory is not named "trunk".
TEST_F(FileUtilsTest, GetProjectRootPathFromUnchangedWorkingDir) {
std::string path = GetProjectRootPath();
TEST_F(FileUtilsTest, ProjectRootPathFromUnchangedWorkingDir) {
std::string path = ProjectRootPath();
std::string expected_end = "trunk";
expected_end = kPathDelimiter + expected_end + kPathDelimiter;
ASSERT_EQ(path.length() - expected_end.length(), path.find(expected_end));
}
// Similar to the above test, but for the output dir
TEST_F(FileUtilsTest, GetOutputDirFromUnchangedWorkingDir) {
std::string path = GetOutputDir();
TEST_F(FileUtilsTest, OutputPathFromUnchangedWorkingDir) {
std::string path = OutputPath();
std::string expected_end = "out";
expected_end = kPathDelimiter + expected_end + kPathDelimiter;
ASSERT_EQ(path.length() - expected_end.length(), path.find(expected_end));
@ -71,38 +71,38 @@ TEST_F(FileUtilsTest, GetOutputDirFromUnchangedWorkingDir) {
// Tests setting the current working directory to a directory three levels
// deeper from the current one. Then testing that the project path returned
// is still the same, when the function under test is called again.
TEST_F(FileUtilsTest, GetProjectRootPathFromDeeperWorkingDir) {
std::string path = GetProjectRootPath();
TEST_F(FileUtilsTest, ProjectRootPathFromDeeperWorkingDir) {
std::string path = ProjectRootPath();
std::string original_working_dir = path; // This is the correct project root
// Change to a subdirectory path (the full path doesn't have to exist).
path += "foo/bar/baz";
chdir(path.c_str());
ASSERT_EQ(original_working_dir, GetProjectRootPath());
ASSERT_EQ(original_working_dir, ProjectRootPath());
}
// Similar to the above test, but for the output dir
TEST_F(FileUtilsTest, GetOutputDirFromDeeperWorkingDir) {
std::string path = GetOutputDir();
TEST_F(FileUtilsTest, OutputPathFromDeeperWorkingDir) {
std::string path = OutputPath();
std::string original_working_dir = path;
path += "foo/bar/baz";
chdir(path.c_str());
ASSERT_EQ(original_working_dir, GetOutputDir());
ASSERT_EQ(original_working_dir, OutputPath());
}
// Tests with current working directory set to a directory higher up in the
// directory tree than the project root dir. This case shall return a specified
// error string as a directory (which will be an invalid path).
TEST_F(FileUtilsTest, GetProjectRootPathFromRootWorkingDir) {
TEST_F(FileUtilsTest, ProjectRootPathFromRootWorkingDir) {
// Change current working dir to the root of the current file system
// (this will always be "above" our project root dir).
chdir(kPathDelimiter);
ASSERT_EQ(kCannotFindProjectRootDir, GetProjectRootPath());
ASSERT_EQ(kCannotFindProjectRootDir, ProjectRootPath());
}
// Similar to the above test, but for the output dir
TEST_F(FileUtilsTest, GetOutputDirFromRootWorkingDir) {
TEST_F(FileUtilsTest, OutputPathFromRootWorkingDir) {
chdir(kPathDelimiter);
ASSERT_EQ(kCannotFindProjectRootDir, GetOutputDir());
ASSERT_EQ("./", OutputPath());
}
} // namespace test