Skip to content

Latest commit

 

History

History
220 lines (187 loc) · 5.67 KB

music_timidity.c

File metadata and controls

220 lines (187 loc) · 5.67 KB
 
1
2
/*
SDL_mixer: An audio mixer library based on the SDL library
Mar 1, 2018
Mar 1, 2018
3
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* This file supports playing MIDI files with timidity */
#ifdef MUSIC_MID_TIMIDITY
#include "music_timidity.h"
#include "timidity/timidity.h"
Oct 21, 2017
Oct 21, 2017
31
32
33
34
typedef struct
{
int play_count;
MidiSong *song;
Oct 21, 2017
Oct 21, 2017
35
36
37
SDL_AudioStream *stream;
void *buffer;
Sint32 buffer_size;
Oct 21, 2017
Oct 21, 2017
38
39
40
41
} TIMIDITY_Music;
static int TIMIDITY_Seek(void *context, double position);
Oct 21, 2017
Oct 21, 2017
42
static void TIMIDITY_Delete(void *context);
Oct 21, 2017
Oct 21, 2017
43
44
45
static int TIMIDITY_Open(const SDL_AudioSpec *spec)
{
Oct 18, 2017
Oct 18, 2017
46
return Timidity_Init();
47
48
49
50
}
static void TIMIDITY_Close(void)
{
Oct 18, 2017
Oct 18, 2017
51
Timidity_Exit();
52
53
54
55
}
void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc)
{
Oct 21, 2017
Oct 21, 2017
56
TIMIDITY_Music *music;
Oct 21, 2017
Oct 21, 2017
57
58
SDL_AudioSpec spec;
SDL_bool need_stream = SDL_FALSE;
Oct 21, 2017
Oct 21, 2017
59
60
61
62
63
64
65
music = (TIMIDITY_Music *)SDL_calloc(1, sizeof(*music));
if (!music) {
SDL_OutOfMemory();
return NULL;
}
Oct 21, 2017
Oct 21, 2017
66
67
68
69
70
71
SDL_memcpy(&spec, &music_spec, sizeof(spec));
if (spec.channels > 2) {
need_stream = SDL_TRUE;
spec.channels = 2;
}
music->song = Timidity_LoadSong(src, &spec);
Oct 21, 2017
Oct 21, 2017
72
if (!music->song) {
Oct 21, 2017
Oct 21, 2017
73
TIMIDITY_Delete(music);
Oct 21, 2017
Oct 21, 2017
74
75
76
return NULL;
}
Oct 21, 2017
Oct 21, 2017
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
if (need_stream) {
music->stream = SDL_NewAudioStream(spec.format, spec.channels, spec.freq,
music_spec.format, music_spec.channels, music_spec.freq);
if (!music->stream) {
TIMIDITY_Delete(music);
return NULL;
}
music->buffer_size = spec.samples * (SDL_AUDIO_BITSIZE(spec.format) / 8) * spec.channels;
music->buffer = SDL_malloc(music->buffer_size);
if (!music->buffer) {
SDL_OutOfMemory();
TIMIDITY_Delete(music);
return NULL;
}
}
Oct 21, 2017
Oct 21, 2017
94
if (freesrc) {
Oct 18, 2017
Oct 18, 2017
95
SDL_RWclose(src);
96
97
98
99
100
101
}
return music;
}
static void TIMIDITY_SetVolume(void *context, int volume)
{
Oct 21, 2017
Oct 21, 2017
102
103
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Timidity_SetVolume(music->song, volume);
Oct 21, 2017
Oct 21, 2017
106
static int TIMIDITY_Play(void *context, int play_count)
Oct 21, 2017
Oct 21, 2017
108
109
110
111
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
music->play_count = play_count;
Timidity_Start(music->song);
return TIMIDITY_Seek(music, 0.0);
Oct 21, 2017
Oct 21, 2017
114
static int TIMIDITY_GetSome(void *context, void *data, int bytes, SDL_bool *done)
Oct 21, 2017
Oct 21, 2017
116
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Oct 21, 2017
Oct 21, 2017
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
int filled, amount, expected;
if (music->stream) {
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
}
}
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
return 0;
}
if (music->stream) {
expected = music->buffer_size;
amount = Timidity_PlaySome(music->song, music->buffer, music->buffer_size);
if (SDL_AudioStreamPut(music->stream, music->buffer, amount) < 0) {
return -1;
}
} else {
expected = bytes;
amount = Timidity_PlaySome(music->song, data, bytes);
}
if (amount < expected) {
Oct 21, 2017
Oct 21, 2017
144
145
146
147
148
149
150
151
152
153
154
155
if (music->play_count == 1) {
/* We didn't consume anything and we're done */
music->play_count = 0;
} else {
int play_count = -1;
if (music->play_count > 0) {
play_count = (music->play_count - 1);
}
if (TIMIDITY_Play(music, play_count) < 0) {
return -1;
}
}
Oct 18, 2017
Oct 18, 2017
156
}
Oct 21, 2017
Oct 21, 2017
157
158
159
160
161
162
163
164
165
166
167
if (music->stream) {
/* We'll pick it up from the stream next time around */
return 0;
} else {
/* We wrote output data */
return amount;
}
}
static int TIMIDITY_GetAudio(void *context, void *data, int bytes)
{
return music_pcm_getaudio(context, data, bytes, MIX_MAX_VOLUME, TIMIDITY_GetSome);
Oct 18, 2017
Oct 18, 2017
170
static int TIMIDITY_Seek(void *context, double position)
Oct 21, 2017
Oct 21, 2017
172
173
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Timidity_Seek(music->song, (Uint32)(position * 1000));
Oct 18, 2017
Oct 18, 2017
174
return 0;
175
176
177
178
}
static void TIMIDITY_Delete(void *context)
{
Oct 21, 2017
Oct 21, 2017
179
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Oct 21, 2017
Oct 21, 2017
180
181
182
183
184
185
186
187
188
189
if (music->song) {
Timidity_FreeSong(music->song);
}
if (music->stream) {
SDL_FreeAudioStream(music->stream);
}
if (music->buffer) {
SDL_free(music->buffer);
}
Oct 21, 2017
Oct 21, 2017
190
SDL_free(music);
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
}
Mix_MusicInterface Mix_MusicInterface_TIMIDITY =
{
"TIMIDITY",
MIX_MUSIC_TIMIDITY,
MUS_MID,
SDL_FALSE,
SDL_FALSE,
NULL, /* Load */
TIMIDITY_Open,
TIMIDITY_CreateFromRW,
NULL, /* CreateFromFile */
TIMIDITY_SetVolume,
TIMIDITY_Play,
Oct 18, 2017
Oct 18, 2017
207
NULL, /* IsPlaying */
Oct 18, 2017
Oct 18, 2017
209
TIMIDITY_Seek,
210
211
212
213
214
215
216
217
218
219
220
NULL, /* Pause */
NULL, /* Resume */
NULL, /* Stop */
TIMIDITY_Delete,
TIMIDITY_Close,
NULL, /* Unload */
};
#endif /* MUSIC_MID_TIMIDITY */
/* vi: set ts=4 sw=4 expandtab: */