/* $Id$ */ /** @file libtimidity.cpp Playing music via the timidity library. */ #include "../stdafx.h" #include "../openttd.h" #include "../sound_type.h" #include "../variables.h" #include "../debug.h" #include "libtimidity.h" #include #include #include #include #include #include #include #include #if defined(PSP) #include #endif /* PSP */ enum MidiState { MIDI_STOPPED = 0, MIDI_PLAYING = 1, }; static struct { MidIStream *stream; MidSongOptions options; MidSong *song; MidiState status; uint32 song_length; uint32 song_position; } _midi; #if defined(PSP) static void AudioOutCallback(void *buf, unsigned int _reqn, void *userdata) { memset(buf, 0, _reqn * PSP_NUM_AUDIO_CHANNELS); if (_midi.status == MIDI_PLAYING) { mid_song_read_wave(_midi.song, buf, _reqn * PSP_NUM_AUDIO_CHANNELS); } } #endif /* PSP */ static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity; const char *MusicDriver_LibTimidity::Start(const char * const *param) { _midi.status = MIDI_STOPPED; if (mid_init(param == NULL ? NULL : (char *)param[0]) < 0) { /* If init fails, it can be because no configuration was found. * If it was not forced via param, try to load it without a * configuration. Who knows that works. */ if (param != NULL || mid_init_no_config() < 0) { return "error initializing timidity"; } } DEBUG(driver, 1, "successfully initialised timidity"); _midi.options.rate = 44100; _midi.options.format = MID_AUDIO_S16LSB; _midi.options.channels = 2; #if defined(PSP) _midi.options.buffer_size = PSP_NUM_AUDIO_SAMPLES; #else _midi.options.buffer_size = _midi.options.rate; #endif #if defined(PSP) pspAudioInit(); pspAudioSetChannelCallback(_midi.options.channels, &AudioOutCallback, NULL); pspAudioSetVolume(_midi.options.channels, PSP_VOLUME_MAX, PSP_VOLUME_MAX); #endif /* PSP */ return NULL; } void MusicDriver_LibTimidity::Stop() { if (_midi.status == MIDI_PLAYING) { _midi.status = MIDI_STOPPED; mid_song_free(_midi.song); } mid_exit(); } void MusicDriver_LibTimidity::PlaySong(const char *filename) { _midi.stream = mid_istream_open_file(filename); if (_midi.stream == NULL) { DEBUG(driver, 0, "Could not open music file"); return; } _midi.song = mid_song_load(_midi.stream, &_midi.options); mid_istream_close(_midi.stream); _midi.song_length = mid_song_get_total_time(_midi.song); if (_midi.song == NULL) { DEBUG(driver, 1, "Invalid MIDI file"); return; } mid_song_start(_midi.song); _midi.status = MIDI_PLAYING; } void MusicDriver_LibTimidity::StopSong() { _midi.status = MIDI_STOPPED; mid_song_free(_midi.song); } bool MusicDriver_LibTimidity::IsSongPlaying() { if (_midi.status == MIDI_PLAYING) { _midi.song_position = mid_song_get_time(_midi.song); if (_midi.song_position >= _midi.song_length) { _midi.status = MIDI_STOPPED; _midi.song_position = 0; } } return (_midi.status == MIDI_PLAYING); } void MusicDriver_LibTimidity::SetVolume(byte vol) { if (_midi.song != NULL) mid_song_set_volume(_midi.song, vol); }