diff options
Diffstat (limited to 'webrtc/modules/audio_coding/test/TwoWayCommunication.cc')
-rw-r--r-- | webrtc/modules/audio_coding/test/TwoWayCommunication.cc | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/webrtc/modules/audio_coding/test/TwoWayCommunication.cc b/webrtc/modules/audio_coding/test/TwoWayCommunication.cc new file mode 100644 index 0000000000..56e136bd34 --- /dev/null +++ b/webrtc/modules/audio_coding/test/TwoWayCommunication.cc @@ -0,0 +1,299 @@ +/* + * 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 "TwoWayCommunication.h" + +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#ifdef WIN32 +#include <Windows.h> +#endif + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/engine_configurations.h" +#include "webrtc/common_types.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" +#include "webrtc/system_wrappers/include/trace.h" +#include "webrtc/test/testsupport/fileutils.h" + +namespace webrtc { + +#define MAX_FILE_NAME_LENGTH_BYTE 500 + +TwoWayCommunication::TwoWayCommunication(int testMode) + : _acmA(AudioCodingModule::Create(1)), + _acmRefA(AudioCodingModule::Create(3)), + _testMode(testMode) { + AudioCodingModule::Config config; + // The clicks will be more obvious in FAX mode. TODO(henrik.lundin) Really? + config.neteq_config.playout_mode = kPlayoutFax; + config.id = 2; + _acmB.reset(AudioCodingModule::Create(config)); + config.id = 4; + _acmRefB.reset(AudioCodingModule::Create(config)); +} + +TwoWayCommunication::~TwoWayCommunication() { + delete _channel_A2B; + delete _channel_B2A; + delete _channelRef_A2B; + delete _channelRef_B2A; +#ifdef WEBRTC_DTMF_DETECTION + if (_dtmfDetectorA != NULL) { + delete _dtmfDetectorA; + } + if (_dtmfDetectorB != NULL) { + delete _dtmfDetectorB; + } +#endif + _inFileA.Close(); + _inFileB.Close(); + _outFileA.Close(); + _outFileB.Close(); + _outFileRefA.Close(); + _outFileRefB.Close(); +} + +void TwoWayCommunication::ChooseCodec(uint8_t* codecID_A, + uint8_t* codecID_B) { + rtc::scoped_ptr<AudioCodingModule> tmpACM(AudioCodingModule::Create(0)); + uint8_t noCodec = tmpACM->NumberOfCodecs(); + CodecInst codecInst; + printf("List of Supported Codecs\n"); + printf("========================\n"); + for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) { + EXPECT_EQ(tmpACM->Codec(codecCntr, &codecInst), 0); + printf("%d- %s\n", codecCntr, codecInst.plname); + } + printf("\nChoose a send codec for side A [0]: "); + char myStr[15] = ""; + EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL); + *codecID_A = (uint8_t) atoi(myStr); + + printf("\nChoose a send codec for side B [0]: "); + EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL); + *codecID_B = (uint8_t) atoi(myStr); + + printf("\n"); +} + +void TwoWayCommunication::SetUp() { + uint8_t codecID_A; + uint8_t codecID_B; + + ChooseCodec(&codecID_A, &codecID_B); + CodecInst codecInst_A; + CodecInst codecInst_B; + CodecInst dummyCodec; + EXPECT_EQ(0, _acmA->Codec(codecID_A, &codecInst_A)); + EXPECT_EQ(0, _acmB->Codec(codecID_B, &codecInst_B)); + EXPECT_EQ(0, _acmA->Codec(6, &dummyCodec)); + + //--- Set A codecs + EXPECT_EQ(0, _acmA->RegisterSendCodec(codecInst_A)); + EXPECT_EQ(0, _acmA->RegisterReceiveCodec(codecInst_B)); + //--- Set ref-A codecs + EXPECT_EQ(0, _acmRefA->RegisterSendCodec(codecInst_A)); + EXPECT_EQ(0, _acmRefA->RegisterReceiveCodec(codecInst_B)); + + //--- Set B codecs + EXPECT_EQ(0, _acmB->RegisterSendCodec(codecInst_B)); + EXPECT_EQ(0, _acmB->RegisterReceiveCodec(codecInst_A)); + + //--- Set ref-B codecs + EXPECT_EQ(0, _acmRefB->RegisterSendCodec(codecInst_B)); + EXPECT_EQ(0, _acmRefB->RegisterReceiveCodec(codecInst_A)); + + uint16_t frequencyHz; + + //--- Input A + std::string in_file_name = webrtc::test::ResourcePath( + "audio_coding/testfile32kHz", "pcm"); + frequencyHz = 32000; + printf("Enter input file at side A [%s]: ", in_file_name.c_str()); + PCMFile::ChooseFile(&in_file_name, 499, &frequencyHz); + _inFileA.Open(in_file_name, frequencyHz, "rb"); + + //--- Output A + std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm"; + printf("Output file at side A: %s\n", out_file_a.c_str()); + printf("Sampling frequency (in Hz) of the above file: %u\n", frequencyHz); + _outFileA.Open(out_file_a, frequencyHz, "wb"); + std::string ref_file_name = webrtc::test::OutputPath() + "ref_outA.pcm"; + _outFileRefA.Open(ref_file_name, frequencyHz, "wb"); + + //--- Input B + in_file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", + "pcm"); + frequencyHz = 32000; + printf("\n\nEnter input file at side B [%s]: ", in_file_name.c_str()); + PCMFile::ChooseFile(&in_file_name, 499, &frequencyHz); + _inFileB.Open(in_file_name, frequencyHz, "rb"); + + //--- Output B + std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm"; + printf("Output file at side B: %s\n", out_file_b.c_str()); + printf("Sampling frequency (in Hz) of the above file: %u\n", frequencyHz); + _outFileB.Open(out_file_b, frequencyHz, "wb"); + ref_file_name = webrtc::test::OutputPath() + "ref_outB.pcm"; + _outFileRefB.Open(ref_file_name, frequencyHz, "wb"); + + //--- Set A-to-B channel + _channel_A2B = new Channel; + _acmA->RegisterTransportCallback(_channel_A2B); + _channel_A2B->RegisterReceiverACM(_acmB.get()); + //--- Do the same for the reference + _channelRef_A2B = new Channel; + _acmRefA->RegisterTransportCallback(_channelRef_A2B); + _channelRef_A2B->RegisterReceiverACM(_acmRefB.get()); + + //--- Set B-to-A channel + _channel_B2A = new Channel; + _acmB->RegisterTransportCallback(_channel_B2A); + _channel_B2A->RegisterReceiverACM(_acmA.get()); + //--- Do the same for reference + _channelRef_B2A = new Channel; + _acmRefB->RegisterTransportCallback(_channelRef_B2A); + _channelRef_B2A->RegisterReceiverACM(_acmRefA.get()); +} + +void TwoWayCommunication::SetUpAutotest() { + CodecInst codecInst_A; + CodecInst codecInst_B; + CodecInst dummyCodec; + + EXPECT_EQ(0, _acmA->Codec("ISAC", &codecInst_A, 16000, 1)); + EXPECT_EQ(0, _acmB->Codec("L16", &codecInst_B, 8000, 1)); + EXPECT_EQ(0, _acmA->Codec(6, &dummyCodec)); + + //--- Set A codecs + EXPECT_EQ(0, _acmA->RegisterSendCodec(codecInst_A)); + EXPECT_EQ(0, _acmA->RegisterReceiveCodec(codecInst_B)); + + //--- Set ref-A codecs + EXPECT_GT(_acmRefA->RegisterSendCodec(codecInst_A), -1); + EXPECT_GT(_acmRefA->RegisterReceiveCodec(codecInst_B), -1); + + //--- Set B codecs + EXPECT_GT(_acmB->RegisterSendCodec(codecInst_B), -1); + EXPECT_GT(_acmB->RegisterReceiveCodec(codecInst_A), -1); + + //--- Set ref-B codecs + EXPECT_EQ(0, _acmRefB->RegisterSendCodec(codecInst_B)); + EXPECT_EQ(0, _acmRefB->RegisterReceiveCodec(codecInst_A)); + + uint16_t frequencyHz; + + //--- Input A and B + std::string in_file_name = webrtc::test::ResourcePath( + "audio_coding/testfile32kHz", "pcm"); + frequencyHz = 16000; + _inFileA.Open(in_file_name, frequencyHz, "rb"); + _inFileB.Open(in_file_name, frequencyHz, "rb"); + + //--- Output A + std::string output_file_a = webrtc::test::OutputPath() + "outAutotestA.pcm"; + frequencyHz = 16000; + _outFileA.Open(output_file_a, frequencyHz, "wb"); + std::string output_ref_file_a = webrtc::test::OutputPath() + + "ref_outAutotestA.pcm"; + _outFileRefA.Open(output_ref_file_a, frequencyHz, "wb"); + + //--- Output B + std::string output_file_b = webrtc::test::OutputPath() + "outAutotestB.pcm"; + frequencyHz = 16000; + _outFileB.Open(output_file_b, frequencyHz, "wb"); + std::string output_ref_file_b = webrtc::test::OutputPath() + + "ref_outAutotestB.pcm"; + _outFileRefB.Open(output_ref_file_b, frequencyHz, "wb"); + + //--- Set A-to-B channel + _channel_A2B = new Channel; + _acmA->RegisterTransportCallback(_channel_A2B); + _channel_A2B->RegisterReceiverACM(_acmB.get()); + //--- Do the same for the reference + _channelRef_A2B = new Channel; + _acmRefA->RegisterTransportCallback(_channelRef_A2B); + _channelRef_A2B->RegisterReceiverACM(_acmRefB.get()); + + //--- Set B-to-A channel + _channel_B2A = new Channel; + _acmB->RegisterTransportCallback(_channel_B2A); + _channel_B2A->RegisterReceiverACM(_acmA.get()); + //--- Do the same for reference + _channelRef_B2A = new Channel; + _acmRefB->RegisterTransportCallback(_channelRef_B2A); + _channelRef_B2A->RegisterReceiverACM(_acmRefA.get()); +} + +void TwoWayCommunication::Perform() { + if (_testMode == 0) { + SetUpAutotest(); + } else { + SetUp(); + } + unsigned int msecPassed = 0; + unsigned int secPassed = 0; + + int32_t outFreqHzA = _outFileA.SamplingFrequency(); + int32_t outFreqHzB = _outFileB.SamplingFrequency(); + + AudioFrame audioFrame; + + auto codecInst_B = _acmB->SendCodec(); + ASSERT_TRUE(codecInst_B); + + // In the following loop we tests that the code can handle misuse of the APIs. + // In the middle of a session with data flowing between two sides, called A + // and B, APIs will be called, and the code should continue to run, and be + // able to recover. + while (!_inFileA.EndOfFile() && !_inFileB.EndOfFile()) { + msecPassed += 10; + EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0); + EXPECT_GE(_acmA->Add10MsData(audioFrame), 0); + EXPECT_GE(_acmRefA->Add10MsData(audioFrame), 0); + + EXPECT_GT(_inFileB.Read10MsData(audioFrame), 0); + + EXPECT_GE(_acmB->Add10MsData(audioFrame), 0); + EXPECT_GE(_acmRefB->Add10MsData(audioFrame), 0); + EXPECT_EQ(0, _acmA->PlayoutData10Ms(outFreqHzA, &audioFrame)); + _outFileA.Write10MsData(audioFrame); + EXPECT_EQ(0, _acmRefA->PlayoutData10Ms(outFreqHzA, &audioFrame)); + _outFileRefA.Write10MsData(audioFrame); + EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame)); + _outFileB.Write10MsData(audioFrame); + EXPECT_EQ(0, _acmRefB->PlayoutData10Ms(outFreqHzB, &audioFrame)); + _outFileRefB.Write10MsData(audioFrame); + + // Update time counters each time a second of data has passed. + if (msecPassed >= 1000) { + msecPassed = 0; + secPassed++; + } + // Re-register send codec on side B. + if (((secPassed % 5) == 4) && (msecPassed >= 990)) { + EXPECT_EQ(0, _acmB->RegisterSendCodec(*codecInst_B)); + EXPECT_TRUE(_acmB->SendCodec()); + } + // Initialize receiver on side A. + if (((secPassed % 7) == 6) && (msecPassed == 0)) + EXPECT_EQ(0, _acmA->InitializeReceiver()); + // Re-register codec on side A. + if (((secPassed % 7) == 6) && (msecPassed >= 990)) { + EXPECT_EQ(0, _acmA->RegisterReceiveCodec(*codecInst_B)); + } + } +} + +} // namespace webrtc |