diff --git a/src/modules/audio_device/main/interface/audio_device.h b/src/modules/audio_device/main/interface/audio_device.h index 1a2b81761f..b534b4f317 100644 --- a/src/modules/audio_device/main/interface/audio_device.h +++ b/src/modules/audio_device/main/interface/audio_device.h @@ -8,209 +8,186 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_H -#define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_H +#ifndef MODULES_AUDIO_DEVICE_MAIN_INTERFACE_AUDIO_DEVICE_H_ +#define MODULES_AUDIO_DEVICE_MAIN_INTERFACE_AUDIO_DEVICE_H_ #include "module.h" #include "audio_device_defines.h" namespace webrtc { -class AudioDeviceModule : public Module -{ -public: - enum ErrorCode - { - kAdmErrNone = 0, - kAdmErrArgument = 1 - }; +class AudioDeviceModule : public RefCountedModule { + public: + enum ErrorCode { + kAdmErrNone = 0, + kAdmErrArgument = 1 + }; - enum AudioLayer - { - kPlatformDefaultAudio = 0, - kWindowsWaveAudio = 1, - kWindowsCoreAudio = 2, - kLinuxAlsaAudio = 3, - kLinuxPulseAudio = 4, - kDummyAudio = 5 - }; + enum AudioLayer { + kPlatformDefaultAudio = 0, + kWindowsWaveAudio = 1, + kWindowsCoreAudio = 2, + kLinuxAlsaAudio = 3, + kLinuxPulseAudio = 4, + kDummyAudio = 5 + }; - enum WindowsDeviceType - { - kDefaultCommunicationDevice = -1, - kDefaultDevice = -2 - }; + enum WindowsDeviceType { + kDefaultCommunicationDevice = -1, + kDefaultDevice = -2 + }; - enum BufferType - { - kFixedBufferSize = 0, - kAdaptiveBufferSize = 1 - }; + enum BufferType { + kFixedBufferSize = 0, + kAdaptiveBufferSize = 1 + }; - enum ChannelType - { - kChannelLeft = 0, - kChannelRight = 1, - kChannelBoth = 2 - }; + enum ChannelType { + kChannelLeft = 0, + kChannelRight = 1, + kChannelBoth = 2 + }; -public: - // Factory methods (resource allocation/deallocation) - static AudioDeviceModule* Create( - const int32_t id, - const AudioLayer audioLayer = kPlatformDefaultAudio); - static void Destroy(AudioDeviceModule* module); + public: + // Retrieve the currently utilized audio layer + virtual int32_t ActiveAudioLayer(AudioLayer* audioLayer) const = 0; - // Retrieve the currently utilized audio layer - virtual int32_t ActiveAudioLayer(AudioLayer* audioLayer) const = 0; + // Error handling + virtual ErrorCode LastError() const = 0; + virtual int32_t RegisterEventObserver(AudioDeviceObserver* eventCallback) = 0; - // Module methods - static int32_t GetVersion(char* version, - uint32_t& remainingBufferInBytes, - uint32_t& position); - virtual int32_t ChangeUniqueId(const int32_t id) = 0; + // Full-duplex transportation of PCM audio + virtual int32_t RegisterAudioCallback(AudioTransport* audioCallback) = 0; - // Error handling - virtual ErrorCode LastError() const = 0; - virtual int32_t RegisterEventObserver( - AudioDeviceObserver* eventCallback) = 0; + // Main initialization and termination + virtual int32_t Init() = 0; + virtual int32_t Terminate() = 0; + virtual bool Initialized() const = 0; - // Full-duplex transportation of PCM audio - virtual int32_t RegisterAudioCallback(AudioTransport* audioCallback) = 0; - - // Main initialization and termination - virtual int32_t Init() = 0; - virtual int32_t Terminate() = 0; - virtual bool Initialized() const = 0; - - // Device enumeration - virtual int16_t PlayoutDevices() = 0; - virtual int16_t RecordingDevices() = 0; - virtual int32_t PlayoutDeviceName(uint16_t index, + // Device enumeration + virtual int16_t PlayoutDevices() = 0; + virtual int16_t RecordingDevices() = 0; + virtual int32_t PlayoutDeviceName(uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) = 0; + virtual int32_t RecordingDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) = 0; - virtual int32_t RecordingDeviceName(uint16_t index, - char name[kAdmMaxDeviceNameSize], - char guid[kAdmMaxGuidSize]) = 0; - // Device selection - virtual int32_t SetPlayoutDevice(uint16_t index) = 0; - virtual int32_t SetPlayoutDevice(WindowsDeviceType device) = 0; - virtual int32_t SetRecordingDevice(uint16_t index) = 0; - virtual int32_t SetRecordingDevice(WindowsDeviceType device) = 0; + // Device selection + virtual int32_t SetPlayoutDevice(uint16_t index) = 0; + virtual int32_t SetPlayoutDevice(WindowsDeviceType device) = 0; + virtual int32_t SetRecordingDevice(uint16_t index) = 0; + virtual int32_t SetRecordingDevice(WindowsDeviceType device) = 0; - // Audio transport initialization - virtual int32_t PlayoutIsAvailable(bool* available) = 0; - virtual int32_t InitPlayout() = 0; - virtual bool PlayoutIsInitialized() const = 0; - virtual int32_t RecordingIsAvailable(bool* available) = 0; - virtual int32_t InitRecording() = 0; - virtual bool RecordingIsInitialized() const = 0; + // Audio transport initialization + virtual int32_t PlayoutIsAvailable(bool* available) = 0; + virtual int32_t InitPlayout() = 0; + virtual bool PlayoutIsInitialized() const = 0; + virtual int32_t RecordingIsAvailable(bool* available) = 0; + virtual int32_t InitRecording() = 0; + virtual bool RecordingIsInitialized() const = 0; - // Audio transport control - virtual int32_t StartPlayout() = 0; - virtual int32_t StopPlayout() = 0; - virtual bool Playing() const = 0; - virtual int32_t StartRecording() = 0; - virtual int32_t StopRecording() = 0; - virtual bool Recording() const = 0; + // Audio transport control + virtual int32_t StartPlayout() = 0; + virtual int32_t StopPlayout() = 0; + virtual bool Playing() const = 0; + virtual int32_t StartRecording() = 0; + virtual int32_t StopRecording() = 0; + virtual bool Recording() const = 0; - // Microphone Automatic Gain Control (AGC) - virtual int32_t SetAGC(bool enable) = 0; - virtual bool AGC() const = 0; + // Microphone Automatic Gain Control (AGC) + virtual int32_t SetAGC(bool enable) = 0; + virtual bool AGC() const = 0; - // Volume control based on the Windows Wave API (Windows only) - virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, - uint16_t volumeRight) = 0; - virtual int32_t WaveOutVolume(uint16_t* volumeLeft, - uint16_t* volumeRight) const = 0; + // Volume control based on the Windows Wave API (Windows only) + virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, + uint16_t volumeRight) = 0; + virtual int32_t WaveOutVolume(uint16_t* volumeLeft, + uint16_t* volumeRight) const = 0; - // Audio mixer initialization - virtual int32_t SpeakerIsAvailable(bool* available) = 0; - virtual int32_t InitSpeaker() = 0; - virtual bool SpeakerIsInitialized() const = 0; - virtual int32_t MicrophoneIsAvailable(bool* available) = 0; - virtual int32_t InitMicrophone() = 0; - virtual bool MicrophoneIsInitialized() const = 0; + // Audio mixer initialization + virtual int32_t SpeakerIsAvailable(bool* available) = 0; + virtual int32_t InitSpeaker() = 0; + virtual bool SpeakerIsInitialized() const = 0; + virtual int32_t MicrophoneIsAvailable(bool* available) = 0; + virtual int32_t InitMicrophone() = 0; + virtual bool MicrophoneIsInitialized() const = 0; - // Speaker volume controls - virtual int32_t SpeakerVolumeIsAvailable(bool* available) = 0; - virtual int32_t SetSpeakerVolume(uint32_t volume) = 0; - virtual int32_t SpeakerVolume(uint32_t* volume) const = 0; - virtual int32_t MaxSpeakerVolume(uint32_t* maxVolume) const = 0; - virtual int32_t MinSpeakerVolume(uint32_t* minVolume) const = 0; - virtual int32_t SpeakerVolumeStepSize(uint16_t* stepSize) const = 0; + // Speaker volume controls + virtual int32_t SpeakerVolumeIsAvailable(bool* available) = 0; + virtual int32_t SetSpeakerVolume(uint32_t volume) = 0; + virtual int32_t SpeakerVolume(uint32_t* volume) const = 0; + virtual int32_t MaxSpeakerVolume(uint32_t* maxVolume) const = 0; + virtual int32_t MinSpeakerVolume(uint32_t* minVolume) const = 0; + virtual int32_t SpeakerVolumeStepSize(uint16_t* stepSize) const = 0; - // Microphone volume controls - virtual int32_t MicrophoneVolumeIsAvailable(bool* available) = 0; - virtual int32_t SetMicrophoneVolume(uint32_t volume) = 0; - virtual int32_t MicrophoneVolume(uint32_t* volume) const = 0; - virtual int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const = 0; - virtual int32_t MinMicrophoneVolume(uint32_t* minVolume) const = 0; - virtual int32_t MicrophoneVolumeStepSize(uint16_t* stepSize) const = 0; + // Microphone volume controls + virtual int32_t MicrophoneVolumeIsAvailable(bool* available) = 0; + virtual int32_t SetMicrophoneVolume(uint32_t volume) = 0; + virtual int32_t MicrophoneVolume(uint32_t* volume) const = 0; + virtual int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const = 0; + virtual int32_t MinMicrophoneVolume(uint32_t* minVolume) const = 0; + virtual int32_t MicrophoneVolumeStepSize(uint16_t* stepSize) const = 0; - // Speaker mute control - virtual int32_t SpeakerMuteIsAvailable(bool* available) = 0; - virtual int32_t SetSpeakerMute(bool enable) = 0; - virtual int32_t SpeakerMute(bool* enabled) const = 0; + // Speaker mute control + virtual int32_t SpeakerMuteIsAvailable(bool* available) = 0; + virtual int32_t SetSpeakerMute(bool enable) = 0; + virtual int32_t SpeakerMute(bool* enabled) const = 0; - // Microphone mute control - virtual int32_t MicrophoneMuteIsAvailable(bool* available) = 0; - virtual int32_t SetMicrophoneMute(bool enable) = 0; - virtual int32_t MicrophoneMute(bool* enabled) const = 0; + // Microphone mute control + virtual int32_t MicrophoneMuteIsAvailable(bool* available) = 0; + virtual int32_t SetMicrophoneMute(bool enable) = 0; + virtual int32_t MicrophoneMute(bool* enabled) const = 0; - // Microphone boost control - virtual int32_t MicrophoneBoostIsAvailable(bool* available) = 0; - virtual int32_t SetMicrophoneBoost(bool enable) = 0; - virtual int32_t MicrophoneBoost(bool* enabled) const = 0; + // Microphone boost control + virtual int32_t MicrophoneBoostIsAvailable(bool* available) = 0; + virtual int32_t SetMicrophoneBoost(bool enable) = 0; + virtual int32_t MicrophoneBoost(bool* enabled) const = 0; - // Stereo support - virtual int32_t StereoPlayoutIsAvailable(bool* available) const = 0; - virtual int32_t SetStereoPlayout(bool enable) = 0; - virtual int32_t StereoPlayout(bool* enabled) const = 0; - virtual int32_t StereoRecordingIsAvailable(bool* available) const = 0; - virtual int32_t SetStereoRecording(bool enable) = 0; - virtual int32_t StereoRecording(bool* enabled) const = 0; - virtual int32_t SetRecordingChannel(const ChannelType channel) = 0; - virtual int32_t RecordingChannel(ChannelType* channel) const = 0; + // Stereo support + virtual int32_t StereoPlayoutIsAvailable(bool* available) const = 0; + virtual int32_t SetStereoPlayout(bool enable) = 0; + virtual int32_t StereoPlayout(bool* enabled) const = 0; + virtual int32_t StereoRecordingIsAvailable(bool* available) const = 0; + virtual int32_t SetStereoRecording(bool enable) = 0; + virtual int32_t StereoRecording(bool* enabled) const = 0; + virtual int32_t SetRecordingChannel(const ChannelType channel) = 0; + virtual int32_t RecordingChannel(ChannelType* channel) const = 0; - // Delay information and control - virtual int32_t SetPlayoutBuffer(const BufferType type, - uint16_t sizeMS = 0) = 0; - virtual int32_t PlayoutBuffer(BufferType* type, - uint16_t* sizeMS) const = 0; - virtual int32_t PlayoutDelay(uint16_t* delayMS) const = 0; - virtual int32_t RecordingDelay(uint16_t* delayMS) const = 0; + // Delay information and control + virtual int32_t SetPlayoutBuffer(const BufferType type, + uint16_t sizeMS = 0) = 0; + virtual int32_t PlayoutBuffer(BufferType* type, uint16_t* sizeMS) const = 0; + virtual int32_t PlayoutDelay(uint16_t* delayMS) const = 0; + virtual int32_t RecordingDelay(uint16_t* delayMS) const = 0; - // CPU load - virtual int32_t CPULoad(uint16_t* load) const = 0; + // CPU load + virtual int32_t CPULoad(uint16_t* load) const = 0; - // Recording of raw PCM data - virtual int32_t StartRawOutputFileRecording( - const char pcmFileNameUTF8[kAdmMaxFileNameSize]) = 0; - virtual int32_t StopRawOutputFileRecording() = 0; - virtual int32_t StartRawInputFileRecording( - const char pcmFileNameUTF8[kAdmMaxFileNameSize]) = 0; - virtual int32_t StopRawInputFileRecording() = 0; + // Recording of raw PCM data + virtual int32_t StartRawOutputFileRecording( + const char pcmFileNameUTF8[kAdmMaxFileNameSize]) = 0; + virtual int32_t StopRawOutputFileRecording() = 0; + virtual int32_t StartRawInputFileRecording( + const char pcmFileNameUTF8[kAdmMaxFileNameSize]) = 0; + virtual int32_t StopRawInputFileRecording() = 0; - // Native sample rate controls (samples/sec) - virtual int32_t SetRecordingSampleRate(const uint32_t samplesPerSec) = 0; - virtual int32_t RecordingSampleRate(uint32_t* samplesPerSec) const = 0; - virtual int32_t SetPlayoutSampleRate(const uint32_t samplesPerSec) = 0; - virtual int32_t PlayoutSampleRate(uint32_t* samplesPerSec) const = 0; + // Native sample rate controls (samples/sec) + virtual int32_t SetRecordingSampleRate(const uint32_t samplesPerSec) = 0; + virtual int32_t RecordingSampleRate(uint32_t* samplesPerSec) const = 0; + virtual int32_t SetPlayoutSampleRate(const uint32_t samplesPerSec) = 0; + virtual int32_t PlayoutSampleRate(uint32_t* samplesPerSec) const = 0; - // Mobile device specific functions - virtual int32_t ResetAudioDevice() = 0; - virtual int32_t SetLoudspeakerStatus(bool enable) = 0; - virtual int32_t GetLoudspeakerStatus(bool* enabled) const = 0; + // Mobile device specific functions + virtual int32_t ResetAudioDevice() = 0; + virtual int32_t SetLoudspeakerStatus(bool enable) = 0; + virtual int32_t GetLoudspeakerStatus(bool* enabled) const = 0; - // Android specific function - static int32_t SetAndroidObjects(void* javaVM, void* env, void* context); - -protected: - virtual ~AudioDeviceModule() {}; + protected: + virtual ~AudioDeviceModule() {}; }; } // namespace webrtc -#endif // WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_H +#endif // MODULES_AUDIO_DEVICE_MAIN_INTERFACE_AUDIO_DEVICE_H_ diff --git a/src/modules/audio_device/main/source/audio_device_impl.cc b/src/modules/audio_device/main/source/audio_device_impl.cc index f4d865c877..8f5a58d035 100644 --- a/src/modules/audio_device/main/source/audio_device_impl.cc +++ b/src/modules/audio_device/main/source/audio_device_impl.cc @@ -10,6 +10,7 @@ #include "audio_device_impl.h" #include "audio_device_config.h" +#include "system_wrappers/interface/ref_count.h" #include #include @@ -73,31 +74,32 @@ namespace webrtc // AudioDeviceModule::Create() // ---------------------------------------------------------------------------- -AudioDeviceModule* AudioDeviceModule::Create(const WebRtc_Word32 id, - const AudioLayer audioLayer) +AudioDeviceModule* AudioDeviceModuleImpl::Create(const WebRtc_Word32 id, + const AudioLayer audioLayer) { - WEBRTC_TRACE(kTraceModuleCall, kTraceAudioDevice, id, "Create(audioLayer=%d)", (int)audioLayer); + WEBRTC_TRACE(kTraceModuleCall, kTraceAudioDevice, id, + "Create(audioLayer=%d)", (int)audioLayer); - // Create the generic (platform independent) implementation - // - AudioDeviceModuleImpl* audioDevice = static_cast (new AudioDeviceModuleImpl(id, audioLayer)); + // Create the generic ref counted (platform independent) implementation. + RefCountImpl* audioDevice = + new RefCountImpl(id, audioLayer); + // Ensure that the current platform is supported. if (audioDevice->CheckPlatform() == -1) { delete audioDevice; return NULL; } - // Create the platform-dependent implementation - // + // Create the platform-dependent implementation. if (audioDevice->CreatePlatformSpecificObjects() == -1) { delete audioDevice; return NULL; } - // Ensure that the generic audio buffer can communicate with the platform-specific parts - // + // Ensure that the generic audio buffer can communicate with the + // platform-specific parts. if (audioDevice->AttachAudioBuffer() == -1) { delete audioDevice; @@ -107,58 +109,6 @@ AudioDeviceModule* AudioDeviceModule::Create(const WebRtc_Word32 id, return audioDevice; } -// ---------------------------------------------------------------------------- -// AudioDeviceModule::Destroy() -// ---------------------------------------------------------------------------- - -void AudioDeviceModule::Destroy(AudioDeviceModule* module) -{ - if (module) - { - WEBRTC_TRACE(kTraceModuleCall, kTraceAudioDevice, static_cast(module)->Id(), "Destroy()"); - delete static_cast(module); - } -} - -// ---------------------------------------------------------------------------- -// AudioDeviceModule::GetVersion() -// ---------------------------------------------------------------------------- - -WebRtc_Word32 AudioDeviceModule::GetVersion(WebRtc_Word8* version, WebRtc_UWord32& remainingBufferInBytes, WebRtc_UWord32& position) -{ - if (version == NULL) - { - WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1, "invalid buffer pointer in argument"); - return -1; - } - WebRtc_Word8 ourVersion[] = "AudioDevice 1.1.0"; - WebRtc_UWord32 ourLength = (WebRtc_UWord32)strlen(ourVersion); - if (remainingBufferInBytes < (ourLength + 1)) - { - WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, "version string requires %d bytes", (ourLength + 1)); - return -1; - } - memcpy(&version[position], ourVersion, ourLength); - version[position + ourLength] = '\0'; // null terminaion - remainingBufferInBytes -= (ourLength + 1); - position += (ourLength + 1); - WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1, "version: %s", version); - return 0; -} - -// ---------------------------------------------------------------------------- -// SetAndroidObjects -// ---------------------------------------------------------------------------- - -WebRtc_Word32 AudioDeviceModule::SetAndroidObjects(void* javaVM, void* env, void* context) -{ -#if defined(WEBRTC_ANDROID) && !defined(WEBRTC_ANDROID_OPENSLES) - return SetAndroidAudioDeviceObjects(javaVM, env, context); -#else - return -1; -#endif -} - // ============================================================================ // Construction & Destruction // ============================================================================ @@ -473,20 +423,17 @@ WebRtc_Word32 AudioDeviceModuleImpl::AttachAudioBuffer() AudioDeviceModuleImpl::~AudioDeviceModuleImpl() { WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", __FUNCTION__); + + if (_ptrAudioDevice) { - CriticalSectionScoped lock(_critSect); + delete _ptrAudioDevice; + _ptrAudioDevice = NULL; + } - if (_ptrAudioDevice) - { - delete _ptrAudioDevice; - _ptrAudioDevice = NULL; - } - - if (_ptrAudioDeviceUtility) - { - delete _ptrAudioDeviceUtility; - _ptrAudioDeviceUtility = NULL; - } + if (_ptrAudioDeviceUtility) + { + delete _ptrAudioDeviceUtility; + _ptrAudioDeviceUtility = NULL; } delete &_critSect; @@ -515,8 +462,24 @@ WebRtc_Word32 AudioDeviceModuleImpl::ChangeUniqueId(const WebRtc_Word32 id) WebRtc_Word32 AudioDeviceModuleImpl::Version(WebRtc_Word8* version, WebRtc_UWord32& remainingBufferInBytes, WebRtc_UWord32& position) const { - WEBRTC_TRACE(kTraceModuleCall, kTraceAudioDevice, _id, "Version(remainingBufferInBytes=%d)", remainingBufferInBytes); - return GetVersion(version, remainingBufferInBytes, position); + if (version == NULL) + { + WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1, "invalid buffer pointer in argument"); + return -1; + } + WebRtc_Word8 ourVersion[] = "AudioDevice 1.1.0"; + WebRtc_UWord32 ourLength = (WebRtc_UWord32)strlen(ourVersion); + if (remainingBufferInBytes < (ourLength + 1)) + { + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, "version string requires %d bytes", (ourLength + 1)); + return -1; + } + memcpy(&version[position], ourVersion, ourLength); + version[position + ourLength] = '\0'; // null terminaion + remainingBufferInBytes -= (ourLength + 1); + position += (ourLength + 1); + WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1, "version: %s", version); + return 0; } // ---------------------------------------------------------------------------- diff --git a/src/modules/audio_device/main/source/audio_device_impl.h b/src/modules/audio_device/main/source/audio_device_impl.h index 9c8495211b..90cadf0882 100644 --- a/src/modules/audio_device/main/source/audio_device_impl.h +++ b/src/modules/audio_device/main/source/audio_device_impl.h @@ -40,7 +40,7 @@ public: AudioDeviceModuleImpl(const WebRtc_Word32 id, const AudioLayer audioLayer); virtual ~AudioDeviceModuleImpl(); -public: // Module +public: // RefCountedModule virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); virtual WebRtc_Word32 Version( WebRtc_Word8 *version, WebRtc_UWord32& remainingBufferInBytes, @@ -53,7 +53,6 @@ public: static AudioDeviceModule* Create( const WebRtc_Word32 id, const AudioLayer audioLayer = kPlatformDefaultAudio); - static void Destroy(AudioDeviceModule* module); // Retrieve the currently utilized audio layer virtual WebRtc_Word32 ActiveAudioLayer(AudioLayer* audioLayer) const; diff --git a/src/voice_engine.gyp b/src/voice_engine.gyp index 868fe9ecf9..86e6df4b04 100644 --- a/src/voice_engine.gyp +++ b/src/voice_engine.gyp @@ -46,6 +46,8 @@ ], 'include_dirs': [ 'voice_engine/main/test/auto_test', + 'modules/interface', + 'modules/audio_device/main/interface', ], 'sources': [ 'voice_engine/main/test/auto_test/voe_cpu_test.cc', diff --git a/src/voice_engine/main/interface/voe_base.h b/src/voice_engine/main/interface/voe_base.h index 546f925700..be6849cc35 100644 --- a/src/voice_engine/main/interface/voe_base.h +++ b/src/voice_engine/main/interface/voe_base.h @@ -113,16 +113,12 @@ public: // and warning notifications. virtual int DeRegisterVoiceEngineObserver() = 0; - // Installs and enables a user-defined external audio device module - // which implements all the audio layer functionality. - virtual int RegisterAudioDeviceModule(AudioDeviceModule& adm) = 0; - - // Removes and disables the external audio device module. - virtual int DeRegisterAudioDeviceModule() = 0; - // Initiates all common parts of the VoiceEngine; e.g. all // encoders/decoders, the sound card and core receiving components. - virtual int Init() = 0; + // This method also makes it possible to install a user-defined + // external Audio Device Module (ADM) which implements all the audio + // layer functionality in a separate (reference counted) module. + virtual int Init(AudioDeviceModule* external_adm = NULL) = 0; // Terminates all VoiceEngine functions and releses allocated resources. virtual int Terminate() = 0; diff --git a/src/voice_engine/main/source/shared_data.cc b/src/voice_engine/main/source/shared_data.cc index ddb257e47b..2362da5bb6 100644 --- a/src/voice_engine/main/source/shared_data.cc +++ b/src/voice_engine/main/source/shared_data.cc @@ -28,7 +28,6 @@ SharedData::SharedData() : _apiCritPtr(CriticalSectionWrapper::CreateCriticalSection()), _channelManager(_gInstanceCounter), _engineStatistics(_gInstanceCounter), - _usingExternalAudioDevice(false), _audioDevicePtr(NULL), _audioProcessingModulePtr(NULL), _moduleProcessThreadPtr(ProcessThread::CreateProcessThread()), @@ -54,9 +53,8 @@ SharedData::~SharedData() { OutputMixer::Destroy(_outputMixerPtr); TransmitMixer::Destroy(_transmitMixerPtr); - if (!_usingExternalAudioDevice) - { - AudioDeviceModule::Destroy(_audioDevicePtr); + if (_audioDevicePtr) { + _audioDevicePtr->Release(); } AudioProcessing::Destroy(_audioProcessingModulePtr); delete _apiCritPtr; diff --git a/src/voice_engine/main/source/shared_data.h b/src/voice_engine/main/source/shared_data.h index 27427d0ba6..40b95e4560 100644 --- a/src/voice_engine/main/source/shared_data.h +++ b/src/voice_engine/main/source/shared_data.h @@ -39,7 +39,6 @@ protected: CriticalSectionWrapper* _apiCritPtr; ChannelManager _channelManager; Statistics _engineStatistics; - bool _usingExternalAudioDevice; AudioDeviceModule* _audioDevicePtr; OutputMixer* _outputMixerPtr; TransmitMixer* _transmitMixerPtr; diff --git a/src/voice_engine/main/source/voe_base_impl.cc b/src/voice_engine/main/source/voe_base_impl.cc index a25a3e4cae..9e0ab52ccf 100644 --- a/src/voice_engine/main/source/voe_base_impl.cc +++ b/src/voice_engine/main/source/voe_base_impl.cc @@ -10,20 +10,19 @@ #include "voe_base_impl.h" -#include "voice_engine_impl.h" -#include "voe_errors.h" -#include "trace.h" +#include "audio_coding_module.h" +#include "audio_device_impl.h" +#include "audio_processing.h" +#include "channel.h" #include "critical_section_wrapper.h" #include "file_wrapper.h" -#include "audio_processing.h" - -#include "channel.h" #include "output_mixer.h" -#include "transmit_mixer.h" - -#include "audio_coding_module.h" #include "signal_processing_library.h" +#include "trace.h" +#include "transmit_mixer.h" #include "utility.h" +#include "voe_errors.h" +#include "voice_engine_impl.h" #if (defined(_WIN32) && defined(_DLL) && (_MSC_VER == 1400)) // Fix for VS 2005 MD/MDd link problem @@ -356,48 +355,10 @@ int VoEBaseImpl::DeRegisterVoiceEngineObserver() return 0; } -int VoEBaseImpl::RegisterAudioDeviceModule(AudioDeviceModule& adm) +int VoEBaseImpl::Init(AudioDeviceModule* external_adm) { - WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), - "RegisterAudioDeviceModule(adm=%p)", &adm); - CriticalSectionScoped cs(*_apiCritPtr); - - if (_engineStatistics.Initialized()) - { - _engineStatistics.SetLastError(VE_INVALID_OPERATION, kTraceError, - "Cannot register ADM when initialized"); - return -1; - } - - _audioDevicePtr = &adm; - _usingExternalAudioDevice = true; - - return 0; -} - -int VoEBaseImpl::DeRegisterAudioDeviceModule() -{ - WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), - "DeRegisterAudioDeviceModule()"); - CriticalSectionScoped cs(*_apiCritPtr); - - if (_engineStatistics.Initialized()) - { - _engineStatistics.SetLastError(VE_INVALID_OPERATION, kTraceError, - "Cannot de-register ADM when " - "initialized"); - return -1; - } - - _audioDevicePtr = NULL; - _usingExternalAudioDevice = false; - - return 0; -} - -int VoEBaseImpl::Init() -{ - WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), "Init()"); + WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), + "Init(external_adm=0x%p)", external_adm); CriticalSectionScoped cs(*_apiCritPtr); if (_engineStatistics.Initialized()) @@ -558,15 +519,14 @@ int VoEBaseImpl::Init() } } - // Create the Audio Device Module (ADM) if it does not already exist - - if (_audioDevicePtr == NULL) + // Create and internal ADM if the user has not added and external + // ADM implementation as input to Init(). + if (external_adm == NULL) { - // Create the ADM - // _audioDeviceLayer is set by - // VoEHardwareImpl::SetAudioDeviceLayer - _audioDevicePtr = AudioDeviceModule::Create(VoEId(_instanceId, -1), - _audioDeviceLayer); + // Create the internal ADM implementation. + _audioDevicePtr = AudioDeviceModuleImpl::Create( + VoEId(_instanceId, -1), _audioDeviceLayer); + if (_audioDevicePtr == NULL) { _engineStatistics.SetLastError(VE_NO_MEMORY, kTraceCritical, @@ -574,6 +534,16 @@ int VoEBaseImpl::Init() return -1; } } + else + { + // Use the already existing external ADM implementation. + _audioDevicePtr = external_adm; + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), + "An external ADM implementation will be used in VoiceEngine"); + } + + // Increase the reference counter for both external and internal usage. + _audioDevicePtr->AddRef(); // Register the ADM to the process thread, which will drive the error // callback mechanism @@ -1485,13 +1455,11 @@ WebRtc_Word32 VoEBaseImpl::AddADMVersion(char* str) const AudioDeviceModule* admPtr(_audioDevicePtr); if (_audioDevicePtr == NULL) { - admPtr = AudioDeviceModule::Create(-1); + admPtr = AudioDeviceModuleImpl::Create(-1); } + admPtr->AddRef(); int len = AddModuleVersion(admPtr, str); - if (_audioDevicePtr == NULL) - { - AudioDeviceModule::Destroy(admPtr); - } + admPtr->Release(); return len; } @@ -1872,11 +1840,9 @@ WebRtc_Word32 VoEBaseImpl::TerminateInternal() "TerminateInternal() failed to " "terminate the ADM"); } - if (!_usingExternalAudioDevice) - { - AudioDeviceModule::Destroy(_audioDevicePtr); - _audioDevicePtr = NULL; - } + + _audioDevicePtr->Release(); + _audioDevicePtr = NULL; } // AP module diff --git a/src/voice_engine/main/source/voe_base_impl.h b/src/voice_engine/main/source/voe_base_impl.h index a7c9fafa50..cbc2beb47a 100644 --- a/src/voice_engine/main/source/voe_base_impl.h +++ b/src/voice_engine/main/source/voe_base_impl.h @@ -34,11 +34,7 @@ public: virtual int DeRegisterVoiceEngineObserver(); - virtual int RegisterAudioDeviceModule(AudioDeviceModule& adm); - - virtual int DeRegisterAudioDeviceModule(); - - virtual int Init(); + virtual int Init(AudioDeviceModule* external_adm = NULL); virtual int Terminate(); diff --git a/src/voice_engine/main/source/voice_engine_core.gyp b/src/voice_engine/main/source/voice_engine_core.gyp index 89fd02308c..ef7739f8f1 100644 --- a/src/voice_engine/main/source/voice_engine_core.gyp +++ b/src/voice_engine/main/source/voice_engine_core.gyp @@ -30,6 +30,7 @@ 'include_dirs': [ '../../..', '../interface', + '../../../modules/audio_device/main/source', ], 'direct_dependent_settings': { 'include_dirs': [ diff --git a/src/voice_engine/main/source/voice_engine_impl.cc b/src/voice_engine/main/source/voice_engine_impl.cc index 137542bcdf..07af08e33e 100644 --- a/src/voice_engine/main/source/voice_engine_impl.cc +++ b/src/voice_engine/main/source/voice_engine_impl.cc @@ -10,8 +10,13 @@ #include "voice_engine_impl.h" #include "trace.h" + #ifdef WEBRTC_ANDROID -#include "audio_device.h" // SetAndroidObjects +extern "C" +{ +extern WebRtc_Word32 SetAndroidAudioDeviceObjects( + void* javaVM, void* env, void* context); +} // extern "C" #endif namespace webrtc @@ -300,8 +305,10 @@ bool VoiceEngine::Delete(VoiceEngine*& voiceEngine, bool ignoreRefCounters) int VoiceEngine::SetAndroidObjects(void* javaVM, void* env, void* context) { -#ifdef WEBRTC_ANDROID - return AudioDeviceModule::SetAndroidObjects(javaVM, env, context); +#if defined(WEBRTC_ANDROID) && !defined(WEBRTC_ANDROID_OPENSLES) + // modules/audio_device/main/source/android/audio_device_android_jni.cc + // contains the actual implementation. + return SetAndroidAudioDeviceObjects(javaVM, env, context); #else return -1; #endif diff --git a/src/voice_engine/main/test/auto_test/voe_extended_test.cc b/src/voice_engine/main/test/auto_test/voe_extended_test.cc index 07996b4407..a06afca377 100644 --- a/src/voice_engine/main/test/auto_test/voe_extended_test.cc +++ b/src/voice_engine/main/test/auto_test/voe_extended_test.cc @@ -16,6 +16,7 @@ #include "thread_wrapper.h" #include "voe_extended_test.h" #include "../../source/voice_engine_defines.h" // defines build macros +#include "system_wrappers/interface/ref_count.h" #if defined(_WIN32) #include @@ -60,6 +61,46 @@ extern int GetResource(char* resource, char* dest, int destLen); extern char* GetResource(char* resource); extern const char* GetResource(const char* resource); +// ---------------------------------------------------------------------------- +// External AudioDeviceModule implementation +// ---------------------------------------------------------------------------- + +// static +AudioDeviceModuleImpl* AudioDeviceModuleImpl::Create() { + AudioDeviceModuleImpl* xADM = new AudioDeviceModuleImpl(); + if (xADM) + xADM->AddRef(); + return xADM; +} + +// static +bool AudioDeviceModuleImpl::Destroy(AudioDeviceModuleImpl* adm) { + if (!adm) + return false; + int32_t count = adm->Release(); + if (count != 0) { + return false; + } else { + delete adm; + return true; + } +} + +AudioDeviceModuleImpl::AudioDeviceModuleImpl() + : _ref_count(0) {} + +AudioDeviceModuleImpl::~AudioDeviceModuleImpl() {} + +int32_t AudioDeviceModuleImpl::AddRef() { + return ++_ref_count; +} + +int32_t AudioDeviceModuleImpl::Release() { + // Avoid self destruction in this mock implementation. + // Ensures that we can always check the reference counter while alive. + return --_ref_count; +} + // ---------------------------------------------------------------------------- // External transport (Transport) implementations: // ---------------------------------------------------------------------------- @@ -461,6 +502,41 @@ int VoEExtendedTest::TestBase() ANL(); ANL(); + // ------------------------------------------------------------------------ + // >> Init(AudioDeviceModule) + // + // Note that our mock implementation of the ADM also mocks the + // reference counting part. This approach enables us to keep track + // of the internal reference counter without checking return values + // from the ADM and we also avoid the built-in self destruction. + // + // TODO(henrika): this test does not verify that external ADM methods + // are called by the VoiceEngine once registered. We could extend + // the mock implementation and add counters for each ADM API to ensure + // that they are called in the correct sequence and the correct number + // of times. + + TEST_LOG("\nTesting: Init in combination with an external ADM\n"); + + // Create the ADM and call AddRef within the factory method. + AudioDeviceModuleImpl* xADM = AudioDeviceModuleImpl::Create(); + ASSERT_FALSE(xADM == NULL); + ASSERT_TRUE(xADM->ReferenceCounter() == 1); + + // Verify default usage case for external ADM. + TEST_MUSTPASS(base->Init(xADM)); MARK(); + ASSERT_TRUE(xADM->ReferenceCounter() == 2); + TEST_MUSTPASS(base->Terminate()); + ASSERT_TRUE(xADM->ReferenceCounter() == 1); + + // Our reference-count implementation does not self destruct. + // We do it manually here instead by calling Release followed by delete. + ASSERT_TRUE(AudioDeviceModuleImpl::Destroy(xADM)); + ANL(); AOK(); ANL(); + + // >> end of Init(AudioDeviceModule) + // ------------------------------------------------------------------------ + /////////////////////////// // MaxNumOfChannels diff --git a/src/voice_engine/main/test/auto_test/voe_extended_test.h b/src/voice_engine/main/test/auto_test/voe_extended_test.h index 65afd6cfb3..6d378b1667 100644 --- a/src/voice_engine/main/test/auto_test/voe_extended_test.h +++ b/src/voice_engine/main/test/auto_test/voe_extended_test.h @@ -12,11 +12,198 @@ #define WEBRTC_VOICE_ENGINE_VOE_EXTENDED_TEST_H #include "voe_standard_test.h" +#include "audio_device.h" namespace voetest { class VoETestManager; +// ---------------------------------------------------------------------------- +// AudioDeviceModule +// +// Implementation of the ADM to be used as external ADM in VoiceEngine. +// This implementation is only a mock class, i.e., it does not provide +// any real audio support. +// ---------------------------------------------------------------------------- + +class AudioDeviceModuleImpl : public AudioDeviceModule { + public: + // Factory methods + static AudioDeviceModuleImpl* Create(); + static bool Destroy(AudioDeviceModuleImpl* adm); + + // Helper methods which allows us to get some handy information about + // this mock implementation. + int32_t ReferenceCounter() const { return _ref_count; } + + // RefCountedModule implementation (mocks default implementation) + virtual int32_t AddRef(); + virtual int32_t Release(); + + // Module implementation + virtual int32_t Version(char* version, + uint32_t& remaining_buffer_in_bytes, uint32_t& position) const { return 0;} + virtual int32_t ChangeUniqueId(const int32_t id) { return 0; } + virtual int32_t TimeUntilNextProcess() { return -1;} + virtual int32_t Process() { return 0; } + + // AudioDeviceModule implementation + virtual int32_t ActiveAudioLayer(AudioLayer* audioLayer) const { return 0; } + + virtual ErrorCode LastError() const { return static_cast (0); } + virtual int32_t RegisterEventObserver(AudioDeviceObserver* eventCallback) { + return 0; + } + + virtual int32_t RegisterAudioCallback(AudioTransport* audioCallback) { + return 0; + } + + virtual int32_t Init() { return 0; } + virtual int32_t Terminate() { return 0; } + virtual bool Initialized() const { return true; } + + virtual int16_t PlayoutDevices() { return -1; } + virtual int16_t RecordingDevices() { return -1; } + virtual int32_t PlayoutDeviceName(uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) { return -1; } + virtual int32_t RecordingDeviceName(uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) { return -1; } + + virtual int32_t SetPlayoutDevice(uint16_t index) { return 0; } + virtual int32_t SetPlayoutDevice(WindowsDeviceType device) { return 0; } + virtual int32_t SetRecordingDevice(uint16_t index) { return 0; } + virtual int32_t SetRecordingDevice(WindowsDeviceType device) { return 0; } + + virtual int32_t PlayoutIsAvailable(bool* available) { + *available = true; + return 0; + } + virtual int32_t InitPlayout() { return 0; } + virtual bool PlayoutIsInitialized() const { return true; } + virtual int32_t RecordingIsAvailable(bool* available) { + *available = true; + return 0; + } + virtual int32_t InitRecording() { return 0; } + virtual bool RecordingIsInitialized() const { return true; } + + virtual int32_t StartPlayout() { return 0; } + virtual int32_t StopPlayout() { return 0; } + virtual bool Playing() const { return true; } + virtual int32_t StartRecording() { return 0; } + virtual int32_t StopRecording() { return 0; } + virtual bool Recording() const { return true; } + + virtual int32_t SetAGC(bool enable) { return -1; } + virtual bool AGC() const { return false; } + + virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, + uint16_t volumeRight) { return -1; } + virtual int32_t WaveOutVolume(uint16_t* volumeLeft, + uint16_t* volumeRight) const { return -1; } + + virtual int32_t SpeakerIsAvailable(bool* available) { + *available = true; + return 0; + } + virtual int32_t InitSpeaker() { return 0; } + virtual bool SpeakerIsInitialized() const { return true; } + virtual int32_t MicrophoneIsAvailable(bool* available) { + *available = true; + return 0; + } + virtual int32_t InitMicrophone() { return 0; } + virtual bool MicrophoneIsInitialized() const { return true; } + + virtual int32_t SpeakerVolumeIsAvailable(bool* available) { return -1; } + virtual int32_t SetSpeakerVolume(uint32_t volume) { return -1; } + virtual int32_t SpeakerVolume(uint32_t* volume) const { return -1; } + virtual int32_t MaxSpeakerVolume(uint32_t* maxVolume) const { return -1; } + virtual int32_t MinSpeakerVolume(uint32_t* minVolume) const { return -1; } + virtual int32_t SpeakerVolumeStepSize(uint16_t* stepSize) const { + return -1; + } + + virtual int32_t MicrophoneVolumeIsAvailable(bool* available) { return -1; } + virtual int32_t SetMicrophoneVolume(uint32_t volume) { return -1; } + virtual int32_t MicrophoneVolume(uint32_t* volume) const { return -1; } + virtual int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const { return -1; } + virtual int32_t MinMicrophoneVolume(uint32_t* minVolume) const { return -1; } + virtual int32_t MicrophoneVolumeStepSize(uint16_t* stepSize) const { + return -1; + } + + virtual int32_t SpeakerMuteIsAvailable(bool* available) { return -1; } + virtual int32_t SetSpeakerMute(bool enable) { return -1; } + virtual int32_t SpeakerMute(bool* enabled) const { return -1; } + + virtual int32_t MicrophoneMuteIsAvailable(bool* available) { return -1; } + virtual int32_t SetMicrophoneMute(bool enable) { return -1; } + virtual int32_t MicrophoneMute(bool* enabled) const { return -1; } + + virtual int32_t MicrophoneBoostIsAvailable(bool* available) { return -1; } + virtual int32_t SetMicrophoneBoost(bool enable) { return -1; } + virtual int32_t MicrophoneBoost(bool* enabled) const { return -1; } + + virtual int32_t StereoPlayoutIsAvailable(bool* available) const { + return -1; } + virtual int32_t SetStereoPlayout(bool enable) { return -1; } + virtual int32_t StereoPlayout(bool* enabled) const { return -1; } + virtual int32_t StereoRecordingIsAvailable(bool* available) const { + return -1; + } + virtual int32_t SetStereoRecording(bool enable) { return -1; } + virtual int32_t StereoRecording(bool* enabled) const { return -1; } + virtual int32_t SetRecordingChannel(const ChannelType channel) { + return -1; + } + virtual int32_t RecordingChannel(ChannelType* channel) const { return -1; } + + virtual int32_t SetPlayoutBuffer(const BufferType type, + uint16_t sizeMS = 0) { return -1; } + virtual int32_t PlayoutBuffer(BufferType* type, uint16_t* sizeMS) const { + return -1; + } + virtual int32_t PlayoutDelay(uint16_t* delayMS) const { return -1; } + virtual int32_t RecordingDelay(uint16_t* delayMS) const { return -1; } + + virtual int32_t CPULoad(uint16_t* load) const { return -1; } + + virtual int32_t StartRawOutputFileRecording( + const char pcmFileNameUTF8[kAdmMaxFileNameSize]) { return -1; } + virtual int32_t StopRawOutputFileRecording() { return -1; } + virtual int32_t StartRawInputFileRecording( + const char pcmFileNameUTF8[kAdmMaxFileNameSize]) { return -1; } + virtual int32_t StopRawInputFileRecording() { return -1; } + + virtual int32_t SetRecordingSampleRate(const uint32_t samplesPerSec) { + return -1; + } + virtual int32_t RecordingSampleRate(uint32_t* samplesPerSec) const { + return -1; + } + virtual int32_t SetPlayoutSampleRate(const uint32_t samplesPerSec) { + return -1; + } + virtual int32_t PlayoutSampleRate(uint32_t* samplesPerSec) const { + return -1; + } + + virtual int32_t ResetAudioDevice() { return -1; } + virtual int32_t SetLoudspeakerStatus(bool enable) { return -1; } + virtual int32_t GetLoudspeakerStatus(bool* enabled) const { return -1; } + +protected: + AudioDeviceModuleImpl(); + ~AudioDeviceModuleImpl(); + +private: + volatile int32_t _ref_count; +}; + // ---------------------------------------------------------------------------- // Transport // ---------------------------------------------------------------------------- diff --git a/src/voice_engine/main/test/auto_test/voe_test_defines.h b/src/voice_engine/main/test/auto_test/voe_test_defines.h index 1ed6396a3e..0de1b4186f 100644 --- a/src/voice_engine/main/test/auto_test/voe_test_defines.h +++ b/src/voice_engine/main/test/auto_test/voe_test_defines.h @@ -150,6 +150,9 @@ } \ } #else +#define ASSERT_TRUE(expr) TEST_MUSTPASS(!(expr)) +#define ASSERT_FALSE(expr) TEST_MUSTPASS(expr) +#define TEST_MUSTFAIL(expr) TEST_MUSTPASS(!((expr) == -1)) #define TEST_MUSTPASS(expr) \ { \ if ((expr)) \ diff --git a/third_party_mods/libjingle/source/talk/session/phone/webrtcvoiceengine.cc b/third_party_mods/libjingle/source/talk/session/phone/webrtcvoiceengine.cc index f67404aeca..266e767758 100644 --- a/third_party_mods/libjingle/source/talk/session/phone/webrtcvoiceengine.cc +++ b/third_party_mods/libjingle/source/talk/session/phone/webrtcvoiceengine.cc @@ -232,6 +232,12 @@ void WebRtcVoiceEngine::Construct() { if (tracing_->SetTraceCallback(this) == -1) { LOG_RTCERR0(SetTraceCallback); } + // Update reference counters for the external ADM(s). + if (adm_) + adm_->AddRef(); + if (adm_sc_) + adm_sc_->AddRef(); + if (voe_wrapper_->base()->RegisterVoiceEngineObserver(*this) == -1) { LOG_RTCERR0(RegisterVoiceEngineObserver); } @@ -266,12 +272,12 @@ WebRtcVoiceEngine::~WebRtcVoiceEngine() { } if (adm_) { voe_wrapper_.reset(); - webrtc::AudioDeviceModule::Destroy(adm_); + adm_->Release(); adm_ = NULL; } if (adm_sc_) { voe_wrapper_sc_.reset(); - webrtc::AudioDeviceModule::Destroy(adm_sc_); + adm_sc_->Release(); adm_sc_ = NULL; } @@ -297,21 +303,9 @@ bool WebRtcVoiceEngine::InitInternal() { static_cast(talk_base::LS_INFO)); ApplyLogging(); - if (adm_) { - if (voe_wrapper_->base()->RegisterAudioDeviceModule(*adm_) == -1) { - LOG_RTCERR0_EX(Init, voe_wrapper_->error()); - return false; - } - } - if (adm_sc_) { - if (voe_wrapper_sc_->base()->RegisterAudioDeviceModule(*adm_sc_) == -1) { - LOG_RTCERR0_EX(Init, voe_wrapper_sc_->error()); - return false; - } - } - - // Init WebRtc VoiceEngine, enabling AEC logging if specified in SetLogging. - if (voe_wrapper_->base()->Init() == -1) { + // Init WebRtc VoiceEngine, enabling AEC logging if specified in SetLogging, + // and install the externally provided (and implemented) ADM. + if (voe_wrapper_->base()->Init(adm_) == -1) { LOG_RTCERR0_EX(Init, voe_wrapper_->error()); return false; } @@ -372,7 +366,8 @@ bool WebRtcVoiceEngine::InitInternal() { #endif // Initialize the VoiceEngine instance that we'll use to play out sound clips. - if (voe_wrapper_sc_->base()->Init() == -1) { + // Also, install the externally provided (and implemented) ADM. + if (voe_wrapper_sc_->base()->Init(adm_sc_) == -1) { LOG_RTCERR0_EX(Init, voe_wrapper_sc_->error()); return false; } @@ -410,6 +405,7 @@ void WebRtcVoiceEngine::Terminate() { voe_wrapper_sc_->base()->Terminate(); voe_wrapper_->base()->Terminate(); + desired_local_monitor_enable_ = false; }