ios - (快速)当 AudioStreamPacketDescription 为 nil 时调试 CrashIfClientProvidedBogusAudioBufferList 的方法?

标签 ios swift core-audio swift2

我在尝试一次时遇到了 CrashIfClientProvidedBogusAudioBufferList 异常 AudioConverterFillComplexBuffer 回调返回。抛出此异常的可能原因是什么?

作为引用,这是我的电话

AudioConverterFillComplexBuffer(audioConverterRef,  
fillComplexCallback,  
&convertInfo,  
&framesToDecode,  
&localPcmBufferList,  

&回调:

func fillComplexxCallback(myConverter: AudioConverterRef, packetNumber: UnsafeMutablePointer<UInt32>,   
ioData: UnsafeMutablePointer<AudioBufferList>, aspd: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>>,  
userInfo: UnsafeMutablePointer<Void>) -> OSStatus {  

    var convertInfo = UnsafeMutablePointer<AudioConvertInfo>(userInfo).memory  

    if (packetNumber.memory > (convertInfo.audioBuffer.mDataByteSize / convertInfo.numberOfPackets)) {  
        packetNumber.memory = (convertInfo.audioBuffer.mDataByteSize / convertInfo.numberOfPackets)  
    }  

    ioData.memory.mNumberBuffers = 1  
    var buffer = AudioBuffer(mNumberChannels: 2, mDataByteSize: convertInfo.audioBuffer.mDataByteSize, mData: ioData.memory.mBuffers.mData)  
    ioData.memory.mBuffers = buffer  

     /* if the following is uncommented out, a exception is thrown */
    // aspd.memory = convertInfo.packetDescriptions 
    packetNumber.memory = convertInfo.numberOfPackets  
    convertInfo.done = true  

        return 0  
}  

这是AudioConvertInfo 的 结构:

struct AudioConvertInfo {
    var done: Bool! //conversion of audio is finished
    var numberOfPackets: UInt32!
    var audioBuffer: AudioBuffer!
    var audioPlayer: CCPlayer!
    var packetDescriptions: AudioStreamPacketDescription!

    init(done: Bool?, numberOfPackets: UInt32?, audioBuffer: AudioBuffer?, packetDescriptions: AudioStreamPacketDescription!, audioPlayer: CCPlayer!) {
        self.done = done
        self.numberOfPackets = numberOfPackets
        self.audioBuffer = audioBuffer
        self.packetDescriptions = packetDescriptions
        self.audioPlayer = audioPlayer
    }
}

我似乎找不到任何可靠的文档。我注意到 aspd (AudioStreamPacketDescription) 正在返回 nil。这对于确定音频数据缓冲区中数据包大小不同或音频数据包之间存在非音频数据的数据包很重要。此代码将在 aspd.memory = convertInfo.packetDescriptions 上引发异常,但如果代码被注释掉 - 将引发 CrashIfClientProvidedBogusAudioBufferList。我的理论是,如果我弄清楚为什么 AudioStreamPacketDescription 为 nil,此回调将正常工作

最佳答案

看起来像AudioStreamPacketDescription is nil不是问题。
根据 Apple 文档,它可以为零,基本上取决于音频格式:
AudioConverterComplexInputDataProc

outDataPacketDescription: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>> - If not NULL on input, the audio converter expects this callback to provide an array of AudioStreamPacketDescription structures on output, one for each packet of audio data you are providing in the ioData parameter.

AudioConverterFillComplexBuffer

outPacketDescription: UnsafeMutablePointer<AudioStreamPacketDescription> - On input, must point to a block of memory capable of holding the number of packet descriptions specified in the ioOutputDataPacketSize parameter. (See Audio Format Services Reference for functions that let you determine whether an audio format uses packet descriptions). If not NULL on output and if the audio converter’s output format uses packet descriptions, then this parameter contains an array of packet descriptions.

真正的问题放在了AudioConvertInfo这一行的结构:

var packetDescriptions: AudioStreamPacketDescription!  

结构保持单一 AudioStreamPacketDescription结构。
然后你在fillComplexCallback中使用它功能:

outDataPacketDescription.memory.memory = convertInfo.packetDescriptions

所以你试图设置单个 AudioStreamPacketDescription结构到参数 outDataPacketDescription需要 AudioStreamPacketDescription 的数组结构(不仅仅是单个实例)。

这个问题可以通过保留和使用 AudioStreamPacketDescription 数组来解决。结构。
AudioConvertInfo 的更新版本结构:

struct AudioConvertInfo {
    var done: Bool!
    var numberOfPackets: UInt32!
    var audioBuffer: AudioBuffer!
    var audioPlayer: CCPlayer!
    var packetDescriptions: UnsafeMutablePointer<AudioStreamPacketDescription>!

    init(done: Bool?, numberOfPackets: UInt32?, audioBuffer: AudioBuffer?, packetDescriptions: UnsafeMutablePointer<AudioStreamPacketDescription>!, audioPlayer: CCPlayer!) {
        self.done = done
        self.numberOfPackets = numberOfPackets
        self.audioBuffer = audioBuffer
        self.packetDescriptions = packetDescriptions
        self.audioPlayer = audioPlayer
    }
}

// Usage:
convertInfo = AudioConvertInfo(done: false, numberOfPackets: numberPackets, audioBuffer: AudioBuffer(mNumberChannels: 2, mDataByteSize: numberBytes, mData: &iData), packetDescriptions: packetDescriptions, audioPlayer: self)

fillComplexCallback 的更新版本功能:

func fillComplexCallback(inAudioConverter: AudioConverterRef, ioNumberDataPackets: UnsafeMutablePointer<UInt32>, ioData: UnsafeMutablePointer<AudioBufferList>, outDataPacketDescription: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>>, inUserData: UnsafeMutablePointer<Void>) -> OSStatus {
    var convertInfo = UnsafeMutablePointer<AudioConvertInfo>(inUserData).memory

    if convertInfo.done == true {
        ioNumberDataPackets.memory = 0
        return 100
    }
    ioData.memory.mNumberBuffers = 1
    let buffer = convertInfo.audioBuffer
    ioData.memory.mBuffers = buffer

    if outDataPacketDescription != nil {
        outDataPacketDescription.memory = convertInfo.packetDescriptions
    }

    ioNumberDataPackets.memory = convertInfo.numberOfPackets
    convertInfo.done = true

    return 0
}

// Usage:  
status = AudioConverterFillComplexBuffer(audioConverterRef, fillComplexCallback, &convertInfo!, &framesToDecode, &localPcmBufferList!, nil)

希望它能解决您的问题。

关于ios - (快速)当 AudioStreamPacketDescription 为 nil 时调试 CrashIfClientProvidedBogusAudioBufferList 的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31708398/

相关文章:

ios - AVAudioMix 音频闪避不起作用

iOS - 添加 UITabBarController 毁了我为 TableViews 定制的 AppDelegate.m

ios - 如何在 Google map Xcode 顶部显示 subview 或按钮

xml - 如何在 Swift 2.0 中使用 Alamofire 3.0 .responsePropertyList?

swift - 为什么在我的结构中调用 self.init 之前出现错误 'self'?

objective-c - 当 AudioSessionActive 为 NO 时,无法通过硬件按钮控制 AVAudioPlayer 的音量

ios - 以编程方式设置 RGB

ios - 属性与主类中的属性类型不匹配

ios - MidiClientCreate notificationproc 没有被调用

ios - 从 Viewcontroller 与模型类进行录制