尝试
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryMixWithOthers, // 1
sizeof (allowMixing), // 2
&allowMixing // 3
);
或者您可以使用 kAudioUnitType_Mixer 类型的 AudioUnit。
AudioComponentDescription MixerUnitDescription;
MixerUnitDescription.componentType = kAudioUnitType_Mixer;
MixerUnitDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer;
MixerUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
MixerUnitDescription.componentFlags = 0;
MixerUnitDescription.componentFlagsMask = 0;
将它们 (mixer_unit,voice_processing_unit) 添加到 AUGraph 中。为混音器单元设置输入总线计数 2。
UInt32 busCount = 2; // bus count for mixer unit input
status = AudioUnitSetProperty (mixer_unit,
kAudioUnitProperty_ElementCount,
kAudioUnitScope_Input,
0,
&busCount,
sizeof(busCount)
);
为mixer_unit的每条总线添加渲染回调:
for (UInt16 busNumber = 0; busNumber < busCount; ++busNumber) {
AURenderCallbackStruct inputCallbackStruct;
inputCallbackStruct.inputProc = &VoiceMixRenderCallback;
inputCallbackStruct.inputProcRefCon = self;
status = AUGraphSetNodeInputCallback (_mixSaveGraph,
mixerNode,
busNumber,
&inputCallbackStruct
);
if (status) { printf("AudioUnitSetProperty set callback"); return NO; }
}
将mixer_unit的输出总线连接到io_unit的输入总线:
status = AUGraphConnectNodeInput (_mixSaveGraph,
mixerNode, // source node
0, // source node output bus number
saveNode, // destination node
0 // desintation node input bus number
);
启动图表,您将收到不同总线号(0 和 1)的读卡器回调,如下所示:
static OSStatus VoiceMixRenderCallback(void * inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData )
{
OSStatus status;
AURecorder *recorder = (AURecorder*)inRefCon;
if (inBusNumber == BUS_ONE && (recorder.isMusicPlaying)) {
//Get data from music file. try ExtAudioFileRead
} else if (inBusNumber == BUS_TWO) {
status = AudioUnitRender(recorder.io_unit, ioActionFlags, inTimeStamp, INPUT_BUS, inNumberFrames, ioData);
//Get data from io unit's input bus.
if (status)
{
printf("AudioUnitRender for record error");
*ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
}
} else {
*ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
}
return noErr;
}