Macos 如何使用audioConverterFillComplexBuffer及其回调?
我需要一个关于如何使用audioConverterFillComplexBuffer及其回调的逐步演练。不,别让我看苹果的文档。我照他们说的做,转换总是失败。不,不要告诉我去寻找audioConverterFillComplexBuffer及其回调在使用中的示例-我已经复制了十几个这样的示例,包括逐行和修改,转换总是失败。不,输入数据没有任何问题。不,这不是endian的问题。不,问题不是我的OS X版本 问题是我不明白audioConverterFillComplexBuffer是如何工作的,所以我不知道我做错了什么。没有任何东西能帮助我理解,因为似乎地球上也没有人真正理解audioConverterFillComplexBuffer是如何工作的。从实际使用它的人(我在他们的代码中间谍货物崇拜编程)到学习核心音频和/或苹果本身的作者(http://stackoverflow.com/questions/13604612/core-audio-how-can-one-packet-one-byte-when-clearly-one-packet-4-bytes) 这不仅是我的问题,也是任何想在Mac平台上编程高性能音频的人的问题。显然是错误的陈腐文档和不起作用的示例毫无乐趣Macos 如何使用audioConverterFillComplexBuffer及其回调?,macos,core-audio,Macos,Core Audio,我需要一个关于如何使用audioConverterFillComplexBuffer及其回调的逐步演练。不,别让我看苹果的文档。我照他们说的做,转换总是失败。不,不要告诉我去寻找audioConverterFillComplexBuffer及其回调在使用中的示例-我已经复制了十几个这样的示例,包括逐行和修改,转换总是失败。不,输入数据没有任何问题。不,这不是endian的问题。不,问题不是我的OS X版本 问题是我不明白audioConverterFillComplexBuffer是如何工作的,
再说一次,我需要一步一步地演练如何使用audioConverterFillComplexBuffer及其回调,整个Mac开发者社区也是如此 这是一个非常古老的问题,但我认为仍然相关。我花了几天的时间来解决这个问题,最终实现了成功的转化。我当然不是专家,但我将概述我对其工作原理的理解。请注意,我正在使用Swift,这也是我正在学习的 以下是主要函数参数:
inAudioConverter:AudioConverterRef
:这一个非常简单,只需传入以前创建的AudioConverterRef
inInputDataProc:AudioConverter ComplexInputDataProc
:非常复杂的回调。我们将回到这个话题
inInputDataProcUserData,UnsafemtableRawPointer?
:这是对可能需要提供给回调函数的任何数据的引用。重要的是,即使在swift中,回调也不能继承上下文。例如,您可能需要访问AudioFileID或跟踪到目前为止读取的数据包数量
ioOutputDataPacketSize:UnsafeMutablePointer
:这个有点误导。名称意味着它是数据包大小,但阅读文档意味着我们了解到它是输出格式预期的数据包总数。您可以将其计算为outPacketCount=frameCount/outStreamDescription.mFramesPerPacket
outOutputData:UnsafeMutablePointer
:这是一个音频缓冲区列表,您需要用足够的空间初始化该列表以保存预期的输出数据。大小可以计算为byteSize=outPacketCount*outMaxPacketSize
outPacketDescription:UnsafeMutablePointer?
:这是可选的。如果需要数据包描述,请传入一块大小为outPacketCount*sizof(AudioStreamPacketDescription)
的内存
当转换器运行时,它将重复调用回调函数以请求更多数据进行转换。回调的主要任务只是从源数据中读取请求的数字数据包。然后转换器将数据包转换为输出格式并填充输出缓冲区。以下是回调的参数:
音频转换器:音频转换器ref
:再次打开音频转换器。你可能不需要用这个
ioNumberDataPackets:UnsafeMutablePointer
:要读取的数据包数。读取后,必须将其设置为实际读取的数据包数(如果到达末尾,可能会小于请求的数据包数)
ioData:UnsafeMutablePointer
:已配置的音频缓冲区列表,实际数据除外。您需要以足够的容量初始化ioData.mBuffers.mData,以容纳预期数量的数据包,即ioNumberDataPackets*inMaxPacketSize
。将ioData.mBuffers.mDataByteSize的值设置为匹配
outDataPacketDescription:UnsafeMutablePointer?
:根据使用的格式,转换器可能需要跟踪数据包描述。您需要用足够的容量初始化它,以容纳预期数量的数据包描述
inUserData:UnsafeMutableRawPointer?
:提供给转换器的用户数据
因此,要开始,您需要:
ioData
,使其具有足够的容量来存储源数据的ioNumberDataPackets
outDataPacketDescription
,使其具有足够的容量来存储音频流packetdescription的ioNumberDataPackets
ioNumberDataPackets
设置为实际读取的数据包数noErr
var转换器:AudioConverterRef?
//用户数据保存AudioFileID、输入最大数据包大小和读取的数据包计数
var uData=(fRef,maxPacketSize,UnsafeMutablePointer.allocate(容量:1))
err=音频转换器新建(&inStreamDesc,&outStreamDesc,&converter)
err=AudioConverterFillComplexBuffer(转换器!,{u0,ioNumberDataPackets