(svn r27729) -Codechange: Do not count static NewGRF when checking for the maximum...
[openttd.git] / src / music / libtimidity.cpp
blob1cb2adc0f99de754dc244995d2f50ebeab86943e
1 /* $Id$ */
3 /*
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/>.
8 */
10 /** @file libtimidity.cpp Playing music via the timidity library. */
12 #include "../stdafx.h"
13 #include "../openttd.h"
14 #include "../sound_type.h"
15 #include "../debug.h"
16 #include "libtimidity.h"
17 #include <fcntl.h>
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21 #include <signal.h>
22 #include <sys/stat.h>
23 #include <errno.h>
24 #include <timidity.h>
25 #if defined(PSP)
26 #include <pspaudiolib.h>
27 #endif /* PSP */
29 #include "../safeguards.h"
31 /** The state of playing. */
32 enum MidiState {
33 MIDI_STOPPED = 0,
34 MIDI_PLAYING = 1,
37 static struct {
38 MidIStream *stream;
39 MidSongOptions options;
40 MidSong *song;
42 MidiState status;
43 uint32 song_length;
44 uint32 song_position;
45 } _midi; ///< Metadata about the midi we're playing.
47 #if defined(PSP)
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);
55 #endif /* PSP */
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;
63 _midi.song = NULL;
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;
78 #if defined(PSP)
79 _midi.options.buffer_size = PSP_NUM_AUDIO_SAMPLES;
80 #else
81 _midi.options.buffer_size = _midi.options.rate;
82 #endif
84 #if defined(PSP)
85 pspAudioInit();
86 pspAudioSetChannelCallback(_midi.options.channels, &AudioOutCallback, NULL);
87 pspAudioSetVolume(_midi.options.channels, PSP_VOLUME_MAX, PSP_VOLUME_MAX);
88 #endif /* PSP */
90 return NULL;
93 void MusicDriver_LibTimidity::Stop()
95 if (_midi.status == MIDI_PLAYING) this->StopSong();
96 mid_exit();
99 void MusicDriver_LibTimidity::PlaySong(const char *filename)
101 this->StopSong();
103 _midi.stream = mid_istream_open_file(filename);
104 if (_midi.stream == NULL) {
105 DEBUG(driver, 0, "Could not open music file");
106 return;
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");
115 return;
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);
127 _midi.song = NULL;
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);