携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情
文本主要分析在Audio Unit框架中构建音频组件的六种设计模式,需要在不同的场景下采用不同的模式来构建。
1、介绍
上面已经学了各种音频单元,并且设置回调,以及对音频流的操作,接下来就需要选择设计模式,和进行编码来实现音频功能.
总共有六种模式,每种模式会有相同的特性
- 必须有一个I/O单元
- 在整个音频处理图中使用音频单元流格式
- 在特定位置设置流格式或流格式的某些部分
2、I/O直连模式
示意图:
说明:
- 直接将音频发送到输出硬件,不进行任何的为音频处理(虽然这没有多大的实用价值,但是基于此模式构建托管的app的音频单元是验证和巩固我们对音频单元概念的理解的好方法。)
- 图中可以看到,在输入和输出的向外侧都强制放置了硬件流格式,当我们指定向内侧使用的流格式,就需要在音频单元需要进行格式转换,我们知道为了避免不必要的采样率转换,APP内部直接使用硬件采样率
- 默认情况下是禁止 输入的 element ,因此我们需要手动开启它。否则,音频无法流动。
- 在图中所示的模式利用了两个远程I/O 元件之间的音频单元连接。
- 具体来说,我们不需要在音频元件的输入scope 上的output element 设置流格式。连接传播我们为input element 指定的格式。
- 输出元件的朝外侧采用音频输出硬件的流格式,输出元件需要根据对输出音频格式执行格式转换。
- 无需配置任何的音频数据缓冲区
3、没有渲染回调函数的I/O
示意图:
说明:
- 在将音频输出前增加一个或多个其他音频单元,可以构建功能更复杂的APP
- 例如,我们可以使用多声道混音器单元将传入的麦克风音频定位在立体声场中或提供输出音量控制。
- 混音器的音频流格式随着两个单元之间的连接自动建立传输,不需要我们人为设置了。除非需要更改格式传播
- 不需要配置任何的音频数据缓冲区
4、带有渲染回调函数的I/O
示意图:
说明:
- 在输出流数据前增加渲染回调函数,对音频流进行操作
- 在一个非常简单的情况下,我们可以使用渲染回调函数来调整输出音量
- 我们还可以进行比如颤音、铃声调制、回声或者其他的效果,可以通过Accelerate框架中的傅里叶变换和积分公式,可以做无穷无尽的事情
- 将渲染回调函数添加到element0的Input scope,当该元素需要获取下一组音频样本值时,就会调用这个回调函数
- 反过来,我们的回调通过调用远程I/O单元的输入element的渲染回调函数来获取新样本
- 当像这样使用渲染回调函数建立了从一个音频单元到另一个音频单元的音频路径时,回调函数取代了音频单元连接
- 与其他I/O 模式一样,我们必须在远程I/O 单元上开启输入,默认情况下输入是禁止的
- 而且,对于其他I/O模式,我们无需要配置任何音频数据缓冲区
5、仅有渲染回调函数的输出
对于游戏音乐和合成器选择此模式,需要合成声音
示意图:
说明:
- 简单的是,这种模式设计到一个渲染回调函数,它直接连接到远程I/O 单元输出element 的 output的 scope
使用相同的模式可以构建具有更复杂的音频结构的app。 比如当我们希望生成多个声音,将它们混合在一起,然后通过设备的输出硬件播放他们
说明:
- 进行不同声音的混合
- 这里该模式采用音频处理grahp和两个额外的音频单元,多声道混音器和Ipod EQ
- 需要注意Ipod EQ 要求我们在输入和输出上设置完整的流格式。
- 另一方面,多通道混音器只需要再其输出上设置正确的采样率。
- 然后,整个流格式由音频单元连接从混音器的输出传播到远程I/O单元输出单元的input scope。
6、其他的设计模式
仅有渲染回调函数的输入:
- 录制和分析音频
- 回调函数由应用程序调用,然后它调用RemoteI/O 单元的input元素的render方法。
注意:
- 在大多数情况下,像这样的应用程序的更好选择是使用音频队列对象
- 使用音频队列对象提高了更大的灵活性,因为他的渲染回调函数不在实时线程上。
通用输出单元:
- 执行离线音频处理
- 与远程I/O 单元不同,该音频单元不连接到设备的音频硬件
- 当使用它向app发送音频时,它取决于app调用其render 方法