Skip to content

Latest commit

 

History

History
221 lines (188 loc) · 5.68 KB

music_timidity.c

File metadata and controls

221 lines (188 loc) · 5.68 KB
 
1
2
/*
SDL_mixer: An audio mixer library based on the SDL library
Jan 5, 2019
Jan 5, 2019
3
Copyright (C) 1997-2019 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)
{
Nov 18, 2019
Nov 18, 2019
46
(void) spec;
Oct 18, 2017
Oct 18, 2017
47
return Timidity_Init();
48
49
50
51
}
static void TIMIDITY_Close(void)
{
Oct 18, 2017
Oct 18, 2017
52
Timidity_Exit();
53
54
55
56
}
void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc)
{
Oct 21, 2017
Oct 21, 2017
57
TIMIDITY_Music *music;
Oct 21, 2017
Oct 21, 2017
58
59
SDL_AudioSpec spec;
SDL_bool need_stream = SDL_FALSE;
Oct 21, 2017
Oct 21, 2017
60
61
62
63
64
65
66
music = (TIMIDITY_Music *)SDL_calloc(1, sizeof(*music));
if (!music) {
SDL_OutOfMemory();
return NULL;
}
Oct 21, 2017
Oct 21, 2017
67
68
69
70
71
72
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
73
if (!music->song) {
Oct 21, 2017
Oct 21, 2017
74
TIMIDITY_Delete(music);
Oct 21, 2017
Oct 21, 2017
75
76
77
return NULL;
}
Oct 21, 2017
Oct 21, 2017
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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
95
if (freesrc) {
Oct 18, 2017
Oct 18, 2017
96
SDL_RWclose(src);
97
98
99
100
101
102
}
return music;
}
static void TIMIDITY_SetVolume(void *context, int volume)
{
Oct 21, 2017
Oct 21, 2017
103
104
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Timidity_SetVolume(music->song, volume);
Oct 21, 2017
Oct 21, 2017
107
static int TIMIDITY_Play(void *context, int play_count)
Oct 21, 2017
Oct 21, 2017
109
110
111
112
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
115
static int TIMIDITY_GetSome(void *context, void *data, int bytes, SDL_bool *done)
Oct 21, 2017
Oct 21, 2017
117
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Oct 21, 2017
Oct 21, 2017
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
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);
}
Nov 17, 2019
Nov 17, 2019
143
Oct 21, 2017
Oct 21, 2017
144
if (amount < expected) {
Oct 21, 2017
Oct 21, 2017
145
146
147
148
149
150
151
152
153
154
155
156
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
157
}
Oct 21, 2017
Oct 21, 2017
158
159
160
161
162
163
164
165
166
167
168
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
171
static int TIMIDITY_Seek(void *context, double position)
Oct 21, 2017
Oct 21, 2017
173
174
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Timidity_Seek(music->song, (Uint32)(position * 1000));
Oct 18, 2017
Oct 18, 2017
175
return 0;
176
177
178
179
}
static void TIMIDITY_Delete(void *context)
{
Oct 21, 2017
Oct 21, 2017
180
TIMIDITY_Music *music = (TIMIDITY_Music *)context;
Oct 21, 2017
Oct 21, 2017
181
182
183
184
185
186
187
188
189
190
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
191
SDL_free(music);
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
}
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
208
NULL, /* IsPlaying */
Oct 18, 2017
Oct 18, 2017
210
TIMIDITY_Seek,
211
212
213
214
215
216
217
218
219
220
221
NULL, /* Pause */
NULL, /* Resume */
NULL, /* Stop */
TIMIDITY_Delete,
TIMIDITY_Close,
NULL, /* Unload */
};
#endif /* MUSIC_MID_TIMIDITY */
/* vi: set ts=4 sw=4 expandtab: */