Skip to content

Conversation

ipavlidakis
Copy link
Contributor

🔗 Issue Links

Resolves https://linear.app/stream/issue/VID-798/disable-ios-audio-processing-by-exposing-sethifienabled

🎯 Goal

Allow enabling/disabling HiFi audio.

🛠 Implementation

Provide a detailed description of the implementation and explain your decisions if you find them relevant.

🎨 Showcase

Add relevant screenshots and/or videos/gifs to easily see what this PR changes, if applicable.

Before After
img img

🧪 Manual Testing Notes

Explain how this change can be tested manually, if applicable.

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change follows zero ⚠️ policy (required)
  • This change should receive manual QA
  • Changelog is updated with client-facing changes
  • New code is covered by unit tests
  • Comparison screenshots added for visual changes
  • Affected documentation updated (tutorial, CMS)

@ipavlidakis ipavlidakis self-assigned this Aug 22, 2025
@ipavlidakis ipavlidakis requested a review from a team as a code owner August 22, 2025 10:28
@ipavlidakis ipavlidakis added the enhancement New feature or request label Aug 22, 2025
@ipavlidakis ipavlidakis requested review from Copilot and removed request for a team August 22, 2025 10:28
Copy link

2 Warnings
⚠️ Please be sure to complete the Contributor Checklist in the Pull Request description
⚠️ Big PR

Generated by 🚫 Danger

Copy link

github-actions bot commented Aug 22, 2025

Public Interface

 open class StreamAudioFilterProcessingModule: RTCDefaultAudioProcessingModule, AudioProcessingModule, @unchecked Sendable  
-   public var activeAudioFilter: AudioFilter?
+   public var isHiFiEnabled: Bool
-   
+   public var activeAudioFilter: AudioFilter?
- 
+   
-   public init(config: RTCAudioProcessingConfig? = nil,capturePostProcessingDelegate: AudioFilterCapturePostProcessingModule = StreamAudioFilterCapturePostProcessingModule(),renderPreProcessingDelegate: RTCAudioCustomProcessingDelegate? = nil)
+ 
-   
+   public init(config: RTCAudioProcessingConfig? = nil,capturePostProcessingDelegate: AudioFilterCapturePostProcessingModule = StreamAudioFilterCapturePostProcessingModule(),renderPreProcessingDelegate: RTCAudioCustomProcessingDelegate? = nil)
- 
+   
-   override public func apply(_ config: RTCAudioProcessingConfig)
+ 
-   public func setAudioFilter(_ filter: AudioFilter?)
+   override public func apply(_ config: RTCAudioProcessingConfig)
+   public func setAudioFilter(_ filter: AudioFilter?)

 public final class MicrophoneManager: ObservableObject, CallSettingsManager, @unchecked Sendable  
-   public func disable()async throws
+   public func disable()async throws 
+   public func setHiFiEnabled(_ isEnabled: Bool)async

 open class StreamAudioFilterCapturePostProcessingModule: NSObject, AudioFilterCapturePostProcessingModule, @unchecked Sendable  
-   public private var audioFilter: AudioFilter?
+   public var isHiFiEnabled: Bool
-   public private var sampleRate: Int
+   public private var audioFilter: AudioFilter?
-   public private var channels: Int
+   public private var sampleRate: Int
-   
+   public private var channels: Int
- 
+   
-   override public init()
+ 
-   
+   override public init()
- 
+   
-   open func setAudioFilter(_ audioFilter: AudioFilter?)
+ 
-   open func audioProcessingInitialize(sampleRate sampleRateHz: Int,channels: Int)
+   open func setAudioFilter(_ audioFilter: AudioFilter?)
-   open func audioProcessingProcess(audioBuffer: RTCAudioBuffer)
+   open func audioProcessingInitialize(sampleRate sampleRateHz: Int,channels: Int)
-   open func audioProcessingRelease()
+   open func audioProcessingProcess(audioBuffer: RTCAudioBuffer)
+   open func audioProcessingRelease()

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements HiFi (High-Fidelity) audio support by exposing audio media constraints configuration throughout the WebRTC stack. The implementation allows disabling iOS audio processing features like echo cancellation and noise suppression to preserve original audio quality.

Key changes:

  • Added HiFi audio constraints that disable audio processing features for high-quality audio capture
  • Introduced a PeerConnectionFactory protocol to abstract peer connection creation and support better testing
  • Exposed setHiFiEnabled API through MicrophoneManager for public consumption

Reviewed Changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Sources/StreamVideo/WebRTC/DefaultRTCMediaConstraints.swift Added HiFi audio constraints with disabled processing features
Sources/StreamVideo/CallSettings/MicrophoneManager.swift Added public setHiFiEnabled API for controlling HiFi audio mode
Sources/StreamVideo/Controllers/CallController.swift Added internal setHiFiEnabled method that delegates to WebRTC coordinator
Sources/StreamVideo/WebRTC/v2/WebRTCCoordinator.swift Added setHiFiEnabled method to configure audio constraints
Sources/StreamVideo/WebRTC/v2/WebRTCStateAdapter.swift Added audioMediaConstraints property and setAudioMediaConstraints method
Sources/StreamVideo/WebRTC/PeerConnectionFactory/PeerConnectionFactory.swift Added PeerConnectionFactory protocol for better abstraction
StreamVideoTests/Mock/MockPeerConnectionFactory.swift Created MockPeerConnectionFactory implementing the new protocol

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@@ -82,6 +82,9 @@ actor WebRTCStateAdapter: ObservableObject, StreamAudioSessionAdapterDelegate {

// Various private and internal properties.
private(set) var initialCallSettings: CallSettings?
/// The current audio media constraints used for audio track creation.
/// Defaults to standard constraints with audio processing enabled.
Copy link
Preview

Copilot AI Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should clarify that this property affects only newly created audio tracks, not existing ones. Consider adding a note about when constraints are applied.

Suggested change
/// Defaults to standard constraints with audio processing enabled.
/// Note: This property only affects newly created audio tracks; changing it does not impact existing tracks.
/// Constraints are applied only at the time an audio track is created. Defaults to standard constraints with audio processing enabled.

Copilot uses AI. Check for mistakes.

@@ -464,6 +490,68 @@ final class WebRTCStateAdapter_Tests: XCTestCase, @unchecked Sendable {
XCTAssertEqual(mockPublisher.timesCalled(.beginScreenSharing), 0)
}

func test_configurePeerConnections_defaultAudioMediaConstraints_publisherWasConfiguredWithCorrectAudioeMediaConstraints(
Copy link
Preview

Copilot AI Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in the function name: 'AudioeMediaConstraints' should be 'AudioMediaConstraints'.

Suggested change
func test_configurePeerConnections_defaultAudioMediaConstraints_publisherWasConfiguredWithCorrectAudioeMediaConstraints(
func test_configurePeerConnections_defaultAudioMediaConstraints_publisherWasConfiguredWithCorrectAudioMediaConstraints(

Copilot uses AI. Check for mistakes.

XCTAssertEqual(publisherRecordedInput.audioMediaConstraints, .defaultConstraints)
}

func test_configurePeerConnections_HiFiAudioMediaConstraints_publisherWasConfiguredWithCorrectAudioeMediaConstraints(
Copy link
Preview

Copilot AI Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in the function name: 'AudioeMediaConstraints' should be 'AudioMediaConstraints'.

Suggested change
func test_configurePeerConnections_HiFiAudioMediaConstraints_publisherWasConfiguredWithCorrectAudioeMediaConstraints(
func test_configurePeerConnections_HiFiAudioMediaConstraints_publisherWasConfiguredWithCorrectAudioMediaConstraints(

Copilot uses AI. Check for mistakes.

@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented Aug 22, 2025

SDK Size

title develop branch diff status
StreamVideo 8.19 MB 8.21 MB +18 KB 🟢
StreamVideoSwiftUI 2.29 MB 2.29 MB 0 KB 🟢
StreamVideoUIKit 2.41 MB 2.41 MB 0 KB 🟢
StreamWebRTC 9.85 MB 9.85 MB 0 KB 🟢

Copy link

@ipavlidakis ipavlidakis marked this pull request as draft August 22, 2025 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants