6254
|
1 |
/* $Id: extmidi.c 4692 2006-05-02 19:09:49Z peter1138 $ */
|
|
2 |
|
|
3 |
#include "../stdafx.h"
|
|
4 |
#include "../openttd.h"
|
|
5 |
#include "../sound.h"
|
|
6 |
#include "../string.h"
|
|
7 |
#include "../variables.h"
|
|
8 |
#include "../debug.h"
|
|
9 |
#include "libtimidity.h"
|
|
10 |
#include <fcntl.h>
|
|
11 |
#include <sys/types.h>
|
|
12 |
#include <sys/wait.h>
|
|
13 |
#include <unistd.h>
|
|
14 |
#include <signal.h>
|
|
15 |
#include <sys/stat.h>
|
|
16 |
#include <errno.h>
|
|
17 |
#include <timidity.h>
|
|
18 |
#if defined(PSP)
|
|
19 |
#include <pspaudiolib.h>
|
|
20 |
#endif /* PSP */
|
|
21 |
|
|
22 |
enum MidiState {
|
|
23 |
MIDI_STOPPED = 0,
|
|
24 |
MIDI_PLAYING = 1,
|
|
25 |
};
|
|
26 |
|
|
27 |
static struct {
|
|
28 |
MidIStream *stream;
|
|
29 |
MidSongOptions options;
|
|
30 |
MidSong *song;
|
|
31 |
|
|
32 |
MidiState status;
|
|
33 |
uint32 song_length;
|
|
34 |
uint32 song_position;
|
|
35 |
} _midi;
|
|
36 |
|
|
37 |
#if defined(PSP)
|
|
38 |
static void AudioOutCallback(void *buf, unsigned int _reqn, void *userdata)
|
|
39 |
{
|
|
40 |
memset(buf, 0, _reqn * PSP_NUM_AUDIO_CHANNELS);
|
|
41 |
if (_midi.status == MIDI_PLAYING) {
|
|
42 |
mid_song_read_wave(_midi.song, buf, _reqn * PSP_NUM_AUDIO_CHANNELS);
|
|
43 |
}
|
|
44 |
}
|
|
45 |
#endif /* PSP */
|
|
46 |
|
|
47 |
static const char *LibtimidityMidiStart(const char *const *param)
|
|
48 |
{
|
|
49 |
_midi.status = MIDI_STOPPED;
|
|
50 |
|
|
51 |
if (mid_init(param == NULL ? NULL : (char *)param[0]) < 0) {
|
|
52 |
/* If init fails, it can be because no configuration was found.
|
|
53 |
* If it was not forced via param, try to load it without a
|
|
54 |
* configuration. Who knows that works. */
|
|
55 |
if (param != NULL || mid_init_no_config() < 0) {
|
|
56 |
DEBUG(driver, 0, "error initializing timidity");
|
|
57 |
return NULL;
|
|
58 |
}
|
|
59 |
}
|
|
60 |
DEBUG(driver, 1, "successfully initialised timidity");
|
|
61 |
|
|
62 |
_midi.options.rate = 44100;
|
|
63 |
_midi.options.format = MID_AUDIO_S16LSB;
|
|
64 |
_midi.options.channels = 2;
|
|
65 |
#if defined(PSP)
|
|
66 |
_midi.options.buffer_size = PSP_NUM_AUDIO_SAMPLES;
|
|
67 |
#else
|
|
68 |
_midi.options.buffer_size = _midi.options.rate;
|
|
69 |
#endif
|
|
70 |
|
|
71 |
#if defined(PSP)
|
|
72 |
pspAudioInit();
|
|
73 |
pspAudioSetChannelCallback(_midi.options.channels, &AudioOutCallback, NULL);
|
|
74 |
pspAudioSetVolume(_midi.options.channels, PSP_VOLUME_MAX, PSP_VOLUME_MAX);
|
|
75 |
#endif /* PSP */
|
|
76 |
|
|
77 |
return NULL;
|
|
78 |
}
|
|
79 |
|
|
80 |
static void LibtimidityMidiStop(void)
|
|
81 |
{
|
|
82 |
if (_midi.status == MIDI_PLAYING) {
|
|
83 |
_midi.status = MIDI_STOPPED;
|
|
84 |
mid_song_free(_midi.song);
|
|
85 |
}
|
|
86 |
mid_exit();
|
|
87 |
}
|
|
88 |
|
|
89 |
static void LibtimidityMidiPlaySong(const char *filename)
|
|
90 |
{
|
|
91 |
_midi.stream = mid_istream_open_file(filename);
|
|
92 |
if (_midi.stream == NULL) {
|
|
93 |
DEBUG(driver, 0, "Could not open music file");
|
|
94 |
return;
|
|
95 |
}
|
|
96 |
|
|
97 |
_midi.song = mid_song_load(_midi.stream, &_midi.options);
|
|
98 |
mid_istream_close(_midi.stream);
|
|
99 |
_midi.song_length = mid_song_get_total_time(_midi.song);
|
|
100 |
|
|
101 |
if (_midi.song == NULL) {
|
|
102 |
DEBUG(driver, 1, "Invalid MIDI file");
|
|
103 |
return;
|
|
104 |
}
|
|
105 |
|
|
106 |
mid_song_start(_midi.song);
|
|
107 |
_midi.status = MIDI_PLAYING;
|
|
108 |
}
|
|
109 |
|
|
110 |
static void LibtimidityMidiStopSong(void)
|
|
111 |
{
|
|
112 |
_midi.status = MIDI_STOPPED;
|
|
113 |
mid_song_free(_midi.song);
|
|
114 |
}
|
|
115 |
|
|
116 |
static bool LibtimidityMidiIsPlaying(void)
|
|
117 |
{
|
|
118 |
if (_midi.status == MIDI_PLAYING) {
|
|
119 |
_midi.song_position = mid_song_get_time(_midi.song);
|
|
120 |
if (_midi.song_position >= _midi.song_length) {
|
|
121 |
_midi.status = MIDI_STOPPED;
|
|
122 |
_midi.song_position = 0;
|
|
123 |
}
|
|
124 |
}
|
|
125 |
|
|
126 |
return (_midi.status == MIDI_PLAYING);
|
|
127 |
}
|
|
128 |
|
|
129 |
static void LibtimidityMidiSetVolume(byte vol)
|
|
130 |
{
|
|
131 |
if (_midi.song != NULL)
|
|
132 |
mid_song_set_volume(_midi.song, vol);
|
|
133 |
}
|
|
134 |
|
|
135 |
const HalMusicDriver _libtimidity_music_driver = {
|
|
136 |
LibtimidityMidiStart,
|
|
137 |
LibtimidityMidiStop,
|
|
138 |
LibtimidityMidiPlaySong,
|
|
139 |
LibtimidityMidiStopSong,
|
|
140 |
LibtimidityMidiIsPlaying,
|
|
141 |
LibtimidityMidiSetVolume,
|
|
142 |
};
|
|
143 |
|