From b351d6a8d8ded3fa114b40cefdff7ae12a5fdb4f Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Fri, 11 Nov 2011 13:26:05 +0000 Subject: [PATCH] Reverting rev 929 due to failing assert on Linux. Failing at: audio_buffer.cc:159 TBR=mflodman Review URL: http://webrtc-codereview.appspot.com/270008 git-svn-id: http://webrtc.googlecode.com/svn/trunk@935 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/voice_engine/main/source/channel.cc | 2 +- .../main/source/transmit_mixer.cc | 9 +- src/voice_engine/main/source/voe_base_impl.cc | 300 +++++++++--------- .../main/source/voe_codec_impl.cc | 32 +- 4 files changed, 160 insertions(+), 183 deletions(-) diff --git a/src/voice_engine/main/source/channel.cc b/src/voice_engine/main/source/channel.cc index ae9628e22d..d83da87501 100644 --- a/src/voice_engine/main/source/channel.cc +++ b/src/voice_engine/main/source/channel.cc @@ -5898,7 +5898,7 @@ Channel::EncodeAndSend() WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), "Channel::EncodeAndSend()"); - assert(_audioFrame._audioChannel <= 2); + assert(_audioFrame._audioChannel == 1); if (_audioFrame._payloadDataLengthInSamples == 0) { WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), diff --git a/src/voice_engine/main/source/transmit_mixer.cc b/src/voice_engine/main/source/transmit_mixer.cc index c078fade7b..f4ccf5f230 100644 --- a/src/voice_engine/main/source/transmit_mixer.cc +++ b/src/voice_engine/main/source/transmit_mixer.cc @@ -1158,13 +1158,9 @@ TransmitMixer::GenerateAudioFrame(const WebRtc_Word16 audioSamples[], "samplesPerSec=%u, mixingFrequency=%u)", nSamples, samplesPerSec, mixingFrequency); - ResamplerType resampType = (nChannels == 1)? - kResamplerSynchronous : kResamplerSynchronousStereo; - - if (_audioResampler.ResetIfNeeded(samplesPerSec, mixingFrequency, - resampType) != 0) + kResamplerSynchronous) != 0) { WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1), "TransmitMixer::GenerateAudioFrame() unable to resample"); @@ -1172,7 +1168,7 @@ TransmitMixer::GenerateAudioFrame(const WebRtc_Word16 audioSamples[], } if (_audioResampler.Push( (WebRtc_Word16*) audioSamples, - nSamples * nChannels, + nSamples, _audioFrame._payloadData, AudioFrame::kMaxAudioFrameSizeSamples, (int&) _audioFrame._payloadDataLengthInSamples) == -1) @@ -1182,7 +1178,6 @@ TransmitMixer::GenerateAudioFrame(const WebRtc_Word16 audioSamples[], return -1; } - _audioFrame._payloadDataLengthInSamples /= nChannels; _audioFrame._id = _instanceId; _audioFrame._timeStamp = -1; _audioFrame._frequencyInHz = mixingFrequency; diff --git a/src/voice_engine/main/source/voe_base_impl.cc b/src/voice_engine/main/source/voe_base_impl.cc index 2b91db9063..c1c81d61d8 100644 --- a/src/voice_engine/main/source/voe_base_impl.cc +++ b/src/voice_engine/main/source/voe_base_impl.cc @@ -159,6 +159,21 @@ WebRtc_Word32 VoEBaseImpl::RecordedDataIsAvailable( assert(_transmitMixerPtr != NULL); assert(_audioDevicePtr != NULL); + // Always use mono representation within VoE + if (nChannels == 2) + { + WebRtc_Word16* audio16ptr = (WebRtc_Word16*) audioSamples; + WebRtc_Word32 audio32; + for (WebRtc_UWord32 i = 0; i < nSamples; i++) + { + // y(i) = (1/2)*(x(2i) + x(2i+1)) => (1/2)*(left(i) + right(i)) + audio32 = audio16ptr[2 * i]; + audio32 += audio16ptr[2 * i + 1]; + audio32 >>= 1; + audio16ptr[i] = static_cast (audio32); + } + } + bool isAnalogAGC(false); WebRtc_UWord32 maxVolume(0); WebRtc_UWord16 currentVoEMicLevel(0); @@ -204,9 +219,12 @@ WebRtc_Word32 VoEBaseImpl::RecordedDataIsAvailable( currentVoEMicLevel = (WebRtc_UWord16) _oldVoEMicLevel; } + // Sending side only supports mono + const WebRtc_UWord8 nAudioChannels(1); + // Perform channel-independent operations // (APM, mix with file, record to file, mute, etc.) - _transmitMixerPtr->PrepareDemux(audioSamples, nSamples, nChannels, + _transmitMixerPtr->PrepareDemux(audioSamples, nSamples, nAudioChannels, samplesPerSec, (WebRtc_UWord16) totalDelayMS, clockDrift, currentVoEMicLevel); @@ -365,6 +383,129 @@ int VoEBaseImpl::Init(AudioDeviceModule* external_adm) } } + // Create the AudioProcessing Module if it does not exist. + + if (_audioProcessingModulePtr == NULL) + { + _audioProcessingModulePtr = AudioProcessing::Create( + VoEId(_instanceId, -1)); + if (_audioProcessingModulePtr == NULL) + { + _engineStatistics.SetLastError(VE_NO_MEMORY, kTraceCritical, + "Init() failed to create the AP module"); + return -1; + } + voe::Utility::TraceModuleVersion(VoEId(_instanceId, -1), + *_audioProcessingModulePtr); + + // Ensure that mixers in both directions has access to the created APM + _transmitMixerPtr->SetAudioProcessingModule(_audioProcessingModulePtr); + _outputMixerPtr->SetAudioProcessingModule(_audioProcessingModulePtr); + + if (_audioProcessingModulePtr->echo_cancellation()-> + set_device_sample_rate_hz( + kVoiceEngineAudioProcessingDeviceSampleRateHz)) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set the device sample rate to 48K for AP " + " module"); + return -1; + } + // Using 8 kHz as inital Fs. Might be changed already at first call. + if (_audioProcessingModulePtr->set_sample_rate_hz(8000)) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set the sample rate to 8K for AP module"); + return -1; + } + + if (_audioProcessingModulePtr->set_num_channels(1, 1) != 0) + { + _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceError, + "Init() failed to set channels for the primary audio stream"); + return -1; + } + + if (_audioProcessingModulePtr->set_num_reverse_channels(1) != 0) + { + _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceError, + "Init() failed to set channels for the primary audio stream"); + return -1; + } + // high-pass filter + if (_audioProcessingModulePtr->high_pass_filter()->Enable( + WEBRTC_VOICE_ENGINE_HP_DEFAULT_STATE) != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set the high-pass filter for AP module"); + return -1; + } + // Echo Cancellation + if (_audioProcessingModulePtr->echo_cancellation()-> + enable_drift_compensation(false) != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set drift compensation for AP module"); + return -1; + } + if (_audioProcessingModulePtr->echo_cancellation()->Enable( + WEBRTC_VOICE_ENGINE_EC_DEFAULT_STATE)) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set echo cancellation state for AP module"); + return -1; + } + // Noise Reduction + if (_audioProcessingModulePtr->noise_suppression()->set_level( + (NoiseSuppression::Level) WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE) + != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set noise reduction level for AP module"); + return -1; + } + if (_audioProcessingModulePtr->noise_suppression()->Enable( + WEBRTC_VOICE_ENGINE_NS_DEFAULT_STATE) != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set noise reduction state for AP module"); + return -1; + } + // Automatic Gain control + if (_audioProcessingModulePtr->gain_control()->set_analog_level_limits( + kMinVolumeLevel,kMaxVolumeLevel) != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set AGC analog level for AP module"); + return -1; + } + if (_audioProcessingModulePtr->gain_control()->set_mode( + (GainControl::Mode) WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE) + != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set AGC mode for AP module"); + return -1; + } + if (_audioProcessingModulePtr->gain_control()->Enable( + WEBRTC_VOICE_ENGINE_AGC_DEFAULT_STATE) + != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set AGC state for AP module"); + return -1; + } + // VAD + if (_audioProcessingModulePtr->voice_detection()->Enable( + WEBRTC_VOICE_ENGINE_VAD_DEFAULT_STATE) + != 0) + { + _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, + "Init() failed to set VAD state for AP module"); + return -1; + } + } + // Create and internal ADM if the user has not added and external // ADM implementation as input to Init(). if (external_adm == NULL) @@ -471,149 +612,7 @@ int VoEBaseImpl::Init(AudioDeviceModule* external_adm) "Init() failed to initialize the microphone"); } - // Set number of channels - _audioDevicePtr->StereoPlayoutIsAvailable(&available); - if (_audioDevicePtr->SetStereoPlayout(available) != 0) - { - _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, - "Init() failed to set mono/stereo playout mode"); - } - _audioDevicePtr->StereoRecordingIsAvailable(&available); - if (_audioDevicePtr->SetStereoRecording(available) != 0) - { - _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, - "Init() failed to set mono/stereo recording mode"); - } - int recordingChannels = available ? 2 : 1; - - // APM initialization done after sound card since we need - // to know if we support stereo recording or not. - - // Create the AudioProcessing Module if it does not exist. - - if (_audioProcessingModulePtr == NULL) - { - _audioProcessingModulePtr = AudioProcessing::Create( - VoEId(_instanceId, -1)); - if (_audioProcessingModulePtr == NULL) - { - _engineStatistics.SetLastError(VE_NO_MEMORY, kTraceCritical, - "Init() failed to create the AP module"); - return -1; - } - voe::Utility::TraceModuleVersion(VoEId(_instanceId, -1), - *_audioProcessingModulePtr); - - // Ensure that mixers in both directions has access to the created APM - _transmitMixerPtr->SetAudioProcessingModule(_audioProcessingModulePtr); - _outputMixerPtr->SetAudioProcessingModule(_audioProcessingModulePtr); - - if (_audioProcessingModulePtr->echo_cancellation()-> - set_device_sample_rate_hz( - kVoiceEngineAudioProcessingDeviceSampleRateHz)) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set the device sample rate to 48K for AP " - " module"); - return -1; - } - // Using 8 kHz as inital Fs. Might be changed already at first call. - if (_audioProcessingModulePtr->set_sample_rate_hz(8000)) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set the sample rate to 8K for AP module"); - return -1; - } - - // Assume mono sending until a send codec is set. - if (_audioProcessingModulePtr->set_num_channels(recordingChannels, 1) != 0) - { - _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceError, - "Init() failed to set channels for the primary audio stream"); - return -1; - } - - if (_audioProcessingModulePtr->set_num_reverse_channels(1) != 0) - { - _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceError, - "Init() failed to set channels for the primary audio stream"); - return -1; - } - // high-pass filter - if (_audioProcessingModulePtr->high_pass_filter()->Enable( - WEBRTC_VOICE_ENGINE_HP_DEFAULT_STATE) != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set the high-pass filter for AP module"); - return -1; - } - // Echo Cancellation - if (_audioProcessingModulePtr->echo_cancellation()-> - enable_drift_compensation(false) != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set drift compensation for AP module"); - return -1; - } - if (_audioProcessingModulePtr->echo_cancellation()->Enable( - WEBRTC_VOICE_ENGINE_EC_DEFAULT_STATE)) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set echo cancellation state for AP module"); - return -1; - } - // Noise Reduction - if (_audioProcessingModulePtr->noise_suppression()->set_level( - (NoiseSuppression::Level) WEBRTC_VOICE_ENGINE_NS_DEFAULT_MODE) - != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set noise reduction level for AP module"); - return -1; - } - if (_audioProcessingModulePtr->noise_suppression()->Enable( - WEBRTC_VOICE_ENGINE_NS_DEFAULT_STATE) != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set noise reduction state for AP module"); - return -1; - } - // Automatic Gain control - if (_audioProcessingModulePtr->gain_control()->set_analog_level_limits( - kMinVolumeLevel,kMaxVolumeLevel) != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set AGC analog level for AP module"); - return -1; - } - if (_audioProcessingModulePtr->gain_control()->set_mode( - (GainControl::Mode) WEBRTC_VOICE_ENGINE_AGC_DEFAULT_MODE) - != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set AGC mode for AP module"); - return -1; - } - if (_audioProcessingModulePtr->gain_control()->Enable( - WEBRTC_VOICE_ENGINE_AGC_DEFAULT_STATE) - != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set AGC state for AP module"); - return -1; - } - // VAD - if (_audioProcessingModulePtr->voice_detection()->Enable( - WEBRTC_VOICE_ENGINE_VAD_DEFAULT_STATE) - != 0) - { - _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError, - "Init() failed to set VAD state for AP module"); - return -1; - } - } - - // Set default AGC mode for the ADM + // Set default AGC mode for the ADM #ifdef WEBRTC_VOICE_ENGINE_AGC bool enable(false); if (_audioProcessingModulePtr->gain_control()->mode() @@ -628,6 +627,19 @@ int VoEBaseImpl::Init(AudioDeviceModule* external_adm) } } #endif + // Set number of channels + _audioDevicePtr->StereoPlayoutIsAvailable(&available); + if (_audioDevicePtr->SetStereoPlayout(available) != 0) + { + _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, + "Init() failed to set mono/stereo playout mode"); + } + _audioDevicePtr->StereoRecordingIsAvailable(&available); + if (_audioDevicePtr->SetStereoRecording(available) != 0) + { + _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, + "Init() failed to set mono/stereo recording mode"); + } return _engineStatistics.SetInitialized(); } diff --git a/src/voice_engine/main/source/voe_codec_impl.cc b/src/voice_engine/main/source/voe_codec_impl.cc index b4f7cdce24..cf0d2d0ff3 100644 --- a/src/voice_engine/main/source/voe_codec_impl.cc +++ b/src/voice_engine/main/source/voe_codec_impl.cc @@ -135,7 +135,7 @@ int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec) "SetSendCodec() invalid codec name"); return -1; } - if ((copyCodec.channels != 1) && (copyCodec.channels != 2)) + if (copyCodec.channels != 1) { _engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError, "SetSendCodec() invalid number of " @@ -167,36 +167,6 @@ int VoECodecImpl::SetSendCodec(int channel, const CodecInst& codec) return -1; } - // Need to check if we should change APM settings for mono/stereo. - // We'll check all channels (sending or not), so we don't have to - // check this again when starting/stopping sending. - - voe::ScopedChannel sc2(_channelManager); - void* iterator(NULL); - channelPtr = sc2.GetFirstChannel(iterator); - int maxNumChannels = 1; - while (channelPtr != NULL) - { - CodecInst tmpCdc; - channelPtr->GetSendCodec(tmpCdc); - if (tmpCdc.channels > maxNumChannels) - maxNumChannels = tmpCdc.channels; - - channelPtr = sc2.GetNextChannel(iterator); - } - - bool available(false); - _audioDevicePtr->StereoRecordingIsAvailable(&available); - int recordingChannels = available ? 2 : 1; - - if (_audioProcessingModulePtr->set_num_channels(recordingChannels, maxNumChannels) != 0) - { - _engineStatistics.SetLastError(VE_SOUNDCARD_ERROR, kTraceError, - "Init() failed to set APM channels for the send audio stream"); - return -1; - } - - return 0; }