Skip to content

Latest commit

 

History

History
1609 lines (1485 loc) · 39.4 KB

music.c

File metadata and controls

1609 lines (1485 loc) · 39.4 KB
 
Oct 21, 1999
Oct 21, 1999
1
/*
Dec 31, 2011
Dec 31, 2011
2
SDL_mixer: An audio mixer library based on the SDL library
Feb 15, 2013
Feb 15, 2013
3
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
Dec 31, 2011
Dec 31, 2011
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.
Oct 21, 1999
Oct 21, 1999
20
21
*/
Dec 14, 2001
Dec 14, 2001
22
/* $Id$ */
Dec 14, 2001
Dec 14, 2001
23
Oct 23, 1999
Oct 23, 1999
24
25
#include <stdlib.h>
#include <string.h>
Oct 16, 2001
Oct 16, 2001
26
#include <ctype.h>
Nov 19, 2005
Nov 19, 2005
27
#include <assert.h>
Dec 21, 1999
Dec 21, 1999
28
29
#include "SDL_endian.h"
#include "SDL_audio.h"
Dec 27, 1999
Dec 27, 1999
30
#include "SDL_timer.h"
Oct 21, 1999
Oct 21, 1999
31
Jan 14, 2000
Jan 14, 2000
32
#include "SDL_mixer.h"
Oct 21, 1999
Oct 21, 1999
33
34
35
36
37
38
39
#ifdef CMD_MUSIC
#include "music_cmd.h"
#endif
#ifdef WAV_MUSIC
#include "wavestream.h"
#endif
Nov 16, 2009
Nov 16, 2009
40
41
42
#ifdef MODPLUG_MUSIC
#include "music_modplug.h"
#endif
Oct 3, 2009
Oct 3, 2009
43
44
#ifdef MOD_MUSIC
#include "music_mod.h"
Oct 21, 1999
Oct 21, 1999
45
46
#endif
#ifdef MID_MUSIC
Sep 5, 2001
Sep 5, 2001
47
48
49
# ifdef USE_TIMIDITY_MIDI
# include "timidity.h"
# endif
Mar 20, 2011
Mar 20, 2011
50
51
52
# ifdef USE_FLUIDSYNTH_MIDI
# include "fluidsynth.h"
# endif
Sep 5, 2001
Sep 5, 2001
53
54
55
# ifdef USE_NATIVE_MIDI
# include "native_midi.h"
# endif
Oct 21, 1999
Oct 21, 1999
56
#endif
Jul 3, 2000
Jul 3, 2000
57
58
59
#ifdef OGG_MUSIC
#include "music_ogg.h"
#endif
Oct 21, 1999
Oct 21, 1999
60
#ifdef MP3_MUSIC
May 12, 2006
May 12, 2006
61
#include "dynamic_mp3.h"
Jul 15, 2007
Jul 15, 2007
62
63
64
65
#endif
#ifdef MP3_MAD_MUSIC
#include "music_mad.h"
#endif
Feb 27, 2008
Feb 27, 2008
66
67
68
#ifdef FLAC_MUSIC
#include "music_flac.h"
#endif
Oct 21, 1999
Oct 21, 1999
69
Jul 15, 2007
Jul 15, 2007
70
#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
Oct 21, 1999
Oct 21, 1999
71
72
73
static SDL_AudioSpec used_mixer;
#endif
Jul 15, 2007
Jul 15, 2007
74
Feb 1, 2000
Feb 1, 2000
75
76
int volatile music_active = 1;
static int volatile music_stopped = 0;
Oct 21, 1999
Oct 21, 1999
77
78
static int music_loops = 0;
static char *music_cmd = NULL;
Feb 1, 2000
Feb 1, 2000
79
static Mix_Music * volatile music_playing = NULL;
Nov 11, 1999
Nov 11, 1999
80
static int music_volume = MIX_MAX_VOLUME;
Oct 23, 1999
Oct 23, 1999
81
Oct 21, 1999
Oct 21, 1999
82
struct _Mix_Music {
May 22, 2013
May 22, 2013
83
84
Mix_MusicType type;
union {
Oct 21, 1999
Oct 21, 1999
85
#ifdef CMD_MUSIC
May 22, 2013
May 22, 2013
86
MusicCMD *cmd;
Oct 21, 1999
Oct 21, 1999
87
88
#endif
#ifdef WAV_MUSIC
May 22, 2013
May 22, 2013
89
WAVStream *wave;
Oct 21, 1999
Oct 21, 1999
90
#endif
Nov 16, 2009
Nov 16, 2009
91
#ifdef MODPLUG_MUSIC
May 22, 2013
May 22, 2013
92
modplug_data *modplug;
Nov 16, 2009
Nov 16, 2009
93
#endif
Oct 3, 2009
Oct 3, 2009
94
#ifdef MOD_MUSIC
May 22, 2013
May 22, 2013
95
struct MODULE *module;
Oct 21, 1999
Oct 21, 1999
96
97
#endif
#ifdef MID_MUSIC
Sep 5, 2001
Sep 5, 2001
98
#ifdef USE_TIMIDITY_MIDI
May 22, 2013
May 22, 2013
99
MidiSong *midi;
Sep 5, 2001
Sep 5, 2001
100
#endif
Mar 20, 2011
Mar 20, 2011
101
#ifdef USE_FLUIDSYNTH_MIDI
May 22, 2013
May 22, 2013
102
FluidSynthMidiSong *fluidsynthmidi;
Mar 20, 2011
Mar 20, 2011
103
#endif
Aug 19, 2001
Aug 19, 2001
104
#ifdef USE_NATIVE_MIDI
May 22, 2013
May 22, 2013
105
NativeMidiSong *nativemidi;
Aug 19, 2001
Aug 19, 2001
106
#endif
Oct 21, 1999
Oct 21, 1999
107
#endif
Jul 3, 2000
Jul 3, 2000
108
#ifdef OGG_MUSIC
May 22, 2013
May 22, 2013
109
OGG_music *ogg;
Jul 3, 2000
Jul 3, 2000
110
#endif
Oct 21, 1999
Oct 21, 1999
111
#ifdef MP3_MUSIC
May 22, 2013
May 22, 2013
112
SMPEG *mp3;
Jul 15, 2007
Jul 15, 2007
113
114
#endif
#ifdef MP3_MAD_MUSIC
May 22, 2013
May 22, 2013
115
mad_data *mp3_mad;
Feb 27, 2008
Feb 27, 2008
116
117
#endif
#ifdef FLAC_MUSIC
May 22, 2013
May 22, 2013
118
FLAC_music *flac;
Oct 21, 1999
Oct 21, 1999
119
#endif
May 22, 2013
May 22, 2013
120
121
122
123
124
} data;
Mix_Fading fading;
int fade_step;
int fade_steps;
int error;
Oct 21, 1999
Oct 21, 1999
125
};
Dec 27, 1999
Dec 27, 1999
126
#ifdef MID_MUSIC
Sep 5, 2001
Sep 5, 2001
127
#ifdef USE_TIMIDITY_MIDI
Oct 21, 1999
Oct 21, 1999
128
static int timidity_ok;
Dec 17, 2001
Dec 17, 2001
129
static int samplesize;
Sep 5, 2001
Sep 5, 2001
130
#endif
Mar 20, 2011
Mar 20, 2011
131
132
133
#ifdef USE_FLUIDSYNTH_MIDI
static int fluidsynth_ok;
#endif
Aug 19, 2001
Aug 19, 2001
134
135
136
#ifdef USE_NATIVE_MIDI
static int native_midi_ok;
#endif
Dec 27, 1999
Dec 27, 1999
137
#endif
Oct 21, 1999
Oct 21, 1999
138
Nov 11, 1999
Nov 11, 1999
139
140
141
/* Used to calculate fading steps */
static int ms_per_step;
Jun 5, 2009
Jun 5, 2009
142
143
144
145
/* rcg06042009 report available decoders at runtime. */
static const char **music_decoders = NULL;
static int num_decoders = 0;
Mar 20, 2011
Mar 20, 2011
146
147
148
149
150
/* Semicolon-separated SoundFont paths */
#ifdef MID_MUSIC
char* soundfont_paths = NULL;
#endif
Nov 5, 2009
Nov 5, 2009
151
int Mix_GetNumMusicDecoders(void)
Jun 5, 2009
Jun 5, 2009
152
{
May 22, 2013
May 22, 2013
153
return(num_decoders);
Jun 5, 2009
Jun 5, 2009
154
155
156
157
}
const char *Mix_GetMusicDecoder(int index)
{
May 22, 2013
May 22, 2013
158
159
160
161
if ((index < 0) || (index >= num_decoders)) {
return NULL;
}
return(music_decoders[index]);
Jun 5, 2009
Jun 5, 2009
162
163
164
165
}
static void add_music_decoder(const char *decoder)
{
Jun 18, 2013
Jun 18, 2013
166
void *ptr = SDL_realloc((void *)music_decoders, (num_decoders + 1) * sizeof (const char *));
May 22, 2013
May 22, 2013
167
168
169
170
171
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
music_decoders = (const char **) ptr;
music_decoders[num_decoders++] = decoder;
Jun 5, 2009
Jun 5, 2009
172
173
}
Oct 30, 1999
Oct 30, 1999
174
/* Local low-level functions prototypes */
Nov 9, 2003
Nov 9, 2003
175
static void music_internal_initialize_volume(void);
May 16, 2002
May 16, 2002
176
177
178
179
180
static void music_internal_volume(int volume);
static int music_internal_play(Mix_Music *music, double position);
static int music_internal_position(double position);
static int music_internal_playing();
static void music_internal_halt(void);
Oct 26, 1999
Oct 26, 1999
181
Dec 27, 1999
Dec 27, 1999
182
183
184
185
186
187
/* Support for hooking when the music has finished */
static void (*music_finished_hook)(void) = NULL;
void Mix_HookMusicFinished(void (*music_finished)(void))
{
May 22, 2013
May 22, 2013
188
189
190
SDL_LockAudio();
music_finished_hook = music_finished;
SDL_UnlockAudio();
Dec 27, 1999
Dec 27, 1999
191
192
193
}
Nov 19, 2005
Nov 19, 2005
194
/* If music isn't playing, halt it if no looping is required, restart it */
Jun 2, 2013
Jun 2, 2013
195
/* othesrchise. NOP if the music is playing */
Nov 19, 2005
Nov 19, 2005
196
197
static int music_halt_or_loop (void)
{
May 22, 2013
May 22, 2013
198
199
200
201
/* Restart music if it has to loop */
if (!music_internal_playing())
{
Jan 4, 2012
Jan 4, 2012
202
#ifdef USE_NATIVE_MIDI
May 22, 2013
May 22, 2013
203
204
205
206
207
208
209
210
211
212
/* Native MIDI handles looping internally */
if (music_playing->type == MUS_MID && native_midi_ok) {
music_loops = 0;
}
#endif
/* Restart music if it has to loop at a high level */
if (music_loops)
{
Mix_Fading current_fade;
Jul 9, 2013
Jul 9, 2013
213
214
215
if (music_loops > 0) {
--music_loops;
}
May 22, 2013
May 22, 2013
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
current_fade = music_playing->fading;
music_internal_play(music_playing, 0.0);
music_playing->fading = current_fade;
}
else
{
music_internal_halt();
if (music_finished_hook)
music_finished_hook();
return 0;
}
}
return 1;
Nov 19, 2005
Nov 19, 2005
231
232
233
234
}
Oct 21, 1999
Oct 21, 1999
235
236
237
/* Mixing function */
void music_mixer(void *udata, Uint8 *stream, int len)
{
May 22, 2013
May 22, 2013
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
int left = 0;
if ( music_playing && music_active ) {
/* Handle fading */
if ( music_playing->fading != MIX_NO_FADING ) {
if ( music_playing->fade_step++ < music_playing->fade_steps ) {
int volume;
int fade_step = music_playing->fade_step;
int fade_steps = music_playing->fade_steps;
if ( music_playing->fading == MIX_FADING_OUT ) {
volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
} else { /* Fading in */
volume = (music_volume * fade_step) / fade_steps;
}
music_internal_volume(volume);
} else {
if ( music_playing->fading == MIX_FADING_OUT ) {
music_internal_halt();
if ( music_finished_hook ) {
music_finished_hook();
}
return;
}
music_playing->fading = MIX_NO_FADING;
}
}
music_halt_or_loop();
if (!music_internal_playing())
return;
switch (music_playing->type) {
Oct 21, 1999
Oct 21, 1999
271
#ifdef CMD_MUSIC
May 22, 2013
May 22, 2013
272
273
274
case MUS_CMD:
/* The playing is done externally */
break;
Oct 21, 1999
Oct 21, 1999
275
276
#endif
#ifdef WAV_MUSIC
May 22, 2013
May 22, 2013
277
278
279
case MUS_WAV:
left = WAVStream_PlaySome(stream, len);
break;
Oct 21, 1999
Oct 21, 1999
280
#endif
Nov 16, 2009
Nov 16, 2009
281
#ifdef MODPLUG_MUSIC
May 22, 2013
May 22, 2013
282
283
284
case MUS_MODPLUG:
left = modplug_playAudio(music_playing->data.modplug, stream, len);
break;
Nov 16, 2009
Nov 16, 2009
285
#endif
Oct 3, 2009
Oct 3, 2009
286
#ifdef MOD_MUSIC
May 22, 2013
May 22, 2013
287
288
289
case MUS_MOD:
left = MOD_playAudio(music_playing->data.module, stream, len);
break;
Oct 21, 1999
Oct 21, 1999
290
291
#endif
#ifdef MID_MUSIC
May 22, 2013
May 22, 2013
292
case MUS_MID:
Jan 1, 2012
Jan 1, 2012
293
#ifdef USE_NATIVE_MIDI
May 22, 2013
May 22, 2013
294
295
296
297
if ( native_midi_ok ) {
/* Native midi is handled asynchronously */
goto skip;
}
Jan 1, 2012
Jan 1, 2012
298
#endif
Mar 20, 2011
Mar 20, 2011
299
#ifdef USE_FLUIDSYNTH_MIDI
May 22, 2013
May 22, 2013
300
301
302
303
if ( fluidsynth_ok ) {
fluidsynth_playsome(music_playing->data.fluidsynthmidi, stream, len);
goto skip;
}
Mar 20, 2011
Mar 20, 2011
304
305
#endif
#ifdef USE_TIMIDITY_MIDI
May 22, 2013
May 22, 2013
306
307
308
309
310
if ( timidity_ok ) {
int samples = len / samplesize;
Timidity_PlaySome(stream, samples);
goto skip;
}
Oct 21, 1999
Oct 21, 1999
311
#endif
May 22, 2013
May 22, 2013
312
break;
Sep 5, 2001
Sep 5, 2001
313
#endif
Jul 3, 2000
Jul 3, 2000
314
#ifdef OGG_MUSIC
May 22, 2013
May 22, 2013
315
316
317
318
case MUS_OGG:
left = OGG_playAudio(music_playing->data.ogg, stream, len);
break;
Jul 3, 2000
Jul 3, 2000
319
#endif
Feb 27, 2008
Feb 27, 2008
320
#ifdef FLAC_MUSIC
May 22, 2013
May 22, 2013
321
322
323
case MUS_FLAC:
left = FLAC_playAudio(music_playing->data.flac, stream, len);
break;
Feb 27, 2008
Feb 27, 2008
324
#endif
Oct 21, 1999
Oct 21, 1999
325
#ifdef MP3_MUSIC
May 22, 2013
May 22, 2013
326
327
328
case MUS_MP3:
left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
break;
Jul 15, 2007
Jul 15, 2007
329
330
#endif
#ifdef MP3_MAD_MUSIC
May 22, 2013
May 22, 2013
331
332
333
case MUS_MP3_MAD:
left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
break;
Oct 21, 1999
Oct 21, 1999
334
#endif
May 22, 2013
May 22, 2013
335
336
337
338
339
default:
/* Unknown music type?? */
break;
}
}
Oct 2, 2009
Oct 2, 2009
340
Jan 1, 2012
Jan 1, 2012
341
skip:
May 22, 2013
May 22, 2013
342
343
344
345
346
347
/* Handle seamless music looping */
if (left > 0 && left < len) {
music_halt_or_loop();
if (music_internal_playing())
music_mixer(udata, stream+(len-left), left);
}
Oct 21, 1999
Oct 21, 1999
348
349
350
351
352
353
}
/* Initialize the music players with a certain desired audio format */
int open_music(SDL_AudioSpec *mixer)
{
#ifdef WAV_MUSIC
May 22, 2013
May 22, 2013
354
355
356
if ( WAVStream_Init(mixer) == 0 ) {
add_music_decoder("WAVE");
}
Oct 21, 1999
Oct 21, 1999
357
#endif
Nov 16, 2009
Nov 16, 2009
358
#ifdef MODPLUG_MUSIC
May 22, 2013
May 22, 2013
359
360
361
if ( modplug_init(mixer) == 0 ) {
add_music_decoder("MODPLUG");
}
Nov 16, 2009
Nov 16, 2009
362
#endif
Oct 3, 2009
Oct 3, 2009
363
#ifdef MOD_MUSIC
May 22, 2013
May 22, 2013
364
365
366
if ( MOD_init(mixer) == 0 ) {
add_music_decoder("MIKMOD");
}
Oct 21, 1999
Oct 21, 1999
367
368
#endif
#ifdef MID_MUSIC
Sep 5, 2001
Sep 5, 2001
369
#ifdef USE_TIMIDITY_MIDI
May 22, 2013
May 22, 2013
370
371
372
373
374
375
376
377
samplesize = mixer->size / mixer->samples;
if ( Timidity_Init(mixer->freq, mixer->format,
mixer->channels, mixer->samples) == 0 ) {
timidity_ok = 1;
add_music_decoder("TIMIDITY");
} else {
timidity_ok = 0;
}
Sep 5, 2001
Sep 5, 2001
378
#endif
Mar 20, 2011
Mar 20, 2011
379
#ifdef USE_FLUIDSYNTH_MIDI
May 22, 2013
May 22, 2013
380
381
382
383
384
385
if ( fluidsynth_init(mixer) == 0 ) {
fluidsynth_ok = 1;
add_music_decoder("FLUIDSYNTH");
} else {
fluidsynth_ok = 0;
}
Mar 20, 2011
Mar 20, 2011
386
#endif
Aug 19, 2001
Aug 19, 2001
387
#ifdef USE_NATIVE_MIDI
Mar 20, 2011
Mar 20, 2011
388
#ifdef USE_FLUIDSYNTH_MIDI
May 22, 2013
May 22, 2013
389
390
native_midi_ok = !fluidsynth_ok;
if ( native_midi_ok )
Mar 20, 2011
Mar 20, 2011
391
#endif
Sep 5, 2001
Sep 5, 2001
392
#ifdef USE_TIMIDITY_MIDI
May 22, 2013
May 22, 2013
393
394
395
396
397
native_midi_ok = !timidity_ok;
if ( !native_midi_ok ) {
native_midi_ok = (getenv("SDL_NATIVE_MUSIC") != NULL);
}
if ( native_midi_ok )
Sep 5, 2001
Sep 5, 2001
398
#endif
May 22, 2013
May 22, 2013
399
400
401
native_midi_ok = native_midi_detect();
if ( native_midi_ok )
add_music_decoder("NATIVEMIDI");
Aug 19, 2001
Aug 19, 2001
402
#endif
Oct 21, 1999
Oct 21, 1999
403
#endif
Jul 3, 2000
Jul 3, 2000
404
#ifdef OGG_MUSIC
May 22, 2013
May 22, 2013
405
406
407
if ( OGG_init(mixer) == 0 ) {
add_music_decoder("OGG");
}
Jul 3, 2000
Jul 3, 2000
408
#endif
Feb 27, 2008
Feb 27, 2008
409
#ifdef FLAC_MUSIC
May 22, 2013
May 22, 2013
410
411
412
if ( FLAC_init(mixer) == 0 ) {
add_music_decoder("FLAC");
}
Feb 27, 2008
Feb 27, 2008
413
#endif
Jul 15, 2007
Jul 15, 2007
414
#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
May 22, 2013
May 22, 2013
415
416
417
/* Keep a copy of the mixer */
used_mixer = *mixer;
add_music_decoder("MP3");
Oct 21, 1999
Oct 21, 1999
418
#endif
Jun 5, 2009
Jun 5, 2009
419
May 22, 2013
May 22, 2013
420
421
422
music_playing = NULL;
music_stopped = 0;
Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
Oct 21, 1999
Oct 21, 1999
423
May 22, 2013
May 22, 2013
424
425
/* Calculate the number of ms for each callback */
ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
Nov 11, 1999
Nov 11, 1999
426
May 22, 2013
May 22, 2013
427
return(0);
Oct 21, 1999
Oct 21, 1999
428
429
}
Oct 16, 2001
Oct 16, 2001
430
431
432
/* Portable case-insensitive string compare function */
int MIX_string_equals(const char *str1, const char *str2)
{
May 22, 2013
May 22, 2013
433
434
435
436
437
438
439
440
while ( *str1 && *str2 ) {
if ( toupper((unsigned char)*str1) !=
toupper((unsigned char)*str2) )
break;
++str1;
++str2;
}
return (!*str1 && !*str2);
Oct 16, 2001
Oct 16, 2001
441
442
}
Jan 4, 2012
Jan 4, 2012
443
444
static int detect_mp3(Uint8 *magic)
{
May 22, 2013
May 22, 2013
445
446
447
448
449
450
451
452
453
454
455
456
457
458
if ( strncmp((char *)magic, "ID3", 3) == 0 ) {
return 1;
}
/* Detection code lifted from SMPEG */
if(((magic[0] & 0xff) != 0xff) || // No sync bits
((magic[1] & 0xf0) != 0xf0) || //
((magic[2] & 0xf0) == 0x00) || // Bitrate is 0
((magic[2] & 0xf0) == 0xf0) || // Bitrate is 15
((magic[2] & 0x0c) == 0x0c) || // Frequency is 3
((magic[1] & 0x06) == 0x00)) { // Layer is 4
return(0);
}
return 1;
Jan 4, 2012
Jan 4, 2012
459
460
461
462
463
464
465
}
/* MUS_MOD can't be auto-detected. If no other format was detected, MOD is
* assumed and MUS_MOD will be returned, meaning that the format might not
* actually be MOD-based.
*
* Returns MUS_NONE in case of errors. */
Jun 2, 2013
Jun 2, 2013
466
static Mix_MusicType detect_music_type(SDL_RWops *src)
Jan 4, 2012
Jan 4, 2012
467
{
May 22, 2013
May 22, 2013
468
469
470
Uint8 magic[5];
Uint8 moremagic[9];
Jun 2, 2013
Jun 2, 2013
471
472
Sint64 start = SDL_RWtell(src);
if (SDL_RWread(src, magic, 1, 4) != 4 || SDL_RWread(src, moremagic, 1, 8) != 8 ) {
May 22, 2013
May 22, 2013
473
474
475
Mix_SetError("Couldn't read from RWops");
return MUS_NONE;
}
Jun 2, 2013
Jun 2, 2013
476
SDL_RWseek(src, start, RW_SEEK_SET);
May 22, 2013
May 22, 2013
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
magic[4]='\0';
moremagic[8] = '\0';
/* WAVE files have the magic four bytes "RIFF"
AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */
if (((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
(strcmp((char *)magic, "FORM") == 0)) {
return MUS_WAV;
}
/* Ogg Vorbis files have the magic four bytes "OggS" */
if (strcmp((char *)magic, "OggS") == 0) {
return MUS_OGG;
}
/* FLAC files have the magic four bytes "fLaC" */
if (strcmp((char *)magic, "fLaC") == 0) {
return MUS_FLAC;
}
/* MIDI files have the magic four bytes "MThd" */
if (strcmp((char *)magic, "MThd") == 0) {
return MUS_MID;
}
if (detect_mp3(magic)) {
return MUS_MP3;
}
/* Assume MOD format.
*
* Apparently there is no way to check if the file is really a MOD,
* or there are too many formats supported by MikMod/ModPlug, or
* MikMod/ModPlug does this check by itself. */
return MUS_MOD;
Jan 4, 2012
Jan 4, 2012
512
513
}
Oct 21, 1999
Oct 21, 1999
514
515
516
/* Load a music file */
Mix_Music *Mix_LoadMUS(const char *file)
{
Jun 2, 2013
Jun 2, 2013
517
SDL_RWops *src;
May 22, 2013
May 22, 2013
518
519
520
Mix_Music *music;
Mix_MusicType type;
char *ext = strrchr(file, '.');
Oct 21, 1999
Oct 21, 1999
521
Jan 4, 2012
Jan 4, 2012
522
#ifdef CMD_MUSIC
May 22, 2013
May 22, 2013
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
if ( music_cmd ) {
/* Allocate memory for the music structure */
music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
if ( music == NULL ) {
Mix_SetError("Out of memory");
return(NULL);
}
music->error = 0;
music->type = MUS_CMD;
music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
if ( music->data.cmd == NULL ) {
SDL_free(music);
music = NULL;
}
return music;
}
#endif
Jun 2, 2013
Jun 2, 2013
541
542
src = SDL_RWFromFile(file, "rb");
if ( src == NULL ) {
May 22, 2013
May 22, 2013
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
Mix_SetError("Couldn't open '%s'", file);
return NULL;
}
/* Use the extension as a first guess on the file type */
type = MUS_NONE;
ext = strrchr(file, '.');
/* No need to guard these with #ifdef *_MUSIC stuff,
* since we simply call Mix_LoadMUSType_RW() later */
if ( ext ) {
++ext; /* skip the dot in the extension */
if ( MIX_string_equals(ext, "WAV") ) {
type = MUS_WAV;
} else if ( MIX_string_equals(ext, "MID") ||
MIX_string_equals(ext, "MIDI") ||
MIX_string_equals(ext, "KAR") ) {
type = MUS_MID;
} else if ( MIX_string_equals(ext, "OGG") ) {
type = MUS_OGG;
} else if ( MIX_string_equals(ext, "FLAC") ) {
type = MUS_FLAC;
} else if ( MIX_string_equals(ext, "MPG") ||
MIX_string_equals(ext, "MPEG") ||
MIX_string_equals(ext, "MP3") ||
MIX_string_equals(ext, "MAD") ) {
type = MUS_MP3;
}
}
if ( type == MUS_NONE ) {
Jun 2, 2013
Jun 2, 2013
572
type = detect_music_type(src);
May 22, 2013
May 22, 2013
573
574
575
576
577
}
/* We need to know if a specific error occurs; if not, we'll set a
* generic one, so we clear the current one. */
Mix_SetError("");
Jun 2, 2013
Jun 2, 2013
578
music = Mix_LoadMUSType_RW(src, type, SDL_TRUE);
May 22, 2013
May 22, 2013
579
if ( music == NULL && Mix_GetError()[0] == '\0' ) {
Jun 2, 2013
Jun 2, 2013
580
Mix_SetError("Unrecognized music format");
May 22, 2013
May 22, 2013
581
582
}
return music;
Jan 4, 2012
Jan 4, 2012
583
584
}
Jun 2, 2013
Jun 2, 2013
585
Mix_Music *Mix_LoadMUS_RW(SDL_RWops *src, int freesrc)
Jan 4, 2012
Jan 4, 2012
586
{
Jun 2, 2013
Jun 2, 2013
587
return Mix_LoadMUSType_RW(src, MUS_NONE, freesrc);
Jan 4, 2012
Jan 4, 2012
588
589
}
Jun 2, 2013
Jun 2, 2013
590
Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc)
Jan 4, 2012
Jan 4, 2012
591
{
May 22, 2013
May 22, 2013
592
Mix_Music *music;
Jun 2, 2013
Jun 2, 2013
593
Sint64 start;
May 22, 2013
May 22, 2013
594
Jun 2, 2013
Jun 2, 2013
595
if (!src) {
May 22, 2013
May 22, 2013
596
597
598
Mix_SetError("RWops pointer is NULL");
return NULL;
}
Jun 2, 2013
Jun 2, 2013
599
start = SDL_RWtell(src);
May 22, 2013
May 22, 2013
600
601
602
603
/* If the caller wants auto-detection, figure out what kind of file
* this is. */
if (type == MUS_NONE) {
Jun 2, 2013
Jun 2, 2013
604
if ((type = detect_music_type(src)) == MUS_NONE) {
May 22, 2013
May 22, 2013
605
606
/* Don't call Mix_SetError() here since detect_music_type()
* does that. */
Jun 2, 2013
Jun 2, 2013
607
608
609
if (freesrc) {
SDL_RWclose(src);
}
May 22, 2013
May 22, 2013
610
611
612
613
614
615
616
617
return NULL;
}
}
/* Allocate memory for the music structure */
music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
if (music == NULL ) {
Mix_SetError("Out of memory");
Jun 2, 2013
Jun 2, 2013
618
619
620
if (freesrc) {
SDL_RWclose(src);
}
May 22, 2013
May 22, 2013
621
622
return NULL;
}
Jun 2, 2013
Jun 2, 2013
623
music->error = 1;
May 22, 2013
May 22, 2013
624
625
switch (type) {
Oct 21, 1999
Oct 21, 1999
626
#ifdef WAV_MUSIC
May 22, 2013
May 22, 2013
627
case MUS_WAV:
Jun 2, 2013
Jun 2, 2013
628
629
630
631
music->type = MUS_WAV;
music->data.wave = WAVStream_LoadSong_RW(src, freesrc);
if (music->data.wave) {
music->error = 0;
May 22, 2013
May 22, 2013
632
633
}
break;
Oct 21, 1999
Oct 21, 1999
634
#endif
Jul 3, 2000
Jul 3, 2000
635
#ifdef OGG_MUSIC
May 22, 2013
May 22, 2013
636
637
case MUS_OGG:
music->type = MUS_OGG;
Jun 2, 2013
Jun 2, 2013
638
639
640
music->data.ogg = OGG_new_RW(src, freesrc);
if (music->data.ogg) {
music->error = 0;
May 22, 2013
May 22, 2013
641
642
}
break;
Jul 3, 2000
Jul 3, 2000
643
#endif
Feb 27, 2008
Feb 27, 2008
644
#ifdef FLAC_MUSIC
May 22, 2013
May 22, 2013
645
646
case MUS_FLAC:
music->type = MUS_FLAC;
Jun 2, 2013
Jun 2, 2013
647
648
649
music->data.flac = FLAC_new_RW(src, freesrc);
if (music->data.flac) {
music->error = 0;
May 22, 2013
May 22, 2013
650
651
}
break;
Feb 27, 2008
Feb 27, 2008
652
#endif
Oct 21, 1999
Oct 21, 1999
653
#ifdef MP3_MUSIC
May 22, 2013
May 22, 2013
654
case MUS_MP3:
Jun 2, 2013
Jun 2, 2013
655
if (Mix_Init(MIX_INIT_MP3)) {
May 22, 2013
May 22, 2013
656
657
SMPEG_Info info;
music->type = MUS_MP3;
Jun 2, 2013
Jun 2, 2013
658
659
music->data.mp3 = smpeg.SMPEG_new_rwops(src, &info, freesrc, 0);
if (!info.has_audio) {
May 22, 2013
May 22, 2013
660
Mix_SetError("MPEG file does not have any audio stream.");
Jun 2, 2013
Jun 2, 2013
661
662
663
smpeg.SMPEG_delete(music->data.mp3);
/* Deleting the MP3 closed the source if desired */
freesrc = SDL_FALSE;
May 22, 2013
May 22, 2013
664
665
} else {
smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
Jun 2, 2013
Jun 2, 2013
666
music->error = 0;
May 22, 2013
May 22, 2013
667
668
669
}
}
break;
Jan 4, 2012
Jan 4, 2012
670
#elif defined(MP3_MAD_MUSIC)
May 22, 2013
May 22, 2013
671
672
case MUS_MP3:
music->type = MUS_MP3_MAD;
Jun 2, 2013
Jun 2, 2013
673
674
675
676
music->data.mp3_mad = mad_openFileRW(src, &used_mixer, freesrc);
if (music->data.mp3_mad) {
music->error = 0;
} else {
May 22, 2013
May 22, 2013
677
678
679
Mix_SetError("Could not initialize MPEG stream.");
}
break;
Jul 15, 2007
Jul 15, 2007
680
#endif
Jan 4, 2012
Jan 4, 2012
681
#ifdef MID_MUSIC
May 22, 2013
May 22, 2013
682
683
case MUS_MID:
music->type = MUS_MID;
Jan 4, 2012
Jan 4, 2012
684
#ifdef USE_NATIVE_MIDI
Jun 2, 2013
Jun 2, 2013
685
686
687
688
689
690
if (native_midi_ok) {
SDL_RWseek(src, start, RW_SEEK_SET);
music->data.nativemidi = native_midi_loadsong_RW(src, freesrc);
if (music->data.nativemidi) {
music->error = 0;
} else {
May 22, 2013
May 22, 2013
691
692
693
694
Mix_SetError("%s", native_midi_error());
}
break;
}
Jan 4, 2012
Jan 4, 2012
695
696
#endif
#ifdef USE_FLUIDSYNTH_MIDI
Jun 2, 2013
Jun 2, 2013
697
698
699
700
701
if (fluidsynth_ok) {
SDL_RWseek(src, start, RW_SEEK_SET);
music->data.fluidsynthmidi = fluidsynth_loadsong_RW(src, freesrc);
if (music->data.fluidsynthmidi) {
music->error = 0;
May 22, 2013
May 22, 2013
702
703
704
}
break;
}
Jan 4, 2012
Jan 4, 2012
705
706
#endif
#ifdef USE_TIMIDITY_MIDI
Jun 2, 2013
Jun 2, 2013
707
708
709
710
711
712
if (timidity_ok) {
SDL_RWseek(src, start, RW_SEEK_SET);
music->data.midi = Timidity_LoadSong_RW(src, freesrc);
if (music->data.midi) {
music->error = 0;
} else {
May 22, 2013
May 22, 2013
713
714
715
716
717
718
719
Mix_SetError("%s", Timidity_Error());
}
} else {
Mix_SetError("%s", Timidity_Error());
}
#endif
break;
Jan 4, 2012
Jan 4, 2012
720
721
#endif
#if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
May 22, 2013
May 22, 2013
722
case MUS_MOD:
Jan 4, 2012
Jan 4, 2012
723
#ifdef MODPLUG_MUSIC
Jun 2, 2013
Jun 2, 2013
724
725
if (music->error) {
SDL_RWseek(src, start, RW_SEEK_SET);
May 22, 2013
May 22, 2013
726
music->type = MUS_MODPLUG;
Jun 2, 2013
Jun 2, 2013
727
728
music->data.modplug = modplug_new_RW(src, freesrc);
if (music->data.modplug) {
May 22, 2013
May 22, 2013
729
730
731
music->error = 0;
}
}
Nov 16, 2009
Nov 16, 2009
732
#endif
Oct 3, 2009
Oct 3, 2009
733
#ifdef MOD_MUSIC
Jun 2, 2013
Jun 2, 2013
734
735
if (music->error) {
SDL_RWseek(src, start, RW_SEEK_SET);
May 22, 2013
May 22, 2013
736
music->type = MUS_MOD;
Jun 2, 2013
Jun 2, 2013
737
738
music->data.module = MOD_new_RW(src, freesrc);
if (music->data.module) {
May 22, 2013
May 22, 2013
739
740
741
music->error = 0;
}
}
Oct 21, 1999
Oct 21, 1999
742
#endif
May 22, 2013
May 22, 2013
743
break;
Jan 4, 2012
Jan 4, 2012
744
745
#endif
May 22, 2013
May 22, 2013
746
747
default:
Mix_SetError("Unrecognized music format");
Jun 2, 2013
Jun 2, 2013
748
break;
May 22, 2013
May 22, 2013
749
} /* switch (want) */
Mar 20, 2011
Mar 20, 2011
750
May 22, 2013
May 22, 2013
751
752
if (music->error) {
SDL_free(music);
Jun 2, 2013
Jun 2, 2013
753
754
755
756
757
758
if (freesrc) {
SDL_RWclose(src);
} else {
SDL_RWseek(src, start, RW_SEEK_SET);
}
music = NULL;
May 22, 2013
May 22, 2013
759
}
Jun 2, 2013
Jun 2, 2013
760
return music;
Oct 21, 1999
Oct 21, 1999
761
762
763
764
765
}
/* Free a music chunk previously loaded */
void Mix_FreeMusic(Mix_Music *music)
{
May 22, 2013
May 22, 2013
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
if ( music ) {
/* Stop the music if it's currently playing */
SDL_LockAudio();
if ( music == music_playing ) {
/* Wait for any fade out to finish */
while ( music->fading == MIX_FADING_OUT ) {
SDL_UnlockAudio();
SDL_Delay(100);
SDL_LockAudio();
}
if ( music == music_playing ) {
music_internal_halt();
}
}
SDL_UnlockAudio();
switch (music->type) {
Oct 21, 1999
Oct 21, 1999
782
#ifdef CMD_MUSIC
May 22, 2013
May 22, 2013
783
784
785
case MUS_CMD:
MusicCMD_FreeSong(music->data.cmd);
break;
Oct 21, 1999
Oct 21, 1999
786
787
#endif
#ifdef WAV_MUSIC
May 22, 2013
May 22, 2013
788
789
790
case MUS_WAV:
WAVStream_FreeSong(music->data.wave);
break;
Oct 21, 1999
Oct 21, 1999
791
#endif
Nov 16, 2009
Nov 16, 2009
792
#ifdef MODPLUG_MUSIC
May 22, 2013
May 22, 2013
793
794
795
case MUS_MODPLUG:
modplug_delete(music->data.modplug);
break;
Nov 16, 2009
Nov 16, 2009
796
#endif
Oct 3, 2009
Oct 3, 2009
797
#ifdef MOD_MUSIC
May 22, 2013
May 22, 2013
798
799
800
case MUS_MOD:
MOD_delete(music->data.module);
break;
Oct 21, 1999
Oct 21, 1999
801
802
#endif
#ifdef MID_MUSIC
May 22, 2013
May 22, 2013
803
case MUS_MID:
Aug 19, 2001
Aug 19, 2001
804
#ifdef USE_NATIVE_MIDI
May 22, 2013
May 22, 2013
805
806
807
808
if ( native_midi_ok ) {
native_midi_freesong(music->data.nativemidi);
goto skip;
}
Mar 20, 2011
Mar 20, 2011
809
810
#endif
#ifdef USE_FLUIDSYNTH_MIDI
May 22, 2013
May 22, 2013
811
812
813
814
if ( fluidsynth_ok ) {
fluidsynth_freesong(music->data.fluidsynthmidi);
goto skip;
}
Aug 19, 2001
Aug 19, 2001
815
#endif
Sep 5, 2001
Sep 5, 2001
816
#ifdef USE_TIMIDITY_MIDI
May 22, 2013
May 22, 2013
817
818
819
820
if ( timidity_ok ) {
Timidity_FreeSong(music->data.midi);
goto skip;
}
Sep 5, 2001
Sep 5, 2001
821
#endif
May 22, 2013
May 22, 2013
822
break;
Oct 21, 1999
Oct 21, 1999
823
#endif
Jul 3, 2000
Jul 3, 2000
824
#ifdef OGG_MUSIC
May 22, 2013
May 22, 2013
825
826
827
case MUS_OGG:
OGG_delete(music->data.ogg);
break;
Jul 3, 2000
Jul 3, 2000
828
#endif
Feb 27, 2008
Feb 27, 2008
829
#ifdef FLAC_MUSIC
May 22, 2013
May 22, 2013
830
831
832
case MUS_FLAC:
FLAC_delete(music->data.flac);
break;
Feb 27, 2008
Feb 27, 2008
833
#endif
Oct 21, 1999
Oct 21, 1999
834
#ifdef MP3_MUSIC
May 22, 2013
May 22, 2013
835
836
837
case MUS_MP3:
smpeg.SMPEG_delete(music->data.mp3);
break;
Jul 15, 2007
Jul 15, 2007
838
839
#endif
#ifdef MP3_MAD_MUSIC
May 22, 2013
May 22, 2013
840
841
842
case MUS_MP3_MAD:
mad_closeFile(music->data.mp3_mad);
break;
Oct 21, 1999
Oct 21, 1999
843
#endif
May 22, 2013
May 22, 2013
844
845
846
847
default:
/* Unknown music type?? */
break;
}
Mar 20, 2011
Mar 20, 2011
848
849
skip:
May 22, 2013
May 22, 2013
850
851
SDL_free(music);
}
Oct 21, 1999
Oct 21, 1999
852
853
}
May 19, 2002
May 19, 2002
854
855
856
857
858
/* Find out the music format of a mixer music, or the currently playing
music, if 'music' is NULL.
*/
Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
{
May 22, 2013
May 22, 2013
859
860
861
862
863
864
865
866
867
868
869
870
Mix_MusicType type = MUS_NONE;
if ( music ) {
type = music->type;
} else {
SDL_LockAudio();
if ( music_playing ) {
type = music_playing->type;
}
SDL_UnlockAudio();
}
return(type);
May 19, 2002
May 19, 2002
871
872
}
May 16, 2002
May 16, 2002
873
874
875
/* Play a music chunk. Returns 0, or -1 if there was an error.
*/
static int music_internal_play(Mix_Music *music, double position)
Oct 21, 1999
Oct 21, 1999
876
{
May 22, 2013
May 22, 2013
877
int retval = 0;
May 16, 2002
May 16, 2002
878
Jan 6, 2012
Jan 6, 2012
879
#if defined(__MACOSX__) && defined(USE_NATIVE_MIDI)
May 22, 2013
May 22, 2013
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
/* This fixes a bug with native MIDI on Mac OS X, where you
can't really stop and restart MIDI from the audio callback.
*/
if ( music == music_playing && music->type == MUS_MID && native_midi_ok ) {
/* Just a seek suffices to restart playing */
music_internal_position(position);
return 0;
}
#endif
/* Note the music we're playing */
if ( music_playing ) {
music_internal_halt();
}
music_playing = music;
/* Set the initial volume */
if ( music->type != MUS_MOD ) {
music_internal_initialize_volume();
}
/* Set up for playback */
switch (music->type) {
Oct 21, 1999
Oct 21, 1999
903
#ifdef CMD_MUSIC
May 22, 2013
May 22, 2013
904
905
906
case MUS_CMD:
MusicCMD_Start(music->data.cmd);
break;
Oct 21, 1999
Oct 21, 1999
907
908
#endif
#ifdef WAV_MUSIC
May 22, 2013
May 22, 2013
909
910
911
case MUS_WAV:
WAVStream_Start(music->data.wave);
break;
Oct 21, 1999
Oct 21, 1999
912
#endif
Nov 16, 2009
Nov 16, 2009
913
#ifdef MODPLUG_MUSIC
May 22, 2013
May 22, 2013
914
915
916
917
918
case MUS_MODPLUG:
/* can't set volume until file is loaded, so finally set it now */
music_internal_initialize_volume();
modplug_play(music->data.modplug);
break;
Nov 16, 2009
Nov 16, 2009
919
#endif
Oct 3, 2009
Oct 3, 2009
920
#ifdef MOD_MUSIC
May 22, 2013
May 22, 2013
921
922
923
924
925
case MUS_MOD:
MOD_play(music->data.module);
/* Player_SetVolume() does nothing before Player_Start() */
music_internal_initialize_volume();
break;
Oct 21, 1999
Oct 21, 1999
926
927
#endif
#ifdef MID_MUSIC
May 22, 2013
May 22, 2013
928
case MUS_MID:
Aug 19, 2001
Aug 19, 2001
929
#ifdef USE_NATIVE_MIDI
May 22, 2013
May 22, 2013
930
931
932
933
if ( native_midi_ok ) {
native_midi_start(music->data.nativemidi, music_loops);
goto skip;
}
Mar 20, 2011
Mar 20, 2011
934
935
#endif
#ifdef USE_FLUIDSYNTH_MIDI
May 22, 2013
May 22, 2013
936
937
938
939
if (fluidsynth_ok ) {
fluidsynth_start(music->data.fluidsynthmidi);
goto skip;
}
Aug 19, 2001
Aug 19, 2001
940
#endif
Sep 5, 2001
Sep 5, 2001
941
#ifdef USE_TIMIDITY_MIDI
May 22, 2013
May 22, 2013
942
943
944
945
if ( timidity_ok ) {
Timidity_Start(music->data.midi);
goto skip;
}
Sep 5, 2001
Sep 5, 2001
946
#endif
May 22, 2013
May 22, 2013
947
break;
Oct 21, 1999
Oct 21, 1999
948
#endif
Jul 3, 2000
Jul 3, 2000
949
#ifdef OGG_MUSIC
May 22, 2013
May 22, 2013
950
951
952
case MUS_OGG:
OGG_play(music->data.ogg);
break;
Jul 3, 2000
Jul 3, 2000
953
#endif
Feb 27, 2008
Feb 27, 2008
954
#ifdef FLAC_MUSIC
May 22, 2013
May 22, 2013
955
956
957
case MUS_FLAC:
FLAC_play(music->data.flac);
break;
Feb 27, 2008
Feb 27, 2008
958
#endif
Oct 21, 1999
Oct 21, 1999
959
#ifdef MP3_MUSIC
May 22, 2013
May 22, 2013
960
961
962
963
964
case MUS_MP3:
smpeg.SMPEG_enableaudio(music->data.mp3,1);
smpeg.SMPEG_enablevideo(music->data.mp3,0);
smpeg.SMPEG_play(music_playing->data.mp3);
break;
Jul 15, 2007
Jul 15, 2007
965
966
#endif
#ifdef MP3_MAD_MUSIC
May 22, 2013
May 22, 2013
967
968
969
case MUS_MP3_MAD:
mad_start(music->data.mp3_mad);
break;
Oct 21, 1999
Oct 21, 1999
970
#endif
May 22, 2013
May 22, 2013
971
972
973
974
975
default:
Mix_SetError("Can't play unknown music type");
retval = -1;
break;
}
Oct 30, 1999
Oct 30, 1999
976
Mar 20, 2011
Mar 20, 2011
977
skip:
May 22, 2013
May 22, 2013
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
/* Set the playback position, note any errors if an offset is used */
if ( retval == 0 ) {
if ( position > 0.0 ) {
if ( music_internal_position(position) < 0 ) {
Mix_SetError("Position not implemented for music type");
retval = -1;
}
} else {
music_internal_position(0.0);
}
}
/* If the setup failed, we're not playing any music anymore */
if ( retval < 0 ) {
music_playing = NULL;
}
return(retval);
May 16, 2002
May 16, 2002
995
996
}
int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
Oct 30, 1999
Oct 30, 1999
997
{
May 22, 2013
May 22, 2013
998
999
1000
int retval;
if ( ms_per_step == 0 ) {