4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file libtimidity.cpp Playing music via the timidity library. */
12 #include "../stdafx.h"
13 #include "../openttd.h"
14 #include "../sound_type.h"
16 #include "libtimidity.h"
18 #include <sys/types.h>
26 #include <pspaudiolib.h>
29 #include "../safeguards.h"
31 /** The state of playing. */
39 MidSongOptions options
;
45 } _midi
; ///< Metadata about the midi we're playing.
48 static void AudioOutCallback(void *buf
, unsigned int _reqn
, void *userdata
)
50 memset(buf
, 0, _reqn
* PSP_NUM_AUDIO_CHANNELS
);
51 if (_midi
.status
== MIDI_PLAYING
) {
52 mid_song_read_wave(_midi
.song
, buf
, _reqn
* PSP_NUM_AUDIO_CHANNELS
);
57 /** Factory for the libtimidity driver. */
58 static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity
;
60 const char *MusicDriver_LibTimidity::Start(const char * const *param
)
62 _midi
.status
= MIDI_STOPPED
;
65 if (mid_init(param
== NULL
? NULL
: const_cast<char *>(param
[0])) < 0) {
66 /* If init fails, it can be because no configuration was found.
67 * If it was not forced via param, try to load it without a
68 * configuration. Who knows that works. */
69 if (param
!= NULL
|| mid_init_no_config() < 0) {
70 return "error initializing timidity";
73 DEBUG(driver
, 1, "successfully initialised timidity");
75 _midi
.options
.rate
= 44100;
76 _midi
.options
.format
= MID_AUDIO_S16LSB
;
77 _midi
.options
.channels
= 2;
79 _midi
.options
.buffer_size
= PSP_NUM_AUDIO_SAMPLES
;
81 _midi
.options
.buffer_size
= _midi
.options
.rate
;
86 pspAudioSetChannelCallback(_midi
.options
.channels
, &AudioOutCallback
, NULL
);
87 pspAudioSetVolume(_midi
.options
.channels
, PSP_VOLUME_MAX
, PSP_VOLUME_MAX
);
93 void MusicDriver_LibTimidity::Stop()
95 if (_midi
.status
== MIDI_PLAYING
) this->StopSong();
99 void MusicDriver_LibTimidity::PlaySong(const char *filename
)
103 _midi
.stream
= mid_istream_open_file(filename
);
104 if (_midi
.stream
== NULL
) {
105 DEBUG(driver
, 0, "Could not open music file");
109 _midi
.song
= mid_song_load(_midi
.stream
, &_midi
.options
);
110 mid_istream_close(_midi
.stream
);
111 _midi
.song_length
= mid_song_get_total_time(_midi
.song
);
113 if (_midi
.song
== NULL
) {
114 DEBUG(driver
, 1, "Invalid MIDI file");
118 mid_song_start(_midi
.song
);
119 _midi
.status
= MIDI_PLAYING
;
122 void MusicDriver_LibTimidity::StopSong()
124 _midi
.status
= MIDI_STOPPED
;
125 /* mid_song_free cannot handle NULL! */
126 if (_midi
.song
!= NULL
) mid_song_free(_midi
.song
);
130 bool MusicDriver_LibTimidity::IsSongPlaying()
132 if (_midi
.status
== MIDI_PLAYING
) {
133 _midi
.song_position
= mid_song_get_time(_midi
.song
);
134 if (_midi
.song_position
>= _midi
.song_length
) {
135 _midi
.status
= MIDI_STOPPED
;
136 _midi
.song_position
= 0;
140 return (_midi
.status
== MIDI_PLAYING
);
143 void MusicDriver_LibTimidity::SetVolume(byte vol
)
145 if (_midi
.song
!= NULL
) mid_song_set_volume(_midi
.song
, vol
);