From 6b6ff558a8445ef9b2bf1eb577903fbb94bc2969 Mon Sep 17 00:00:00 2001 From: "tina.legrand@webrtc.org" Date: Wed, 11 Jan 2012 10:12:54 +0000 Subject: [PATCH] Implementation if mono-to-stereo and vice versa in ACM. Added stereo-to-mono and mono-to-stereo tests to end of TestStereo.cpp. BUG=Aim to resolve issue 207, "Investigate stereo capture handling in modules" TEST=audio_coding_module_test Review URL: http://webrtc-codereview.appspot.com/345002 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1385 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../main/source/audio_coding_module_impl.cc | 77 +++- .../main/source/audio_coding_module_impl.h | 2 + .../audio_coding/main/test/TestStereo.cpp | 391 +++++++++++++----- .../audio_coding/main/test/TestStereo.h | 9 +- 4 files changed, 365 insertions(+), 114 deletions(-) diff --git a/src/modules/audio_coding/main/source/audio_coding_module_impl.cc b/src/modules/audio_coding/main/source/audio_coding_module_impl.cc index ecffffda4a..67c8fd5b53 100644 --- a/src/modules/audio_coding/main/source/audio_coding_module_impl.cc +++ b/src/modules/audio_coding/main/source/audio_coding_module_impl.cc @@ -54,6 +54,8 @@ AudioCodingModuleImpl::AudioCodingModuleImpl( _dtxEnabled(false), _vadMode(VADNormal), _stereoSend(false), + _prev_received_channel(0), + _expected_channels(1), _currentSendCodecIdx(-1), // invalid value _sendCodecRegistered(false), _acmCritSect(CriticalSectionWrapper::CreateCriticalSection()), @@ -806,7 +808,7 @@ mono codecs are supported, i.e. channels=1.", sendCodec.channels); // could not initialize the encoder // Check if already have a registered codec - // Depending on that differet messages are logged + // Depending on that different messages are logged if(!_sendCodecRegistered) { _currentSendCodecIdx = -1; // invalid value @@ -1154,9 +1156,35 @@ match"); bool resamplingRequired = ((WebRtc_Word32)audioFrame._frequencyInHz != _sendCodecInst.plfreq); + // If number of channels in audio doesn't match codec mode, we need + // either mono-to-stereo or stereo-to-mono conversion. + WebRtc_Word16 audio[WEBRTC_10MS_PCM_AUDIO]; + int audio_channels = _sendCodecInst.channels; + if (audioFrame._audioChannel != _sendCodecInst.channels) { + if (_sendCodecInst.channels == 2) { + // Do mono-to-stereo conversion by copying each sample. + for (int k = 0; k < audioFrame._payloadDataLengthInSamples; k++) { + audio[k * 2] = audioFrame._payloadData[k]; + audio[(k * 2) + 1] = audioFrame._payloadData[k]; + } + } else if (_sendCodecInst.channels == 1) { + // Do stereo-to-mono conversion by creating the average of the stereo + // samples. + for (int k = 0; k < audioFrame._payloadDataLengthInSamples; k++) { + audio[k] = (audioFrame._payloadData[k * 2] + + audioFrame._payloadData[(k * 2) + 1]) >> 1; + } + } + } else { + // Copy payload data for future use. + memcpy(audio, audioFrame._payloadData, + audioFrame._payloadDataLengthInSamples * audio_channels * + sizeof(WebRtc_UWord16)); + } + WebRtc_UWord32 currentTimestamp; WebRtc_Word32 status; - // if it is required, we have to do a resampling + // if it is required, we have to do a resampling. if(resamplingRequired) { WebRtc_Word16 resampledAudio[WEBRTC_10MS_PCM_AUDIO]; @@ -1179,8 +1207,8 @@ match"); ((double)_sendCodecInst.plfreq / (double)audioFrame._frequencyInHz)); newLengthSmpl = _inputResampler.Resample10Msec( - audioFrame._payloadData, audioFrame._frequencyInHz, - resampledAudio, sendPlFreq, _sendCodecInst.channels); + audio, audioFrame._frequencyInHz, resampledAudio, sendPlFreq, + audio_channels); if(newLengthSmpl < 0) { @@ -1189,15 +1217,15 @@ match"); return -1; } status = _codecs[_currentSendCodecIdx]->Add10MsData(currentTimestamp, - resampledAudio, newLengthSmpl, audioFrame._audioChannel); + resampledAudio, newLengthSmpl, audio_channels); } else { currentTimestamp = audioFrame._timeStamp; status = _codecs[_currentSendCodecIdx]->Add10MsData(currentTimestamp, - audioFrame._payloadData, audioFrame._payloadDataLengthInSamples, - audioFrame._audioChannel); + audio, audioFrame._payloadDataLengthInSamples, + audio_channels); } _lastInTimestamp = audioFrame._timeStamp; _lastTimestamp = currentTimestamp; @@ -1773,10 +1801,6 @@ AudioCodingModuleImpl::IncomingPacket( // we are going to use ONE iSAC instance for decoding both WB and // SWB payloads. If payload is changed there might be a need to reset // sampling rate of decoder. depending what we have received "now". - // TODO (tlegrand): Change or remove the following comment - // I cannot use the function that BV has written, i.e. - // "DecoderParamByPlType()" as for iSAC there is one instance and - // multiple payloads. for(int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) { if(_registeredPlTypes[i] == myPayloadType) @@ -1792,6 +1816,16 @@ AudioCodingModuleImpl::IncomingPacket( } _codecs[i]->UpdateDecoderSampFreq(i); _netEq.SetReceivedStereo(_stereoReceive[i]); + + // Store number of channels we expect to receive for the + // current payload type. + if (_stereoReceive[i]) { + _expected_channels = 2; + } + + // Reset previous received channel + _prev_received_channel = 0; + break; } } @@ -1800,6 +1834,27 @@ AudioCodingModuleImpl::IncomingPacket( } } + // Check that number of received channels match the setup for the + // received codec. + if (_expected_channels == 2) { + if ((_prev_received_channel == 1) && (rtpInfo.type.Audio.channel == 1)) { + // We expect every second call to this function to be for channel 2, + // since we are in stereo-receive mode. + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id, + "IncomingPacket() Error, payload is" + "mono, but codec registered as stereo."); + return -1; + } + _prev_received_channel = rtpInfo.type.Audio.channel; + } else if (rtpInfo.type.Audio.channel == 2) { + // Codec is registered as mono, but we receive a stereo packet. + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id, + "IncomingPacket() Error, payload is" + "stereo, but codec registered as mono."); + return -1; + } + + // Insert packet into NetEQ. return _netEq.RecIn(incomingPayload, payloadLength, rtpInfo); } diff --git a/src/modules/audio_coding/main/source/audio_coding_module_impl.h b/src/modules/audio_coding/main/source/audio_coding_module_impl.h index c6eeb9c257..c0260f836e 100644 --- a/src/modules/audio_coding/main/source/audio_coding_module_impl.h +++ b/src/modules/audio_coding/main/source/audio_coding_module_impl.h @@ -326,6 +326,8 @@ private: WebRtc_Word16 _mirrorCodecIdx[ACMCodecDB::kMaxNumCodecs]; bool _stereoReceive[ACMCodecDB::kMaxNumCodecs]; bool _stereoSend; + int _prev_received_channel; + int _expected_channels; WebRtc_Word32 _currentSendCodecIdx; bool _sendCodecRegistered; ACMResampler _inputResampler; diff --git a/src/modules/audio_coding/main/test/TestStereo.cpp b/src/modules/audio_coding/main/test/TestStereo.cpp index 50fa7f0ac0..ef633de665 100644 --- a/src/modules/audio_coding/main/test/TestStereo.cpp +++ b/src/modules/audio_coding/main/test/TestStereo.cpp @@ -115,11 +115,17 @@ TestPackStereo::SendData( payloadDataSize = payloadSize*2; } - // Call ACM with two packets, one for each channel - rtpInfo.type.Audio.channel = 1; - status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadDataMaster, payloadDataSize/2, rtpInfo); - rtpInfo.type.Audio.channel = 2; - status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadDataSlave, payloadDataSize/2, rtpInfo); + if (_codecType != 4) { + // Call ACM with two packets, one for each channel + rtpInfo.type.Audio.channel = 1; + status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadDataMaster, payloadDataSize/2, rtpInfo); + rtpInfo.type.Audio.channel = 2; + status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadDataSlave, payloadDataSize/2, rtpInfo); + } else { + // Mono case, call ACM with one packet. + rtpInfo.type.Audio.channel = 1; + status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadData, payloadDataSize, rtpInfo); + } if (frameType != kAudioFrameCN) { _payloadSize = payloadDataSize; @@ -191,8 +197,11 @@ TestStereo::~TestStereo() void TestStereo::Perform() { - char fileName[500]; + char file_name_stereo[500]; + char file_name_mono[500]; WebRtc_UWord16 frequencyHz; + int audio_channels; + int codec_channels; if(_testMode == 0) { @@ -201,11 +210,14 @@ void TestStereo::Perform() "---------- TestStereo ----------"); } - strcpy(fileName, "./test/data/audio_coding/teststereo32kHz.pcm"); + strcpy(file_name_stereo, "./test/data/audio_coding/teststereo32kHz.pcm"); + strcpy(file_name_mono, "./test/data/audio_coding/testfile32kHz.pcm"); frequencyHz = 32000; - _inFileA.Open(fileName, frequencyHz, "rb"); - _inFileA.ReadStereo(true); + _in_file_stereo.Open(file_name_stereo, frequencyHz, "rb"); + _in_file_stereo.ReadStereo(true); + _in_file_mono.Open(file_name_mono, frequencyHz, "rb"); + _in_file_mono.ReadStereo(false); _acmA = AudioCodingModule::Create(0); _acmB = AudioCodingModule::Create(1); @@ -216,6 +228,7 @@ void TestStereo::Perform() WebRtc_UWord8 numEncoders = _acmA->NumberOfCodecs(); CodecInst myCodecParam; + // Register receiving codecs as stereo. for(WebRtc_UWord8 n = 0; n < numEncoders; n++) { _acmB->Codec(n, myCodecParam); @@ -229,15 +242,23 @@ void TestStereo::Perform() } } - // Create and connect the channel + // Create and connect the channel. _channelA2B = new TestPackStereo; _acmA->RegisterTransportCallback(_channelA2B); _channelA2B->RegisterReceiverACM(_acmB); + // + // Test Stereo-To-Stereo for all codecs. + // + audio_channels = 2; + codec_channels = 2; + // All codecs are tested for all allowed sampling frequencies, rates and packet sizes #ifdef WEBRTC_CODEC_G722 if(_testMode != 0) { printf("=======================================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-stereo\n"); } else { printf("."); } @@ -245,27 +266,29 @@ void TestStereo::Perform() _testCntr++; OpenOutFile(_testCntr); char codecG722[] = "G722"; - RegisterSendCodec('A', codecG722, 16000, 64000, 160); - Run(_channelA2B); - RegisterSendCodec('A', codecG722, 16000, 64000, 320); - Run(_channelA2B); - RegisterSendCodec('A', codecG722, 16000, 64000, 480); - Run(_channelA2B); - RegisterSendCodec('A', codecG722, 16000, 64000, 640); - Run(_channelA2B); - RegisterSendCodec('A', codecG722, 16000, 64000, 800); - Run(_channelA2B); - RegisterSendCodec('A', codecG722, 16000, 64000, 960); - Run(_channelA2B); + RegisterSendCodec('A', codecG722, 16000, 64000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecG722, 16000, 64000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecG722, 16000, 64000, 480, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecG722, 16000, 64000, 640, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecG722, 16000, 64000, 800, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecG722, 16000, 64000, 960, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(true, true, VADNormal); - RegisterSendCodec('A', codecG722, 16000, 64000, 320); - Run(_channelA2B); + RegisterSendCodec('A', codecG722, 16000, 64000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(false, false, VADNormal); _outFileB.Close(); #endif #ifdef WEBRTC_CODEC_PCM16 if(_testMode != 0) { printf("=======================================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-stereo\n"); } else { printf("."); } @@ -273,53 +296,59 @@ void TestStereo::Perform() _testCntr++; OpenOutFile(_testCntr); char codecL16[] = "L16"; - RegisterSendCodec('A', codecL16, 8000, 128000, 80); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 8000, 128000, 160); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 8000, 128000, 240); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 8000, 128000, 320); - Run(_channelA2B); + RegisterSendCodec('A', codecL16, 8000, 128000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 8000, 128000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 8000, 128000, 240, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 8000, 128000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(true, true, VADNormal); - RegisterSendCodec('A', codecL16, 8000, 128000, 80); - Run(_channelA2B); + RegisterSendCodec('A', codecL16, 8000, 128000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(false, false, VADNormal); _outFileB.Close(); + if(_testMode != 0) { printf("=======================================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-stereo\n"); } else { printf("."); } _testCntr++; OpenOutFile(_testCntr); - RegisterSendCodec('A', codecL16, 16000, 256000, 160); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 16000, 256000, 320); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 16000, 256000, 480); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 16000, 256000, 640); - Run(_channelA2B); + RegisterSendCodec('A', codecL16, 16000, 256000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 16000, 256000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 16000, 256000, 480, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 16000, 256000, 640, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(true, true, VADNormal); - RegisterSendCodec('A', codecL16, 16000, 256000, 160); - Run(_channelA2B); + RegisterSendCodec('A', codecL16, 16000, 256000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(false, false, VADNormal); _outFileB.Close(); + if(_testMode != 0) { printf("=======================================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-stereo\n"); } else { printf("."); } _testCntr++; OpenOutFile(_testCntr); - RegisterSendCodec('A', codecL16, 32000, 512000, 320); - Run(_channelA2B); - RegisterSendCodec('A', codecL16, 32000, 512000, 640); - Run(_channelA2B); + RegisterSendCodec('A', codecL16, 32000, 512000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecL16, 32000, 512000, 640, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(true, true, VADNormal); - RegisterSendCodec('A', codecL16, 32000, 512000, 320); - Run(_channelA2B); + RegisterSendCodec('A', codecL16, 32000, 512000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(false, false, VADNormal); _outFileB.Close(); #endif @@ -327,66 +356,213 @@ void TestStereo::Perform() #ifdef PCMA_AND_PCMU if(_testMode != 0) { printf("=======================================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-stereo\n"); } else { printf("."); } _channelA2B->SetCodecType(0); + audio_channels = 2; + codec_channels = 2; _testCntr++; OpenOutFile(_testCntr); char codecPCMA[] = "PCMA"; - RegisterSendCodec('A', codecPCMA, 8000, 64000, 80); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMA, 8000, 64000, 160); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMA, 8000, 64000, 240); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMA, 8000, 64000, 320); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMA, 8000, 64000, 400); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMA, 8000, 64000, 480); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 240, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 400, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 480, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(true, true, VADNormal); - RegisterSendCodec('A', codecPCMA, 8000, 64000, 80); - Run(_channelA2B); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(false, false, VADNormal); _outFileB.Close(); if(_testMode != 0) { printf("=======================================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-stereo\n"); } else { printf("."); } _testCntr++; OpenOutFile(_testCntr); - Run(_channelA2B); char codecPCMU[] = "PCMU"; - RegisterSendCodec('A', codecPCMU, 8000, 64000, 80); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMU, 8000, 64000, 160); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMU, 8000, 64000, 240); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMU, 8000, 64000, 320); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMU, 8000, 64000, 400); - Run(_channelA2B); - RegisterSendCodec('A', codecPCMU, 8000, 64000, 480); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 240, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 400, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 480, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(true, true, VADNormal); - RegisterSendCodec('A', codecPCMU, 8000, 64000, 80); - Run(_channelA2B); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); _acmA->SetVAD(false, false, VADNormal); - Run(_channelA2B); + Run(_channelA2B, audio_channels, codec_channels); _outFileB.Close(); - if(_testMode != 0) { - printf("=======================================================================\n"); - } else { - printf("."); - } #endif - /* Print out which codecs were tested, and which were not, in the run */ + // + // Test Mono-To-Stereo for all codecs. + // + audio_channels = 1; + codec_channels = 2; +#ifdef WEBRTC_CODEC_G722 + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + _channelA2B->SetCodecType(3); + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecG722, 16000, 64000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); +#endif +#ifdef WEBRTC_CODEC_PCM16 + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + _channelA2B->SetCodecType(1); + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecL16, 8000, 128000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecL16, 16000, 256000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecL16, 32000, 512000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); +#endif +#ifdef PCMA_AND_PCMU + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + _channelA2B->SetCodecType(0); + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); +#endif + + // + // Test Stereo-To-Mono for all codecs. + // + audio_channels = 2; + codec_channels = 1; + _channelA2B->SetCodecType(4); + + // Register receivers as mono. + for(WebRtc_UWord8 n = 0; n < numEncoders; n++) { + _acmB->Codec(n, myCodecParam); + if(!strcmp(myCodecParam.plname, "L16") || + !strcmp(myCodecParam.plname, "PCMA")|| + !strcmp(myCodecParam.plname, "PCMU")|| + !strcmp(myCodecParam.plname, "G722")) { + myCodecParam.channels = 1; + _acmB->RegisterReceiveCodec(myCodecParam); + } + } +#ifdef WEBRTC_CODEC_G722 + // Run stereo audio and mono codec. + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-mono\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecG722, 16000, 64000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); +#endif +#ifdef WEBRTC_CODEC_PCM16 + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-mono\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecL16, 8000, 128000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Stereo-to-mono\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecL16, 16000, 256000, 160, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecL16, 32000, 512000, 320, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); +#endif +#ifdef PCMA_AND_PCMU + if(_testMode != 0) { + printf("===============================================================\n"); + printf("Test number: %d\n",_testCntr + 1); + printf("Test type: Mono-to-stereo\n"); + } + _testCntr++; + OpenOutFile(_testCntr); + RegisterSendCodec('A', codecPCMU, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + RegisterSendCodec('A', codecPCMA, 8000, 64000, 80, codec_channels); + Run(_channelA2B, audio_channels, codec_channels); + _outFileB.Close(); +#endif + + // Print out which codecs were tested, and which were not, in the run. if(_testMode != 0) { - printf("The following codecs was INCLUDED in the test:\n"); + printf("/nThe following codecs was INCLUDED in the test:\n"); #ifdef WEBRTC_CODEC_G722 printf(" G.722\n"); #endif @@ -415,11 +591,12 @@ WebRtc_Word16 TestStereo::RegisterSendCodec(char side, char* codecName, WebRtc_Word32 samplingFreqHz, int rate, - int packSize) + int packSize, + int channels) { if(_testMode != 0) { // Print out codec and settings - printf("codec: %s Freq: %d Rate: %d PackSize: %d", codecName, samplingFreqHz, rate, packSize); + printf("Codec: %s Freq: %d Rate: %d PackSize: %d", codecName, samplingFreqHz, rate, packSize); } // Store packetsize in samples, used to validate the recieved packet @@ -454,7 +631,7 @@ WebRtc_Word16 TestStereo::RegisterSendCodec(char side, } CodecInst myCodecParam; - // Get all codec paramters before registering + // Get all codec parameters before registering CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam, samplingFreqHz)); myCodecParam.rate = rate; myCodecParam.pacsize = packSize; @@ -462,14 +639,15 @@ WebRtc_Word16 TestStereo::RegisterSendCodec(char side, myCodecParam.channels = 1; CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam)); // Register codec as stereo. - myCodecParam.channels = 2; - CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam)); - + if (channels == 2) { + myCodecParam.channels = 2; + CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam)); + } // Initialization was successful. return 0; } -void TestStereo::Run(TestPackStereo* channel) +void TestStereo::Run(TestPackStereo* channel, int in_channels, int out_channels) { AudioFrame audioFrame; @@ -480,10 +658,22 @@ void TestStereo::Run(TestPackStereo* channel) int errorCount = 0; // Only run 1 second for each test case - while((_counter<1000)&& (!_inFileA.EndOfFile())) + // TODO(tlegrand): either remove |_counter| or start using it as the comment + // above says. Now |_counter| is always 0. + while(_counter<1000) { // Add 10 msec to ACM - _inFileA.Read10MsData(audioFrame); + if (in_channels == 1) { + if (_in_file_mono.EndOfFile()) { + break; + } + _in_file_mono.Read10MsData(audioFrame); + } else { + if (_in_file_stereo.EndOfFile()) { + break; + } + _in_file_stereo.Read10MsData(audioFrame); + } CHECK_ERROR(_acmA->Add10MsData(audioFrame)); // Run sender side of ACM @@ -491,8 +681,9 @@ void TestStereo::Run(TestPackStereo* channel) // Verify that the received packet size matches the settings recSize = channel->GetPayloadSize(); - if ((0PlayoutData10Ms(outFreqHzB, audioFrame)); // Write output speech to file - _outFileB.Write10MsData(audioFrame._payloadData, audioFrame._payloadDataLengthInSamples*audioFrame._audioChannel); + _outFileB.Write10MsData( + audioFrame._payloadData, + audioFrame._payloadDataLengthInSamples * audioFrame._audioChannel); } if (errorCount) @@ -523,8 +716,8 @@ void TestStereo::Run(TestPackStereo* channel) if (_counter == 1000) { _counter = 0; } - if (_inFileA.EndOfFile()) { - _inFileA.Rewind(); + if (_in_file_stereo.EndOfFile()) { + _in_file_stereo.Rewind(); } } diff --git a/src/modules/audio_coding/main/test/TestStereo.h b/src/modules/audio_coding/main/test/TestStereo.h index a4478802bd..94a0c564da 100644 --- a/src/modules/audio_coding/main/test/TestStereo.h +++ b/src/modules/audio_coding/main/test/TestStereo.h @@ -65,9 +65,10 @@ private: char* codecName, WebRtc_Word32 sampFreqHz, int rate, - int packSize); + int packSize, + int channels); - void Run(TestPackStereo* channel); + void Run(TestPackStereo* channel, int in_channels, int out_channels); void OpenOutFile(WebRtc_Word16 testNumber); void DisplaySendReceiveCodec(); @@ -86,9 +87,9 @@ private: TestPackStereo* _channelA2B; - PCMFile _inFileA; + PCMFile _in_file_stereo; + PCMFile _in_file_mono; PCMFile _outFileB; - PCMFile _inFileStereo; WebRtc_Word16 _testCntr; WebRtc_UWord16 _packSizeSamp; WebRtc_UWord16 _packSizeBytes;