From 3fef8b27db8a86c16cabb26341b83f73462afb5c Mon Sep 17 00:00:00 2001 From: Peter Hanspers Date: Tue, 21 Jan 2025 14:54:51 +0100 Subject: [PATCH] Adding an error callback to AudioDeviceModuleIOS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds an optional callback closure and an enum representing the error. Bug: webrtc:390314937 Change-Id: If9a22dd6d90d5c4d94175e021511766ea49acec2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/374420 Commit-Queue: Peter Hanspers Reviewed-by: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#43780} --- sdk/BUILD.gn | 12 ++ sdk/objc/native/api/audio_device_module.h | 10 ++ sdk/objc/native/api/audio_device_module.mm | 18 ++- .../api/audio_device_module_error_handler.h | 54 +++++++ .../src/audio/audio_device_module_ios.h | 6 +- .../src/audio/audio_device_module_ios.mm | 137 +++++++++++++++--- 6 files changed, 214 insertions(+), 23 deletions(-) create mode 100644 sdk/objc/native/api/audio_device_module_error_handler.h diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index e445cdc90f..4a9d1f66a9 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -231,6 +231,7 @@ if (is_ios || is_mac) { deps = [ ":audio_device", + ":audio_device_module_error_handler", "../api:make_ref_counted", "../api/audio:audio_device", "../modules/audio_device:audio_device_generic", @@ -290,6 +291,7 @@ if (is_ios || is_mac) { ] deps = [ + ":audio_device_module_error_handler", ":audio_objc", ":audio_session_observer", ":base_objc", @@ -507,6 +509,16 @@ if (is_ios || is_mac) { } } + rtc_source_set("audio_device_module_error_handler") { + visibility = [ ":*" ] + + sources = [ "objc/native/api/audio_device_module_error_handler.h" ] + + public_configs = [ ":common_config_objc" ] + + deps = [] + } + rtc_library("objc_audio_device_module") { visibility = [ "*" ] allow_poison = [ "environment_construction" ] diff --git a/sdk/objc/native/api/audio_device_module.h b/sdk/objc/native/api/audio_device_module.h index 25aafbbecc..7b9e535fed 100644 --- a/sdk/objc/native/api/audio_device_module.h +++ b/sdk/objc/native/api/audio_device_module.h @@ -14,6 +14,7 @@ #include #include "api/audio/audio_device.h" +#include "sdk/objc/native/api/audio_device_module_error_handler.h" namespace webrtc { @@ -31,6 +32,15 @@ rtc::scoped_refptr CreateMutedDetectAudioDeviceModule( AudioDeviceModule::MutedSpeechEventHandler muted_speech_event_handler, bool bypass_voice_processing = false); +// If `muted_speech_event_handler` is exist, audio unit will catch speech +// activity while muted. +// Provide `error_handler` to receive callbacks on errors such as microphone +// init failed or playout start failied. +rtc::scoped_refptr CreateMutedDetectAudioDeviceModule( + AudioDeviceModule::MutedSpeechEventHandler muted_speech_event_handler, + ADMErrorHandler error_handler, + bool bypass_voice_processing = false); + } // namespace webrtc #endif // SDK_OBJC_NATIVE_API_AUDIO_DEVICE_MODULE_H_ diff --git a/sdk/objc/native/api/audio_device_module.mm b/sdk/objc/native/api/audio_device_module.mm index 0c9af722bd..40f6b9b916 100644 --- a/sdk/objc/native/api/audio_device_module.mm +++ b/sdk/objc/native/api/audio_device_module.mm @@ -22,7 +22,9 @@ rtc::scoped_refptr CreateAudioDeviceModule( RTC_DLOG(LS_INFO) << __FUNCTION__; #if defined(WEBRTC_IOS) return rtc::make_ref_counted( - bypass_voice_processing, nullptr); + bypass_voice_processing, + /*muted_speech_event_handler=*/nullptr, + /*error_handler=*/nullptr); #else RTC_LOG(LS_ERROR) << "current platform is not supported => this module will self destruct!"; @@ -31,12 +33,22 @@ rtc::scoped_refptr CreateAudioDeviceModule( } rtc::scoped_refptr CreateMutedDetectAudioDeviceModule( - AudioDeviceModule::MutedSpeechEventHandler handler, + AudioDeviceModule::MutedSpeechEventHandler muted_speech_event_handler, + bool bypass_voice_processing) { + RTC_DLOG(LS_INFO) << __FUNCTION__; + return CreateMutedDetectAudioDeviceModule(muted_speech_event_handler, + /*error_handler=*/nullptr, + bypass_voice_processing); +} + +rtc::scoped_refptr CreateMutedDetectAudioDeviceModule( + AudioDeviceModule::MutedSpeechEventHandler muted_speech_event_handler, + ADMErrorHandler error_handler, bool bypass_voice_processing) { RTC_DLOG(LS_INFO) << __FUNCTION__; #if defined(WEBRTC_IOS) return rtc::make_ref_counted( - bypass_voice_processing, handler); + bypass_voice_processing, muted_speech_event_handler, error_handler); #else RTC_LOG(LS_ERROR) << "current platform is not supported => this module will self destruct!"; diff --git a/sdk/objc/native/api/audio_device_module_error_handler.h b/sdk/objc/native/api/audio_device_module_error_handler.h new file mode 100644 index 0000000000..1b73a533bb --- /dev/null +++ b/sdk/objc/native/api/audio_device_module_error_handler.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 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. + */ + +#ifndef SDK_OBJC_NATIVE_API_AUDIO_DEVICE_MODULE_ERROR_HANDLER_H +#define SDK_OBJC_NATIVE_API_AUDIO_DEVICE_MODULE_ERROR_HANDLER_H + +namespace webrtc { +enum ADMError : uint8_t { + // Generic. + kNotInitialized, + kInitializationFailed, + kTerminateFailed, + + // Playout / speaker errors. + kInitSpeakerFailed, + kPlayoutInitFailed, + kPlayoutStartFailed, + kPlayoutFailed, + kPlayoutDeviceFailed, + kPlayoutDelayFailed, + kPlayoutDeviceNameFailed, + kStereoPlayoutFailed, + kSpeakerMuteFailed, + kSpeakerVolumeFailed, + + // Recording / microphone errors. + kInitMicrophoneFailed, + kRecordingInitFailed, + kRecordingStartFailed, + kRecordingFailed, + kRecordingDeviceFailed, + kRecordingDeviceNameFailed, + kStereoRecordingFailed, + kMicrophoneMuteFailed, + kMicrophoneVolumeFailed, + + // Others. + kNoActiveAudioLayer, + kRegisterAudioCallbackFailed, + kEnableBuiltInAECFailed, + kEnableBuiltInAGCFailed, + kEnableBuiltInNSFailed, +}; +typedef void (^ADMErrorHandler)(ADMError error); +} // namespace webrtc + +#endif // SDK_OBJC_NATIVE_API_AUDIO_DEVICE_MODULE_ERROR_HANDLER_H diff --git a/sdk/objc/native/src/audio/audio_device_module_ios.h b/sdk/objc/native/src/audio/audio_device_module_ios.h index d92fd943d4..394e1ff9bd 100644 --- a/sdk/objc/native/src/audio/audio_device_module_ios.h +++ b/sdk/objc/native/src/audio/audio_device_module_ios.h @@ -18,6 +18,7 @@ #include "audio_device_ios.h" #include "modules/audio_device/audio_device_buffer.h" #include "rtc_base/checks.h" +#include "sdk/objc/native/api/audio_device_module_error_handler.h" namespace webrtc { @@ -31,7 +32,8 @@ class AudioDeviceModuleIOS : public AudioDeviceModule { explicit AudioDeviceModuleIOS( bool bypass_voice_processing, - MutedSpeechEventHandler muted_speech_event_handler); + MutedSpeechEventHandler muted_speech_event_handler, + ADMErrorHandler error_handler); ~AudioDeviceModuleIOS() override; // Retrieve the currently utilized audio layer @@ -134,8 +136,10 @@ class AudioDeviceModuleIOS : public AudioDeviceModule { int GetRecordAudioParameters(AudioParameters* params) const override; #endif // WEBRTC_IOS private: + void ReportError(ADMError error) const; const bool bypass_voice_processing_; MutedSpeechEventHandler muted_speech_event_handler_; + ADMErrorHandler error_handler_; bool initialized_ = false; const std::unique_ptr task_queue_factory_; std::unique_ptr audio_device_; diff --git a/sdk/objc/native/src/audio/audio_device_module_ios.mm b/sdk/objc/native/src/audio/audio_device_module_ios.mm index ed6e6633fc..3a7abb479c 100644 --- a/sdk/objc/native/src/audio/audio_device_module_ios.mm +++ b/sdk/objc/native/src/audio/audio_device_module_ios.mm @@ -22,18 +22,20 @@ #include "audio_device_ios.h" #endif -#define CHECKinitialized_() \ - { \ - if (!initialized_) { \ - return -1; \ - }; \ +#define CHECKinitialized_() \ + { \ + if (!initialized_) { \ + ReportError(kNotInitialized); \ + return -1; \ + }; \ } -#define CHECKinitialized__BOOL() \ - { \ - if (!initialized_) { \ - return false; \ - }; \ +#define CHECKinitialized__BOOL() \ + { \ + if (!initialized_) { \ + ReportError(kNotInitialized); \ + return false; \ + }; \ } namespace webrtc { @@ -41,9 +43,11 @@ namespace ios_adm { AudioDeviceModuleIOS::AudioDeviceModuleIOS( bool bypass_voice_processing, - MutedSpeechEventHandler muted_speech_event_handler) + MutedSpeechEventHandler muted_speech_event_handler, + ADMErrorHandler error_handler) : bypass_voice_processing_(bypass_voice_processing), muted_speech_event_handler_(muted_speech_event_handler), + error_handler_(error_handler), task_queue_factory_(CreateDefaultTaskQueueFactory()) { RTC_LOG(LS_INFO) << "current platform is IOS"; RTC_LOG(LS_INFO) << "iPhone Audio APIs will be utilized."; @@ -59,10 +63,17 @@ AudioDeviceModuleIOS::~AudioDeviceModuleIOS() { RTC_DLOG(LS_INFO) << __FUNCTION__; } +void AudioDeviceModuleIOS::ReportError(ADMError error) const { + if (error_handler_) { + error_handler_(error); + } +} + int32_t AudioDeviceModuleIOS::ActiveAudioLayer(AudioLayer* audioLayer) const { RTC_DLOG(LS_INFO) << __FUNCTION__; AudioLayer activeAudio; if (audio_device_->ActiveAudioLayer(activeAudio) == -1) { + ReportError(kNoActiveAudioLayer); return -1; } *audioLayer = activeAudio; @@ -88,6 +99,7 @@ int32_t AudioDeviceModuleIOS::Init() { static_cast(AudioDeviceGeneric::InitStatus::NUM_STATUSES)); if (status != AudioDeviceGeneric::InitStatus::OK) { RTC_LOG(LS_ERROR) << "Audio device initialization failed."; + ReportError(kInitializationFailed); return -1; } initialized_ = true; @@ -98,6 +110,7 @@ int32_t AudioDeviceModuleIOS::Terminate() { RTC_DLOG(LS_INFO) << __FUNCTION__; if (!initialized_) return 0; if (audio_device_->Terminate() == -1) { + ReportError(kTerminateFailed); return -1; } initialized_ = false; @@ -112,13 +125,21 @@ bool AudioDeviceModuleIOS::Initialized() const { int32_t AudioDeviceModuleIOS::InitSpeaker() { RTC_DLOG(LS_INFO) << __FUNCTION__; CHECKinitialized_(); - return audio_device_->InitSpeaker(); + int32_t result = audio_device_->InitSpeaker(); + if (result != 0) { + ReportError(kInitSpeakerFailed); + } + return result; } int32_t AudioDeviceModuleIOS::InitMicrophone() { RTC_DLOG(LS_INFO) << __FUNCTION__; CHECKinitialized_(); - return audio_device_->InitMicrophone(); + int32_t result = audio_device_->InitMicrophone(); + if (result != 0) { + ReportError(kInitMicrophoneFailed); + } + return result; } int32_t AudioDeviceModuleIOS::SpeakerVolumeIsAvailable(bool* available) { @@ -126,6 +147,7 @@ int32_t AudioDeviceModuleIOS::SpeakerVolumeIsAvailable(bool* available) { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->SpeakerVolumeIsAvailable(isAvailable) == -1) { + ReportError(kSpeakerVolumeFailed); return -1; } *available = isAvailable; @@ -136,7 +158,11 @@ int32_t AudioDeviceModuleIOS::SpeakerVolumeIsAvailable(bool* available) { int32_t AudioDeviceModuleIOS::SetSpeakerVolume(uint32_t volume) { RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << volume << ")"; CHECKinitialized_(); - return audio_device_->SetSpeakerVolume(volume); + int32_t result = audio_device_->SetSpeakerVolume(volume); + if (result != 0) { + ReportError(kSpeakerVolumeFailed); + } + return result; } int32_t AudioDeviceModuleIOS::SpeakerVolume(uint32_t* volume) const { @@ -144,6 +170,7 @@ int32_t AudioDeviceModuleIOS::SpeakerVolume(uint32_t* volume) const { CHECKinitialized_(); uint32_t level = 0; if (audio_device_->SpeakerVolume(level) == -1) { + ReportError(kSpeakerVolumeFailed); return -1; } *volume = level; @@ -171,6 +198,7 @@ int32_t AudioDeviceModuleIOS::MaxSpeakerVolume(uint32_t* maxVolume) const { CHECKinitialized_(); uint32_t maxVol = 0; if (audio_device_->MaxSpeakerVolume(maxVol) == -1) { + ReportError(kSpeakerVolumeFailed); return -1; } *maxVolume = maxVol; @@ -181,6 +209,7 @@ int32_t AudioDeviceModuleIOS::MinSpeakerVolume(uint32_t* minVolume) const { CHECKinitialized_(); uint32_t minVol = 0; if (audio_device_->MinSpeakerVolume(minVol) == -1) { + ReportError(kSpeakerVolumeFailed); return -1; } *minVolume = minVol; @@ -192,6 +221,7 @@ int32_t AudioDeviceModuleIOS::SpeakerMuteIsAvailable(bool* available) { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->SpeakerMuteIsAvailable(isAvailable) == -1) { + ReportError(kSpeakerMuteFailed); return -1; } *available = isAvailable; @@ -202,7 +232,11 @@ int32_t AudioDeviceModuleIOS::SpeakerMuteIsAvailable(bool* available) { int32_t AudioDeviceModuleIOS::SetSpeakerMute(bool enable) { RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; CHECKinitialized_(); - return audio_device_->SetSpeakerMute(enable); + int32_t result = audio_device_->SetSpeakerMute(enable); + if (result != 0) { + ReportError(kSpeakerMuteFailed); + } + return result; } int32_t AudioDeviceModuleIOS::SpeakerMute(bool* enabled) const { @@ -210,6 +244,7 @@ int32_t AudioDeviceModuleIOS::SpeakerMute(bool* enabled) const { CHECKinitialized_(); bool muted = false; if (audio_device_->SpeakerMute(muted) == -1) { + ReportError(kSpeakerMuteFailed); return -1; } *enabled = muted; @@ -222,6 +257,7 @@ int32_t AudioDeviceModuleIOS::MicrophoneMuteIsAvailable(bool* available) { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->MicrophoneMuteIsAvailable(isAvailable) == -1) { + ReportError(kMicrophoneMuteFailed); return -1; } *available = isAvailable; @@ -232,7 +268,11 @@ int32_t AudioDeviceModuleIOS::MicrophoneMuteIsAvailable(bool* available) { int32_t AudioDeviceModuleIOS::SetMicrophoneMute(bool enable) { RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; CHECKinitialized_(); - return (audio_device_->SetMicrophoneMute(enable)); + int32_t result = audio_device_->SetMicrophoneMute(enable); + if (result != 0) { + ReportError(kMicrophoneMuteFailed); + } + return result; } int32_t AudioDeviceModuleIOS::MicrophoneMute(bool* enabled) const { @@ -240,6 +280,7 @@ int32_t AudioDeviceModuleIOS::MicrophoneMute(bool* enabled) const { CHECKinitialized_(); bool muted = false; if (audio_device_->MicrophoneMute(muted) == -1) { + ReportError(kMicrophoneMuteFailed); return -1; } *enabled = muted; @@ -252,6 +293,7 @@ int32_t AudioDeviceModuleIOS::MicrophoneVolumeIsAvailable(bool* available) { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->MicrophoneVolumeIsAvailable(isAvailable) == -1) { + ReportError(kMicrophoneVolumeFailed); return -1; } *available = isAvailable; @@ -270,6 +312,7 @@ int32_t AudioDeviceModuleIOS::MicrophoneVolume(uint32_t* volume) const { CHECKinitialized_(); uint32_t level = 0; if (audio_device_->MicrophoneVolume(level) == -1) { + ReportError(kMicrophoneVolumeFailed); return -1; } *volume = level; @@ -283,6 +326,7 @@ int32_t AudioDeviceModuleIOS::StereoRecordingIsAvailable( CHECKinitialized_(); bool isAvailable = false; if (audio_device_->StereoRecordingIsAvailable(isAvailable) == -1) { + ReportError(kStereoRecordingFailed); return -1; } *available = isAvailable; @@ -296,6 +340,7 @@ int32_t AudioDeviceModuleIOS::SetStereoRecording(bool enable) { if (enable) { RTC_LOG(LS_WARNING) << "recording in stereo is not supported"; } + ReportError(kStereoRecordingFailed); return -1; } @@ -304,6 +349,7 @@ int32_t AudioDeviceModuleIOS::StereoRecording(bool* enabled) const { CHECKinitialized_(); bool stereo = false; if (audio_device_->StereoRecording(stereo) == -1) { + ReportError(kStereoRecordingFailed); return -1; } *enabled = stereo; @@ -316,6 +362,7 @@ int32_t AudioDeviceModuleIOS::StereoPlayoutIsAvailable(bool* available) const { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->StereoPlayoutIsAvailable(isAvailable) == -1) { + ReportError(kStereoPlayoutFailed); return -1; } *available = isAvailable; @@ -329,10 +376,12 @@ int32_t AudioDeviceModuleIOS::SetStereoPlayout(bool enable) { if (audio_device_->PlayoutIsInitialized()) { RTC_LOG(LS_ERROR) << "unable to set stereo mode while playing side is initialized"; + ReportError(kStereoPlayoutFailed); return -1; } if (audio_device_->SetStereoPlayout(enable)) { RTC_LOG(LS_WARNING) << "stereo playout is not supported"; + ReportError(kStereoPlayoutFailed); return -1; } int8_t nChannels(1); @@ -348,6 +397,7 @@ int32_t AudioDeviceModuleIOS::StereoPlayout(bool* enabled) const { CHECKinitialized_(); bool stereo = false; if (audio_device_->StereoPlayout(stereo) == -1) { + ReportError(kStereoPlayoutFailed); return -1; } *enabled = stereo; @@ -360,6 +410,7 @@ int32_t AudioDeviceModuleIOS::PlayoutIsAvailable(bool* available) { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->PlayoutIsAvailable(isAvailable) == -1) { + ReportError(kPlayoutFailed); return -1; } *available = isAvailable; @@ -372,6 +423,7 @@ int32_t AudioDeviceModuleIOS::RecordingIsAvailable(bool* available) { CHECKinitialized_(); bool isAvailable = false; if (audio_device_->RecordingIsAvailable(isAvailable) == -1) { + ReportError(kRecordingFailed); return -1; } *available = isAvailable; @@ -383,6 +435,7 @@ int32_t AudioDeviceModuleIOS::MaxMicrophoneVolume(uint32_t* maxVolume) const { CHECKinitialized_(); uint32_t maxVol(0); if (audio_device_->MaxMicrophoneVolume(maxVol) == -1) { + ReportError(kMicrophoneVolumeFailed); return -1; } *maxVolume = maxVol; @@ -393,6 +446,7 @@ int32_t AudioDeviceModuleIOS::MinMicrophoneVolume(uint32_t* minVolume) const { CHECKinitialized_(); uint32_t minVol(0); if (audio_device_->MinMicrophoneVolume(minVol) == -1) { + ReportError(kMicrophoneVolumeFailed); return -1; } *minVolume = minVol; @@ -416,7 +470,11 @@ int32_t AudioDeviceModuleIOS::SetPlayoutDevice(uint16_t index) { int32_t AudioDeviceModuleIOS::SetPlayoutDevice(WindowsDeviceType device) { RTC_DLOG(LS_INFO) << __FUNCTION__; CHECKinitialized_(); - return audio_device_->SetPlayoutDevice(device); + int32_t result = audio_device_->SetPlayoutDevice(device); + if (result != 0) { + ReportError(kPlayoutDeviceFailed); + } + return result; } int32_t AudioDeviceModuleIOS::PlayoutDeviceName( @@ -426,9 +484,11 @@ int32_t AudioDeviceModuleIOS::PlayoutDeviceName( RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << index << ", ...)"; CHECKinitialized_(); if (name == NULL) { + ReportError(kPlayoutDeviceNameFailed); return -1; } if (audio_device_->PlayoutDeviceName(index, name, guid) == -1) { + ReportError(kPlayoutDeviceNameFailed); return -1; } if (name != NULL) { @@ -447,9 +507,11 @@ int32_t AudioDeviceModuleIOS::RecordingDeviceName( RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << index << ", ...)"; CHECKinitialized_(); if (name == NULL) { + ReportError(kRecordingDeviceNameFailed); return -1; } if (audio_device_->RecordingDeviceName(index, name, guid) == -1) { + ReportError(kRecordingDeviceNameFailed); return -1; } if (name != NULL) { @@ -478,7 +540,11 @@ int32_t AudioDeviceModuleIOS::SetRecordingDevice(uint16_t index) { int32_t AudioDeviceModuleIOS::SetRecordingDevice(WindowsDeviceType device) { RTC_DLOG(LS_INFO) << __FUNCTION__; CHECKinitialized_(); - return audio_device_->SetRecordingDevice(device); + int32_t result = audio_device_->SetRecordingDevice(device); + if (result < 0) { + ReportError(kRecordingDeviceFailed); + } + return result; } int32_t AudioDeviceModuleIOS::InitPlayout() { @@ -488,6 +554,9 @@ int32_t AudioDeviceModuleIOS::InitPlayout() { return 0; } int32_t result = audio_device_->InitPlayout(); + if (result < 0) { + ReportError(kPlayoutInitFailed); + } RTC_DLOG(LS_INFO) << "output: " << result; RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess", static_cast(result == 0)); @@ -501,6 +570,9 @@ int32_t AudioDeviceModuleIOS::InitRecording() { return 0; } int32_t result = audio_device_->InitRecording(); + if (result < 0) { + ReportError(kRecordingInitFailed); + } RTC_DLOG(LS_INFO) << "output: " << result; RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitRecordingSuccess", static_cast(result == 0)); @@ -527,6 +599,9 @@ int32_t AudioDeviceModuleIOS::StartPlayout() { } audio_device_buffer_.get()->StartPlayout(); int32_t result = audio_device_->StartPlayout(); + if (result < 0) { + ReportError(kPlayoutStartFailed); + } RTC_DLOG(LS_INFO) << "output: " << result; RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartPlayoutSuccess", static_cast(result == 0)); @@ -538,6 +613,9 @@ int32_t AudioDeviceModuleIOS::StopPlayout() { CHECKinitialized_(); int32_t result = audio_device_->StopPlayout(); audio_device_buffer_.get()->StopPlayout(); + if (result < 0) { + ReportError(kPlayoutFailed); + } RTC_DLOG(LS_INFO) << "output: " << result; RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopPlayoutSuccess", static_cast(result == 0)); @@ -558,6 +636,9 @@ int32_t AudioDeviceModuleIOS::StartRecording() { } audio_device_buffer_.get()->StartRecording(); int32_t result = audio_device_->StartRecording(); + if (result < 0) { + ReportError(kRecordingStartFailed); + } RTC_DLOG(LS_INFO) << "output: " << result; RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartRecordingSuccess", static_cast(result == 0)); @@ -569,6 +650,9 @@ int32_t AudioDeviceModuleIOS::StopRecording() { CHECKinitialized_(); int32_t result = audio_device_->StopRecording(); audio_device_buffer_.get()->StopRecording(); + if (result < 0) { + ReportError(kRecordingFailed); + } RTC_DLOG(LS_INFO) << "output: " << result; RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopRecordingSuccess", static_cast(result == 0)); @@ -584,13 +668,19 @@ bool AudioDeviceModuleIOS::Recording() const { int32_t AudioDeviceModuleIOS::RegisterAudioCallback( AudioTransport* audioCallback) { RTC_DLOG(LS_INFO) << __FUNCTION__; - return audio_device_buffer_.get()->RegisterAudioCallback(audioCallback); + int32_t result = + audio_device_buffer_.get()->RegisterAudioCallback(audioCallback); + if (result < 0) { + ReportError(kRegisterAudioCallbackFailed); + } + return result; } int32_t AudioDeviceModuleIOS::PlayoutDelay(uint16_t* delayMS) const { CHECKinitialized_(); uint16_t delay = 0; if (audio_device_->PlayoutDelay(delay) == -1) { + ReportError(kPlayoutDelayFailed); RTC_LOG(LS_ERROR) << "failed to retrieve the playout delay"; return -1; } @@ -610,6 +700,9 @@ int32_t AudioDeviceModuleIOS::EnableBuiltInAEC(bool enable) { RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; CHECKinitialized_(); int32_t ok = audio_device_->EnableBuiltInAEC(enable); + if (ok < 0) { + ReportError(kEnableBuiltInAECFailed); + } RTC_DLOG(LS_INFO) << "output: " << ok; return ok; } @@ -626,6 +719,9 @@ int32_t AudioDeviceModuleIOS::EnableBuiltInAGC(bool enable) { RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; CHECKinitialized_(); int32_t ok = audio_device_->EnableBuiltInAGC(enable); + if (ok < 0) { + ReportError(kEnableBuiltInAGCFailed); + } RTC_DLOG(LS_INFO) << "output: " << ok; return ok; } @@ -642,6 +738,9 @@ int32_t AudioDeviceModuleIOS::EnableBuiltInNS(bool enable) { RTC_DLOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")"; CHECKinitialized_(); int32_t ok = audio_device_->EnableBuiltInNS(enable); + if (ok < 0) { + ReportError(kEnableBuiltInNSFailed); + } RTC_DLOG(LS_INFO) << "output: " << ok; return ok; }