Example #1
0
int main (int argc, const char * argv[]) 
{
	if (argc == 1) {
		fprintf (stderr, "%s\n", usageStr);
		exit(0);
	}
	
	char* filePath = 0;
	bool shouldPlay = false;
	bool shouldSetBank = false;
    bool shouldUseMIDIEndpoint = false;
	bool shouldPrint = true;
	bool waitAtEnd = false;
	bool diskStream = false;
	
	OSType dataFormat = 0;
	Float64 srate = 0;
	const char* outputFilePath = 0;
	
	MusicSequenceLoadFlags	loadFlags = 0;
	
	char* bankPath = 0;
	Float32 startTime = 0;
	UInt32 numFrames = 512;
	
	for (int i = 1; i < argc; ++i)
	{
		if (!strcmp ("-p", argv[i]))
		{
			shouldPlay = true;
		}
		else if (!strcmp ("-w", argv[i]))
		{
			waitAtEnd = true;
		}
		else if (!strcmp ("-d", argv[i]))
		{
			diskStream = true;
		}
		else if (!strcmp ("-b", argv[i])) 
		{
			shouldSetBank = true;
			if (++i == argc) goto malformedInput;
			bankPath = const_cast<char*>(argv[i]);
		}
		else if (!strcmp ("-n", argv[i]))
		{
			shouldPrint = false;
		}
		else if ((filePath == 0) && (argv[i][0] == '/' || argv[i][0] == '~'))
		{
			filePath = const_cast<char*>(argv[i]);
		}
		else if (!strcmp ("-t", argv[i])) 
		{
			if (++i == argc) goto malformedInput;
			sscanf (argv[i], "%f", &startTime);
		}
		else if (!strcmp("-e", argv[i]))
        {
            shouldUseMIDIEndpoint = true;
        }
		else if (!strcmp("-c", argv[i]))
        {
            loadFlags = kMusicSequenceLoadSMF_ChannelsToTracks;
        }
        else if (!strcmp ("-i", argv[i])) 
		{
			if (++i == argc) goto malformedInput;
			sscanf (argv[i], "%ld", &numFrames);
		}
        else if (!strcmp ("-f", argv[i])) 
		{
			if (i + 3 >= argc) goto malformedInput;
			outputFilePath = argv[++i];
			str2OSType (argv[++i], dataFormat);
			sscanf (argv[++i], "%lf", &srate);
		}
		else
		{
malformedInput:
			fprintf (stderr, "%s\n", usageStr);
			exit (1);
		}
	}
	
	if (filePath == 0) {
		fprintf (stderr, "You have to specify a MIDI file to print or play\n");
		fprintf (stderr, "%s\n", usageStr);
		exit (1);
	}
	
	if (shouldUseMIDIEndpoint && outputFilePath) {
		printf ("can't write a file when you try to play out to a MIDI Endpoint\n");
		exit (1);
	}
	
	MusicSequence sequence;
	OSStatus result;
	
	require_noerr (result = LoadSMF (filePath, sequence, loadFlags), fail);
			
	if (shouldPrint) 
		CAShow (sequence);
	
	if (shouldPlay)
	{
        AUGraph graph = 0;
        AudioUnit theSynth = 0;
		
		require_noerr (result = MusicSequenceGetAUGraph (sequence, &graph), fail);
		require_noerr (result = AUGraphOpen (graph), fail);     
		  
		require_noerr (result = GetSynthFromGraph (graph, theSynth), fail);
		require_noerr (result = AudioUnitSetProperty (theSynth,
										kAudioUnitProperty_CPULoad,
										kAudioUnitScope_Global, 0,
										&maxCPULoad, sizeof(maxCPULoad)), fail);

        if (shouldUseMIDIEndpoint) 
		{
			MIDIClientRef	theMidiClient;
			MIDIClientCreate(CFSTR("Play Sequence"), NULL, NULL, &theMidiClient);		
            
			ItemCount destCount = MIDIGetNumberOfDestinations();
            if (destCount == 0) {
                fprintf (stderr, "No MIDI Endpoints to play to.\n");
                exit(1);
            }
            
            require_noerr (result = MusicSequenceSetMIDIEndpoint (sequence, MIDIGetDestination(0)), fail);
        } 
		else 
		{   
			if (shouldSetBank) {                
				FSRef soundBankRef;
				require_noerr (result = FSPathMakeRef ((const UInt8*)bankPath, &soundBankRef, 0), fail);
								
				printf ("Setting Sound Bank:%s\n", bankPath);
					
				require_noerr (result = AudioUnitSetProperty (theSynth,
												kMusicDeviceProperty_SoundBankFSRef,
												kAudioUnitScope_Global, 0,
												&soundBankRef, sizeof(soundBankRef)), fail);
			}
						
			if (diskStream) {
				UInt32 value = diskStream;
				require_noerr (result = AudioUnitSetProperty (theSynth,
											kMusicDeviceProperty_StreamFromDisk,
											kAudioUnitScope_Global, 0,
											&value, sizeof(value)), fail);
			}

			if (outputFilePath) {
				// need to tell synth that is going to render a file.
				UInt32 value = 1;
				require_noerr (result = AudioUnitSetProperty (theSynth,
												kAudioUnitProperty_OfflineRender,
												kAudioUnitScope_Global, 0,
												&value, sizeof(value)), fail);
			}
			
			require_noerr (result = SetUpGraph (graph, numFrames, srate, (outputFilePath != NULL)), fail);
			
			if (shouldPrint) {
				printf ("Sample Rate: %.1f \n", srate);
				printf ("Disk Streaming is enabled: %c\n", (diskStream ? 'T' : 'F'));
			}
			
			require_noerr (result = AUGraphInitialize (graph), fail);

            if (shouldPrint)
				CAShow (graph);
        }
        
		MusicPlayer player;
		require_noerr (result = NewMusicPlayer (&player), fail);

		require_noerr (result = MusicPlayerSetSequence (player, sequence), fail);

	// figure out sequence length
		UInt32 ntracks;
		require_noerr(MusicSequenceGetTrackCount (sequence, &ntracks), fail);
		MusicTimeStamp sequenceLength = 0;
		for (UInt32 i = 0; i < ntracks; ++i) {
			MusicTrack track;
			MusicTimeStamp trackLength;
			UInt32 propsize = sizeof(MusicTimeStamp);
			require_noerr (result = MusicSequenceGetIndTrack(sequence, i, &track), fail);
			require_noerr (result = MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength,
							&trackLength, &propsize), fail);
			if (trackLength > sequenceLength)
				sequenceLength = trackLength;
		}
	
	// now I'm going to add 8 beats on the end for the reverb/long releases to tail off...
		sequenceLength += 8;
		
		require_noerr (result = MusicPlayerSetTime (player, startTime), fail);
		
		require_noerr (result = MusicPlayerPreroll (player), fail);
		
		if (shouldPrint) {
			printf ("Ready to play: %s, %.2f beats long\n\t<Enter> to continue: ", filePath, sequenceLength); 

			getc(stdin);
		}
		
		startRunningTime = AudioGetCurrentHostTime ();
		
		require_noerr (result = MusicPlayerStart (player), fail);
		
		if (outputFilePath) 
			WriteOutputFile (outputFilePath, dataFormat, srate, sequenceLength, shouldPrint, graph, numFrames, player);
		else
			PlayLoop (player, graph, sequenceLength, shouldPrint, waitAtEnd);
					
		require_noerr (result = MusicPlayerStop (player), fail);
		if (shouldPrint) printf ("finished playing\n");
			
// this shows you how you should dispose of everything
		require_noerr (result = DisposeMusicPlayer (player), fail);
		require_noerr (result = DisposeMusicSequence(sequence), fail);
		// don't own the graph so don't dispose it (the seq owns it as we never set it ourselves, we just got it....)
	}
	else {
		require_noerr (result = DisposeMusicSequence(sequence), fail);
	}
	
	while (waitAtEnd)
		CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false);
		
    return 0;
	
fail:
	if (shouldPrint) printf ("Error = %ld\n", result);
	return result;
}
int main (int argc, const char * argv[]) 
{
	char* filePath = NULL;
	bool overwrite = false;
	ComponentDescription	compDesc = {0, 0, 0, 0, 0};
	AudioFileID inputFileID = 0;
	AudioFileID outputFileID = 0;
	CAStreamBasicDescription desc;
	AudioUnit theUnit = 0;
	
	setbuf (stdout, NULL);
	
	for (int i = 1; i < argc; ++i)
	{
		if (strcmp (argv[i], "-u") == 0) {
            if ( (i + 3) < argc ) {                
                compDesc.componentType = str2OSType (argv[i + 1]);
                compDesc.componentSubType = str2OSType (argv[i + 2]);
                compDesc.componentManufacturer = str2OSType (argv[i + 3]);
				Component comp = FindNextComponent (NULL, &compDesc);
				if (comp == NULL)
					break;
				OpenAComponent (comp, &theUnit);
				i += 3;
			} else {
				printf ("Which Component:\n%s", usageStr);
				return -1;
			}
		}
		else if (strcmp (argv[i], "-f") == 0) {
			filePath = const_cast<char*>(argv[++i]);
			printf ("Input File:%s\n", filePath);
		}
		else if (strcmp (argv[i], "-o") == 0) {
			overwrite = true;
		}
		else {
			printf ("%s\n", usageStr);
			return -1;
		}
	}
	
	if (compDesc.componentType == 0) {
		printf ("Must specify AU:\n%s\n", usageStr);
		return -1;
	}
	
	if (theUnit == 0) {
		printf ("Can't find specified unit\n");
		return -1;
	}
	
	if (filePath == NULL) {
		printf ("Must specify file to process:\n%s\n", usageStr);
		return -1;
	}
	
	OSStatus result = 0;
	if (result = InputFile (filePath, inputFileID)) {
		printf ("Result = %ld, parsing input file, exit...\n", result);
		return result;
	}
			
		
	UInt32 fileType;
	UInt32 size = sizeof (fileType);
	result = AudioFileGetProperty (inputFileID, kAudioFilePropertyFileFormat, &size, &fileType);
	if (result) {
		printf ("Error getting File Type of input file:%ld, exit...\n", result);
		return result;
	}
	size = sizeof (desc);
	result = AudioFileGetProperty (inputFileID, kAudioFilePropertyDataFormat, &size, &desc);
	if (result) {
		printf ("Error getting File Format of input file:%ld, exit...\n", result);
		return result;
	}
	if (desc.IsPCM() == false) {
		printf ("Only processing linear PCM file types and data:\n");
		desc.Print();
		return -1;
	}
	result = OutputFile (filePath, fileType, compDesc.componentSubType, overwrite, desc, outputFileID);
	if (result) {
		printf ("Error creating output file:%ld, exit...\n", result);
		return result;
	}	
	
// at this point we're ready to process	
	return Process (theUnit, compDesc, inputFileID, desc, outputFileID);
}
Example #3
0
void ParseArgs (int argc, char * const argv[],
                AudioFileTypeID	&	outFormat,
                Float64	&			outSampleRate,
                OSType	&			outFileType,
                CFURLRef&			outInputFileURL,
                CFURLRef&			outOutputFileURL,
                UInt32  &			outBitDepth,
                UInt32  &			outBitRate)
{
	if (argc < 2) {
		printf ("No Input File specified\n");
		UsageString(1);
	}
	
	// support "ConvertFile -h" usage
	if (argc == 2 && !strcmp("-h", argv[1])) {
		UsageString(0);
	}
	
	// first validate our initial condition
	const char* inputFileName = argv[1];
	
	outInputFileURL = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault, (const UInt8 *)inputFileName, strlen(inputFileName), false);
	if (!outInputFileURL) {
		printf ("* * Bad input file path\n");
		UsageString(1);
    }
	
	outBitRate = 0;
	outBitDepth = 0;
	
	// look to see if a format or different file output has been specified
	for (int i = 2; i < argc; ++i) {
		if (!strcmp ("-d", argv[i])) {
			str2OSType (argv[++i], outFormat);
			outSampleRate = 0;
		}
		else if (!strcmp ("-r", argv[i])) {
			sscanf (argv[++i], "%lf", &outSampleRate);
			outFormat = 0;
		}
		else if (!strcmp("-bd", argv[i])) {
			int temp;
			sscanf (argv[++i], "%d", &temp);
			outBitDepth = temp;
		}
		else if (!strcmp ("-f", argv[i])) {
			str2OSType (argv[++i], outFileType);
		}
		else if (!strcmp ("-b", argv[i])) {
			int temp;
			sscanf (argv[++i], "%u", &temp);
			outBitRate = temp;
		}
		else if (!strcmp ("-h", argv[i])) {
			UsageString(0);
		}
		else {
			printf ("* * Unknown command: %s\n", argv[i]);
			UsageString(1);
		}
	}
	
    // output file
	UInt32 size = sizeof(CFArrayRef);
	CFArrayRef extensions;
	OSStatus err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_ExtensionsForType,
                                          sizeof(OSType), &outFileType,
                                          &size, &extensions);
	XThrowIfError (err, "Getting the file extensions for file type");
    
	// just take the first extension
	CFStringRef ext = (CFStringRef)CFArrayGetValueAtIndex(extensions, 0);
	char extstr[32];
	Boolean res = CFStringGetCString(ext, extstr, 32, kCFStringEncodingUTF8);
	XThrowIfError (!res, "CFStringGetCString");
	
	// release the array as we're done with this now
	CFRelease (extensions);
    
	char outFname[256];
#if TARGET_OS_WIN32
	char drive[3], dir[256];
	_splitpath_s(inputFileName, drive, 3, dir, 256, NULL, 0, NULL, 0);
	_makepath_s(outFname, 256, drive, dir, "outfile", extstr);
#else
    //	char outFname[64];
	sprintf (outFname, "/tmp/outfile.%s", extstr);
#endif
	outOutputFileURL = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault, (const UInt8 *)outFname, strlen(outFname), false);
	if (!outOutputFileURL) {
		printf ("* * Bad output file path\n");
		UsageString(1);
    }
}