gpt4 book ai didi

ios - 用户切换耳机时如何更改 AVAudioPlayerNode 格式

转载 作者:行者123 更新时间:2023-12-01 16:21:24 25 4
gpt4 key购买 nike

我需要播放根据输出设备的采样率生成的任意音调。用户需要连接有线或无线耳机才能收听音频。

由于现代耳机的原始采样率为 44100 或 48000,因此我需要以某种方式使用不同的 AVAudioFormat 重新初始化我的 AVAudioPlayerNode。什么都不做,音频开始失真。但是,在尝试attachdetachconnectdisconnectNodeOutput 时,我遇到了各种死锁。有时它会在我第一次尝试切换耳机时锁定执行(我同时连接了 2 个耳机,一个 SR 为 44100 的通用耳机和 SR 为 48000 的 Airpods),很少,它会在第二个时卡住试试。

这是我的代码:

private let engine = AVAudioEngine()

private let audioUnit = MyAudioUnit()

init() {
let audioSession = AVAudioSession.sharedInstance()
let sampleRate = audioSession.sampleRate
format = AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: sampleRate,
channels: AVAudioChannelCount(audioSession.outputNumberOfChannels),
interleaved: false
)!

engine.attach(audioUnit)
engine.connect(
audioUnit,
to: engine.mainMixerNode,
format: format
)

NotificationCenter.default.addObserver(
self,
selector: #selector(self.handleInterruption),
name: Notification.Name.AVAudioEngineConfigurationChange,
object: engine
)
}

@objc
private func handleInterruption(_ notification: Notification) {
DispatchQueue.main.async {
let audioSession = AVAudioSession.sharedInstance()
let sampleRate = audioSession.sampleRate
self.format = AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: sampleRate,
channels: AVAudioChannelCount(audioSession.outputNumberOfChannels),
interleaved: false
)!

self.engine.detach(self.audioUnit)
self.engine.attach(self.audioUnit)
self.engine.connect(
self.audioUnit,
to: self.engine.mainMixerNode,
format: self.format
)
}
}

// method called on main thread only
// BTW, using audioUnit.stop() instead of pause() would also introduce a deadlock
func setActive(_ active: Bool) {
...

if active {
try! engine.start()
audioUnit.play()
} else {
audioUnit.pause()
engine.stop()
engine.reset()
}
}

我已经尝试了多种“重新连接”AVAudioEngine 的变体,但它们都以以下死锁告终:

enter image description here

enter image description here

我也试过将它留在后台线程中,但没关系。一旦应用尝试再次使用 AVAudioEngine,一切都会卡住。

那么,是否有一种正确的方法来重新连接 AVAudioPlayerNode 以更新采样率?或者可能不依赖于耳机的 native 采样率并使音频在静态采样率下正常发声?提前致谢!

最佳答案

根据您当前的设置,当音频路径和采样率发生变化时您不需要执行任何操作。

您当前的设置如下:

+------+    +-----+    +------+
|player| -> |mixer| -> |output|
+------+ +-----+ +------+

在播放器和输出节点之间安装混音器的好处之一是混音器将为您进行采样率转换。因此即使扬声器的采样率为 48000Hz,您的播放器也可以输出 44100Hz。

另一件需要注意的事情是,将播放器连接到混音器时,format 参数应该是播放器节点输出的格式。这应该能够通过将 format 设置为 nil 来推断,如下所示:

engine.connect(player, to: engine.mainMixerNode, format: nil)

关于ios - 用户切换耳机时如何更改 AVAudioPlayerNode 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58804714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com