Skip to content

Commit 86c4c5f

Browse files
committed
Update to 137.0.46 and improve stereoPlayout control
1 parent 55ac2f6 commit 86c4c5f

File tree

4 files changed

+69
-86
lines changed

4 files changed

+69
-86
lines changed

Sources/StreamVideo/Utils/AudioSession/AudioDeviceModule/AudioDeviceModule.swift

Lines changed: 51 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -200,29 +200,27 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
200200
.store(in: disposableBag)
201201

202202
source.manualRestoreVoiceProcessingOnMono = true
203-
(source as? RTCAudioDeviceModule)?.setRecordingAlwaysPreparedMode(false)
203+
(source as? RTCAudioDeviceModule)?.setRecordingAlwaysPreparedMode(true)
204204
}
205205

206206
// MARK: - Recording
207207

208-
func startPlayout() throws {
209-
try throwingExecution("Unable to start playout") {
210-
source.initAndStartPlayout()
208+
func setPlayout(_ isActive: Bool) throws {
209+
try RetriableTask.run(iterations: 3) {
210+
try throwingExecution("Unable to start playout") {
211+
if isActive {
212+
return source.initAndStartPlayout()
213+
} else {
214+
return source.stopPlayout()
215+
}
216+
}
211217
}
212218
}
213219

214220
/// Enables or disables recording on the wrapped audio device module.
215221
/// - Parameter isEnabled: When `true` recording starts, otherwise stops.
216222
/// - Throws: `ClientError` when the underlying module reports a failure.
217223
func setRecording(_ isEnabled: Bool) throws {
218-
defer {
219-
log.throwing("Unable to start playout", subsystems: .audioSession) {
220-
try throwingExecution("setReocording defer") {
221-
source.initAndStartPlayout()
222-
}
223-
}
224-
}
225-
226224
guard isEnabled != isRecording else {
227225
return
228226
}
@@ -254,22 +252,12 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
254252
/// - Parameter isMuted: `true` to mute the microphone, `false` to unmute.
255253
/// - Throws: `ClientError` when the underlying module reports a failure.
256254
func setMuted(_ isMuted: Bool) throws {
257-
defer {
258-
log.throwing("Unable to start playout", subsystems: .audioSession) {
259-
try throwingExecution("setMuted defer") {
260-
source.initAndStartPlayout()
261-
}
262-
}
263-
}
264-
265255
guard isMuted != isMicrophoneMuted else {
266256
return
267257
}
268258

269-
if isStereoPlayoutEnabled {
270-
try throwingExecution("Unable to stop playout") {
271-
source.stopPlayout()
272-
}
259+
if !isMuted {
260+
_ = source.initAndStartRecording()
273261
}
274262

275263
try throwingExecution("Unable to setMicrophoneMuted:\(isMuted)") {
@@ -284,53 +272,8 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
284272
function: StaticString = #function,
285273
line: UInt = #line
286274
) throws {
287-
defer {
288-
log.throwing("Unable to start playout", subsystems: .audioSession) {
289-
try throwingExecution("setStereoPlayoutEnabled defer") {
290-
source.initAndStartPlayout()
291-
}
292-
}
293-
}
294-
/// We explicitelly avoid checking the current state of isStereoPlayoutEnabled as there are case
295-
/// where the value may be true but playout isn't stereo and a restart is required.
296-
let currentVoiceProcessingEnabled = source.isVoiceProcessingEnabled
297-
let currentVoiceProcessingBypassed = source.isVoiceProcessingBypassed
298-
299-
func onFailureReset() {
300-
_ = source.setVoiceProcessingEnabled(currentVoiceProcessingEnabled)
301-
_ = source.setVoiceProcessingBypassed(currentVoiceProcessingBypassed)
302-
_ = source.setVoiceProcessingAGCEnabled(currentVoiceProcessingEnabled)
303-
try? startPlayout()
304-
}
305-
306-
/// To enable stereoPlayout we need to do the following in the order mentioned below:
307-
/// 1. disable voice-processing
308-
/// 2. disable voice-processing-agc
309-
/// 3. set voice-processing-bypassed to `true`
310-
/// 4. set stereo-playout to `true`
311-
///
312-
/// To disable stereoPlayout we need to do the following in the order mentioned below:
313-
/// 1. set stereo-playout to `false`
314-
/// 2. set voice-processing-bypassed to `false`
315-
/// 3. enable voice-processing
316-
/// 4. enable voice-processing-agc
317-
318-
_ = source.stopPlayout()
319-
do {
320-
if isEnabled {
321-
try throwingExecution("Failed to disable VoiceProcessing.") { source.setVoiceProcessingEnabled(false) }
322-
try throwingExecution("Failed to disable VoiceProcessingAGC.") { source.setVoiceProcessingAGCEnabled(false) }
323-
try throwingExecution("Failed to enable VoiceProcessing bypass.") { source.setVoiceProcessingBypassed(true) }
324-
try throwingExecution("Failed to enable Stereo Playout.") { source.setStereoPlayoutEnabled(true) }
325-
} else {
326-
try throwingExecution("Failed to disable Stereo Playout.") { source.setStereoPlayoutEnabled(false) }
327-
try throwingExecution("Failed to disable VoiceProcessing bypass.") { source.setVoiceProcessingBypassed(false) }
328-
try throwingExecution("Failed to enable VoiceProcessing.") { source.setVoiceProcessingEnabled(true) }
329-
try throwingExecution("Failed to enable VoiceProcessingAGC.") { source.setVoiceProcessingAGCEnabled(true) }
330-
}
331-
} catch {
332-
onFailureReset()
333-
throw error
275+
try throwingExecution("Failed to enable Stereo Playout.") {
276+
source.setStereoPlayoutEnabled(isEnabled)
334277
}
335278

336279
guard source.isStereoPlayoutEnabled != isEnabled else {
@@ -341,7 +284,6 @@ final class AudioDeviceModule: NSObject, RTCAudioDeviceModuleDelegate, Encodable
341284
return
342285
}
343286

344-
onFailureReset()
345287
throw ClientError(
346288
"Failed to"
347289
+ " setStereoPlayoutEnabled:\(isEnabled)."
@@ -621,3 +563,40 @@ extension AVAudioEngine {
621563
return "\(asbd.mChannelsPerFrame) ch @ \(asbd.mSampleRate) Hz"
622564
}
623565
}
566+
567+
enum RetriableTask {
568+
static func run(
569+
iterations: Int,
570+
operation: () throws -> Void
571+
) throws {
572+
try execute(
573+
currentIteration: 0,
574+
iterations: iterations,
575+
operation: operation
576+
)
577+
}
578+
579+
private static func execute(
580+
currentIteration: Int,
581+
iterations: Int,
582+
operation: () throws -> Void
583+
) throws {
584+
do {
585+
return try operation()
586+
} catch {
587+
if currentIteration < iterations - 1 {
588+
do {
589+
return try execute(
590+
currentIteration: currentIteration + 1,
591+
iterations: iterations,
592+
operation: operation
593+
)
594+
} catch {
595+
throw error
596+
}
597+
} else {
598+
throw error
599+
}
600+
}
601+
}
602+
}

Sources/StreamVideo/Utils/AudioSession/RTCAudioStore/Namespace/Effects/RTCAudioStore+StereoPlayoutEffect.swift

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,21 @@ extension RTCAudioStore {
4545
return
4646
}
4747

48-
Publishers
49-
.CombineLatest(
50-
audioDeviceModule
51-
.isStereoPlayoutAvailablePublisher
52-
.removeDuplicates(),
53-
statePublisher
54-
.map(\.isMicrophoneMuted)
55-
.removeDuplicates()
56-
)
57-
.map { $0 && $1 }
48+
audioDeviceModule
49+
.isStereoPlayoutAvailablePublisher
50+
.removeDuplicates()
5851
.debounce(for: .seconds(1), scheduler: processingQueue)
5952
.receive(on: processingQueue)
6053
.sink { [weak self, weak audioDeviceModule] isPlayoutAvailable in
61-
self?.dispatcher?.dispatch(.stereo(.setPlayoutAvailable(isPlayoutAvailable)))
54+
self?.dispatcher?.dispatch(
55+
.stereo(
56+
.setPlayoutAvailable(isPlayoutAvailable)
57+
)
58+
)
6259
log.throwing(subsystems: .audioSession) {
63-
try audioDeviceModule?.setStereoPlayoutEnabled(isPlayoutAvailable)
60+
try audioDeviceModule?.setStereoPlayoutEnabled(
61+
isPlayoutAvailable
62+
)
6463
}
6564
}
6665
.store(in: disposableBag)

Sources/StreamVideo/Utils/AudioSession/RTCAudioStore/Namespace/Middleware/RTCAudioStore+AudioDeviceModuleMiddleware.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ extension RTCAudioStore {
2525
line: UInt
2626
) {
2727
switch action {
28+
case .setActive(let value):
29+
log.throwing(subsystems: .audioSession) {
30+
try state.audioDeviceModule?.setPlayout(value)
31+
}
32+
2833
case .setInterrupted(let value):
2934
if let audioDeviceModule = state.audioDeviceModule {
3035
log.throwing(
@@ -154,7 +159,7 @@ extension RTCAudioStore {
154159
return
155160
}
156161

157-
try audioDeviceModule.startPlayout()
162+
try audioDeviceModule.setPlayout(state.isActive)
158163

159164
audioDeviceModule
160165
.isRecordingPublisher

StreamVideo.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11492,7 +11492,7 @@
1149211492
repositoryURL = "https://github.com/GetStream/stream-video-swift-webrtc.git";
1149311493
requirement = {
1149411494
kind = exactVersion;
11495-
version = 137.0.45;
11495+
version = 137.0.46;
1149611496
};
1149711497
};
1149811498
40F445C32A9E1D91004BE3DA /* XCRemoteSwiftPackageReference "stream-chat-swift-test-helpers" */ = {

0 commit comments

Comments
 (0)