Paste number 22194: Not Setting Format results in success

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:
Raw Source | XML | Display As
-(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.

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.