Created
January 29, 2010 03:51
-
-
Save alexbw/289428 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Setting up the Audio Session... | |
// Initialize and configure the audio session, and add an interuption listener | |
AudioSessionInitialize(NULL, NULL, sessionInterruptionListener, self); | |
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; | |
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); | |
// Allow iPod audio to continue to play while the app is active. | |
UInt32 flag = 1; | |
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(flag), &flag); | |
// Add a property listener to listen to changes to the session | |
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, sessionPropertyListener, self); | |
Float32 preferredBufferSize = 0.00125; | |
AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize); | |
//set the audio session active | |
AudioSessionSetActive(YES); | |
OSStatus err; | |
// Now start setting up the graph & nodes | |
//create the graph & its only node, which will be of type remoteIO | |
NewAUGraph(&graph); | |
AUNode ioNode; | |
// First describe the node, graphs are made up of nodes connected together, in this graph there is only one node. | |
// the descriptions for the components | |
AudioComponentDescription outputDescription; | |
outputDescription.componentFlags = 0; | |
outputDescription.componentFlagsMask = 0; | |
outputDescription.componentType = kAudioUnitType_Output; | |
outputDescription.componentSubType = kAudioUnitSubType_RemoteIO; | |
outputDescription.componentManufacturer = kAudioUnitManufacturer_Apple; | |
// Create the remoteIO node, and open the graph | |
err = AUGraphAddNode(graph, &outputDescription, &ioNode); | |
NSAssert(err == noErr, @"Failed to add the remoteIO node"); | |
err = AUGraphOpen (graph); | |
NSAssert(err == noErr, @"Opening the audio graph failed"); | |
// Grab an instance of the remoteIO unit from the graph | |
AudioUnit ioUnit; | |
err = AUGraphNodeInfo(graph, ioNode, NULL, &ioUnit); | |
NSAssert(err == noErr, @"NOOO! (couldn't get the node info)"); | |
// Set the audio format on the audio unit instance | |
AudioStreamBasicDescription audioFormat; | |
memset(&audioFormat, 0, sizeof(audioFormat)); | |
// Let's talk formats for just a sec | |
audioFormat.mSampleRate = 44100.0f; | |
audioFormat.mFormatID = kAudioFormatLinearPCM; | |
audioFormat.mFormatFlags = kAudioFormatFlagsCanonical; | |
audioFormat.mFramesPerPacket = 1; | |
audioFormat.mChannelsPerFrame = 1; | |
audioFormat.mBitsPerChannel = 16; | |
audioFormat.mBytesPerPacket = 2; | |
audioFormat.mBytesPerFrame = 2; | |
// set the format on the bus coming into the app ... | |
err = AudioUnitSetProperty(ioUnit, | |
kAudioUnitProperty_StreamFormat, | |
kAudioUnitScope_Output, | |
kInputBus, | |
&audioFormat, | |
sizeof(audioFormat)); | |
NSAssert(err == noErr, @"Error setting Output Scope for Bus 1 (from microphone to app)"); | |
// ... and on the bus leaving the app for the mic | |
err = AudioUnitSetProperty(ioUnit, | |
kAudioUnitProperty_StreamFormat, | |
kAudioUnitScope_Input, | |
kOutputBus, | |
&audioFormat, | |
sizeof(audioFormat)); | |
NSAssert(err == noErr, @"Error setting Input Scope for Bus 0 (from app to mic)"); | |
// Enable IO from the mic to the app... | |
UInt32 one = 1; | |
err = AudioUnitSetProperty(ioUnit, | |
kAudioOutputUnitProperty_EnableIO, | |
kAudioUnitScope_Input, | |
kInputBus, // BUS 1 | |
&one, | |
sizeof(one)); | |
NSAssert(err == noErr, @"Could not enable the Input Scope of Bus 1"); | |
// ... and from the app back out to the mic | |
err = AudioUnitSetProperty(ioUnit, | |
kAudioOutputUnitProperty_EnableIO, | |
kAudioUnitScope_Output, | |
kOutputBus, // BUS 0 | |
&one, | |
sizeof(one)); | |
NSAssert(err == noErr, @"Could not enable the Output Scope of Bus 0"); | |
// This is what doesn't seem to be working | |
// *********************************** | |
AURenderCallbackStruct playbackCallbackStruct; | |
playbackCallbackStruct.inputProc = continuousDisplayOutputCallback; | |
continuousCallbackData *cd = (continuousCallbackData *)malloc(sizeof(continuousCallbackData)); | |
cd->ssb = secondStageBuffer; | |
cd->au = &outputAudioUnit; | |
playbackCallbackStruct.inputProcRefCon = cd; | |
// Register a callback with the AUNode | |
err = AUGraphSetNodeInputCallback (graph, | |
ioNode, | |
kInputBus, | |
&playbackCallbackStruct); | |
// continuousDisplayOutputCallback() is never entered! I have an NSLog; return; right at the beginning, | |
// and the app sits silent after initialization, and no audio is acquired. | |
// *********************************** | |
// Now we get to start it all up! | |
err = AUGraphInitialize(graph); | |
NSAssert(err == noErr, @"Could not initialize audio graph"); | |
err = AUGraphStart(graph); | |
NSAssert(err == noErr, @"Could not start audio graph"); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment