diff --git a/sdk/objc/native/src/audio/audio_device_ios.mm b/sdk/objc/native/src/audio/audio_device_ios.mm index 3c3117d716..b59791e6e8 100644 --- a/sdk/objc/native/src/audio/audio_device_ios.mm +++ b/sdk/objc/native/src/audio/audio_device_ios.mm @@ -1045,13 +1045,17 @@ bool AudioDeviceIOS::MicrophoneIsInitialized() const { } int32_t AudioDeviceIOS::MicrophoneMuteIsAvailable(bool& available) { - available = false; + available = true; return 0; } int32_t AudioDeviceIOS::SetMicrophoneMute(bool enable) { - RTC_DCHECK_NOTREACHED() << "Not implemented"; - return -1; + OSStatus result = audio_unit_->SetMicrophoneMute(enable); + if (result != noErr) { + RTCLogError(@"Set microphone %s failed, reason %d", enable ? "mute" : "unmute", result); + return -1; + } + return 0; } int32_t AudioDeviceIOS::MicrophoneMute(bool& enabled) const { diff --git a/sdk/objc/native/src/audio/voice_processing_audio_unit.h b/sdk/objc/native/src/audio/voice_processing_audio_unit.h index b40dba01e4..99586a94ed 100644 --- a/sdk/objc/native/src/audio/voice_processing_audio_unit.h +++ b/sdk/objc/native/src/audio/voice_processing_audio_unit.h @@ -92,6 +92,9 @@ class VoiceProcessingAudioUnit { // Uninitializes the underlying audio unit. bool Uninitialize(); + // Mutes the microphone. + bool SetMicrophoneMute(bool enable); + // Calls render on the underlying audio unit. OSStatus Render(AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time_stamp, diff --git a/sdk/objc/native/src/audio/voice_processing_audio_unit.mm b/sdk/objc/native/src/audio/voice_processing_audio_unit.mm index b538a35c23..fe35ce3609 100644 --- a/sdk/objc/native/src/audio/voice_processing_audio_unit.mm +++ b/sdk/objc/native/src/audio/voice_processing_audio_unit.mm @@ -398,6 +398,39 @@ bool VoiceProcessingAudioUnit::Uninitialize() { return true; } +bool VoiceProcessingAudioUnit::SetMicrophoneMute(bool enable) { + RTC_DCHECK_GE(state_, kUninitialized); + + RTCLog(@"Setting microphone %s.", enable ? "mute" : "unmute"); + + OSStatus result = noErr; + if (detect_mute_speech_) { + UInt32 muteUplinkOutput = enable ? 1 : 0; + result = AudioUnitSetProperty(vpio_unit_, + kAUVoiceIOProperty_MuteOutput, + kAudioUnitScope_Global, + kInputBus, + &muteUplinkOutput, + sizeof(muteUplinkOutput)); + } else { + UInt32 enableInput = enable ? 0 : 1; + result = AudioUnitSetProperty(vpio_unit_, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Input, + kInputBus, + &enableInput, + sizeof(enableInput)); + } + + if (result != noErr) { + RTCLogError(@"Failed to %s microphone. Error=%ld", (enable ? "mute" : "unmute"), (long)result); + return false; + } + + RTCLog(@"Set microphone %s.", enable ? "mute" : "unmute"); + return true; +} + OSStatus VoiceProcessingAudioUnit::Render(AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time_stamp, UInt32 output_bus_number,