本文主要学习在Audio Unit是如何限定音频流的格式
主要内容:
- 音频流的认识
- 音频流的使用
1、 音频流认识
说明:
- audio stream
- 音频流是声音的连续数据系列
- packet
- 包是一个或多个相邻帧的集合
- 包含了给定音频数据格式的最小有意义的帧的集合,是可以测量时间的最小数据单位
- 在LPCM中一个packet只有一个frame,如果是压缩格式,可以有多个frame
- channel
- 声道是单声道音频的离散声道,单声道流有一个声道,立体声流有两个声道
- sample
- 采样是音频流中单个声道的数据
- 注意,这里的采样是指整个声道中的采样数据,而frame中的采样只是其中的一部分
- frame
- frame是相同时间的重合的sample的集合
- 比如立体声文件每个frame都有两个sample,一个用于左声道,一个用于右声道
注意:
- 一般来说我们设置的只要一个packet,就是使用恒定比特率CBR格式
- 始终将ASBD的字段初始化为零
- 采样率在以正常速度播放流时,就代表了帧率,每秒流过的帧数
- 还有一个字段mReserved,表示强制8字节对齐,必须设置为0,一般不写也行,但是也要知道,不要以为除了上面的就没有其他的了
- 避免应用程序的采样率和音频硬件采样率的转换
参考链接: iOS音频流格式要求
2、 设置音频流格式
示意图:
位置:
- 我们在关键的地方设置音频流格式,之后在非关键的地方系统会帮助我们设置,系统是在音频单元连接后会自动设置流格式,就自动的将流数据从一个单元传递到另一个单元,无需我们操心
- 音频输入和输出硬件是具有系统给定的音频流格式,这些格式就是线性PCM帧数据,并且是交错的(注意这里是硬件本身的流格式)
方式:
- 系统在处理音频输入和输出时,是会帮我们将这些格式强制放在I/O单元的朝外侧
- 我们负责在I/O单元的向内侧建立音频流格式
- 也就是说远程I/O单元会帮我们进行格式转换,只需要我们给这个音频单元设置好音频流格式,他在输出音频的时候就会自动转换了
- 这里的转换也是通过Format conversion Unit实现的
- 中间与其他的单元进行交互我们也可以设置音频流格式
注意:
- 朝外侧可以理解为input element所在的Input scope是朝外侧,output element所在的output scope也是朝外侧
- 但是我们最好不要设置音频流格式,直接进行格式传播。因为采样率转换也会消耗性能
- 而且只要有可能,我们就尽可能的使用硬件的采样率,这样在执行操作时,无需进行采样率转换,这最大限度的降低了性能消耗
- 音频单元连接的一个关键特性是连接音频数据流格式从起源音频单元的output传播到目标音频单元的Input
- 这里强调的是流格式传播是通过音频单元的连接,传播方向只能从源单元的输出到目标单元的输入进行
- 利用格式传播,可以最大限度的减少我们编写的代码量
3、 具体实现
代码:
说明:
- AudioStreamBasicDescription是来设置音频流格式的
- 配置ASBD指定LPCM格式
- 指定具有相同大小通道的恒定比特率CBR格式
- 可变比特率VBR音频,和信道大小不等的CBR音频,每个packet必须专门由另外的ASBD来设置
- 音频流传入的是媒体帧,所以设置音频流的描述,也即是给媒体帧设置规范。
参数说明:
- 一个packet有多少个帧数据 -- mFramesPerPacket
- 一个packet有多少个字节 -- mBytesPerPacket
- 一个PCM有几个声道 -- mChannelsPerFrame
- 一个PCM有几个字节 -- mBytesPerFrame
- 每个声道的量化精度,也就是采样位数 -- mBitsPerChannel
- mBytesPerFrame = mBitsPerChannel/8