
> 2个频道
>交错
单个通道中每个样本> 2个字节(所以4
每帧字节数)
>采样率为48000.
每个UDP数据包包含480个帧,因此缓冲区的大小为480 * 2(通道)* 2(每个通道的字节数).
我需要设置一个音频单元来播放这些数据包.所以,我的第一个问题是,我应该如何为音频单元设置AudioStreamBasicDescription结构?查看文档我甚至不确定交错PCM是否是可接受的格式.
这是我到目前为止所得到的:
struct AudioStreamBasicDescription { float64 mSampleRate; //48000 UInt32 mFormatID; //????? UInt32 mFormatFlags; //????? UInt32 mBytesPerPacket; //Not sure what "packet" means here UInt32 mFramesPerPacket; //Same as above UInt32 mBytesPerFrame; //Same UInt32 mChannelsPerFrame; //2? UInt32 mBitsPerChannel; //16? UInt32 mReserved; //???};typedef struct AudioStreamBasicDescription AudioStreamBasicDescription; 其次,在设置之后,我不确定如何将帧从UDP回调到实际的音频单元渲染功能.
我目前有一个来自套接字监听器的回调函数,我在其中生成包含我想要播放的音频的int16 *缓冲区.据我了解,我还必须为以下形式的音频单元实现渲染回调:
Osstatus RenderFrames( voID *inRefCon,AudioUnitRenderActionFlags *ioActionFlags,const AudioTimeStamp *inTimeStamp,UInt32 inBusNumber,UInt32 inNumberFrames,audiobufferlist *ioData){ //No IDea what I should do here. return noErr;} 总而言之,我认为我的套接字接收回调应该做的是解码帧,并将它们放在缓冲结构中,以便RenderFrames回调可以从该缓冲区中获取帧,并播放它们.它是否正确?如果是,一旦我在RenderFrames函数中获取下一帧,我如何实际“提交它”进行播放?
解决方法 一次拿这个部分AudioStreamBasicDescriptor
Apple的ASBD文档是here.澄清:
>音频帧是一组时间重合的音频样本.换句话说,每个通道一个样本.因此,对于立体声,这是2.
>对于PCM格式,没有数据包.据说,mBytesPerPacket = mBytesPerFrame,mFramesPerPacket = 1,但我不确定这是否真的被使用过.
>未使用mReserved且必须为0
>有关mFormatID和mFormatFlags,请参阅The documentation. CoreAudioTypes.h中有一个方便的辅助函数CalculateLPCMFlags,用于在CoreAudioTypes.h中计算后者.
>多声道音频通常是交错的(如果你真的不想要它,你可以在mFormatFlags中设置一个位).
>还有另一个辅助函数可以填充整个ASBD – FillOutASBDForLPCM()用于线性PCM的常见情况.
> remoteIO单元不支持mFormatID和mFormatFlags的大量组合 – 我发现在iOS上需要进行实验.
这是我的一个项目的一些工作代码:
AudioStreamBasicDescription inputASBL = {0}; inputASBL.mSampleRate = static_cast<float64>(sampleRate);inputASBL.mFormatID = kAudioFormatlinearPCM;inputASBL.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger,inputASBL.mFramesPerPacket = 1;inputASBL.mChannelsPerFrame = 2;inputASBL.mBitsPerChannel = sizeof(short) * 8;inputASBL.mBytesPerPacket = sizeof(short) * 2;inputASBL.mBytesPerFrame = sizeof(short) * 2;inputASBL.mReserved = 0; 渲染回调
CoreAudio运行Apple所说的拉模型.也就是说,当CoreAudio需要缓冲区填充时,渲染回调被称为实时线程.根据您的问题,您似乎期待相反的情况 – 将数据推送到音频输出.
基本上有两种实现选择:
>在渲染回调中从UDP套接字执行非阻塞读取(作为一般规则,您在此处执行的任何 *** 作都应该是快速且无阻塞的).
>在渲染回调接收和使用时,保持插入样本的音频FIFO.
第二种可能是更好的选择,但是您需要自己管理缓冲区过度和欠量运行.
ioData参数指向分散 – 聚集控制结构.在最简单的情况下,它指向一个包含所有帧的缓冲区,但可以包含几个在它们之间具有足够帧以满足inNumberFrames的帧.通常,一个预分配足够大的缓冲区用于inNumberFrames,将样本复制到其中,然后修改指向buy ioData指向它的audiobufferlist对象.
在您的应用程序中,您可能会对解码后的音频数据包采用分散 – 聚集方法,在解码时分配缓冲区.但是,您并不总是得到所需的延迟,并且可能无法安排inNumberFrames与解码的UDP音频帧相同.
总结以上是内存溢出为你收集整理的ios – 设置音频单元格式并渲染交错PCM音频的回调全部内容,希望文章能够帮你解决ios – 设置音频单元格式并渲染交错PCM音频的回调所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)