探索iOS之AudioUnit音效框架

iOS的AVAudioUnit提供的音效包括:混响、延迟、均衡器、失真、变速、变调等。按照类型划分为Audio Effect和Time Effect,其中Audio Effect包括混响、延迟、均衡器和失真,而Time Effect主要是变速、变调。

一、音效应用层框架

音效的应用层框架以AVAudioUnit作为核心抽象类,如下图所示:

二、音效HAL层

1、音效与HAL层关系图

音效的HAL硬件抽象层属于CoreAudio框架,而AUHAL即AudioUnit的HAL层,用于连接I/O Kit与Mixer Unit的桥梁。如下图所示:

2、音效HAL层核心类

音效硬件抽象层的相关头文件如下:

  •  AUComponent.h: 定义AudioUnit类型.
  • AudioComponent.h: 定义音频组件的接口.
  • AudioOutputUnit.h: 定义输出单元开关的接口.
  • AudioUnit.h: 涵盖AudioUnit框架类.
  • AudioUnitParameters.h: 预定义AudioUnit的参数常量.
  • AudioUnitProperties.h: 预定义AudioUnit的属性类型.

三、Audio Effect

1、均衡器

AVAudioUnitEQ均衡器提供EQ滤波器参数,用于设置频率、增益、滤波器类型,具体如下:

  • bandwidth:均衡器频宽,范围[0.05, 5.0]
  • bypass:频带的触发状态,true代表激活
  • filterType:滤波器类型,包括lowPass、highPass、bandPass等
  • frequency:频率,有效值为20Hz~采样率/2
  • gain:默认为0 dB,范围[-96 dB, 24 dB]

2、失真

AVAudioUnitDistortion失真可以设置预失真、干湿比。干湿比指的是干声音和湿声音的比例,干声音代表直达声,湿声音代表反射声。具体如下:

  • pregain:失真前的增益,默认-6 dB,范围[-80 dB, 20 dB]
  • wetDryMix:干湿比,默认50%,范围[0%, 100%]

3、延迟

AVAudioUnitDelay延迟可以实现回声效果,可设置参数包括延迟时间、衰减系数等,具体如下:

  • delayTime:延迟时间,默认为1s,范围[0, 2]
  • feedback:衰减系数,默认为50%,范围[-100%, 100%]
  • lowPassCutoff:低通截断,默认为15000Hz,范围为10Hz~采样率/2
  • wetDryMix:干湿比,默认100%,范围[0, 100],0代表全为干声音

4、混响

AVAudioUnitReverb混响可以增强音质,混响支持preset预设环境,具体如下:

  • smallRoom:小房间
  • mediumRoom:中房间
  • largeRoom:大房间
  • mediaHall:中走廊
  • largeHall:大走廊
  • plate:平面
  • mediaChamber:中会议厅
  • largeChamber:大会议厅
  • cathedral:大教堂

四、Time Effect

iOS音频底层提供音质较好的变速变调、变速不变调。而Android往往要依赖第三方库SoundTouch或Sonic实现变速不变调,否则在实现变速功能时声调也发生变化。

1、变调

AVAudioUnitTimePitch变调提供设置混叠、音调、速率参数。具体如下(一度等于1200cents):

  • overlap:混叠,默认值8.0,范围[3.0, 32.0]
  • pitch:音调,默认值0,单位cents,范围[-2400, 2400]
  • rate:速率,默认值1.0,范围[1/32, 32.0]

2、变速

AVAudioUnitRarispeed变速,用于设置播放速率,默认值1.0,范围[0.25, 4.0]。

音调计算公式:

pitch = 1200 * log2(rate)

速率计算公式:

rate = pow(2, cents/1200)

五、AVAudioEngine

AVAudioEngine用于管理音频节点,实现各种音效混合输出播放,处理链架构如下:

我们来看看使用AVAudioEngine实现均衡器音效播放,示例代码如下 :

let audioFile   = AVAudioFile ()
let audioEngine = AVAudioEngine()
let playerNode  = AVAudioPlayerNode()
let effectNode  = AVAudioUnitEQ()

// Attach player node
audioEngine.attach(playerNode)

// Attach effect node
audioEngine.attach(effectNode)

// Connect player node to effect node
audioEngine.connect(playerNode, 
                    to: effectNode, 
                    format: audioFile.processingFormat)

// Connect effect node to output node
audioEngine.connect(effectNode, 
                    to: audioEngine.outputNode, 
                    format: audioFile.processingFormat)

启动AVAudioEngine:

do {
    try audioEngine.start()
    playerNode.play()
} catch {
    // handle error
}

停止AVAudioEngine:

playerNode.stop()
audioEngine.stop()

猜你喜欢

转载自blog.csdn.net/u011686167/article/details/130692846