ios audio unit 提供了強大的混音功能, 這就就不介紹audioUnit 的基本邏輯和使用方法了,直接開始介紹介紹
要實現混音必須使用 audioGraph
1 : 第一步 初始化兩個unit ( 一個misUnit 一個 ioUnit )
// augraph
CheckError(NewAUGraph(&auGraph), "NewAUGraph error");
CheckError(AUGraphOpen(auGraph), "open graph fail");
// output audio unit
AudioComponentDescription outputAudioDesc;
outputAudioDesc.componentType = kAudioUnitType_Output;//audioUnit類型(一共有四種)
outputAudioDesc.componentSubType = kAudioUnitSubType_VoiceProcessingIO;//子類型
// outputAudioDesc.componentSubType = kAudioUnitSubType_RemoteIO;;//子類型
outputAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
outputAudioDesc.componentFlags = 0;
outputAudioDesc.componentFlagsMask = 0;
// AUNode outputNode;
CheckError(AUGraphAddNode(auGraph, &outputAudioDesc, &outputNode), "add node fail");
CheckError(AUGraphNodeInfo(auGraph, outputNode, NULL, &outputUnit), "get audio unit fail");
// mix audio unit
AudioComponentDescription mixAudioDesc;
mixAudioDesc.componentType = kAudioUnitType_Mixer;
mixAudioDesc.componentSubType = kAudioUnitSubType_MultiChannelMixer;
mixAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
mixAudioDesc.componentFlags = 0;
mixAudioDesc.componentFlagsMask = 0;
// AUNode mixNode;
CheckError(AUGraphAddNode(auGraph, &mixAudioDesc, &mixNode), "add node fail");
CheckError(AUGraphNodeInfo(auGraph, mixNode, NULL, &mixUnit), "get audio unit fail");
2 鏈接連個unit
// connect augraph 鏈接 auNode
CheckError(AUGraphConnectNodeInput(auGraph,
mixNode,
MIX_UNIT_OUTPUT_BUS,//0
outputNode,
REMOTE_IO_UNIT_OUTPUT_BUS), "connect fail");
3 設置回調
UInt32 busCount = 2;
CheckError(AudioUnitSetProperty(mixUnit,
kAudioUnitProperty_ElementCount,
kAudioUnitScope_Input,
MIX_UNIT_INPUT_BUS0,//0
&busCount,
sizeof(UInt32)), "set property fail");
AURenderCallbackStruct callback0;
callback0.inputProc = mixCallback0;
callback0.inputProcRefCon = (__bridge void *)self;
CheckError(AudioUnitSetProperty(mixUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
MIX_UNIT_INPUT_BUS0,
&callback0, sizeof(AURenderCallbackStruct)), "add mix callback fail");
CheckError(AudioUnitSetProperty(mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
MIX_UNIT_INPUT_BUS0,
&audioFormat, sizeof(AudioStreamBasicDescription)), "set mix format(input 0) fail");
AURenderCallbackStruct callback1;
callback1.inputProc = mixCallback1;
callback1.inputProcRefCon = (__bridge void *)self;
CheckError(AudioUnitSetProperty(mixUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
MIX_UNIT_INPUT_BUS1,
&callback1, sizeof(AURenderCallbackStruct)), "add mix callback fail");
CheckError(AudioUnitSetProperty(mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
MIX_UNIT_INPUT_BUS1,
&audioFormat, sizeof(AudioStreamBasicDescription)), "set mix format(input 1) fail");
_mixStreamFmt = *([[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatInt16
sampleRate:audioFormat.mSampleRate
channels:audioFormat.mChannelsPerFrame
interleaved:YES].streamDescription);
CheckError(AudioUnitSetProperty(mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&_mixStreamFmt,
sizeof(AudioStreamBasicDescription)), "add mix format(output) fail");
4 播放 因爲把兩個Unit鏈接, 只要把取數據的回調設置好系統就可以播放了