Skip to content

Commit 40e7d20

Browse files
committed
Mute mode
1 parent 2fd53d6 commit 40e7d20

File tree

4 files changed

+89
-13
lines changed

4 files changed

+89
-13
lines changed

modules/audio_device/audio_engine_device.h

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,17 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
135135

136136
bool IsInterrupted();
137137

138+
enum RenderMode { Device = 0, Manual = 1 };
139+
enum MuteMode { VoiceProcessing = 0, RestartEngine = 1 };
140+
138141
int32_t SetObserver(AudioDeviceObserver* observer) override;
139142

140143
int32_t SetManualRenderingMode(bool enable);
141144
int32_t ManualRenderingMode(bool* enabled);
142145

146+
int32_t SetMuteMode(MuteMode mode);
147+
int32_t GetMuteMode(MuteMode* mode);
148+
143149
int32_t SetAdvancedDucking(bool enable);
144150
int32_t AdvancedDucking(bool* enabled);
145151

@@ -157,8 +163,6 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
157163

158164
int32_t InitAndStartRecording();
159165

160-
enum RenderMode { Device, Manual };
161-
162166
private:
163167
// Represents the state of the audio engine, including input/output status,
164168
// rendering mode, and various configuration flags.
@@ -176,6 +180,8 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
176180
bool is_interrupted = false;
177181

178182
RenderMode render_mode = RenderMode::Device;
183+
MuteMode mute_mode = MuteMode::VoiceProcessing;
184+
179185
bool voice_processing_enabled = true;
180186
bool voice_processing_bypassed = false;
181187
bool voice_processing_agc_enabled = true;
@@ -194,7 +200,7 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
194200
input_follow_mode == rhs.input_follow_mode &&
195201
input_enabled_persistent_mode == rhs.input_enabled_persistent_mode &&
196202
input_muted == rhs.input_muted && is_interrupted == rhs.is_interrupted &&
197-
render_mode == rhs.render_mode &&
203+
render_mode == rhs.render_mode && mute_mode == rhs.mute_mode &&
198204
voice_processing_enabled == rhs.voice_processing_enabled &&
199205
voice_processing_bypassed == rhs.voice_processing_bypassed &&
200206
voice_processing_agc_enabled == rhs.voice_processing_agc_enabled &&
@@ -209,18 +215,24 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
209215
bool IsOutputInputLinked() const { return input_follow_mode && voice_processing_enabled; }
210216

211217
bool IsOutputEnabled() const {
212-
return IsOutputInputLinked() ? IsInputEnabled() || output_enabled : output_enabled;
218+
return IsOutputInputLinked() ? (IsInputEnabled() || output_enabled) : output_enabled;
213219
}
214220

215221
bool IsOutputRunning() const {
216-
return IsOutputInputLinked() ? input_running || output_running : output_running;
222+
return IsOutputInputLinked() ? (IsInputRunning() || output_running) : output_running;
217223
}
218224

219-
bool IsInputEnabled() const { return input_enabled || input_enabled_persistent_mode; }
220-
bool IsInputRunning() const { return input_running; }
225+
bool IsInputEnabled() const {
226+
return !(mute_mode == MuteMode::RestartEngine && input_muted) &&
227+
(input_enabled || input_enabled_persistent_mode);
228+
}
229+
230+
bool IsInputRunning() const {
231+
return !(mute_mode == MuteMode::RestartEngine && input_muted) && input_running;
232+
}
221233

222-
bool IsAnyEnabled() const { return IsInputEnabled() || output_enabled; }
223-
bool IsAnyRunning() const { return input_running || output_running; }
234+
bool IsAnyEnabled() const { return IsInputEnabled() || IsOutputEnabled(); }
235+
bool IsAnyRunning() const { return IsInputRunning() || IsOutputRunning(); }
224236

225237
bool IsAllEnabled() const {
226238
return IsOutputInputLinked() ? IsInputEnabled() : IsInputEnabled() && output_enabled;
@@ -274,10 +286,16 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
274286
return prev.default_input_device_id != next.default_input_device_id;
275287
}
276288

289+
bool DidUpdateMuteMode() const { return prev.mute_mode != next.mute_mode; }
290+
277291
bool IsEngineRestartRequired() const {
278292
return DidUpdateAudioGraph() || DidUpdateOutputDevice() || DidUpdateInputDevice() ||
293+
// Handle default device updates
279294
(DidUpdateDefaultOutputDevice() && next.IsOutputDefaultDevice()) ||
280-
(DidUpdateDefaultInputDevice() && next.IsInputDefaultDevice());
295+
(DidUpdateDefaultInputDevice() && next.IsInputDefaultDevice()) ||
296+
// Handle mute mode update
297+
(DidUpdateMuteMode() && next.mute_mode == MuteMode::RestartEngine &&
298+
next.IsInputEnabled());
281299
}
282300

283301
// Special case to re-create engine when switching from Speaker & Mic ->

modules/audio_device/audio_engine_device.mm

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,31 @@
10601060
return 0;
10611061
}
10621062

1063+
int32_t AudioEngineDevice::GetMuteMode(MuteMode* mode) {
1064+
LOGI() << "GetMuteMode";
1065+
RTC_DCHECK_RUN_ON(thread_);
1066+
1067+
if (mode == nullptr) {
1068+
return -1;
1069+
}
1070+
1071+
*mode = engine_state_.mute_mode;
1072+
1073+
return 0;
1074+
}
1075+
1076+
int32_t AudioEngineDevice::SetMuteMode(MuteMode mode) {
1077+
RTC_DCHECK_RUN_ON(thread_);
1078+
LOGI() << "SetMuteMode: " << mode;
1079+
1080+
SetEngineState([mode](EngineState state) -> EngineState {
1081+
state.mute_mode = mode;
1082+
return state;
1083+
});
1084+
1085+
return 0;
1086+
}
1087+
10631088
int32_t AudioEngineDevice::InitAndStartRecording() {
10641089
RTC_DCHECK_RUN_ON(thread_);
10651090
LOGI() << "InitAndStartRecording";
@@ -1758,7 +1783,8 @@
17581783
state.next.IsInputEnabled());
17591784
}
17601785

1761-
if (state.next.IsInputEnabled() && this->InputNode().voiceProcessingEnabled &&
1786+
if (state.next.mute_mode == MuteMode::VoiceProcessing && state.next.IsInputEnabled() &&
1787+
this->InputNode().voiceProcessingEnabled &&
17621788
this->InputNode().voiceProcessingInputMuted != state.next.input_muted) {
17631789
LOGI() << "setVoiceProcessingInputMuted: " << state.next.input_muted;
17641790
this->InputNode().voiceProcessingInputMuted = state.next.input_muted;

sdk/objc/api/peerconnection/RTCAudioDeviceModule.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ typedef NS_ENUM(NSInteger, RTCSpeechActivityEvent) {
2828
RTCSpeechActivityEventEnded,
2929
};
3030

31+
typedef NS_ENUM(NSInteger, RTCAudioEngineMuteMode) {
32+
RTCAudioEngineMuteModeUnknown = -1,
33+
RTCAudioEngineMuteModeVoiceProcessing = 0,
34+
RTCAudioEngineMuteModeRestartEngine = 1,
35+
};
36+
3137
RTC_EXTERN NSString *const kRTCAudioEngineInputMixerNodeKey;
3238

3339
@class RTC_OBJC_TYPE(RTCAudioDeviceModule);
@@ -77,8 +83,7 @@ RTC_OBJC_EXPORT @protocol RTC_OBJC_TYPE
7783
configureInputFromSource:(nullable AVAudioNode *)source
7884
toDestination:(AVAudioNode *)destination
7985
withFormat:(AVAudioFormat *)format
80-
context:(NSDictionary *)context
81-
NS_SWIFT_NAME(audioDeviceModule(_:engine:configureInputFromSource:toDestination:format:context:));
86+
context:(NSDictionary *)context NS_SWIFT_NAME(audioDeviceModule(_:engine:configureInputFromSource:toDestination:format:context:));
8287

8388
- (void)audioDeviceModule:(RTC_OBJC_TYPE(RTCAudioDeviceModule) *)audioDeviceModule
8489
engine:(AVAudioEngine *)engine
@@ -137,6 +142,7 @@ RTC_OBJC_EXPORT
137142
@property(nonatomic, assign, getter=isAdvancedDuckingEnabled) BOOL advancedDuckingEnabled;
138143

139144
@property(nonatomic, assign) NSInteger duckingLevel;
145+
@property(nonatomic, assign) RTCAudioEngineMuteMode muteMode;
140146

141147
@property(nonatomic, assign, getter=isVoiceProcessingBypassed) BOOL voiceProcessingBypassed;
142148
@property(nonatomic, assign, getter=isVoiceProcessingAGCEnabled) BOOL voiceProcessingAGCEnabled;

sdk/objc/api/peerconnection/RTCAudioDeviceModule.mm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626

2727
NSString *const kRTCAudioEngineInputMixerNodeKey = webrtc::kAudioEngineInputMixerNodeKey;
2828

29+
inline webrtc::AudioEngineDevice::MuteMode MuteModeToRTC(RTCAudioEngineMuteMode mode) {
30+
return static_cast<webrtc::AudioEngineDevice::MuteMode>(mode);
31+
}
32+
33+
inline RTCAudioEngineMuteMode MuteModeToObjC(webrtc::AudioEngineDevice::MuteMode mode) {
34+
return static_cast<RTCAudioEngineMuteMode>(mode);
35+
}
36+
2937
class AudioDeviceObserver : public webrtc::AudioDeviceObserver {
3038
public:
3139
AudioDeviceObserver(RTC_OBJC_TYPE(RTCAudioDeviceModule) * adm) { adm_ = adm; }
@@ -373,6 +381,24 @@ - (void)setDuckingLevel:(NSInteger)value {
373381
_workerThread->BlockingCall([module, value] { return module->SetDuckingLevel(value) == 0; });
374382
}
375383

384+
- (RTCAudioEngineMuteMode)muteMode {
385+
webrtc::AudioEngineDevice *module = dynamic_cast<webrtc::AudioEngineDevice *>(_native.get());
386+
if (module == nullptr) return RTCAudioEngineMuteModeUnknown;
387+
388+
return _workerThread->BlockingCall([module] {
389+
webrtc::AudioEngineDevice::MuteMode mode;
390+
return module->GetMuteMode(&mode) == 0 ? MuteModeToObjC(mode) : RTCAudioEngineMuteModeUnknown;
391+
});
392+
}
393+
394+
- (void)setMuteMode:(RTCAudioEngineMuteMode)mode {
395+
webrtc::AudioEngineDevice *module = dynamic_cast<webrtc::AudioEngineDevice *>(_native.get());
396+
if (module == nullptr) return;
397+
398+
_workerThread->BlockingCall(
399+
[module, mode] { return module->SetMuteMode(MuteModeToRTC(mode)) == 0; });
400+
}
401+
376402
- (BOOL)isVoiceProcessingBypassed {
377403
webrtc::AudioEngineDevice *module = dynamic_cast<webrtc::AudioEngineDevice *>(_native.get());
378404
if (module == nullptr) return NO;

0 commit comments

Comments
 (0)