Ser*_*les 4 audio audiounit ios
我正在尝试播放我在一系列UDP数据包中收到的音频.它们被解码为具有以下属性的PCM帧:
每个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;
Run Code Online (Sandbox Code Playgroud)
其次,在设置之后,我不确定如何将帧从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;
}
Run Code Online (Sandbox Code Playgroud)
总而言之,我认为我的套接字接收回调应该做的是解码帧,并将它们放在缓冲结构中,以便RenderFrames回调可以从该缓冲区中获取帧,并播放它们.它是否正确?如果是,一旦我在RenderFrames函数中获取下一帧,我如何实际"提交它"进行播放?
一次拿这个部分
Apple的ASBD文档就在这里.澄清:
2. mBytesPerPacket = mBytesPerFrame,mFramesPerPacket=1但我不知道这是否是真正被使用.mReserved 没有使用,必须 0mFormatID和mFormatFlags.CalculateLPCMFlagsCoreAudioTypes.h中有一个方便的辅助函数,用于计算后者CoreAudioTypes.h.mFormatFlags如果你真的不想要它,你可以设置一下).FillOutASBDForLPCM()适用于线性PCM的常见情况.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;
Run Code Online (Sandbox Code Playgroud)
CoreAudio运行Apple所说的拉模型.也就是说,当CoreAudio需要缓冲区填充时,渲染回调被称为实时线程.根据您的问题,您似乎期待相反的情况 - 将数据推送到音频输出.
基本上有两种实现选择:
第二种可能是更好的选择,但是您需要自己管理缓冲区过度和欠量运行.
该ioData论点指向分散 - 聚集控制结构.在最简单的情况下,它指向一个包含所有帧的缓冲区,但可以包含几个它们之间有足够的帧来满足inNumberFrames.通常,预先分配一个足够大的缓冲区inNumberFrames,将样本复制到其中,然后修改AudioBufferList指向buy 的对象ioData以指向它.
在您的应用程序中,您可能会对解码后的音频数据包采用分散 - 聚集方法,在解码时分配缓冲区.但是,您并不总是得到所需的延迟,并且可能无法安排inNumberFrames与解码的UDP音频帧相同.
| 归档时间: |
|
| 查看次数: |
5335 次 |
| 最近记录: |