ios – 设置音频单元格式并渲染交错PCM音频的回调

ios – 设置音频单元格式并渲染交错PCM音频的回调,第1张

概述我正在尝试播放我在一系列UDP数据包中收到的音频.它们被解码为具有以下属性的PCM帧: > 2个频道 >交错 单个通道中每个样本> 2个字节(所以4 每帧字节数) >采样率为48000. 每个UDP数据包包含480个帧,因此缓冲区的大小为480 * 2(通道)* 2(每个通道的字节数). 我需要设置一个音频单元来播放这些数据包.所以,我的第一个问题是,我应该如何为音频单元设置AudioStream 我正在尝试播放我在一系列UDP数据包中收到的音频.它们被解码为具有以下属性的PCM帧:

> 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音频的回调所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1064513.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存