iOS音视频AudioUnit 的使用简介

2,853 阅读2分钟

Audio Unit是iOS音视频最底层的接口

支持混合、均衡、格式转换和实时输入/输出用于录制、播放、离线渲染和实时对话如VoIP(互联网协议语音)等,

它的优点是功能强大,延迟低; 而缺点是学习成本高,难度大。今天重点介绍一下Audio Unit的基本用法。

1、设置AVAudioSession

NSError *error = nil;

AVAudioSession* session = [AVAudioSession sharedInstance];

[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];

[session setActive:YES error:nil];

2、创建描述音频单元

AudioComponentDescription desc;

desc.componentType =kAudioUnitType_Output;

desc.componentSubType =kAudioUnitSubType_VoiceProcessingIO;

//kAudioUnitSubType_RemoteIO不带回音消除功能,,kAudioUnitSubType_VoiceProcessingIO带回音消除功能

desc.componentFlags =0;

desc.componentFlagsMask =0;

desc.componentManufacturer =kAudioUnitManufacturer_Apple;

3、关联查找音频单元

AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

4、获取音频单元实例

status = AudioComponentInstanceNew(inputComponent, &audioUnit);

5、启用录制功能

UInt32 flag = 1;  //falg为1表示开启录制功能,为0则不开启

status = AudioUnitSetProperty(audioUnit,

                              kAudioOutputUnitProperty_EnableIO,

                              kAudioUnitScope_Input,

                              kInputBus,

                              &flag,

                              sizeof(flag));

6、启用播放功能

status = AudioUnitSetProperty(audioUnit,

                               kAudioOutputUnitProperty_EnableIO,

                              kAudioUnitScope_Output,

                              kOutputBus,

                              &flag,

                              sizeof(flag));

7、创建音频流描述

AudioStreamBasicDescription audioFormat;  //声音是44100.00采样率,16bit,单声道,pcm的

audioFormat.mSampleRate = 44100.00;

audioFormat.mFormatID = kAudioFormatLinearPCM;

audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;

audioFormat.mFramesPerPacket = 1;

audioFormat.mChannelsPerFrame = 1;

audioFormat.mBitsPerChannel = 16;

audioFormat.mBytesPerPacket = 2;

audioFormat.mBytesPerFrame = 2;

8、设置录制和播放的音频流描述

8.1、设置录制的音频流描述

status = AudioUnitSetProperty(audioUnit,

                                  kAudioUnitProperty_StreamFormat,

                                  kAudioUnitScope_Output,

                                  kInputBus,

                                  &audioFormat,

                                  sizeof(audioFormat));

8.2 、设置 播放的音频流描述

status = AudioUnitSetProperty(audioUnit,

                                  kAudioUnitProperty_StreamFormat,

                                  kAudioUnitScope_Input,

                                  kOutputBus,

                                  &audioFormat,

                                  sizeof(audioFormat));

9、设置回调

9.1 设置录制的回调

AURenderCallbackStruct callbackStruct;

callbackStruct.inputProc = recordingCallback;

callbackStruct.inputProcRefCon = self;



status = AudioUnitSetProperty(audioUnit,

                              kAudioOutputUnitProperty_SetInputCallback,

                              kAudioUnitScope_Global,

                              kInputBus,

                              &callbackStruct,

                              sizeof(callbackStruct));

9.2、设置播放的回调

callbackStruct.inputProc = playbackCallback;

callbackStruct.inputProcRefCon = self;



status = AudioUnitSetProperty(audioUnit,

                              kAudioUnitProperty_SetRenderCallback,

                              kAudioUnitScope_Global,

                              kOutputBus,

                              &callbackStruct,

                              sizeof(callbackStruct));

10、回调方法

10.1 录制的回调方法

` static OSStatus recordingCallback(void *inRefCon,

                              AudioUnitRenderActionFlags *ioActionFlags,

                              const AudioTimeStamp *inTimeStamp,

                              UInt32 inBusNumber,

                              UInt32 inNumberFrames,

                              AudioBufferList *ioData) {



AudioBufferList *bufferList;

OSStatus status = AudioUnitRender([(shockmanViewController *)inRefCon audioUnit],

                                  ioActionFlags,

                                  inTimeStamp,

                                  inBusNumber,

                                  inNumberFrames,

                                  bufferList);

return noErr;

}`

10.2 、播放的回调方法

`static OSStatus playbackCallback(void *inRefCon,

                             AudioUnitRenderActionFlags *ioActionFlags,

                             const AudioTimeStamp *inTimeStamp,

                             UInt32 inBusNumber,

                             UInt32 inNumberFrames,

                             AudioBufferList *ioData) {



return noErr;

}`

11、初始化AudioUnit

status = AudioUnitInitialize(_audioUnit);

12、开启 AudioUnit

OSStatus status = AudioOutputUnitStart(audioUnit);

13、关闭Audio unit

OSStatus status = AudioOutputUnitStop(audioUnit);

14、销毁Audio unit

AudioComponentInstanceDispose(audioUnit);

15、设置回声消除

///0 开启,1 关闭

`-(void)openOrCloseEchoCancellation:(UInt32)newEchoCancellationStatus

{

UInt32 echoCancellation;

UInt32 size = sizeof(echoCancellation);

AudioUnitGetProperty(_audioUnit,

                     kAUVoiceIOProperty_BypassVoiceProcessing,

                     kAudioUnitScope_Global,

                     0,

                     &echoCancellation,

                     &size);

if (newEchoCancellationStatus == echoCancellation)

{

    return;

}



AudioUnitSetProperty(_audioUnit,

                     kAUVoiceIOProperty_BypassVoiceProcessing,

                     kAudioUnitScope_Global,

                     0,

                     &newEchoCancellationStatus,

                     sizeof(newEchoCancellationStatus));

}

`