OSStatus LoadSMF(const char *filename, MusicSequence& sequence, MusicSequenceLoadFlags loadFlags) { OSStatus result = noErr; require_noerr (result = NewMusicSequence(&sequence), home); CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)filename, strlen(filename), false); require_noerr (result = MusicSequenceFileLoad (sequence, url, 0, loadFlags), home); home: return result; }
OSStatus LoadSMF(const char *filename, MusicSequence& sequence, MusicSequenceLoadFlags loadFlags) { OSStatus result = noErr; CFURLRef url = NULL; FailIf ((result = NewMusicSequence(&sequence)), home, "NewMusicSequence"); url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)filename, strlen(filename), false); FailIf ((result = MusicSequenceFileLoad (sequence, url, 0, loadFlags)), home, "MusicSequenceFileLoad"); home: if (url) CFRelease(url); return result; }
/** * Starts playing a new song. * * @param filename Path to a MIDI file. */ void MusicDriver_Cocoa::PlaySong(const char *filename) { DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename); this->StopSong(); if (_sequence != NULL) { DisposeMusicSequence(_sequence); _sequence = NULL; } if (NewMusicSequence(&_sequence) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to create music sequence"); return; } const char *os_file = OTTD2FS(filename); CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (MacOSVersionIsAtLeast(10, 5, 0)) { if (MusicSequenceFileLoad(_sequence, url, 0, 0) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file"); CFRelease(url); return; } } else #endif { #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) FSRef ref_file; if (!CFURLGetFSRef(url, &ref_file)) { DEBUG(driver, 0, "cocoa_m: Failed to make FSRef"); CFRelease(url); return; } if (MusicSequenceLoadSMFWithFlags(_sequence, &ref_file, 0) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file old style"); CFRelease(url); return; } #endif } CFRelease(url); /* Construct audio graph */ AUGraph graph = NULL; MusicSequenceGetAUGraph(_sequence, &graph); AUGraphOpen(graph); if (AUGraphInitialize(graph) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to initialize AU graph"); return; } /* Figure out sequence length */ UInt32 num_tracks; MusicSequenceGetTrackCount(_sequence, &num_tracks); _seq_length = 0; for (UInt32 i = 0; i < num_tracks; i++) { MusicTrack track = NULL; MusicTimeStamp track_length = 0; UInt32 prop_size = sizeof(MusicTimeStamp); MusicSequenceGetIndTrack(_sequence, i, &track); MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength, &track_length, &prop_size); if (track_length > _seq_length) _seq_length = track_length; } /* Add 8 beats for reverb/long note release */ _seq_length += 8; DoSetVolume(); MusicPlayerSetSequence(_player, _sequence); MusicPlayerPreroll(_player); if (MusicPlayerStart(_player) != noErr) return; _playing = true; DEBUG(driver, 3, "cocoa_m: playing '%s'", filename); }
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; }
// 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 *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; }
int I_RegisterSong (char *data, size_t musicLen) { if(!music_initialized) return 0; // input mus memory file and midi MEMFILE *mus = mem_fopen_read(data, musicLen); MEMFILE *midi = mem_fopen_write(); I_UnRegisterSong(0); int result = mus2mid(mus, midi); switch(result) { case 1: Printf(PRINT_HIGH, "MUS is not valid\n"); break; case 0: case 2: { #ifdef OSX if (NewMusicSequence(&sequence) != noErr) return 0; cfd = CFDataCreate(NULL, (const Uint8 *)mem_fgetbuf(midi), mem_fsize(midi)); if(!cfd) { DisposeMusicSequence(sequence); return 0; } if (MusicSequenceLoadSMFData(sequence, (CFDataRef)cfd) != noErr) { DisposeMusicSequence(sequence); CFRelease(cfd); return 0; } registered_tracks[0].Track = (Mix_Music*)1; #else Mix_Music *music = 0; // older versions of sdl-mixer require a physical midi file to be read, 1.2.7+ can read from memory #ifndef TEMP_MIDI // SDL >= 1.2.7 if (result == 0) // it is a midi { registered_tracks[0].Data = SDL_RWFromMem(mem_fgetbuf(midi), mem_fsize(midi)); } else // it is another format { registered_tracks[0].Data = SDL_RWFromMem(data, musicLen); } if (!registered_tracks[0].Data) { Printf(PRINT_HIGH, "SDL_RWFromMem: %s\n", SDL_GetError()); break; } music = Mix_LoadMUS_RW(registered_tracks[0].Data); if(!music) { Printf(PRINT_HIGH, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); SDL_FreeRW(registered_tracks[0].Data); registered_tracks[0].Data = NULL; break; } #else // SDL <= 1.2.6 - Create a file so it can load the midi FILE *fp = fopen(TEMP_MIDI, "wb+"); if(!fp) { Printf(PRINT_HIGH, "Could not open temporary music file %s, not playing track\n", TEMP_MIDI); break; } for(int i = 0; i < mem_fsize(midi); i++) fputc(mem_fgetbuf(midi)[i], fp); fclose(fp); music = Mix_LoadMUS(TEMP_MIDI); if(!music) { Printf(PRINT_HIGH, "Mix_LoadMUS: %s\n", Mix_GetError()); break; } #endif registered_tracks[0].Track = music; #endif // OSX break; } // case 2 } mem_fclose(mus); mem_fclose(midi); return 1; }