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