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