libtimidity.cpp

Go to the documentation of this file.
00001 /* $Id: libtimidity.cpp 12971 2008-05-06 15:11:33Z rubidium $ */
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 /* PSP */
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 /* PSP */
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 
00054   if (mid_init(param == NULL ? NULL : (char *)param[0]) < 0) {
00055     /* If init fails, it can be because no configuration was found.
00056      *  If it was not forced via param, try to load it without a
00057      *  configuration. Who knows that works. */
00058     if (param != NULL || mid_init_no_config() < 0) {
00059       return "error initializing timidity";
00060     }
00061   }
00062   DEBUG(driver, 1, "successfully initialised timidity");
00063 
00064   _midi.options.rate = 44100;
00065   _midi.options.format = MID_AUDIO_S16LSB;
00066   _midi.options.channels = 2;
00067 #if defined(PSP)
00068   _midi.options.buffer_size = PSP_NUM_AUDIO_SAMPLES;
00069 #else
00070   _midi.options.buffer_size = _midi.options.rate;
00071 #endif
00072 
00073 #if defined(PSP)
00074   pspAudioInit();
00075   pspAudioSetChannelCallback(_midi.options.channels, &AudioOutCallback, NULL);
00076   pspAudioSetVolume(_midi.options.channels, PSP_VOLUME_MAX, PSP_VOLUME_MAX);
00077 #endif /* PSP */
00078 
00079   return NULL;
00080 }
00081 
00082 void MusicDriver_LibTimidity::Stop()
00083 {
00084   if (_midi.status == MIDI_PLAYING) {
00085     _midi.status = MIDI_STOPPED;
00086     mid_song_free(_midi.song);
00087   }
00088   mid_exit();
00089 }
00090 
00091 void MusicDriver_LibTimidity::PlaySong(const char *filename)
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   mid_song_free(_midi.song);
00116 }
00117 
00118 bool MusicDriver_LibTimidity::IsSongPlaying()
00119 {
00120   if (_midi.status == MIDI_PLAYING) {
00121     _midi.song_position = mid_song_get_time(_midi.song);
00122     if (_midi.song_position >= _midi.song_length) {
00123       _midi.status = MIDI_STOPPED;
00124       _midi.song_position = 0;
00125     }
00126   }
00127 
00128   return (_midi.status == MIDI_PLAYING);
00129 }
00130 
00131 void MusicDriver_LibTimidity::SetVolume(byte vol)
00132 {
00133   if (_midi.song != NULL)
00134     mid_song_set_volume(_midi.song, vol);
00135 }

Generated on Mon Mar 9 23:33:48 2009 for openttd by  doxygen 1.5.6