libtimidity.cpp
Go to the documentation of this file.00001
00002
00005 #include "../stdafx.h"
00006 #include "../openttd.h"
00007 #include "../sound_type.h"
00008 #include "../variables.h"
00009 #include "../debug.h"
00010 #include "libtimidity.h"
00011 #include <fcntl.h>
00012 #include <sys/types.h>
00013 #include <sys/wait.h>
00014 #include <unistd.h>
00015 #include <signal.h>
00016 #include <sys/stat.h>
00017 #include <errno.h>
00018 #include <timidity.h>
00019 #if defined(PSP)
00020 #include <pspaudiolib.h>
00021 #endif
00022
00023 enum MidiState {
00024 MIDI_STOPPED = 0,
00025 MIDI_PLAYING = 1,
00026 };
00027
00028 static struct {
00029 MidIStream *stream;
00030 MidSongOptions options;
00031 MidSong *song;
00032
00033 MidiState status;
00034 uint32 song_length;
00035 uint32 song_position;
00036 } _midi;
00037
00038 #if defined(PSP)
00039 static void AudioOutCallback(void *buf, unsigned int _reqn, void *userdata)
00040 {
00041 memset(buf, 0, _reqn * PSP_NUM_AUDIO_CHANNELS);
00042 if (_midi.status == MIDI_PLAYING) {
00043 mid_song_read_wave(_midi.song, buf, _reqn * PSP_NUM_AUDIO_CHANNELS);
00044 }
00045 }
00046 #endif
00047
00048 static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity;
00049
00050 const char *MusicDriver_LibTimidity::Start(const char * const *param)
00051 {
00052 _midi.status = MIDI_STOPPED;
00053 _midi.song = NULL;
00054
00055 if (mid_init(param == NULL ? NULL : (char *)param[0]) < 0) {
00056
00057
00058
00059 if (param != NULL || mid_init_no_config() < 0) {
00060 return "error initializing timidity";
00061 }
00062 }
00063 DEBUG(driver, 1, "successfully initialised timidity");
00064
00065 _midi.options.rate = 44100;
00066 _midi.options.format = MID_AUDIO_S16LSB;
00067 _midi.options.channels = 2;
00068 #if defined(PSP)
00069 _midi.options.buffer_size = PSP_NUM_AUDIO_SAMPLES;
00070 #else
00071 _midi.options.buffer_size = _midi.options.rate;
00072 #endif
00073
00074 #if defined(PSP)
00075 pspAudioInit();
00076 pspAudioSetChannelCallback(_midi.options.channels, &AudioOutCallback, NULL);
00077 pspAudioSetVolume(_midi.options.channels, PSP_VOLUME_MAX, PSP_VOLUME_MAX);
00078 #endif
00079
00080 return NULL;
00081 }
00082
00083 void MusicDriver_LibTimidity::Stop()
00084 {
00085 if (_midi.status == MIDI_PLAYING) this->StopSong();
00086 mid_exit();
00087 }
00088
00089 void MusicDriver_LibTimidity::PlaySong(const char *filename)
00090 {
00091 this->StopSong();
00092
00093 _midi.stream = mid_istream_open_file(filename);
00094 if (_midi.stream == NULL) {
00095 DEBUG(driver, 0, "Could not open music file");
00096 return;
00097 }
00098
00099 _midi.song = mid_song_load(_midi.stream, &_midi.options);
00100 mid_istream_close(_midi.stream);
00101 _midi.song_length = mid_song_get_total_time(_midi.song);
00102
00103 if (_midi.song == NULL) {
00104 DEBUG(driver, 1, "Invalid MIDI file");
00105 return;
00106 }
00107
00108 mid_song_start(_midi.song);
00109 _midi.status = MIDI_PLAYING;
00110 }
00111
00112 void MusicDriver_LibTimidity::StopSong()
00113 {
00114 _midi.status = MIDI_STOPPED;
00115
00116 if (_midi.song != NULL) mid_song_free(_midi.song);
00117 _midi.song = NULL;
00118 }
00119
00120 bool MusicDriver_LibTimidity::IsSongPlaying()
00121 {
00122 if (_midi.status == MIDI_PLAYING) {
00123 _midi.song_position = mid_song_get_time(_midi.song);
00124 if (_midi.song_position >= _midi.song_length) {
00125 _midi.status = MIDI_STOPPED;
00126 _midi.song_position = 0;
00127 }
00128 }
00129
00130 return (_midi.status == MIDI_PLAYING);
00131 }
00132
00133 void MusicDriver_LibTimidity::SetVolume(byte vol)
00134 {
00135 if (_midi.song != NULL) mid_song_set_volume(_midi.song, vol);
00136 }