Exemplo n.º 1
0
void music_pump()
{
	int i;
	MusicTimeStamp current_beat;

	// Dispose up to one MusicPlayer that wants disposing
	if (disposable_tracks && disposable_tracks->dispose_after < time(NULL)) {
		struct disposable_track * next;
		
		// Stop and free
		MusicPlayerStop(disposable_tracks->player);
		DisposeMusicPlayer(disposable_tracks->player);
		
		// Free this record, and move the list to the next record, if any
		next = disposable_tracks->next;
		free(disposable_tracks);
		disposable_tracks = next;
	}
	
	// Iterate over all tracks
	for (i = 0; i < M_MAX_MUSIC; i ++) {	
		// Check to see if we need to loop this track
		if (music_files[i].playing && music_files[i].loop) {
			// Check to see where we are on this track
			MusicPlayerGetTime(music_files[i].player, &current_beat);
			
			if (current_beat > music_files[i].track_length) {
				// We've played past the end of the track, but are supposed to loop
				// Seek back to the beginning
				MusicPlayerSetTime(music_files[i].player, 1);
			}
		}
	}
}
Exemplo n.º 2
0
void native_midi_start(NativeMidiSong *song, int loops)
{
    int vol;

    if (song == NULL)
        return;

    SDL_PauseAudio(1);
    SDL_UnlockAudio();

    if (currentsong)
        MusicPlayerStop(currentsong->player);

    currentsong = song;
    currentsong->loops = loops;

    MusicPlayerPreroll(song->player);
    MusicPlayerSetTime(song->player, 0);
    MusicPlayerStart(song->player);

    GetSequenceAudioUnit(song->sequence, &song->audiounit);

    vol = latched_volume;
    latched_volume++;  /* just make this not match. */
    native_midi_setvolume(vol);

    SDL_LockAudio();
    SDL_PauseAudio(0);
}
Exemplo n.º 3
0
// Stop a specific track
void music_stop_track(enum music_track track)
{
	struct disposable_track *d, *cur;
	
	// Do nothing unless the track is playing
	if (!music_files[track].playing)
		return;
	
	// Seek past the end of the file to stop new music from coming out
	MusicPlayerSetTime(music_files[track].player, music_files[track].track_length + 1);
	
	// Move the MusicPlayer to a new "dispose me" entry
	d = (struct disposable_track *)malloc(sizeof(struct disposable_track));
	d->next = NULL;
	d->player = music_files[track].player;
	d->dispose_after = time(NULL) + 5;
	
	// Add to the end of the list, or make a new list as required
	cur = disposable_tracks;
	while (cur && cur->next)
		cur = cur->next;
	if (cur)
		cur->next = d;
	else
		disposable_tracks = d;
	
	// Mark as not playing and not muted
	music_files[track].playing = 0;
	music_files[track].muted = 0;
}
Exemplo n.º 4
0
int native_midi_active()
{
    MusicTimeStamp currentTime = 0;
    if (currentsong == NULL)
        return 0;

    MusicPlayerGetTime(currentsong->player, &currentTime);
    if ((currentTime < currentsong->endTime) ||
        (currentTime >= kMusicTimeStamp_EndOfTrack)) {
        return 1;
    } else if (currentsong->loops) {
        --currentsong->loops;
        MusicPlayerSetTime(currentsong->player, 0);
        return 1;
    }
    return 0;
}
Exemplo n.º 5
0
// Start playing the given track
void music_start_loop(enum music_track track, int loop)
{
	OSStatus result;
	
	// Load as necessary
	music_load(track);
	
	// Ensure we can we play this
	if (!music_files[track].sequence_loaded)
		return;
	
	// Keep track of if we should loop or not
	music_files[track].loop = loop;
	
	// Is this already playing, or would it be playing if we weren't muted?
	if (music_files[track].playing || music_files[track].muted)
		return;
	
	// TODO: fix the code that calls the music system so that we don't have two tracks running at once
	// For now, stop any other tracks
	music_stop();
	
	// If we're muted, mark this track as muted, and bail out
	if (mute_music) {
		music_files[track].muted = 1;
		return;
	}
	
	// Initialize the music player and attach the sequence
	require_noerr(result = NewMusicPlayer(&music_files[track].player), fail);
	require_noerr(result = MusicPlayerSetSequence(music_files[track].player, music_files[track].sequence), fail);
	
	// Determine the track length if we don't know it already
	if (music_files[track].track_length <= 1.0) {
		UInt32 track_count, i;
		require_noerr(result = MusicSequenceGetTrackCount(music_files[track].sequence, &track_count), fail);

		for (i = 0; i < track_count; i++) {
			MusicTrack midi_track;
			MusicTimeStamp track_length;
			UInt32 property_size = sizeof(MusicTimeStamp);
			
			// Get the track within the MIDI file
			require_noerr(result = MusicSequenceGetIndTrack(music_files[track].sequence, i, &midi_track), fail);
			
			// Determine its length
			require_noerr(result = MusicTrackGetProperty(midi_track, kSequenceTrackProperty_TrackLength, &track_length, &property_size), fail);
			
			// Update the music track length if this MIDI track is longer
			if (track_length > music_files[track].track_length)
				music_files[track].track_length = track_length;
		}		
	}
	
	// Seek and pre-roll to the beginning
	require_noerr(result = MusicPlayerSetTime(music_files[track].player, 0), fail);
	require_noerr(result = MusicPlayerPreroll(music_files[track].player), fail);
	
	// Start playing
	require_noerr(result = MusicPlayerStart(music_files[track].player), fail);
	
	// Mark as playing
	music_files[track].playing = 1;
	
	return;
		
fail:
	WARNING2("unexpected error playing MIDI track; result=%ld", result);
	music_files[track].unplayable = 1;
	return;	
}
JNIEXPORT jint JNICALL Java_com_apple_audio_toolbox_MusicPlayer_MusicPlayerSetTime
  (JNIEnv *, jclass, jint inPlayer, jdouble inTime)
{
	return (jint)MusicPlayerSetTime((MusicPlayer)inPlayer, (MusicTimeStamp)inTime);
}
Exemplo n.º 7
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;
	
	std::set<int> trackSet;
	
	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 ("-s", argv[i])) 
		{
			if (++i == argc) goto malformedInput;
			sscanf (argv[i], "%f", &startTime);
		}
		else if (!strcmp ("-t", argv[i])) 
		{
			int index;
			if (++i == argc) goto malformedInput;
			sscanf (argv[i], "%d", &index);
			trackSet.insert(--index);
		}
		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], "%lu", (unsigned long*)(&numFrames));
		}
        else if (!strcmp ("-f", argv[i])) 
		{
			if (i + 3 >= argc) goto malformedInput;
			outputFilePath = argv[++i];
			StrToOSType (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;
	
	FailIf ((result = LoadSMF (filePath, sequence, loadFlags)), fail, "LoadSMF");
			
	if (shouldPrint) 
		CAShow (sequence);
	
	if (shouldPlay)
	{
        AUGraph graph = 0;
        AudioUnit theSynth = 0;
		
		FailIf ((result = MusicSequenceGetAUGraph (sequence, &graph)), fail, "MusicSequenceGetAUGraph");
		FailIf ((result = AUGraphOpen (graph)), fail, "AUGraphOpen");     
		  
		FailIf ((result = GetSynthFromGraph (graph, theSynth)), fail, "GetSynthFromGraph");
		FailIf ((result = AudioUnitSetProperty (theSynth,
										kAudioUnitProperty_CPULoad,
										kAudioUnitScope_Global, 0,
										&maxCPULoad, sizeof(maxCPULoad))), fail, "AudioUnitSetProperty: kAudioUnitProperty_CPULoad");

        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);
            }
            
            FailIf ((result = MusicSequenceSetMIDIEndpoint (sequence, MIDIGetDestination(0))), fail, "MusicSequenceSetMIDIEndpoint");
        } 
		else 
		{   
			if (shouldSetBank) {
				CFURLRef soundBankURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)bankPath, strlen(bankPath), false);
								
				printf ("Setting Sound Bank:%s\n", bankPath);
					
				result = AudioUnitSetProperty (theSynth,
                                               kMusicDeviceProperty_SoundBankURL,
                                               kAudioUnitScope_Global, 0,
                                               &soundBankURL, sizeof(soundBankURL));
                if (soundBankURL) CFRelease(soundBankURL);
                FailIf (result, fail, "AudioUnitSetProperty: kMusicDeviceProperty_SoundBankURL");								
			}
						
			if (diskStream) {
				UInt32 value = diskStream;
				FailIf ((result = AudioUnitSetProperty (theSynth,
											kMusicDeviceProperty_StreamFromDisk,
											kAudioUnitScope_Global, 0,
											&value, sizeof(value))), fail, "AudioUnitSetProperty: kMusicDeviceProperty_StreamFromDisk");
			}

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

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

		FailIf ((result = MusicPlayerSetSequence (player, sequence)), fail, "MusicPlayerSetSequence");

		// figure out sequence length
		UInt32 ntracks;
		FailIf ((MusicSequenceGetTrackCount (sequence, &ntracks)), fail, "MusicSequenceGetTrackCount");
		MusicTimeStamp sequenceLength = 0;
		bool shouldPrintTracks = shouldPrint && !trackSet.empty();
		if (shouldPrintTracks)
			printf ("Only playing specified tracks:\n\t");
		
		for (UInt32 i = 0; i < ntracks; ++i) {
			MusicTrack track;
			MusicTimeStamp trackLength;
			UInt32 propsize = sizeof(MusicTimeStamp);
			FailIf ((result = MusicSequenceGetIndTrack(sequence, i, &track)), fail, "MusicSequenceGetIndTrack");
			FailIf ((result = MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength,
							&trackLength, &propsize)), fail, "MusicTrackGetProperty: kSequenceTrackProperty_TrackLength");
			if (trackLength > sequenceLength)
				sequenceLength = trackLength;
			
			if (!trackSet.empty() && (trackSet.find(i) == trackSet.end()))
			{
				Boolean mute = true;
				FailIf ((result = MusicTrackSetProperty(track, kSequenceTrackProperty_MuteStatus, &mute, sizeof(mute))), fail, "MusicTrackSetProperty: kSequenceTrackProperty_MuteStatus");
			} 
			else if (shouldPrintTracks) {
				printf ("%d, ", int(i+1));
			}
		}
		if (shouldPrintTracks) 
			printf ("\n");
			
	// now I'm going to add 8 beats on the end for the reverb/long releases to tail off...
		sequenceLength += 8;
		
		FailIf ((result = MusicPlayerSetTime (player, startTime)), fail, "MusicPlayerSetTime");
		
		FailIf ((result = MusicPlayerPreroll (player)), fail, "MusicPlayerPreroll");
		
		if (shouldPrint) {
			printf ("Ready to play: %s, %.2f beats long\n\t<Enter> to continue: ", filePath, sequenceLength); 

			getc(stdin);
		}
		
        startRunningTime = CAHostTimeBase::GetTheCurrentTime();
		
/*		if (waitAtEnd && graph)
			AUGraphStart(graph);
*/		
		FailIf ((result = MusicPlayerStart (player)), fail, "MusicPlayerStart");
		
		if (outputFilePath) 
			WriteOutputFile (outputFilePath, dataFormat, srate, sequenceLength, shouldPrint, graph, numFrames, player);
		else
			PlayLoop (player, graph, sequenceLength, shouldPrint, waitAtEnd);
					
		FailIf ((result = MusicPlayerStop (player)), fail, "MusicPlayerStop");
		if (shouldPrint) printf ("finished playing\n");

/*		if (waitAtEnd) {
			CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false);
			if (graph)
				AUGraphStop(graph);
			if (shouldPrint) printf ("disposing\n");
		}
*/		
// this shows you how you should dispose of everything
		FailIf ((result = DisposeMusicPlayer (player)), fail, "DisposeMusicPlayer");
		FailIf ((result = DisposeMusicSequence(sequence)), fail, "DisposeMusicSequence");
		// 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 {
		FailIf ((result = DisposeMusicSequence(sequence)), fail, "DisposeMusicSequence");
	}
	
	while (waitAtEnd)
		CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false);
		
    return 0;
	
fail:
	if (shouldPrint) printf ("Error = %ld\n", (long)result);
	return result;
}
Exemplo n.º 8
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;
}