static int MIDI_open(Sound_Sample *sample, const char *ext) { Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; SDL_RWops *rw = internal->rw; SDL_AudioSpec spec; MidiSong *song; spec.channels = 2; spec.format = AUDIO_S16SYS; spec.freq = 44100; spec.samples = 4096; song = Timidity_LoadSong(rw, &spec); BAIL_IF_MACRO(song == NULL, "MIDI: Not a MIDI file.", 0); Timidity_SetVolume(song, 100); Timidity_Start(song); SNDDBG(("MIDI: Accepting data stream.\n")); internal->decoder_private = (void *) song; sample->actual.channels = 2; sample->actual.rate = 44100; sample->actual.format = AUDIO_S16SYS; sample->flags = SOUND_SAMPLEFLAG_CANSEEK; return(1); /* we'll handle this data. */ } /* MIDI_open */
static int TIMIDITY_Play(void *context, int play_count) { TIMIDITY_Music *music = (TIMIDITY_Music *)context; music->play_count = play_count; Timidity_Start(music->song); return TIMIDITY_Seek(music, 0.0); }
static int MIDI_rewind(Sound_Sample *sample) { Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; MidiSong *song = (MidiSong *) internal->decoder_private; Timidity_Start(song); return(1); } /* MIDI_rewind */
int main(int argc, char *argv[]) { SDL_AudioSpec audio; SDL_RWops *rw; if (SDL_Init(SDL_INIT_AUDIO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return 1; } atexit(SDL_Quit); if (argc != 2) { fprintf(stderr, "Usage: %s midifile\n", argv[0]); return 1; } audio.freq = 44100; audio.format = AUDIO_S16SYS; audio.channels = 2; audio.samples = 4096; audio.callback = audio_callback; if (SDL_OpenAudio(&audio, NULL) < 0) { fprintf(stderr, "Couldn't open audio device. %s\n", SDL_GetError()); return 1; } if (Timidity_Init() < 0) { fprintf(stderr, "Could not initialise TiMidity.\n"); return 1; } rw = SDL_RWFromFile(argv[1], "rb"); if (rw == NULL) { fprintf(stderr, "Could not create RWops from MIDI file.\n"); return 1; } song = Timidity_LoadSong(rw, &audio); SDL_RWclose(rw); if (song == NULL) { fprintf(stderr, "Could not open MIDI file.\n"); return 1; } Timidity_SetVolume(song, 100); Timidity_Start(song); SDL_PauseAudio(0); while (!done_flag) { SDL_Delay(10); } SDL_PauseAudio(1); Timidity_FreeSong(song); Timidity_Exit(); return 0; }
VOID MIDI_Play( INT iNumRIX, BOOL fLoop ) /*++ Purpose: Start playing the specified music in MIDI format. Parameters: [IN] iNumRIX - number of the music. 0 to stop playing current music. [IN] fLoop - Whether the music should be looped or not. Return value: None. --*/ { FILE *fp; unsigned char *buf; int size; SDL_RWops *rw; #ifdef TIMIDITY if (g_pMid != NULL && iNumRIX == iMidCurrent && Timidity_Active()) #else if (g_pMid != NULL && iNumRIX == iMidCurrent && native_midi_active()) #endif { return; } SOUND_PlayCDA(-1); #ifdef TIMIDITY Timidity_FreeSong(g_pMid); #else native_midi_freesong(g_pMid); #endif g_pMid = NULL; iMidCurrent = -1; if (g_fNoMusic || iNumRIX <= 0) { return; } fp = fopen(PAL_PREFIX "midi.mkf", "rb"); if (fp == NULL) { return; } if (iNumRIX > PAL_MKFGetChunkCount(fp)) { fclose(fp); return; } size = PAL_MKFGetChunkSize(iNumRIX, fp); if (size <= 0) { fclose(fp); return; } buf = (unsigned char *)UTIL_malloc(size); PAL_MKFReadChunk((LPBYTE)buf, size, iNumRIX, fp); fclose(fp); rw = SDL_RWFromConstMem((const void *)buf, size); #ifdef TIMIDITY g_pMid = Timidity_LoadSong_RW(rw); #else g_pMid = native_midi_loadsong_RW(rw); #endif if (g_pMid != NULL) { #ifdef TIMIDITY Timidity_Start(g_pMid); #else native_midi_start(g_pMid); #endif iMidCurrent = iNumRIX; fMidLoop = fLoop; } SDL_RWclose(rw); free(buf); }
/* Play a music chunk. Returns 0, or -1 if there was an error. */ static int music_internal_play(Mix_Music *music, double position) { int retval = 0; #if defined(__MACOSX__) && defined(USE_NATIVE_MIDI) /* This fixes a bug with native MIDI on Mac OS X, where you can't really stop and restart MIDI from the audio callback. */ if ( music == music_playing && music->type == MUS_MID && native_midi_ok ) { /* Just a seek suffices to restart playing */ music_internal_position(position); return 0; } #endif /* Note the music we're playing */ if ( music_playing ) { music_internal_halt(); } music_playing = music; /* Set the initial volume */ if ( music->type != MUS_MOD ) { music_internal_initialize_volume(); } /* Set up for playback */ switch (music->type) { #ifdef CMD_MUSIC case MUS_CMD: MusicCMD_Start(music->data.cmd); break; #endif #ifdef WAV_MUSIC case MUS_WAV: WAVStream_Start(music->data.wave); break; #endif #ifdef MODPLUG_MUSIC case MUS_MODPLUG: /* can't set volume until file is loaded, so finally set it now */ music_internal_initialize_volume(); modplug_play(music->data.modplug); break; #endif #ifdef MOD_MUSIC case MUS_MOD: MOD_play(music->data.module); /* Player_SetVolume() does nothing before Player_Start() */ music_internal_initialize_volume(); break; #endif #ifdef MID_MUSIC case MUS_MID: #ifdef USE_NATIVE_MIDI if ( native_midi_ok ) { native_midi_start(music->data.nativemidi, music_loops); goto skip; } #endif #ifdef USE_FLUIDSYNTH_MIDI if (fluidsynth_ok ) { fluidsynth_start(music->data.fluidsynthmidi); goto skip; } #endif #ifdef USE_TIMIDITY_MIDI if ( timidity_ok ) { Timidity_Start(music->data.midi); goto skip; } #endif break; #endif #ifdef OGG_MUSIC case MUS_OGG: OGG_play(music->data.ogg); break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: FLAC_play(music->data.flac); break; #endif #ifdef MP3_MUSIC case MUS_MP3: smpeg.SMPEG_enableaudio(music->data.mp3,1); smpeg.SMPEG_enablevideo(music->data.mp3,0); smpeg.SMPEG_play(music_playing->data.mp3); break; #endif #ifdef MP3_MAD_MUSIC case MUS_MP3_MAD: mad_start(music->data.mp3_mad); break; #endif default: Mix_SetError("Can't play unknown music type"); retval = -1; break; } skip: /* Set the playback position, note any errors if an offset is used */ if ( retval == 0 ) { if ( position > 0.0 ) { if ( music_internal_position(position) < 0 ) { Mix_SetError("Position not implemented for music type"); retval = -1; } } else { music_internal_position(0.0); } } /* If the setup failed, we're not playing any music anymore */ if ( retval < 0 ) { music_playing = NULL; } return(retval); }