音频处理(AudioUnit)

AudioUnit 实现录音和播放

2020-03-22  本文已影响0人  勇敢的我2017

AudioUnit是iOS底层音频框架,相比于AudioQueue和AVAudioRecorder,能够对音频数据进行更多的控制,可以用来进行混音、均衡、格式转换、实时IO录制、回放、离线渲染等音频处理。
先看下苹果官方的原理图(此处以I/O单元为例):


image.png

谈一下我用AudioUnit 录音播放时遇到的问题
1、刚开始看不懂IO流和StreamFormat 的具体设置,经过仔细阅读明白并记录下来其中1代表Input,0代表Output ,其实也挺神似的.
这个是录音的输入部分即 麦克风--->element1

                     AudioUnitSetProperty(_recordAudioUnit,
                     kAudioOutputUnitProperty_EnableIO,
                     kAudioUnitScope_Input,
                     INPUT_BUS,
                     &flag,
                     sizeof(flag));

这个是播放的 输出部分 即element0---->扬声器

                     AudioUnitSetProperty(_recordAudioUnit,
                     kAudioOutputUnitProperty_EnableIO,
                     kAudioUnitScope_Output,
                     OUTPUT_BUS,
                     &flag,
                     sizeof(flag));

这个是录音的输出部分即 element1---> APP

                    AudioUnitSetProperty(_recordAudioUnit,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Input,
                     OUTPUT_BUS,
                     &audioFormat,
                     sizeof(audioFormat));

这个是播放的输入部分即 APP---> element0

                     AudioUnitSetProperty(_recordAudioUnit,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Output,
                     INPUT_BUS,
                     &audioFormat,
                     sizeof(audioFormat));

总结一下上面的代码 其实很简单
1)一个AudioUnit包含2个element即element0和element1
2)每个element包含输入和输出部分即(Input scope 和 Output scope)。
3)硬件到element的部分我们无法介入,我们能控的就element与我们APP关联的部分即 element1---> APP和APP---> element0。
4)实现录音就是主要关注element1到APP的过程,播放则是关注APP到element0的过程。

2、录音播放部分的回调

                          static OSStatus RecordCallback(void *inRefCon,
                           AudioUnitRenderActionFlags *ioActionFlags,
                           const AudioTimeStamp *inTimeStamp,
                           UInt32 inBusNumber,
                           UInt32 inNumberFrames,
                           AudioBufferList *ioData)

inRefCon:上下文对象 ,inTimeStamp:调用回调的时间,inBusNumber:调用回调的音频单元总数,
inNumberFrames:回调在当前调用时要求提供的音频样本帧的数量,ioData:存放音频数据缓冲区的指针
ioActionFlags:当没有音频数据处理时,该参数允许向音频单元提供提示(具体没有用过)
AudioUnitRender() 把数据渲染到指定的bufferlist 中
播放中的 ioData: 是要把数据填充到ioData中,用来播放

3、播放音频的时候明明是女声播放出来变成男声,后来改变了采样率就正常了

后续我会贴上我用audioUnit 写的录音和播放的demo地址

上一篇下一篇

猜你喜欢

热点阅读