出力デバイスのサンプル レートに基づいて生成される任意のトーンを再生する必要があります。音声を聞くには、有線または無線のヘッドフォンを接続する必要があります。
最新のヘッドフォンは 44100 または 48000 のネイティブ サンプル レートを持つことができるためAVAudioPlayerNode
、別のAVAudioFormat
. 何もしなくても、オーディオが歪んで聞こえ始めます。ただし、、、、またはをしようとすると、さまざまなデッドロックに直面していattach
ます。ヘッドフォンを初めて切り替えようとすると実行がロックされることがあります(同時に2つのヘッドフォンが接続されており、SRが44100の汎用ヘッドセットとSRが48000のAirpodsがあります)、まれに、2番目にフリーズします試す。detach
connect
disconnectNodeOutput
これが私のコードです:
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
が、それらはすべて次のデッドロックに陥りました。
バックグラウンドスレッドに残そうとしましたが、問題ありません。アプリがもう一度使用しようとするとすぐにAVAudioEngine
、すべてが動かなくなります。
AVAudioPlayerNode
では、サンプル レートを更新するためにを再接続する適切な方法はありますか? それとも、ヘッドフォンのネイティブ サンプル レートに依存せず、静的サンプル レートでオーディオ サウンドを正常に鳴らすことは可能でしょうか? 前もって感謝します!