音频队列录制错误:AudioQueueNew 中的 AudioConverterNew 返回了“fmt?”

Posted

技术标签:

【中文标题】音频队列录制错误:AudioQueueNew 中的 AudioConverterNew 返回了“fmt?”【英文标题】:Audio queue recording error: AudioConverterNew from AudioQueueNew returned 'fmt?' 【发布时间】:2015-11-23 23:05:07 【问题描述】:

这是我设置音频队列服务的代码:

aqData = AQRecorderState()
    aqData.mDataFormat.mFormatID             = kAudioFormatMPEG4AAC
    aqData.mDataFormat.mSampleRate           = 16000.0
    aqData.mDataFormat.mChannelsPerFrame     = 1
    aqData.mDataFormat.mBitsPerChannel       = 16
    aqData.mDataFormat.mBytesPerPacket       = aqData.mDataFormat.mChannelsPerFrame * UInt32(sizeof(UInt16))
    aqData.mDataFormat.mBytesPerFrame        = aqData.mDataFormat.mChannelsPerFrame * UInt32(sizeof(UInt16))
    aqData.mDataFormat.mFramesPerPacket      = 1
    aqData.mDataFormat.mFormatFlags          = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian
    aqData.mQueue                            = AudioQueueRef()
    fileType                                 = kAudioFileM4AType

    // create new input for audio queue
    AudioQueueNewInput(&aqData.mDataFormat, handleInputBuffer, &aqData, nil, kCFRunLoopCommonModes, 0, &aqData.mQueue)
    var dataFormatSize:UInt32 = UInt32(sizeof(aqData.mDataFormat.dynamicType))
    AudioQueueGetProperty(aqData.mQueue, kAudioQueueProperty_StreamDescription, &aqData.mDataFormat, &dataFormatSize)

    // create file to store audio
    let data = recordUrl.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    let audioFileURL: CFURLRef = CFURLCreateFromFileSystemRepresentation(nil, UnsafePointer(data.bytes), data.length, false)
    AudioFileCreateWithURL(audioFileURL, fileType, &aqData.mDataFormat, AudioFileFlags.EraseFile, &aqData.mAudioFile)

    // set magic cookie for file if needed
    setMegicCookieForFile(aqData.mQueue, inFile: aqData.mAudioFile)

    // derive buffer size
    deriveBufferSize(aqData.mQueue, ASBDescription: &aqData.mDataFormat, seconds: kBufferLengthInSecond, outbufferSize: &aqData.bufferByteSize)

    // allocate and enqueue each buffer
    for i in 0..<Record.kNumberBuffers 
        AudioQueueAllocateBuffer(aqData.mQueue, aqData.bufferByteSize, &aqData.mBuffers[i])
        AudioQueueEnqueueBuffer(aqData.mQueue, aqData.mBuffers[i], 0, nil)
    

代码在行产生错误

AudioQueueNewInput(&aqData.mDataFormat, handleInputBuffer, &aqData, nil, kCFRunLoopCommonModes, 0, &aqData.mQueue)

错误信息是

AudioConverterNew from AudioQueueNew returned 'fmt?'

io:1 通道,44100 Hz,Float32 client: 1 ch, 44100 Hz, 'aac' (0x00000003) 16 bits/channel, 2 bytes/packet, 1 frames/packet, 2 bytes/frame

我尝试了不同的音频格式设置,但似乎没有一个能修复这个错误。有人可以帮忙吗?

【问题讨论】:

【参考方案1】:

CoreAudioTypes.h 头文件中,我们了解到:

kAudioFormatMPEG4AAC MPEG-4 低复杂度 AAC 音频对象,没有标志。

在同一文件中AudiostreamBasicDescription 上方的评论说:

在压缩音频中,数据包是不可分割的压缩数据块,例如,AAC 数据包将包含 1024 个样本帧。

而且由于 AAC 可以是可变比特率(这在 CAF spec 和注释中有所暗示 对于变量 mBytesPerPacket compressed audio formats) mBitsPerChannelmBytesPerPacketmFramesPerPacket 应该为零。

所以我会尝试更改您的AudioStreamBasicDescription 的这些字段:

aqData.mDataFormat.mBitsPerChannel       = 0
aqData.mDataFormat.mBytesPerPacket       = 0
aqData.mDataFormat.mBytesPerFrame        = 0
aqData.mDataFormat.mFramesPerPacket      = 1024
aqData.mDataFormat.mFormatFlags          = 0

【讨论】:

嗨节奏,谢谢你的回复,这解决了我的问题。但是现在我的 audioqueueinputcallback 没有被调用。你知道原因吗? 你在打电话给AudioQueueStart吗?

以上是关于音频队列录制错误:AudioQueueNew 中的 AudioConverterNew 返回了“fmt?”的主要内容,如果未能解决你的问题,请参考以下文章

iPhone OS 3.0 上的音频录制错误 kAudioQueueErr_CannotStart

使用音频队列框架录制的数据格式

音频队列服务录制到 .mp4 文件,无法播放。和魔术饼干问题

使用如何在 iPhone 中以 mp3 格式录制声音的音频队列服务示例

AudioQueueStop 后音频队列无法重新启动

在 iPhone 上使用 AudioQueue 录制/播放