Re: Playing 2 or more audio data simultaneously
Re: Playing 2 or more audio data simultaneously
- Subject: Re: Playing 2 or more audio data simultaneously
- From: email@hidden (Patrick Beard)
- Date: Thu, 19 Sep 2002 19:03:46 -0700
Perhaps some kind soul should set up a CoreAudio FAQ, and this would be
a good first item for it. And of course, this should be turned into a
1st class piece of sample code that any developer could use. Kudos to
Kurt for having the time (and patience) to write this up.
- Patrick
On Wednesday, September 18, 2002, at 11:53 PM, Kurt Revis wrote:
OK, I'm going to be nice, because I found some code that does (mostly)
exactly what you want. (Warning--this is pretty much typed into mail,
so there may be a few typos--and it's not necessarily great style.)
1. Open the default audio unit
AudioUnit outputAudioUnit;
Boolean setUpOutputAudioUnit() {
if (noErr != OpenDefaultAudioOutput(&outputAudioUnit)
return false;
if (noErr != AudioUnitInitialize(&outputAudioUnit)
return false;
return true;
}
2. Create a mixer AudioUnit
AudioUnit mixerAudioUnit;
Boolean setUpMixerAudioUnit() {
ComponentDescription description;
Component component;
OSStatus err;
description.componentType = kAudioUnitComponentType;
description.componentSubType = kAudioUnitSubType_Mixer;
description.componentManufacturer = kAudioUnitID_StereoMixer;
description.componentFlags = 0;
description.componentFlagsMask = 0;
component = FindNextComponent(NULL, &description);
if (!component)
return false;
if (noErr != OpenAComponent(component, &mixerAudioUnit))
return false;
if (noErr != AudioUnitInitialize(mixerAudioUnit))
return false;
return true;
}
3. Connect the output of the mixer to the audio output
Boolean connectMixer() {
struct AudioUnitConnection connection;
OSStatus err;
connection.sourceAudioUnit = mixerAudioUnit;
connection.sourceOutputNumber = 0;
connection.destInputNumber = 0;
err = AudioUnitSetProperty(outputAudioUnit,
kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0,
&connection, sizeof(struct AudioUnitConnection *));
return (err == noErr);
}
4. For each mixer input that you are dealing with, set up an input
callback
Boolean setUpMixerInputCallback(AudioUnitRenderCallback callback, void
*refCon, UInt32 busNumber) {
struct AudioUnitInputCallback callbackStruct;
OSStatus err;
callbackStruct.inputProc = callback;
callbackStruct.inputProcRefCon = refCon;
err = AudioUnitSetProperty(mixerAudioUnit,
kAudioUnitProperty_SetInputCallback, kAudioUnitScope_Input, busNumber,
&callbackStruct, sizeof(callbackStruct));
return (noErr == err);
}
5. Implement your input callback
OSStatus myMixerInputCallback(void *inRefCon,
AudioUnitRenderActionFlags inActionFlags, const AudioTimeStamp
*inTimeStamp, UInt32 inBusNumber, AudioBuffer *ioData)
{
// inRefCon and inBusNumber will be whatever you passed in to
setUpMixerInputCallback().
// inTimeStamp will be the time that the audio data will be
played. You may ignore it if you don't need it.
// Ignore inActionFlags -- the stuff it describes never got
implemented (I think).
// Write your data into the ioData buffer provided.
// YOUR CODE HERE
return noErr;
}
6. Set everything up and start playing sound
if (setUpOutputAudioUnit() && setUpMixerAudioUnit() && connectMixer())
{
for (each mixer input bus you want to use) {
setUpMixerInputCallback(myMixerInputCallback, yourRefCon,
busNumber);
}
AudioOutputUnitStart(outputAudioUnit);
}
7. Stop and clean up
AudioOutputUnitStop(outputAudioUnit);
CloseComponent(outputAudioUnit);
AudioUnitUninitialize(mixerAudioUnit);
CloseComponent(mixerAudioUnit);
That's all. Any more questions?
By the way, it's considered good form to say "thank you" to people who
help you.
--
Kurt Revis
email@hidden
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.