Skip to content

Commit 821c91a

Browse files
committed
Engine state transition
Squashed: Rename AudioEngineState Refactor engine observer Refactor EngineStateTransition Move EngineStateTransition Refactor EngineState State as class
1 parent 0b84894 commit 821c91a

File tree

6 files changed

+375
-264
lines changed

6 files changed

+375
-264
lines changed

modules/audio_device/audio_engine_device.h

Lines changed: 134 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
105105
public:
106106
enum RenderMode { Device = 0, Manual = 1 };
107107
enum MuteMode { VoiceProcessing = 0, RestartEngine = 1 };
108+
enum SpeechActivityEvent {
109+
kStarted = 0,
110+
kEnded,
111+
};
108112

109113
// Represents the state of the audio engine, including input/output status,
110114
// rendering mode, and various configuration flags.
@@ -189,6 +193,129 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
189193
bool IsInputDefaultDevice() const { return input_device_id == 0; }
190194
};
191195

196+
struct EngineStateTransition {
197+
EngineState prev;
198+
EngineState next;
199+
200+
bool HasNoChanges() const { return prev == next; }
201+
202+
bool DidEnableOutput() const { return !prev.IsOutputEnabled() && next.IsOutputEnabled(); }
203+
204+
bool DidEnableInput() const { return !prev.IsInputEnabled() && next.IsInputEnabled(); }
205+
206+
bool DidDisableOutput() const { return prev.IsOutputEnabled() && !next.IsOutputEnabled(); }
207+
208+
bool DidDisableInput() const { return prev.IsInputEnabled() && !next.IsInputEnabled(); }
209+
210+
bool DidAnyEnable() const { return DidEnableOutput() || DidEnableInput(); }
211+
212+
bool DidAnyDisable() const { return DidDisableOutput() || DidDisableInput(); }
213+
214+
bool DidBeginInterruption() const { return !prev.is_interrupted && next.is_interrupted; }
215+
216+
bool DidEndInterruption() const { return prev.is_interrupted && !next.is_interrupted; }
217+
218+
bool DidUpdateAudioGraph() const {
219+
return (prev.IsInputEnabled() != next.IsInputEnabled()) ||
220+
(prev.IsOutputEnabled() != next.IsOutputEnabled());
221+
}
222+
223+
bool DidUpdateVoiceProcessingEnabled() const {
224+
return prev.voice_processing_enabled != next.voice_processing_enabled;
225+
}
226+
227+
bool DidUpdateOutputDevice() const { return prev.output_device_id != next.output_device_id; }
228+
229+
bool DidUpdateInputDevice() const { return prev.input_device_id != next.input_device_id; }
230+
231+
bool DidUpdateDefaultOutputDevice() const {
232+
return prev.default_output_device_id != next.default_output_device_id;
233+
}
234+
235+
bool DidUpdateDefaultInputDevice() const {
236+
return prev.default_input_device_id != next.default_input_device_id;
237+
}
238+
239+
bool DidUpdateMuteMode() const { return prev.mute_mode != next.mute_mode; }
240+
241+
bool IsEngineRestartRequired() const {
242+
return DidUpdateAudioGraph() || DidUpdateOutputDevice() || DidUpdateInputDevice() ||
243+
// Voice processing enable state updates
244+
DidUpdateVoiceProcessingEnabled() ||
245+
// Handle default device updates
246+
(DidUpdateDefaultOutputDevice() && next.IsOutputDefaultDevice()) ||
247+
(DidUpdateDefaultInputDevice() && next.IsInputDefaultDevice());
248+
}
249+
250+
// Special case to re-create engine when switching from Speaker & Mic ->
251+
// Speaker only.
252+
bool IsEngineRecreateRequired() const {
253+
return (prev.IsOutputEnabled() && next.IsOutputEnabled()) &&
254+
(prev.IsInputEnabled() && !next.IsInputEnabled());
255+
}
256+
257+
bool DidEnableManualRenderingMode() const {
258+
return prev.render_mode != RenderMode::Manual && next.render_mode == RenderMode::Manual;
259+
}
260+
261+
bool DidEnableDeviceRenderingMode() const {
262+
return prev.render_mode != RenderMode::Device && next.render_mode == RenderMode::Device;
263+
}
264+
};
265+
266+
class EngineObserver {
267+
public:
268+
virtual ~EngineObserver() = default;
269+
270+
virtual void OnEngineDidReceiveMutedSpeechActivityEvent(SpeechActivityEvent event) {}
271+
272+
// AVAudioEngine lifecycle
273+
virtual int32_t OnEngineDidCreate(AVAudioEngine* engine,
274+
EngineStateTransition state_transition) {
275+
return 0;
276+
}
277+
278+
virtual int32_t OnEngineWillEnable(AVAudioEngine* engine,
279+
EngineStateTransition state_transition) {
280+
return 0;
281+
}
282+
283+
virtual int32_t OnEngineWillStart(AVAudioEngine* engine,
284+
EngineStateTransition state_transition) {
285+
return 0;
286+
}
287+
288+
virtual int32_t OnEngineDidStop(AVAudioEngine* engine, EngineStateTransition state_transition) {
289+
return 0;
290+
}
291+
292+
virtual int32_t OnEngineDidDisable(AVAudioEngine* engine,
293+
EngineStateTransition state_transition) {
294+
return 0;
295+
}
296+
297+
virtual int32_t OnEngineWillRelease(AVAudioEngine* engine,
298+
EngineStateTransition state_transition) {
299+
return 0;
300+
}
301+
302+
// Override the input node configuration with a custom implementation.
303+
virtual int32_t OnEngineWillConnectInput(AVAudioEngine* engine, AVAudioNode* src,
304+
AVAudioNode* dst, AVAudioFormat* format,
305+
EngineStateTransition state_transition,
306+
NSDictionary* context) {
307+
return 0;
308+
}
309+
310+
// Override the input node configuration with a custom implementation.
311+
virtual int32_t OnEngineWillConnectOutput(AVAudioEngine* engine, AVAudioNode* src,
312+
AVAudioNode* dst, AVAudioFormat* format,
313+
EngineStateTransition state_transition,
314+
NSDictionary* context) {
315+
return 0;
316+
}
317+
};
318+
192319
explicit AudioEngineDevice(bool voice_processing_bypassed);
193320
~AudioEngineDevice() override;
194321

@@ -281,11 +408,13 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
281408

282409
bool IsEngineRunning();
283410

284-
int32_t SetEngineState(EngineState enable);
285-
int32_t GetEngineState(EngineState* enabled);
411+
int32_t SetEngineState(EngineState new_state);
412+
int32_t GetEngineState(EngineState* state);
286413

287414
int32_t SetObserver(AudioDeviceObserver* observer) override;
288415

416+
int32_t SetEngineObserver(EngineObserver* observer);
417+
289418
int32_t SetManualRenderingMode(bool enable);
290419
int32_t ManualRenderingMode(bool* enabled);
291420

@@ -313,85 +442,15 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
313442
int32_t InitAndStartRecording();
314443

315444
private:
316-
struct EngineStateUpdate {
317-
EngineState prev;
318-
EngineState next;
319-
320-
bool HasNoChanges() const { return prev == next; }
321-
322-
bool DidEnableOutput() const { return !prev.IsOutputEnabled() && next.IsOutputEnabled(); }
323-
324-
bool DidEnableInput() const { return !prev.IsInputEnabled() && next.IsInputEnabled(); }
325-
326-
bool DidDisableOutput() const { return prev.IsOutputEnabled() && !next.IsOutputEnabled(); }
327-
328-
bool DidDisableInput() const { return prev.IsInputEnabled() && !next.IsInputEnabled(); }
329-
330-
bool DidAnyEnable() const { return DidEnableOutput() || DidEnableInput(); }
331-
332-
bool DidAnyDisable() const { return DidDisableOutput() || DidDisableInput(); }
333-
334-
bool DidBeginInterruption() const { return !prev.is_interrupted && next.is_interrupted; }
335-
336-
bool DidEndInterruption() const { return prev.is_interrupted && !next.is_interrupted; }
337-
338-
bool DidUpdateAudioGraph() const {
339-
return (prev.IsInputEnabled() != next.IsInputEnabled()) ||
340-
(prev.IsOutputEnabled() != next.IsOutputEnabled());
341-
}
342-
343-
bool DidUpdateVoiceProcessingEnabled() const {
344-
return prev.voice_processing_enabled != next.voice_processing_enabled;
345-
}
346-
347-
bool DidUpdateOutputDevice() const { return prev.output_device_id != next.output_device_id; }
348-
349-
bool DidUpdateInputDevice() const { return prev.input_device_id != next.input_device_id; }
350-
351-
bool DidUpdateDefaultOutputDevice() const {
352-
return prev.default_output_device_id != next.default_output_device_id;
353-
}
354-
355-
bool DidUpdateDefaultInputDevice() const {
356-
return prev.default_input_device_id != next.default_input_device_id;
357-
}
358-
359-
bool DidUpdateMuteMode() const { return prev.mute_mode != next.mute_mode; }
360-
361-
bool IsEngineRestartRequired() const {
362-
return DidUpdateAudioGraph() || DidUpdateOutputDevice() || DidUpdateInputDevice() ||
363-
// Voice processing enable state updates
364-
DidUpdateVoiceProcessingEnabled() ||
365-
// Handle default device updates
366-
(DidUpdateDefaultOutputDevice() && next.IsOutputDefaultDevice()) ||
367-
(DidUpdateDefaultInputDevice() && next.IsInputDefaultDevice());
368-
}
369-
370-
// Special case to re-create engine when switching from Speaker & Mic ->
371-
// Speaker only.
372-
bool IsEngineRecreateRequired() const {
373-
return (prev.IsOutputEnabled() && next.IsOutputEnabled()) &&
374-
(prev.IsInputEnabled() && !next.IsInputEnabled());
375-
}
376-
377-
bool DidEnableManualRenderingMode() const {
378-
return prev.render_mode != RenderMode::Manual && next.render_mode == RenderMode::Manual;
379-
}
380-
381-
bool DidEnableDeviceRenderingMode() const {
382-
return prev.render_mode != RenderMode::Device && next.render_mode == RenderMode::Device;
383-
}
384-
};
385-
386445
EngineState engine_state_ RTC_GUARDED_BY(thread_);
387446

388447
AVAudioInputNode* InputNode();
389448
AVAudioOutputNode* OutputNode();
390449

391450
bool IsMicrophonePermissionGranted();
392451
int32_t ModifyEngineState(std::function<EngineState(EngineState)> state_transform);
393-
int32_t ApplyDeviceEngineState(EngineStateUpdate state);
394-
int32_t ApplyManualEngineState(EngineStateUpdate state);
452+
int32_t ApplyDeviceEngineState(EngineStateTransition state);
453+
int32_t ApplyManualEngineState(EngineStateTransition state);
395454

396455
// AudioEngine observer methods. May be called from any thread.
397456
void ReconfigureEngine(bool is_required);
@@ -430,6 +489,7 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
430489
bool initialized_ RTC_GUARDED_BY(thread_);
431490

432491
AudioDeviceObserver* observer_ RTC_GUARDED_BY(thread_);
492+
EngineObserver* engine_observer_ RTC_GUARDED_BY(thread_);
433493

434494
#if defined(WEBRTC_IOS)
435495
// Audio interruption observer instance.

0 commit comments

Comments
 (0)