From 16e7025255a9af2b9152adbb6780068560553613 Mon Sep 17 00:00:00 2001 From: Vlaho Poluta Date: Thu, 23 Nov 2023 09:44:44 +0100 Subject: [PATCH] Enabling multiple output formats to be used at the same time (#2872) * Expose output format to be able to have multiple multiple formats * Fix hound reported issue * Fix failing test by lazy reading of Settings.audioFormat --- .../AudioKit/Internals/Engine/AudioEngine.swift | 14 ++++++++++---- Sources/AudioKit/Nodes/Mixing/MatrixMixer.swift | 3 +++ Sources/AudioKit/Nodes/Mixing/Mixer.swift | 3 +++ Sources/AudioKit/Nodes/Mixing/Mixer3D.swift | 14 +++++++------- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Sources/AudioKit/Internals/Engine/AudioEngine.swift b/Sources/AudioKit/Internals/Engine/AudioEngine.swift index d0980a9ef8..78c56d17cf 100644 --- a/Sources/AudioKit/Internals/Engine/AudioEngine.swift +++ b/Sources/AudioKit/Internals/Engine/AudioEngine.swift @@ -69,6 +69,10 @@ public class AudioEngine { /// Main mixer at the end of the signal chain public private(set) var mainMixerNode: Mixer? + /// Output format to be used when making connections to the output + public var outputAudioFormat: AVAudioFormat? + private var outputFormat: AVAudioFormat { outputAudioFormat ?? Settings.audioFormat } + /// Input node mixer public class InputNode: Mixer { var isNotConnected = true @@ -122,7 +126,8 @@ public class AudioEngine { // has the sample rate changed? if let currentSampleRate = mainMixerNode?.avAudioNode.outputFormat(forBus: 0).sampleRate, - currentSampleRate != Settings.sampleRate + let currentChannelCount = mainMixerNode?.avAudioNode.outputFormat(forBus: 0).channelCount, + (currentSampleRate != outputFormat.sampleRate || currentChannelCount != outputFormat.channelCount) { Log("Sample Rate has changed, creating new mainMixerNode at", Settings.sampleRate) removeEngineMixer() @@ -139,15 +144,16 @@ public class AudioEngine { } // simulate the AVAudioEngine.mainMixerNode, but create it ourselves to ensure the - // correct sample rate is used from Settings.audioFormat + // correct sample rate is used from outputFormat (default: Settings.audioFormat) private func createEngineMixer() { guard mainMixerNode == nil else { return } let mixer = Mixer(name: "AudioKit Engine Mixer") + mixer.outputFormat = outputFormat avEngine.attach(mixer.avAudioNode) avEngine.connect(mixer.avAudioNode, to: avEngine.outputNode, - format: Settings.audioFormat) + format: outputFormat) mainMixerNode = mixer } @@ -201,7 +207,7 @@ public class AudioEngine { do { avEngine.reset() try avEngine.enableManualRenderingMode(.offline, - format: Settings.audioFormat, + format: outputFormat, maximumFrameCount: maximumFrameCount) try start() } catch let err { diff --git a/Sources/AudioKit/Nodes/Mixing/MatrixMixer.swift b/Sources/AudioKit/Nodes/Mixing/MatrixMixer.swift index 9c096f9308..3ddb0b7b80 100644 --- a/Sources/AudioKit/Nodes/Mixing/MatrixMixer.swift +++ b/Sources/AudioKit/Nodes/Mixing/MatrixMixer.swift @@ -33,6 +33,9 @@ public class MatrixMixer: Node { public var connections: [Node] { inputs } public var avAudioNode: AVAudioNode { unit } + /// Output format to be used when making connections from this node + public var outputFormat = Settings.audioFormat + public let unit = instantiate( componentDescription: AudioComponentDescription( diff --git a/Sources/AudioKit/Nodes/Mixing/Mixer.swift b/Sources/AudioKit/Nodes/Mixing/Mixer.swift index fa97e0bfb9..8d4541af09 100644 --- a/Sources/AudioKit/Nodes/Mixing/Mixer.swift +++ b/Sources/AudioKit/Nodes/Mixing/Mixer.swift @@ -15,6 +15,9 @@ public class Mixer: Node, NamedNode { /// Underlying AVAudioNode public var avAudioNode: AVAudioNode + /// Output format to be used when making connections from this node + public var outputFormat = Settings.audioFormat + /// Name of the node open var name = "(unset)" diff --git a/Sources/AudioKit/Nodes/Mixing/Mixer3D.swift b/Sources/AudioKit/Nodes/Mixing/Mixer3D.swift index bbc8731663..7bcf2bcc32 100644 --- a/Sources/AudioKit/Nodes/Mixing/Mixer3D.swift +++ b/Sources/AudioKit/Nodes/Mixing/Mixer3D.swift @@ -19,14 +19,14 @@ public class Mixer3D: Mixer { fileprivate let mixerAU = AVAudioMixerNode() - public var outputFormat: AVAudioFormat { - guard let monoFormat = AVAudioFormat( + override init(volume: AUValue = 1.0, name: String? = nil) { + super.init(volume: volume, name: name) + + outputFormat = AVAudioFormat( standardFormatWithSampleRate: Settings.audioFormat.sampleRate, - channels: 1) else { - return Settings.audioFormat - } - return monoFormat - } + channels: 1 + ) ?? Settings.audioFormat + } // MARK: - 3D Mixing Properties