设置AVAudioFormat连接功能已经崩溃

时间:2016-08-31 09:04:58

标签: crash avfoundation swift3 avaudioengine

我一直在尝试使用AVAudioEngine来处理烧录的16位流数据。

但传递给AVAudioFormat连接功能总是会崩溃。

代码如下:

let AUDIO_OUTPUT_SAMPLE_RATE    = 44100
let AUDIO_OUTPUT_CHANNELS       = 2
let AUDIO_OUTPUT_BITS           = 16
var audioEngine: AVAudioEngine?
var audioPlayer: AVAudioPlayerNode?

...

    audioEngine = AVAudioEngine()
    audioPlayer = AVAudioPlayerNode()

    audioEngine?.attach(audioPlayer!)

    let mixer = audioEngine?.mainMixerNode
    mixer!.outputVolume = 1.0
    let stereoFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: Double(AUDIO_OUTPUT_SAMPLE_RATE), channels: 2, interleaved: false)
    audioEngine!.connect(audioPlayer!, to: mixer!, format: stereoFormat)

...

audioEngine!。connect(...)正在崩溃

我正在使用Xcode 8 beta 6,OS X El Capitan,而且,这种情况都来自于模拟器和设备。

这是崩溃消息的一部分:

ERROR:    >avae> AVAudioNode.mm:751: AUSetFormat: error -10868
*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -10868'

...
3   AVFAudio  0x000000011e0a5630 _Z19AVAE_RaiseExceptionP8NSStringz + 176
4   AVFAudio  0x000000011e0f270d _ZN19AVAudioNodeImplBase11AUSetFormatEP28OpaqueAudioComponentInstancejjP13AVAudioFormat + 213
5   AVFAudio  0x000000011e0f2630 _ZN19AVAudioNodeImplBase15SetOutputFormatEmP13AVAudioFormat + 46
6   AVFAudio  0x000000011e0f9663 _ZN21AVAudioPlayerNodeImpl15SetOutputFormatEmP13AVAudioFormat + 25
7   AVFAudio  0x000000011e099cfd _ZN18AVAudioEngineGraph8_ConnectEP19AVAudioNodeImplBaseS1_jjP13AVAudioFormat + 2377
8   AVFAudio  0x000000011e09d15f _ZN18AVAudioEngineGraph7ConnectEP11AVAudioNodeS1_mmP13AVAudioFormat + 355
9   AVFAudio  0x000000011e0fc80e _ZN17AVAudioEngineImpl7ConnectEP11AVAudioNodeS1_mmP13AVAudioFormat + 348

从音频文件播放缓冲区和格式没问题。

我做的错误是什么?

感谢。

4 个答案:

答案 0 :(得分:2)

-10868, a.k.a. kAudioUnitErr_FormatNotSupported, so it looks like your PCMFormatInt16 isn't appreciated. Changing it to .PCMFormatFloat32 does work.

答案 1 :(得分:1)

您无需自己创建音频格式,

从实际音频数据(pcm 缓冲区或音频文件)中获取音频格式

<块引用>

来自 WWDC 2016 的音频格式,提供卓越的音频体验

0


<块引用>

来自 WWDC 2015 的实际音频格式理论,Core Audio 的新功能

  • 输出的实际音频格式

44

  • 输入的实际音频格式

44

  • 做音频通道映射,音频位深保持不变

222

答案 2 :(得分:0)

从Apple,AVAudioPlayerNode

在播放缓冲区时,有一个隐含的假设,即缓冲区的采样率与节点的输出格式相同。

然后打印AVAudioPlayerNode的输出格式,即engine.mainMixerNode.inputFormat

    open func connectNodes() {
        print(engine.mainMixerNode.inputFormat(forBus: 0))
        engine.connect(playerNode, to: engine.mainMixerNode, format: readFormat)
    }

结果是

因此选择.pcmFormatFloat32而不是.pcmFormatInt16


OSStatus master website

答案 3 :(得分:0)

您可以使用烧录的 16 位音频格式,但您应该先将其转换。

// Setup your own format
let inputFormat = AVAudioFormat(
    commonFormat: .pcmFormatInt16,
    sampleRate: 44100,
    channels: AVAudioChannelCount(2),
    interleaved: true
)!

let engine = AVAudioEngine()
// Use system format as output format
let outputFormat = engine.mainMixerNode.outputFormat(forBus: 0)
self.converter = AVAudioConverter(from: inputFormat, to: outputFormat)!

self.playerNode = AVAudioPlayerNode()
engine.attach(playerNode)
engine.connect(playerNode, to: engine.mainMixerNode, format: nil)

...

// Prepare input and output buffer
let inputBuffer = AVAudioPCMBuffer(pcmFormat: inputFormat, frameCapacity: maxSamplesPerBuffer)!
let outputBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat, frameCapacity: maxSamplesPerBuffer)!

// When you fill your Int16 buffer with data, send it to converter
self.converter.convert(to: outputBuffer, error: nil) { inNumPackets, outStatus in
    outStatus.pointee = .haveData
    return inputBuffer
}

// Now in outputBuffer sound in system format and we can play it
self.playerNode.scheduleBuffer(outputBuffer)