Skip to content

Latest commit

 

History

History
1117 lines (1042 loc) · 22.7 KB

music.c

File metadata and controls

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