// Ensure that the specified music track is in memory, loading it if required void music_load(enum music_track track) { char name[80] = ""; FILE * midi_f; char * midi_data = NULL; size_t fileLength; int i; OSStatus rv; // Don't (try to) load the track twice if (music_files[track].sequence_loaded || music_files[track].unplayable) return; // Find the name for this track for (i = 0; music_key[i].track != M_MAX_MUSIC; i++) { if (music_key[i].track == track && music_key[i].name) { snprintf(name, sizeof(name), "%s.MID", music_key[track].name); break; } } // Bail out if this track isn't known if (strlen(name) == 0) { music_files[track].unplayable = 1; return; } // Read the MIDI file into memory midi_f = sOpen(name, "rb", FT_MIDI); if (midi_f != NULL) { fileLength = fread_dyn(&midi_data, &fileLength, midi_f); fclose(midi_f); } if (midi_data == NULL) { WARNING2("could not read MIDI file `%s'", name); music_files[track].unplayable = 1; return; } // Initialize the sequence rv = NewMusicSequence(&music_files[track].sequence); if (rv == 0) { // Try to load the sequence out of this buffer #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 /* this is deprecated, but works back to 10.3 */ rv = MusicSequenceLoadSMFDataWithFlags(music_files[track].sequence, CFDataCreate(NULL, (UInt8*)midi_data, fileLength), 0); #else /* not deprecated, but requires 10.5 or later */ rv = MusicSequenceFileLoadData(music_files[track].sequence, CFDataCreate(NULL, (UInt8*)midi_data, fileLength), 0, 0); #endif } // Regardless, free the buffer we read off disk, if any free(midi_data); // Did it work? if (rv) { WARNING2("could not understand MIDI file `%s'", name); music_files[track].unplayable = 1; } else { music_files[track].sequence_loaded = 1; } }
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *src, int freesrc) { NativeMidiSong *retval = NULL; void *buf = NULL; Sint64 len = 0; CFDataRef data = NULL; if (SDL_RWseek(src, 0, RW_SEEK_END) < 0) goto fail; len = SDL_RWtell(src); if (len < 0) goto fail; if (SDL_RWseek(src, 0, RW_SEEK_SET) < 0) goto fail; buf = malloc(len); if (buf == NULL) goto fail; if (SDL_RWread(src, buf, len, 1) != 1) goto fail; retval = malloc(sizeof(NativeMidiSong)); if (retval == NULL) goto fail; memset(retval, '\0', sizeof (*retval)); if (NewMusicPlayer(&retval->player) != noErr) goto fail; if (NewMusicSequence(&retval->sequence) != noErr) goto fail; data = CFDataCreate(NULL, (const UInt8 *) buf, len); if (data == NULL) goto fail; free(buf); buf = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 /* MusicSequenceLoadSMFData() (avail. in 10.2, no 64 bit) is * equivalent to calling MusicSequenceLoadSMFDataWithFlags() * with a flags value of 0 (avail. in 10.3, avail. 64 bit). * So, we use MusicSequenceLoadSMFData() for powerpc versions * but the *WithFlags() on intel which require 10.4 anyway. */ # if defined(__ppc__) || defined(__POWERPC__) if (MusicSequenceLoadSMFData(song->sequence, data) != noErr) goto fail; # else if (MusicSequenceLoadSMFDataWithFlags(retval->sequence, data, 0) != noErr) goto fail; # endif #else /* MusicSequenceFileLoadData() requires 10.5 or later. */ if (MusicSequenceFileLoadData(retval->sequence, data, 0, 0) != noErr) goto fail; #endif CFRelease(data); data = NULL; if (GetSequenceLength(retval->sequence, &retval->endTime) != noErr) goto fail; if (MusicPlayerSetSequence(retval->player, retval->sequence) != noErr) goto fail; if (freesrc) SDL_RWclose(src); return retval; fail: if (retval) { if (retval->sequence) DisposeMusicSequence(retval->sequence); if (retval->player) DisposeMusicPlayer(retval->player); free(retval); } if (data) CFRelease(data); if (buf) free(buf); return NULL; }
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw) { NativeMidiSong *retval = NULL; void *buf = NULL; int len = 0; CFDataRef data = NULL; if (SDL_RWseek(rw, 0, RW_SEEK_END) < 0) goto fail; len = SDL_RWtell(rw); if (len < 0) goto fail; if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0) goto fail; buf = malloc(len); if (buf == NULL) goto fail; if (SDL_RWread(rw, buf, len, 1) != 1) goto fail; retval = malloc(sizeof(NativeMidiSong)); if (retval == NULL) goto fail; memset(retval, '\0', sizeof (*retval)); if (NewMusicPlayer(&retval->player) != noErr) goto fail; if (NewMusicSequence(&retval->sequence) != noErr) goto fail; data = CFDataCreate(NULL, (const UInt8 *) buf, len); if (data == NULL) goto fail; free(buf); buf = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 /* this is deprecated, but works back to 10.3 */ if (MusicSequenceLoadSMFDataWithFlags(retval->sequence, data, 0) != noErr) goto fail; #else /* not deprecated, but requires 10.5 or later */ if (MusicSequenceFileLoadData(retval->sequence, data, 0, 0) != noErr) goto fail; #endif CFRelease(data); data = NULL; if (GetSequenceLength(retval->sequence, &retval->endTime) != noErr) goto fail; if (MusicPlayerSetSequence(retval->player, retval->sequence) != noErr) goto fail; return retval; fail: if (retval) { if (retval->sequence) DisposeMusicSequence(retval->sequence); if (retval->player) DisposeMusicPlayer(retval->player); free(retval); } if (data) CFRelease(data); if (buf) free(buf); return NULL; }