/
music.c
1679 lines (1567 loc) · 36.4 KB
1
/*
2
SDL_mixer: An audio mixer library based on the SDL library
3
Copyright (C) 1997-2009 Sam Lantinga
4
5
6
7
8
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
9
10
11
12
13
This library 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. See the GNU
Library General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20
Sam Lantinga
slouken@libsdl.org
21
22
*/
23
/* $Id$ */
24
25
26
#include <stdlib.h>
#include <string.h>
27
#include <ctype.h>
28
#include <assert.h>
29
30
#include "SDL_endian.h"
#include "SDL_audio.h"
31
#include "SDL_timer.h"
32
33
#include "SDL_mixer.h"
34
35
36
37
38
39
40
41
42
#define SDL_SURROUND
#ifdef SDL_SURROUND
#define MAX_OUTPUT_CHANNELS 6
#else
#define MAX_OUTPUT_CHANNELS 2
#endif
43
44
45
46
47
48
49
50
51
52
53
/* The music command hack is UNIX specific */
#ifndef unix
#undef CMD_MUSIC
#endif
#ifdef CMD_MUSIC
#include "music_cmd.h"
#endif
#ifdef WAV_MUSIC
#include "wavestream.h"
#endif
54
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
55
56
57
58
59
# include "mikmod.h"
# if defined(LIBMIKMOD_VERSION) /* libmikmod 3.1.8 */
# define UNIMOD MODULE
# define MikMod_Init() MikMod_Init(NULL)
# define MikMod_LoadSong(a,b) Player_Load(a,b,0)
60
61
# ifndef LIBMIKMOD_MUSIC
# define MikMod_LoadSongRW(a,b) Player_LoadRW(a,b,0)
62
# endif
63
64
65
66
67
68
# define MikMod_FreeSong Player_Free
extern int MikMod_errno;
# else /* old MikMod 3.0.3 */
# define MikMod_strerror(x) _mm_errmsg[x])
# define MikMod_errno _mm_errno
# endif
69
70
#endif
#ifdef MID_MUSIC
71
72
73
74
75
76
77
78
79
80
81
# ifdef USE_TIMIDITY_MIDI
# include "timidity.h"
# endif
# ifdef USE_NATIVE_MIDI
# include "native_midi.h"
# endif
# if defined(USE_TIMIDITY_MIDI) && defined(USE_NATIVE_MIDI)
# define MIDI_ELSE else
# else
# define MIDI_ELSE
# endif
82
#endif
83
84
85
#ifdef OGG_MUSIC
#include "music_ogg.h"
#endif
86
#ifdef MP3_MUSIC
87
#include "dynamic_mp3.h"
88
89
90
91
#endif
#ifdef MP3_MAD_MUSIC
#include "music_mad.h"
#endif
92
93
94
#ifdef FLAC_MUSIC
#include "music_flac.h"
#endif
95
96
#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
97
98
99
static SDL_AudioSpec used_mixer;
#endif
101
102
int volatile music_active = 1;
static int volatile music_stopped = 0;
103
104
static int music_loops = 0;
static char *music_cmd = NULL;
105
static Mix_Music * volatile music_playing = NULL;
106
static int music_volume = MIX_MAX_VOLUME;
107
108
static int music_swap8;
static int music_swap16;
109
110
struct _Mix_Music {
111
Mix_MusicType type;
112
113
114
115
116
117
118
union {
#ifdef CMD_MUSIC
MusicCMD *cmd;
#endif
#ifdef WAV_MUSIC
WAVStream *wave;
#endif
119
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
120
121
122
UNIMOD *module;
#endif
#ifdef MID_MUSIC
123
#ifdef USE_TIMIDITY_MIDI
124
MidiSong *midi;
125
#endif
126
127
128
#ifdef USE_NATIVE_MIDI
NativeMidiSong *nativemidi;
#endif
129
#endif
130
131
132
#ifdef OGG_MUSIC
OGG_music *ogg;
#endif
133
134
#ifdef MP3_MUSIC
SMPEG *mp3;
135
136
137
#endif
#ifdef MP3_MAD_MUSIC
mad_data *mp3_mad;
138
139
140
#endif
#ifdef FLAC_MUSIC
FLAC_music *flac;
141
142
#endif
} data;
143
Mix_Fading fading;
144
145
int fade_step;
int fade_steps;
146
147
int error;
};
148
#ifdef MID_MUSIC
149
#ifdef USE_TIMIDITY_MIDI
150
static int timidity_ok;
151
static int samplesize;
152
#endif
153
154
155
#ifdef USE_NATIVE_MIDI
static int native_midi_ok;
#endif
156
#endif
157
158
159
160
161
/* Reference for converting mikmod output to 4/6 channels */
static int current_output_channels;
static Uint16 current_output_format;
162
163
164
/* Used to calculate fading steps */
static int ms_per_step;
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* rcg06042009 report available decoders at runtime. */
static const char **music_decoders = NULL;
static int num_decoders = 0;
int Mix_NumMusicDecoders(void)
{
return(num_decoders);
}
const char *Mix_GetMusicDecoder(int index)
{
if ((index < 0) || (index >= num_decoders)) {
return NULL;
}
return(music_decoders[index]);
}
static void add_music_decoder(const char *decoder)
{
void *ptr = realloc(music_decoders, num_decoders * sizeof (const char **));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
music_decoders = (const char **) ptr;
music_decoders[num_decoders++] = decoder;
}
192
/* Local low-level functions prototypes */
193
static void music_internal_initialize_volume(void);
194
195
196
197
198
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);
199
200
201
202
203
204
205
206
207
208
209
210
211
/* Support for hooking when the music has finished */
static void (*music_finished_hook)(void) = NULL;
void Mix_HookMusicFinished(void (*music_finished)(void))
{
SDL_LockAudio();
music_finished_hook = music_finished;
SDL_UnlockAudio();
}
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/* If music isn't playing, halt it if no looping is required, restart it */
/* otherwhise. NOP if the music is playing */
static int music_halt_or_loop (void)
{
/* Restart music if it has to loop */
if (!music_internal_playing())
{
/* Restart music if it has to loop at a high level */
if (music_loops && --music_loops)
{
Mix_Fading 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;
}
242
243
244
/* Mixing function */
void music_mixer(void *udata, Uint8 *stream, int len)
{
245
246
int left = 0;
247
if ( music_playing && music_active ) {
248
/* Handle fading */
249
250
if ( music_playing->fading != MIX_NO_FADING ) {
if ( music_playing->fade_step++ < music_playing->fade_steps ) {
251
int volume;
252
253
int fade_step = music_playing->fade_step;
int fade_steps = music_playing->fade_steps;
254
255
if ( music_playing->fading == MIX_FADING_OUT ) {
256
volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
257
} else { /* Fading in */
258
volume = (music_volume * fade_step) / fade_steps;
259
}
260
music_internal_volume(volume);
261
262
} else {
if ( music_playing->fading == MIX_FADING_OUT ) {
263
264
265
266
music_internal_halt();
if ( music_finished_hook ) {
music_finished_hook();
}
267
return;
268
}
269
music_playing->fading = MIX_NO_FADING;
270
271
}
}
272
273
274
275
276
if (music_halt_or_loop() == 0)
return;
277
278
279
280
281
282
283
284
switch (music_playing->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
/* The playing is done externally */
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
285
left = WAVStream_PlaySome(stream, len);
286
287
break;
#endif
288
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
289
case MUS_MOD:
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
if (current_output_channels > 2) {
int small_len = 2 * len / current_output_channels;
int i;
Uint8 *src, *dst;
VC_WriteBytes((SBYTE *)stream, small_len);
/* and extend to len by copying channels */
src = stream + small_len;
dst = stream + len;
switch (current_output_format & 0xFF) {
case 8:
for ( i=small_len/2; i; --i ) {
src -= 2;
dst -= current_output_channels;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = src[1];
if (current_output_channels == 6) {
dst[4] = src[0];
dst[5] = src[1];
}
}
break;
case 16:
for ( i=small_len/4; i; --i ) {
src -= 4;
dst -= 2 * current_output_channels;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[0];
dst[5] = src[1];
dst[6] = src[2];
dst[7] = src[3];
if (current_output_channels == 6) {
dst[8] = src[0];
dst[9] = src[1];
dst[10] = src[2];
dst[11] = src[3];
}
}
break;
}
}
else VC_WriteBytes((SBYTE *)stream, len);
341
342
if ( music_swap8 ) {
Uint8 *dst;
343
int i;
344
345
346
347
348
349
350
351
dst = stream;
for ( i=len; i; --i ) {
*dst++ ^= 0x80;
}
} else
if ( music_swap16 ) {
Uint8 *dst, tmp;
352
int i;
353
354
355
356
357
358
359
360
361
362
363
364
dst = stream;
for ( i=(len/2); i; --i ) {
tmp = dst[0];
dst[0] = dst[1];
dst[1] = tmp;
dst += 2;
}
}
break;
#endif
#ifdef MID_MUSIC
365
#ifdef USE_TIMIDITY_MIDI
366
case MUS_MID:
367
368
369
370
if ( timidity_ok ) {
int samples = len / samplesize;
Timidity_PlaySome(stream, samples);
}
371
372
break;
#endif
373
#endif
374
375
#ifdef OGG_MUSIC
case MUS_OGG:
376
377
left = OGG_playAudio(music_playing->data.ogg, stream, len);
378
379
break;
#endif
380
381
#ifdef FLAC_MUSIC
case MUS_FLAC:
382
left = FLAC_playAudio(music_playing->data.flac, stream, len);
383
384
break;
#endif
385
#ifdef MP3_MUSIC
386
case MUS_MP3:
387
left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
388
break;
389
390
391
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
392
left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
394
395
396
397
398
399
#endif
default:
/* Unknown music type?? */
break;
}
}
400
401
402
403
404
/* Handle seamless music looping */
if (left > 0 && left < len && music_halt_or_loop()) {
music_mixer(udata, stream+(len-left), left);
}
405
406
407
408
409
410
}
/* Initialize the music players with a certain desired audio format */
int open_music(SDL_AudioSpec *mixer)
{
int music_error;
411
412
413
#ifdef LIBMIKMOD_MUSIC
CHAR *list;
#endif
414
415
416
417
418
music_error = 0;
#ifdef WAV_MUSIC
if ( WAVStream_Init(mixer) < 0 ) {
++music_error;
419
420
} else {
add_music_decoder("WAVE");
421
422
}
#endif
423
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
/* Set the MikMod music format */
music_swap8 = 0;
music_swap16 = 0;
switch (mixer->format) {
case AUDIO_U8:
case AUDIO_S8: {
if ( mixer->format == AUDIO_S8 ) {
music_swap8 = 1;
}
md_mode = 0;
}
break;
case AUDIO_S16LSB:
case AUDIO_S16MSB: {
/* See if we need to correct MikMod mixing */
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
if ( mixer->format == AUDIO_S16MSB ) {
#else
if ( mixer->format == AUDIO_S16LSB ) {
#endif
music_swap16 = 1;
}
md_mode = DMODE_16BITS;
}
break;
default: {
453
Mix_SetError("Unknown hardware audio format");
454
455
456
++music_error;
}
}
457
458
current_output_channels = mixer->channels;
current_output_format = mixer->format;
459
if ( mixer->channels > 1 ) {
460
if ( mixer->channels > MAX_OUTPUT_CHANNELS ) {
461
Mix_SetError("Hardware uses more channels than mixer");
462
463
464
465
++music_error;
}
md_mode |= DMODE_STEREO;
}
466
467
468
md_mixfreq = mixer->freq;
md_device = 0;
md_volume = 96;
469
470
md_musicvolume = 128;
md_sndfxvolume = 128;
471
472
473
md_pansep = 128;
md_reverb = 0;
md_mode |= DMODE_HQMIXER|DMODE_SOFT_MUSIC|DMODE_SURROUND;
474
#ifdef LIBMIKMOD_MUSIC
475
476
477
478
list = MikMod_InfoDriver();
if ( list )
free(list);
else
479
#endif
480
MikMod_RegisterDriver(&drv_nos);
481
#ifdef LIBMIKMOD_MUSIC
482
483
484
485
list = MikMod_InfoLoader();
if ( list )
free(list);
else
486
487
#endif
MikMod_RegisterAllLoaders();
488
if ( MikMod_Init() ) {
489
Mix_SetError("%s", MikMod_strerror(MikMod_errno));
490
491
++music_error;
}
492
add_music_decoder("MIKMOD");
493
494
#endif
#ifdef MID_MUSIC
495
#ifdef USE_TIMIDITY_MIDI
496
samplesize = mixer->size / mixer->samples;
497
if ( Timidity_Init(mixer->freq, mixer->format,
498
mixer->channels, mixer->samples) == 0 ) {
499
timidity_ok = 1;
500
add_music_decoder("TIMIDITY");
501
502
503
} else {
timidity_ok = 0;
}
504
#endif
505
#ifdef USE_NATIVE_MIDI
506
#ifdef USE_TIMIDITY_MIDI
507
native_midi_ok = !timidity_ok;
508
509
if ( native_midi_ok )
#endif
510
native_midi_ok = native_midi_detect();
511
512
if ( native_midi_ok )
add_music_decoder("NATIVEMIDI");
513
#endif
514
#endif
515
516
517
#ifdef OGG_MUSIC
if ( OGG_init(mixer) < 0 ) {
++music_error;
518
519
} else {
add_music_decoder("OGG");
520
521
}
#endif
522
523
524
#ifdef FLAC_MUSIC
if ( FLAC_init(mixer) < 0 ) {
++music_error;
525
526
} else {
add_music_decoder("FLAC");
527
528
}
#endif
529
#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
530
531
/* Keep a copy of the mixer */
used_mixer = *mixer;
532
add_music_decoder("MP3");
533
#endif
534
535
music_playing = NULL;
536
music_stopped = 0;
537
538
539
540
541
if ( music_error ) {
return(-1);
}
Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
542
/* Calculate the number of ms for each callback */
543
ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
544
545
546
547
return(0);
}
548
549
550
551
552
553
554
555
556
557
558
559
560
/* Portable case-insensitive string compare function */
int MIX_string_equals(const char *str1, const char *str2)
{
while ( *str1 && *str2 ) {
if ( toupper((unsigned char)*str1) !=
toupper((unsigned char)*str2) )
break;
++str1;
++str2;
}
return (!*str1 && !*str2);
}
561
562
563
564
/* Load a music file */
Mix_Music *Mix_LoadMUS(const char *file)
{
FILE *fp;
565
char *ext;
566
Uint8 magic[5], moremagic[9];
567
568
569
570
571
572
573
574
Mix_Music *music;
/* Figure out what kind of file this is */
fp = fopen(file, "rb");
if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) {
if ( fp != NULL ) {
fclose(fp);
}
575
Mix_SetError("Couldn't read from '%s'", file);
576
577
return(NULL);
}
578
579
580
581
if (!fread(moremagic, 8, 1, fp)) {
Mix_SetError("Couldn't read from '%s'", file);
return(NULL);
}
582
magic[4] = '\0';
583
moremagic[8] = '\0';
584
585
fclose(fp);
586
587
588
589
/* Figure out the file extension, so we can determine the type */
ext = strrchr(file, '.');
if ( ext ) ++ext; /* skip the dot in the extension */
590
591
592
/* Allocate memory for the music structure */
music = (Mix_Music *)malloc(sizeof(Mix_Music));
if ( music == NULL ) {
593
Mix_SetError("Out of memory");
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
return(NULL);
}
music->error = 0;
#ifdef CMD_MUSIC
if ( music_cmd ) {
music->type = MUS_CMD;
music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
if ( music->data.cmd == NULL ) {
music->error = 1;
}
} else
#endif
#ifdef WAV_MUSIC
/* WAVE files have the magic four bytes "RIFF"
AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
*/
611
if ( (ext && MIX_string_equals(ext, "WAV")) ||
612
((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
613
(strcmp((char *)magic, "FORM") == 0) ) {
614
music->type = MUS_WAV;
615
music->data.wave = WAVStream_LoadSong(file, (char *)magic);
616
if ( music->data.wave == NULL ) {
617
Mix_SetError("Unable to load WAV file");
618
619
620
621
622
623
music->error = 1;
}
} else
#endif
#ifdef MID_MUSIC
/* MIDI files have the magic four bytes "MThd" */
624
625
if ( (ext && MIX_string_equals(ext, "MID")) ||
(ext && MIX_string_equals(ext, "MIDI")) ||
626
627
628
strcmp((char *)magic, "MThd") == 0 ||
( strcmp((char *)magic, "RIFF") == 0 &&
strcmp((char *)(moremagic+4), "RMID") == 0 ) ) {
629
music->type = MUS_MID;
630
631
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
632
music->data.nativemidi = native_midi_loadsong(file);
633
634
635
636
if ( music->data.nativemidi == NULL ) {
Mix_SetError("%s", native_midi_error());
music->error = 1;
}
637
} MIDI_ELSE
638
#endif
639
#ifdef USE_TIMIDITY_MIDI
640
641
642
if ( timidity_ok ) {
music->data.midi = Timidity_LoadSong((char *)file);
if ( music->data.midi == NULL ) {
643
Mix_SetError("%s", Timidity_Error());
644
645
music->error = 1;
}
646
} else {
647
Mix_SetError("%s", Timidity_Error());
648
649
music->error = 1;
}
650
#endif
651
652
} else
#endif
653
654
#ifdef OGG_MUSIC
/* Ogg Vorbis files have the magic four bytes "OggS" */
655
if ( (ext && MIX_string_equals(ext, "OGG")) ||
656
strcmp((char *)magic, "OggS") == 0 ) {
657
658
659
660
661
662
663
music->type = MUS_OGG;
music->data.ogg = OGG_new(file);
if ( music->data.ogg == NULL ) {
music->error = 1;
}
} else
#endif
664
665
666
667
668
669
670
671
672
673
674
#ifdef FLAC_MUSIC
/* FLAC files have the magic four bytes "fLaC" */
if ( (ext && MIX_string_equals(ext, "FLAC")) ||
strcmp((char *)magic, "fLaC") == 0 ) {
music->type = MUS_FLAC;
music->data.flac = FLAC_new(file);
if ( music->data.flac == NULL ) {
music->error = 1;
}
} else
#endif
675
#ifdef MP3_MUSIC
676
if ( (ext && MIX_string_equals(ext, "MPG")) ||
677
(ext && MIX_string_equals(ext, "MP3")) ||
678
(ext && MIX_string_equals(ext, "MPEG")) ||
679
680
(magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
(strncmp((char *)magic, "ID3", 3) == 0) ) {
681
682
683
684
685
686
687
688
689
690
if ( Mix_InitMP3() == 0 ) {
SMPEG_Info info;
music->type = MUS_MP3;
music->data.mp3 = smpeg.SMPEG_new(file, &info, 0);
if ( !info.has_audio ) {
Mix_SetError("MPEG file does not have any audio stream.");
music->error = 1;
} else {
smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
}
691
} else {
692
music->error = 1;
693
694
695
}
} else
#endif
696
697
698
699
700
#ifdef MP3_MAD_MUSIC
if ( (ext && MIX_string_equals(ext, "MPG")) ||
(ext && MIX_string_equals(ext, "MP3")) ||
(ext && MIX_string_equals(ext, "MPEG")) ||
(ext && MIX_string_equals(ext, "MAD")) ||
701
702
(magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
(strncmp((char *)magic, "ID3", 3) == 0) ) {
703
704
705
706
707
708
709
710
music->type = MUS_MP3_MAD;
music->data.mp3_mad = mad_openFile(file, &used_mixer);
if (music->data.mp3_mad == 0) {
Mix_SetError("Could not initialize MPEG stream.");
music->error = 1;
}
} else
#endif
711
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
712
713
714
715
if ( 1 ) {
music->type = MUS_MOD;
music->data.module = MikMod_LoadSong((char *)file, 64);
if ( music->data.module == NULL ) {
716
Mix_SetError("%s", MikMod_strerror(MikMod_errno));
717
music->error = 1;
718
719
720
721
722
} else {
/* Stop implicit looping, fade out and other flags. */
music->data.module->extspd = 1;
music->data.module->panflag = 1;
music->data.module->wrap = 0;
723
music->data.module->loop = 1;
724
725
#if 0 /* Don't set fade out by default - unfortunately there's no real way
to query the status of the song or set trigger actions. Hum. */
726
music->data.module->fadeout = 1;
727
#endif
728
729
730
731
}
} else
#endif
{
732
Mix_SetError("Unrecognized music format");
733
734
735
736
737
738
739
740
741
742
743
744
745
music->error = 1;
}
if ( music->error ) {
free(music);
music = NULL;
}
return(music);
}
/* Free a music chunk previously loaded */
void Mix_FreeMusic(Mix_Music *music)
{
if ( music ) {
746
747
748
749
750
751
752
753
754
755
756
/* 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();
757
}
758
}
759
SDL_UnlockAudio();
760
761
762
763
764
765
766
767
768
769
770
switch (music->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
MusicCMD_FreeSong(music->data.cmd);
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
WAVStream_FreeSong(music->data.wave);
break;
#endif
771
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
772
773
774
775
776
777
case MUS_MOD:
MikMod_FreeSong(music->data.module);
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
778
779
780
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
native_midi_freesong(music->data.nativemidi);
781
} MIDI_ELSE
782
#endif
783
#ifdef USE_TIMIDITY_MIDI
784
785
786
if ( timidity_ok ) {
Timidity_FreeSong(music->data.midi);
}
787
#endif
788
789
break;
#endif
790
791
792
793
794
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_delete(music->data.ogg);
break;
#endif
795
796
797
798
799
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_delete(music->data.flac);
break;
#endif
800
#ifdef MP3_MUSIC
801
case MUS_MP3:
802
803
smpeg.SMPEG_delete(music->data.mp3);
Mix_QuitMP3();
804
break;
805
806
807
808
809
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_closeFile(music->data.mp3_mad);
break;
810
811
812
813
814
815
816
817
818
#endif
default:
/* Unknown music type?? */
break;
}
free(music);
}
}
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
/* 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)
{
Mix_MusicType type = MUS_NONE;
if ( music ) {
type = music->type;
} else {
SDL_LockAudio();
if ( music_playing ) {
type = music_playing->type;
}
SDL_UnlockAudio();
}
return(type);
}
838
839
840
/* Play a music chunk. Returns 0, or -1 if there was an error.
*/
static int music_internal_play(Mix_Music *music, double position)
841
{
842
843
844
845
846
847
848
int retval = 0;
/* Note the music we're playing */
if ( music_playing ) {
music_internal_halt();
}
music_playing = music;
849
850
/* Set the initial volume */
851
852
if ( music->type != MUS_MOD ) {
music_internal_initialize_volume();
853
854
855
}
/* Set up for playback */
856
857
switch (music->type) {
#ifdef CMD_MUSIC
858
859
860
case MUS_CMD:
MusicCMD_Start(music->data.cmd);
break;
861
862
#endif
#ifdef WAV_MUSIC
863
864
865
case MUS_WAV:
WAVStream_Start(music->data.wave);
break;
866
#endif
867
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
868
869
case MUS_MOD:
Player_Start(music->data.module);
870
871
/* Player_SetVolume() does nothing before Player_Start() */
music_internal_initialize_volume();
872
break;
873
874
#endif
#ifdef MID_MUSIC
875
case MUS_MID:
876
#ifdef USE_NATIVE_MIDI
877
878
879
if ( native_midi_ok ) {
native_midi_start(music->data.nativemidi);
} MIDI_ELSE
880
#endif
881
#ifdef USE_TIMIDITY_MIDI
882
883
884
if ( timidity_ok ) {
Timidity_Start(music->data.midi);
}
885
#endif
886
break;
887
#endif
888
#ifdef OGG_MUSIC
889
890
891
case MUS_OGG:
OGG_play(music->data.ogg);
break;
892
#endif
893
894
895
896
897
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_play(music->data.flac);
break;
#endif
898
#ifdef MP3_MUSIC
899
case MUS_MP3:
900
901
902
smpeg.SMPEG_enableaudio(music->data.mp3,1);
smpeg.SMPEG_enablevideo(music->data.mp3,0);
smpeg.SMPEG_play(music_playing->data.mp3);
903
break;
904
905
906
907
908
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_start(music->data.mp3_mad);
break;
909
#endif
910
911
912
913
default:
Mix_SetError("Can't play unknown music type");
retval = -1;
break;
914
}
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
/* 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);
}
int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
935
{
936
937
int retval;
938
939
/* Don't play null pointers :-) */
if ( music == NULL ) {
940
Mix_SetError("music parameter was NULL");
941
942
return(-1);
}
943
944
945
946
947
948
/* Setup the data */
if ( ms ) {
music->fading = MIX_FADING_IN;
} else {
music->fading = MIX_NO_FADING;
949
}
950
951
music->fade_step = 0;
music->fade_steps = ms/ms_per_step;
952
953
954
955
956
957
958
959
/* Play the puppy */
SDL_LockAudio();
/* If the current music is fading out, wait for the fade to complete */
while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
SDL_UnlockAudio();
SDL_Delay(100);
SDL_LockAudio();
960
}
961
music_active = 1;
962
music_loops = loops;
963
964
965
966
967
968
969
970
971
972
973
974
retval = music_internal_play(music, position);
SDL_UnlockAudio();
return(retval);
}
int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
{
return Mix_FadeInMusicPos(music, loops, ms, 0.0);
}
int Mix_PlayMusic(Mix_Music *music, int loops)
{
return Mix_FadeInMusicPos(music, loops, 0, 0.0);
975
976
}
977
978
/* Set the playing music position */
int music_internal_position(double position)
979
{
980
981
982
int retval = 0;
switch (music_playing->type) {
983
#if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC)
984
985
986
case MUS_MOD:
Player_SetPosition((UWORD)position);
break;
987
988
#endif
#ifdef OGG_MUSIC
989
990
991
case MUS_OGG:
OGG_jump_to_time(music_playing->data.ogg, position);
break;
992
#endif
993
994
995
996
997
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_jump_to_time(music_playing->data.flac, position);
break;
#endif
998
#ifdef MP3_MUSIC
999
case MUS_MP3:
1000
if ( position > 0.0 ) {