Paste number 22194: | Not Setting Format results in success |
Pasted by: | Mike Hanna |
When: | 18 years, 8 months ago |
Share: | Tweet this! | http://paste.lisp.org/+H4I |
Channel: | None |
Paste contents: |
-(void)makeGraph
{
XThrowIfError (NewAUGraph (&fGraph), "NewAUGraph");
CAComponentDescription cd;
UInt32 numChannels = 0;
// output node
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
AUNode outputNode;
XThrowIfError (AUGraphNewNode (fGraph, &cd, 0, NULL, &outputNode), "AUGraphNewNode");
// varispeed AU node
AUNode timepitchNode;
cd.componentType = kAudioUnitType_FormatConverter;
cd.componentSubType = kAudioUnitSubType_TimePitch;
XThrowIfError (AUGraphNewNode (fGraph, &cd, 0, NULL, &timepitchNode), "AUGraphNewNode");
// file AU node
AUNode fileNode;
cd.componentType = kAudioUnitType_Generator;
cd.componentSubType = kAudioUnitSubType_AudioFilePlayer;
XThrowIfError (AUGraphNewNode (fGraph, &cd, 0, NULL, &fileNode), "AUGraphNewNode");
// connect & setup
XThrowIfError (AUGraphOpen (fGraph), "AUGraphOpen");
// install overload listener to detect when something is wrong
AudioUnit theFileAU;
XThrowIfError (AUGraphGetNodeInfo(fGraph, fileNode, NULL, NULL, NULL, &theFileAU), "AUGraphGetNodeInfo");
// here's where we connect the local fileNode reference to the global AUFile
fFileAU = CAAudioUnit (fileNode, theFileAU);
// install overload listener to detect when something is wrong
AudioUnit theTimepitchAU;
XThrowIfError (AUGraphGetNodeInfo(fGraph, timepitchNode, NULL, NULL, NULL, &theTimepitchAU), "AUGraphGetNodeInfo");
// here's where we connect the local timepitchNode reference to the global AUVarispeed
fTimepitchAU = CAAudioUnit (timepitchNode, theTimepitchAU);
/*** using SetFormat seems to cause an exception, any idea why? ***/
// XThrowIfError( fFileAU.SetFormat( kAudioUnitScope_Input, 0, fFileFormat ), "SetFormat" );
// printf ("makeGraph file in: ");
// XThrowIfError( fFileAU.SetFormat( kAudioUnitScope_Output, 0, fFileFormat ), "SetFormat" );
// printf ("makeGraph file out: ");
// XThrowIfError( fTimepitchAU.SetFormat( kAudioUnitScope_Input, 0, fFileFormat ), "SetFormat" );
// printf ("makeGraph time in: ");
// XThrowIfError( fTimepitchAU.SetFormat( kAudioUnitScope_Output, 0, fFileFormat ), "SetFormat" );
/*** commenting-out these lines results in successful playback of multichannel audio, why? ***/
// prepare the file AU for playback
// set its output channels
// XThrowIfError (fFileAU.SetNumberChannels (kAudioUnitScope_Output, 0, fFileFormat.NumberChannels()), "SetNumberChannels");
// set the output sample rate of the file AU to be the same as the file:
// XThrowIfError (fFileAU.SetSampleRate (kAudioUnitScope_Output, 0, fFileFormat.mSampleRate), "SetSampleRate");
// load in the file
XThrowIfError (fFileAU.SetProperty(kAudioUnitProperty_ScheduledFileIDs,
kAudioUnitScope_Global, 0, &fAudioFile, sizeof(fAudioFile)), "SetScheduleFile");
/*** commenting-out these lines results in successful playback of multichannel audio, why? ***/
// set the input number of channels of the varispeed AU to be the same as the output of the file AU:
// XThrowIfError (fTimepitchAU.SetNumberChannels (kAudioUnitScope_Input, 0, fFileFormat.NumberChannels()), "SetNumberChannels");
// set the output number of channels of the varispeed AU to be the same as the output of the file AU:
// XThrowIfError (fTimepitchAU.SetNumberChannels (kAudioUnitScope_Output, 0, fFileFormat.NumberChannels()), "SetNumberChannels");
// set the input sample rate of the varispeed AU to be the same as the output of the file AU(ok I'm cheating, I'm getting the file format sample rate):
// XThrowIfError (fTimepitchAU.SetSampleRate (kAudioUnitScope_Input, 0, fFileFormat.mSampleRate), "SetSampleRate");
// connect file node to varispeed node
XThrowIfError (AUGraphConnectNodeInput (fGraph, fileNode, 0, timepitchNode, 0), "AUGraphConnectNodeInput");
// connect varispeed node to output node
XThrowIfError (AUGraphConnectNodeInput (fGraph, timepitchNode, 0, outputNode, 0), "AUGraphConnectNodeInput");
// AT this point we make sure we have the file player AU initialized
// this also propogates the output format of the AU to the output unit
XThrowIfError (AUGraphInitialize (fGraph), "AUGraphInitialize");
// workaround a race condition in the file player AU
usleep (10 * 1000);
// if we have a surround file, then we should try to tell the output AU what the order of the channels will be
if (fFileFormat.NumberChannels() > 2) {
UInt32 layoutSize = 0;
OSStatus err;
// NSLog(@"before AudioFileGetPropertyInfo kAudioFilePropertyChannelLayout");
NSLog(@"layoutSize %d", layoutSize);
try
{
XThrowIfError (err = AudioFileGetPropertyInfo (fAudioFile, kAudioFilePropertyChannelLayout, &layoutSize, NULL),
"kAudioFilePropertyChannelLayout");
}
catch(CAXException)
{
NSLog(@"caught CAXException at AudioFileGetPropertyInfo");
}
if (!err && layoutSize) {
char* layout = new char[layoutSize];
err = AudioFileGetProperty(fAudioFile, kAudioFilePropertyChannelLayout, &layoutSize, layout);
XThrowIfError (err, "Get Layout From AudioFile");
// ok, now get the output AU and set its layout
XThrowIfError (AUGraphGetNodeInfo(fGraph, outputNode, NULL, NULL, NULL, &theFileAU), "AUGraphGetNodeInfo");
delete [] layout;
}
}
XThrowIfError(AudioUnitAddRenderNotify (theFileAU, MyRenderNotification, self), "AudioUnitAddRenderNotify");
}
This paste has no annotations.