@@ -26,8 +26,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
2626 enum Event : Equatable , CustomStringConvertible {
2727 case speechActivityStarted
2828 case speechActivityEnded
29- case didUpdateStereoPlayoutAvailable( Bool )
30- case didUpdateStereoPlayoutEnabled( Bool )
3129 case didCreateAudioEngine( AVAudioEngine )
3230 case willEnableAudioEngine( AVAudioEngine , isPlayoutEnabled: Bool , isRecordingEnabled: Bool )
3331 case willStartAudioEngine( AVAudioEngine , isPlayoutEnabled: Bool , isRecordingEnabled: Bool )
@@ -45,12 +43,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
4543 case . speechActivityEnded:
4644 return " .speechActivityEnded "
4745
48- case . didUpdateStereoPlayoutAvailable( let value) :
49- return " .didUpdateStereoPlayoutAvailable( \( value) ) "
50-
51- case . didUpdateStereoPlayoutEnabled( let value) :
52- return " .didUpdateStereoPlayoutEnabled( \( value) ) "
53-
5446 case . didCreateAudioEngine( let engine) :
5547 return " .didCreateAudioEngine( \( engine) ) "
5648
@@ -94,10 +86,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
9486 var isStereoPlayoutEnabled : Bool { isStereoPlayoutEnabledSubject. value }
9587 var isStereoPlayoutEnabledPublisher : AnyPublisher < Bool , Never > { isStereoPlayoutEnabledSubject. eraseToAnyPublisher ( ) }
9688
97- private let isStereoPlayoutAvailableSubject : CurrentValueSubject < Bool , Never >
98- var isStereoPlayoutAvailable : Bool { isStereoPlayoutAvailableSubject. value }
99- var isStereoPlayoutAvailablePublisher : AnyPublisher < Bool , Never > { isStereoPlayoutAvailableSubject. eraseToAnyPublisher ( ) }
100-
10189 private let isVoiceProcessingBypassedSubject : CurrentValueSubject < Bool , Never >
10290 var isVoiceProcessingBypassed : Bool { isVoiceProcessingBypassedSubject. value }
10391 var isVoiceProcessingBypassedPublisher : AnyPublisher < Bool , Never > { isVoiceProcessingBypassedSubject. eraseToAnyPublisher ( ) }
@@ -129,11 +117,10 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
129117 " isPlaying: \( isPlaying) " +
130118 " , isRecording: \( isRecording) " +
131119 " , isMicrophoneMuted: \( isMicrophoneMuted) " +
132- " , isStereoPlayoutEnabled: \( source. isStereoPlayoutEnabled) " +
133- " , isStereoPlayoutAvailable: \( source. isStereoPlayoutAvailable) " +
134- " , isVoiceProcessingBypassed: \( source. isVoiceProcessingBypassed) " +
135- " , isVoiceProcessingEnabled: \( source. isVoiceProcessingEnabled) " +
136- " , isVoiceProcessingAGCEnabled: \( source. isVoiceProcessingAGCEnabled) " +
120+ " , isStereoPlayoutEnabled: \( isStereoPlayoutEnabled) " +
121+ " , isVoiceProcessingBypassed: \( isVoiceProcessingBypassed) " +
122+ " , isVoiceProcessingEnabled: \( isVoiceProcessingEnabled) " +
123+ " , isVoiceProcessingAGCEnabled: \( isVoiceProcessingAGCEnabled) " +
137124 " , audioLevel: \( audioLevel) " +
138125 " , source: \( source) " +
139126 " , engineOutput: \( engine? . outputDescription ?? " - " ) " +
@@ -153,7 +140,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
153140 self . isPlayingSubject = . init( isPlaying)
154141 self . isRecordingSubject = . init( isRecording)
155142 self . isMicrophoneMutedSubject = . init( isMicrophoneMuted)
156- self . isStereoPlayoutAvailableSubject = . init( source. isStereoPlayoutAvailable)
157143 self . isStereoPlayoutEnabledSubject = . init( source. isStereoPlayoutEnabled)
158144 self . isVoiceProcessingBypassedSubject = . init( source. isVoiceProcessingBypassed)
159145 self . isVoiceProcessingEnabledSubject = . init( source. isVoiceProcessingEnabled)
@@ -198,13 +184,39 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
198184 . receive ( on: dispatchQueue)
199185 . sink { [ weak self] in self ? . isVoiceProcessingAGCEnabledSubject. send ( $0) }
200186 . store ( in: disposableBag)
201-
202- source. manualRestoreVoiceProcessingOnMono = true
203- ( source as? RTCAudioDeviceModule ) ? . setRecordingAlwaysPreparedMode ( true )
204187 }
205188
206189 // MARK: - Recording
207190
191+ func terminate( ) {
192+ _ = source. terminate ( )
193+ }
194+
195+ func setStereoPlayoutPreference( _ isPreferred: Bool ) {
196+ /// - Important: `.voiceProcessing` requires VP to be enabled in order to mute and
197+ /// `.restartEngine` rebuilds the whole graph. Each of them has different issues:
198+ /// - `.voiceProcessing`: as it requires VP to be enabled in order to mute/unmute that
199+ /// means that for outputs where VP is disabled (e.g. stereo) we cannot mute/unmute.
200+ /// - `.restartEngine`: rebuilds the whole graph and requires explicit calling of
201+ /// `initAndStartRecording` .
202+ ( source as? RTCAudioDeviceModule ) ? . setMuteMode (
203+ isPreferred ? . inputMixer : . voiceProcessing
204+ )
205+ /// - Important: We can probably set this one to false when the user doesn't have
206+ /// sendAudio capability.
207+ ( source as? RTCAudioDeviceModule ) ? . setRecordingAlwaysPreparedMode ( true )
208+ source. prefersStereoPlayout = isPreferred
209+ source. setManualRestoreVoiceProcessingOnMono ( isPreferred)
210+
211+ let isMuted = isMicrophoneMuted
212+
213+ _ = source. stopRecording ( )
214+ _ = source. initAndStartRecording ( )
215+ if isMuted {
216+ _ = source. setMicrophoneMuted ( isMuted)
217+ }
218+ }
219+
208220 func setPlayout( _ isActive: Bool ) throws {
209221 try RetriableTask . run ( iterations: 3 ) {
210222 try throwingExecution ( " Unable to start playout " ) {
@@ -256,45 +268,15 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
256268 return
257269 }
258270
259- if !isMuted {
260- _ = source. initAndStartRecording ( )
261- }
262-
263271 try throwingExecution ( " Unable to setMicrophoneMuted: \( isMuted) " ) {
264272 source. setMicrophoneMuted ( isMuted)
265273 }
274+
266275 isMicrophoneMutedSubject. send ( isMuted)
267276 }
268277
269- func setStereoPlayoutEnabled(
270- _ isEnabled: Bool ,
271- file: StaticString = #file,
272- function: StaticString = #function,
273- line: UInt = #line
274- ) throws {
275- try throwingExecution ( " Failed to enable Stereo Playout. " ) {
276- source. setStereoPlayoutEnabled ( isEnabled)
277- }
278-
279- guard source. isStereoPlayoutEnabled != isEnabled else {
280- log. debug (
281- " Stereo playout has been \( isEnabled ? " activated " : " deactivated " ) . " ,
282- subsystems: . audioSession
283- )
284- return
285- }
286-
287- throw ClientError (
288- " Failed to "
289- + " setStereoPlayoutEnabled: \( isEnabled) . "
290- + " ( "
291- + " isVoiceProcessingEnabled: \( source. isVoiceProcessingEnabled) "
292- + " , isVoiceProcessingBypassed: \( source. isVoiceProcessingBypassed) "
293- + " , isVoiceProcessingAGCEnabled: \( source. isVoiceProcessingAGCEnabled) "
294- + " ) " ,
295- file,
296- line
297- )
278+ func refreshStereoPlayoutState( ) {
279+ source. refreshStereoPlayoutState ( )
298280 }
299281
300282 // MARK: - RTCAudioDeviceModuleDelegate
@@ -313,38 +295,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
313295 }
314296 }
315297
316- func audioDeviceModule(
317- _ audioDeviceModule: RTCAudioDeviceModule ,
318- isStereoPlayoutAvailable: Bool
319- ) {
320- guard isStereoPlayoutAvailable != self . isStereoPlayoutAvailable else {
321- return
322- }
323-
324- isStereoPlayoutAvailableSubject. send ( isStereoPlayoutAvailable)
325- subject. send ( . didUpdateStereoPlayoutAvailable( isStereoPlayoutAvailable) )
326- log. debug (
327- " AudioDeviceModule updated isStereoPlayoutAvailable: \( isStereoPlayoutAvailable) . " ,
328- subsystems: . audioSession
329- )
330- }
331-
332- func audioDeviceModule(
333- _ audioDeviceModule: RTCAudioDeviceModule ,
334- isStereoPlayoutEnabled: Bool
335- ) {
336- guard isStereoPlayoutEnabled != self . isStereoPlayoutEnabled else {
337- return
338- }
339-
340- isStereoPlayoutEnabledSubject. send ( isStereoPlayoutEnabled && isStereoPlayoutAvailable)
341- subject. send ( . didUpdateStereoPlayoutEnabled( isStereoPlayoutEnabled && isStereoPlayoutAvailable) )
342- log. debug (
343- " AudioDeviceModule updated isStereoPlayoutEnabled: \( isStereoPlayoutEnabled && isStereoPlayoutAvailable) . " ,
344- subsystems: . audioSession
345- )
346- }
347-
348298 func audioDeviceModule(
349299 _ audioDeviceModule: RTCAudioDeviceModule ,
350300 didCreateEngine engine: AVAudioEngine
@@ -387,6 +337,7 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
387337 )
388338 isPlayingSubject. send ( isPlayoutEnabled)
389339 isRecordingSubject. send ( isRecordingEnabled)
340+
390341 return Constant . successResult
391342 }
392343
@@ -403,7 +354,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
403354 isRecordingEnabled: isRecordingEnabled
404355 )
405356 )
406- audioLevelsAdapter. uninstall ( on: 0 )
407357 isPlayingSubject. send ( isPlayoutEnabled)
408358 isRecordingSubject. send ( isRecordingEnabled)
409359 return Constant . successResult
@@ -422,7 +372,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
422372 isRecordingEnabled: isRecordingEnabled
423373 )
424374 )
425- audioLevelsAdapter. uninstall ( on: 0 )
426375 isPlayingSubject. send ( isPlayoutEnabled)
427376 isRecordingSubject. send ( isRecordingEnabled)
428377 return Constant . successResult
@@ -488,11 +437,20 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
488437 // No-op
489438 }
490439
440+ func audioDeviceModule(
441+ _ module: RTCAudioDeviceModule ,
442+ didUpdateAudioProcessingState state: RTCAudioProcessingState
443+ ) {
444+ isVoiceProcessingEnabledSubject. send ( state. voiceProcessingEnabled)
445+ isVoiceProcessingBypassedSubject. send ( state. voiceProcessingBypassed)
446+ isVoiceProcessingAGCEnabledSubject. send ( state. voiceProcessingAGCEnabled)
447+ isStereoPlayoutEnabledSubject. send ( state. stereoPlayoutEnabled)
448+ }
449+
491450 private enum CodingKeys : String , CodingKey {
492451 case isPlaying
493452 case isRecording
494453 case isMicrophoneMuted
495- case isStereoPlayoutAvailable
496454 case isStereoPlayoutEnabled
497455 case isVoiceProcessingBypassed
498456 case isVoiceProcessingEnabled
@@ -506,7 +464,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
506464 try container. encode ( isPlaying, forKey: . isPlaying)
507465 try container. encode ( isRecording, forKey: . isRecording)
508466 try container. encode ( isMicrophoneMuted, forKey: . isMicrophoneMuted)
509- try container. encode ( isStereoPlayoutAvailable, forKey: . isStereoPlayoutAvailable)
510467 try container. encode ( isStereoPlayoutEnabled, forKey: . isStereoPlayoutEnabled)
511468 try container. encode ( isVoiceProcessingBypassed, forKey: . isVoiceProcessingBypassed)
512469 try container. encode ( isVoiceProcessingEnabled, forKey: . isVoiceProcessingEnabled)
0 commit comments