Skip to content

Latest commit

 

History

History
628 lines (543 loc) · 17 KB

wavestream.c

File metadata and controls

628 lines (543 loc) · 17 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
Jan 2, 2016
Jan 2, 2016
3
Copyright (C) 1997-2016 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 21, 1999
Oct 21, 1999
24
25
26
27
28
/* This file supports streaming WAV files, without volume adjustment */
#include <stdlib.h>
#include <string.h>
Dec 21, 1999
Dec 21, 1999
29
30
31
32
#include "SDL_audio.h"
#include "SDL_mutex.h"
#include "SDL_rwops.h"
#include "SDL_endian.h"
Oct 21, 1999
Oct 21, 1999
33
Nov 30, 2001
Nov 30, 2001
34
#include "SDL_mixer.h"
Oct 21, 1999
Oct 21, 1999
35
36
#include "wavestream.h"
Sep 11, 2001
Sep 11, 2001
37
38
39
40
41
42
43
44
45
46
47
/*
Taken with permission from SDL_wave.h, part of the SDL library,
available at: http://www.libsdl.org/
and placed under the same license as this mixer library.
*/
/* WAVE files are little-endian */
/*******************************************/
/* Define values for Microsoft WAVE format */
/*******************************************/
May 22, 2013
May 22, 2013
48
49
#define RIFF 0x46464952 /* "RIFF" */
#define WAVE 0x45564157 /* "WAVE" */
Jun 22, 2014
Jun 22, 2014
50
#define FMT 0x20746D66 /* "fmt " */
May 22, 2013
May 22, 2013
51
#define DATA 0x61746164 /* "data" */
Jul 7, 2015
Jul 7, 2015
52
#define SMPL 0x6c706d73 /* "smpl" */
May 22, 2013
May 22, 2013
53
54
55
56
#define PCM_CODE 1
#define ADPCM_CODE 2
#define WAVE_MONO 1
#define WAVE_STEREO 2
Sep 11, 2001
Sep 11, 2001
57
Jul 7, 2015
Jul 7, 2015
58
typedef struct {
Sep 11, 2001
Sep 11, 2001
59
/* Not saved in the chunk we read:
Jul 7, 2015
Jul 7, 2015
60
61
Uint32 chunkID;
Uint32 chunkLen;
Sep 11, 2001
Sep 11, 2001
62
*/
May 22, 2013
May 22, 2013
63
64
65
66
67
68
Uint16 encoding;
Uint16 channels; /* 1 = mono, 2 = stereo */
Uint32 frequency; /* One of 11025, 22050, or 44100 Hz */
Uint32 byterate; /* Average bytes per second */
Uint16 blockalign; /* Bytes per sample block */
Uint16 bitspersample; /* One of 8, 12, 16, or 4 for ADPCM */
Sep 11, 2001
Sep 11, 2001
69
70
} WaveFMT;
Jul 7, 2015
Jul 7, 2015
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
typedef struct {
Uint32 identifier;
Uint32 type;
Uint32 start;
Uint32 end;
Uint32 fraction;
Uint32 play_count;
} SampleLoop;
typedef struct {
/* Not saved in the chunk we read:
Uint32 chunkID;
Uint32 chunkLen;
*/
Uint32 manufacturer;
Uint32 product;
Uint32 sample_period;
Uint32 MIDI_unity_note;
Uint32 MIDI_pitch_fraction;
Uint32 SMTPE_format;
Uint32 SMTPE_offset;
Uint32 sample_loops;
Uint32 sampler_data;
SampleLoop loops[];
} SamplerChunk;
Sep 11, 2001
Sep 11, 2001
96
97
98
99
/*********************************************/
/* Define values for AIFF (IFF audio) format */
/*********************************************/
May 22, 2013
May 22, 2013
100
101
102
103
#define FORM 0x4d524f46 /* "FORM" */
#define AIFF 0x46464941 /* "AIFF" */
#define SSND 0x444e5353 /* "SSND" */
#define COMM 0x4d4d4f43 /* "COMM" */
Sep 11, 2001
Sep 11, 2001
104
105
Jul 3, 2000
Jul 3, 2000
106
/* Currently we only support a single stream at a time */
May 16, 2002
May 16, 2002
107
static WAVStream *music = NULL;
Jul 3, 2000
Jul 3, 2000
108
Oct 21, 1999
Oct 21, 1999
109
110
/* This is the format of the audio mixer data */
static SDL_AudioSpec mixer;
Feb 12, 2003
Feb 12, 2003
111
static int wavestream_volume = MIX_MAX_VOLUME;
Oct 21, 1999
Oct 21, 1999
112
113
/* Function to load the WAV/AIFF stream */
Jul 7, 2015
Jul 7, 2015
114
115
static SDL_bool LoadWAVStream(WAVStream *wave);
static SDL_bool LoadAIFFStream(WAVStream *wave);
Oct 21, 1999
Oct 21, 1999
116
117
118
119
120
121
/* Initialize the WAVStream player, with the given mixer settings
This function returns 0, or -1 if there was an error.
*/
int WAVStream_Init(SDL_AudioSpec *mixerfmt)
{
May 22, 2013
May 22, 2013
122
123
mixer = *mixerfmt;
return(0);
Oct 21, 1999
Oct 21, 1999
124
125
}
Feb 12, 2003
Feb 12, 2003
126
void WAVStream_SetVolume(int volume)
Oct 21, 1999
Oct 21, 1999
127
{
May 22, 2013
May 22, 2013
128
wavestream_volume = volume;
Oct 21, 1999
Oct 21, 1999
129
130
}
Jan 4, 2012
Jan 4, 2012
131
/* Load a WAV stream from the given RWops object */
Jun 2, 2013
Jun 2, 2013
132
WAVStream *WAVStream_LoadSong_RW(SDL_RWops *src, int freesrc)
Oct 21, 1999
Oct 21, 1999
133
{
May 22, 2013
May 22, 2013
134
WAVStream *wave;
Jul 7, 2015
Jul 7, 2015
135
SDL_bool loaded = SDL_FALSE;
May 22, 2013
May 22, 2013
136
Jul 7, 2015
Jul 7, 2015
137
if (!mixer.format) {
May 22, 2013
May 22, 2013
138
139
140
Mix_SetError("WAV music output not started");
return(NULL);
}
Jul 7, 2015
Jul 7, 2015
141
May 22, 2013
May 22, 2013
142
wave = (WAVStream *)SDL_malloc(sizeof *wave);
Jul 7, 2015
Jul 7, 2015
143
if (wave) {
Jun 2, 2013
Jun 2, 2013
144
145
146
Uint32 magic;
SDL_zerop(wave);
Jul 7, 2015
Jul 7, 2015
147
wave->src = src;
Jun 2, 2013
Jun 2, 2013
148
149
150
wave->freesrc = freesrc;
magic = SDL_ReadLE32(src);
Jul 7, 2015
Jul 7, 2015
151
152
153
154
if (magic == RIFF || magic == WAVE) {
loaded = LoadWAVStream(wave);
} else if (magic == FORM) {
loaded = LoadAIFFStream(wave);
May 22, 2013
May 22, 2013
155
156
157
} else {
Mix_SetError("Unknown WAVE format");
}
Jul 7, 2015
Jul 7, 2015
158
159
if (!loaded) {
WAVStream_FreeSong(wave);
May 22, 2013
May 22, 2013
160
161
162
return(NULL);
}
SDL_BuildAudioCVT(&wave->cvt,
Jul 7, 2015
Jul 7, 2015
163
wave->spec.format, wave->spec.channels, wave->spec.freq,
May 22, 2013
May 22, 2013
164
165
166
167
168
169
mixer.format, mixer.channels, mixer.freq);
} else {
SDL_OutOfMemory();
return(NULL);
}
return(wave);
Oct 21, 1999
Oct 21, 1999
170
171
172
}
/* Start playback of a given WAV stream */
Feb 12, 2003
Feb 12, 2003
173
void WAVStream_Start(WAVStream *wave)
Oct 21, 1999
Oct 21, 1999
174
{
Jul 7, 2015
Jul 7, 2015
175
176
177
178
179
180
181
int i;
for (i = 0; i < wave->numloops; ++i) {
WAVLoopPoint *loop = &wave->loops[i];
loop->active = SDL_TRUE;
loop->current_play_count = loop->initial_play_count;
}
SDL_RWseek(wave->src, wave->start, RW_SEEK_SET);
May 22, 2013
May 22, 2013
182
music = wave;
Oct 21, 1999
Oct 21, 1999
183
184
}
May 16, 2002
May 16, 2002
185
/* Play some of a stream previously started with WAVStream_Start() */
Jul 7, 2015
Jul 7, 2015
186
static int PlaySome(Uint8 *stream, int len)
Oct 21, 1999
Oct 21, 1999
187
{
Jul 7, 2015
Jul 7, 2015
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
Sint64 pos, stop;
WAVLoopPoint *loop;
Sint64 loop_start;
Sint64 loop_stop;
int i;
int consumed;
pos = SDL_RWtell(music->src);
stop = music->stop;
loop = NULL;
for (i = 0; i < music->numloops; ++i) {
loop = &music->loops[i];
if (loop->active) {
const int bytes_per_sample = (SDL_AUDIO_BITSIZE(music->spec.format) / 8) * music->spec.channels;
loop_start = music->start + loop->start * bytes_per_sample;
loop_stop = music->start + (loop->stop + 1) * bytes_per_sample;
if (pos >= loop_start && pos < loop_stop)
{
stop = loop_stop;
break;
May 22, 2013
May 22, 2013
208
}
Jul 7, 2015
Jul 7, 2015
209
210
211
212
213
214
215
216
217
218
219
220
}
loop = NULL;
}
if (music->cvt.needed) {
int original_len;
original_len = (int)((double)len/music->cvt.len_ratio);
if (music->cvt.len != original_len) {
int worksize;
if (music->cvt.buf != NULL) {
SDL_free(music->cvt.buf);
May 22, 2013
May 22, 2013
221
}
Jul 7, 2015
Jul 7, 2015
222
223
224
225
worksize = original_len*music->cvt.len_mult;
music->cvt.buf=(Uint8 *)SDL_malloc(worksize);
if (music->cvt.buf == NULL) {
return 0;
May 22, 2013
May 22, 2013
226
227
}
music->cvt.len = original_len;
Jul 7, 2015
Jul 7, 2015
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
}
if ((stop - pos) < original_len) {
original_len = (int)(stop - pos);
}
original_len = SDL_RWread(music->src, music->cvt.buf, 1, original_len);
/* At least at the time of writing, SDL_ConvertAudio()
does byte-order swapping starting at the end of the
buffer. Thus, if we are reading 16-bit samples, we
had better make damn sure that we get an even
number of bytes, or we'll get garbage.
*/
if ((music->cvt.src_format & 0x0010) && (original_len & 1)) {
original_len--;
}
music->cvt.len = original_len;
SDL_ConvertAudio(&music->cvt);
Jan 29, 2016
Jan 29, 2016
244
SDL_MixAudioFormat(stream, music->cvt.buf, mixer.format,music->cvt.len_cvt, wavestream_volume);
Jul 7, 2015
Jul 7, 2015
245
246
247
248
249
250
251
252
253
consumed = music->cvt.len_cvt;
} else {
Uint8 *data;
if ((stop - pos) < len) {
len = (int)(stop - pos);
}
data = SDL_stack_alloc(Uint8, len);
if (data) {
len = SDL_RWread(music->src, data, 1, len);
Jan 29, 2016
Jan 29, 2016
254
SDL_MixAudioFormat(stream, data, mixer.format, len, wavestream_volume);
Jul 7, 2015
Jul 7, 2015
255
256
257
258
259
260
261
262
SDL_stack_free(data);
}
consumed = len;
}
if (loop && SDL_RWtell(music->src) >= stop) {
if (loop->current_play_count == 1) {
loop->active = SDL_FALSE;
May 22, 2013
May 22, 2013
263
} else {
Jul 7, 2015
Jul 7, 2015
264
265
if (loop->current_play_count > 0) {
--loop->current_play_count;
May 22, 2013
May 22, 2013
266
}
Jul 7, 2015
Jul 7, 2015
267
SDL_RWseek(music->src, loop_start, RW_SEEK_SET);
May 22, 2013
May 22, 2013
268
269
}
}
Jul 7, 2015
Jul 7, 2015
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
return consumed;
}
int WAVStream_PlaySome(Uint8 *stream, int len)
{
if (!music)
return 0;
while ((SDL_RWtell(music->src) < music->stop) && (len > 0)) {
int consumed = PlaySome(stream, len);
if (!consumed)
break;
stream += consumed;
len -= consumed;
}
return len;
Oct 21, 1999
Oct 21, 1999
287
288
289
}
/* Stop playback of a stream previously started with WAVStream_Start() */
Feb 12, 2003
Feb 12, 2003
290
void WAVStream_Stop(void)
Oct 21, 1999
Oct 21, 1999
291
{
May 22, 2013
May 22, 2013
292
music = NULL;
Oct 21, 1999
Oct 21, 1999
293
294
295
}
/* Close the given WAV stream */
Feb 12, 2003
Feb 12, 2003
296
void WAVStream_FreeSong(WAVStream *wave)
Oct 21, 1999
Oct 21, 1999
297
{
Jul 7, 2015
Jul 7, 2015
298
if (wave) {
May 22, 2013
May 22, 2013
299
/* Clean up associated data */
Jul 7, 2015
Jul 7, 2015
300
301
302
303
if (wave->loops) {
SDL_free(wave->loops);
}
if (wave->cvt.buf) {
May 22, 2013
May 22, 2013
304
305
SDL_free(wave->cvt.buf);
}
Jul 7, 2015
Jul 7, 2015
306
if (wave->freesrc) {
Jun 2, 2013
Jun 2, 2013
307
SDL_RWclose(wave->src);
May 22, 2013
May 22, 2013
308
309
310
}
SDL_free(wave);
}
Oct 21, 1999
Oct 21, 1999
311
312
313
}
/* Return non-zero if a stream is currently playing */
Feb 12, 2003
Feb 12, 2003
314
int WAVStream_Active(void)
Oct 21, 1999
Oct 21, 1999
315
{
May 22, 2013
May 22, 2013
316
int active;
Oct 21, 1999
Oct 21, 1999
317
May 22, 2013
May 22, 2013
318
active = 0;
Jul 7, 2015
Jul 7, 2015
319
if (music && (SDL_RWtell(music->src) < music->stop)) {
May 22, 2013
May 22, 2013
320
321
322
active = 1;
}
return(active);
Oct 21, 1999
Oct 21, 1999
323
324
}
Jul 7, 2015
Jul 7, 2015
325
static SDL_bool ParseFMT(WAVStream *wave, Uint32 chunk_length)
Oct 21, 1999
Oct 21, 1999
326
{
Jul 7, 2015
Jul 7, 2015
327
328
329
330
331
332
333
334
335
SDL_RWops *src = wave->src;
SDL_AudioSpec *spec = &wave->spec;
WaveFMT *format;
Uint8 *data;
SDL_bool loaded = SDL_FALSE;
if (chunk_length < sizeof(*format)) {
Mix_SetError("Wave format chunk too small");
return SDL_FALSE;
May 22, 2013
May 22, 2013
336
337
}
Jul 7, 2015
Jul 7, 2015
338
339
340
341
342
343
344
345
346
347
data = (Uint8 *)SDL_malloc(chunk_length);
if (!data) {
Mix_SetError("Out of memory");
return SDL_FALSE;
}
if (!SDL_RWread(wave->src, data, chunk_length, 1)) {
Mix_SetError("Couldn't read %d bytes from WAV file", chunk_length);
return SDL_FALSE;
}
format = (WaveFMT *)data;
May 22, 2013
May 22, 2013
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/* Decode the audio data format */
switch (SDL_SwapLE16(format->encoding)) {
case PCM_CODE:
/* We can understand this */
break;
default:
Mix_SetError("Unknown WAVE data format");
goto done;
}
spec->freq = SDL_SwapLE32(format->frequency);
switch (SDL_SwapLE16(format->bitspersample)) {
case 8:
spec->format = AUDIO_U8;
break;
case 16:
spec->format = AUDIO_S16;
break;
default:
Mix_SetError("Unknown PCM data format");
goto done;
}
spec->channels = (Uint8) SDL_SwapLE16(format->channels);
spec->samples = 4096; /* Good default buffer size */
Jul 7, 2015
Jul 7, 2015
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
loaded = SDL_TRUE;
done:
SDL_free(data);
return loaded;
}
static SDL_bool ParseDATA(WAVStream *wave, Uint32 chunk_length)
{
wave->start = SDL_RWtell(wave->src);
wave->stop = wave->start + chunk_length;
SDL_RWseek(wave->src, chunk_length, RW_SEEK_CUR);
return SDL_TRUE;
}
static SDL_bool AddLoopPoint(WAVStream *wave, Uint32 play_count, Uint32 start, Uint32 stop)
{
WAVLoopPoint *loop;
WAVLoopPoint *loops = SDL_realloc(wave->loops, (wave->numloops + 1)*sizeof(*wave->loops));
if (!loops) {
Mix_SetError("Out of memory");
return SDL_FALSE;
}
loop = &loops[ wave->numloops ];
loop->start = start;
loop->stop = stop;
loop->initial_play_count = play_count;
loop->current_play_count = play_count;
wave->loops = loops;
++wave->numloops;
return SDL_TRUE;
}
static SDL_bool ParseSMPL(WAVStream *wave, Uint32 chunk_length)
{
SamplerChunk *chunk;
Uint8 *data;
int i;
SDL_bool loaded = SDL_FALSE;
data = (Uint8 *)SDL_malloc(chunk_length);
if (!data) {
Mix_SetError("Out of memory");
return SDL_FALSE;
}
if (!SDL_RWread(wave->src, data, chunk_length, 1)) {
Mix_SetError("Couldn't read %d bytes from WAV file", chunk_length);
return SDL_FALSE;
}
chunk = (SamplerChunk *)data;
for (i = 0; i < SDL_SwapLE32(chunk->sample_loops); ++i) {
const Uint32 LOOP_TYPE_FORWARD = 0;
Uint32 loop_type = SDL_SwapLE32(chunk->loops[i].type);
if (loop_type == LOOP_TYPE_FORWARD) {
AddLoopPoint(wave, SDL_SwapLE32(chunk->loops[i].play_count), SDL_SwapLE32(chunk->loops[i].start), SDL_SwapLE32(chunk->loops[i].end));
May 22, 2013
May 22, 2013
431
}
Jul 7, 2015
Jul 7, 2015
432
433
434
}
loaded = SDL_TRUE;
Oct 21, 1999
Oct 21, 1999
435
436
done:
Jul 7, 2015
Jul 7, 2015
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
SDL_free(data);
return loaded;
}
static SDL_bool LoadWAVStream(WAVStream *wave)
{
SDL_RWops *src = wave->src;
Uint32 chunk_type;
Uint32 chunk_length;
SDL_bool found_FMT = SDL_FALSE;
SDL_bool found_DATA = SDL_FALSE;
/* WAV magic header */
Uint32 wavelen;
Uint32 WAVEmagic;
/* Check the magic header */
wavelen = SDL_ReadLE32(src);
WAVEmagic = SDL_ReadLE32(src);
/* Read the chunks */
for (; ;) {
chunk_type = SDL_ReadLE32(src);
chunk_length = SDL_ReadLE32(src);
if (chunk_length == 0)
break;
switch (chunk_type)
{
case FMT:
found_FMT = SDL_TRUE;
if (!ParseFMT(wave, chunk_length))
return SDL_FALSE;
break;
case DATA:
found_DATA = SDL_TRUE;
if (!ParseDATA(wave, chunk_length))
return SDL_FALSE;
break;
case SMPL:
if (!ParseSMPL(wave, chunk_length))
return SDL_FALSE;
break;
default:
SDL_RWseek(src, chunk_length, RW_SEEK_CUR);
break;
}
May 22, 2013
May 22, 2013
485
}
Jul 7, 2015
Jul 7, 2015
486
487
488
489
if (!found_FMT) {
Mix_SetError("Bad WAV file (no FMT chunk)");
return SDL_FALSE;
May 22, 2013
May 22, 2013
490
}
Jul 7, 2015
Jul 7, 2015
491
492
493
494
495
496
497
if (!found_DATA) {
Mix_SetError("Bad WAV file (no DATA chunk)");
return SDL_FALSE;
}
return SDL_TRUE;
Oct 21, 1999
Oct 21, 1999
498
499
}
Aug 19, 2001
Aug 19, 2001
500
501
502
503
504
/* I couldn't get SANE_to_double() to work, so I stole this from libsndfile.
* I don't pretend to fully understand it.
*/
static Uint32 SANE_to_Uint32 (Uint8 *sanebuf)
Oct 21, 1999
Oct 21, 1999
505
{
May 22, 2013
May 22, 2013
506
507
508
/* Negative number? */
if (sanebuf[0] & 0x80)
return 0;
Aug 19, 2001
Aug 19, 2001
509
May 22, 2013
May 22, 2013
510
511
512
/* Less than 1? */
if (sanebuf[0] <= 0x3F)
return 1;
Aug 19, 2001
Aug 19, 2001
513
May 22, 2013
May 22, 2013
514
515
516
/* Way too big? */
if (sanebuf[0] > 0x40)
return 0x4000000;
Aug 19, 2001
Aug 19, 2001
517
May 22, 2013
May 22, 2013
518
519
520
/* Still too big? */
if (sanebuf[0] == 0x40 && sanebuf[1] > 0x1C)
return 800000000;
Aug 19, 2001
Aug 19, 2001
521
Jul 7, 2015
Jul 7, 2015
522
523
return ((sanebuf[2] << 23) | (sanebuf[3] << 15) | (sanebuf[4] << 7) |
(sanebuf[5] >> 1)) >> (29 - sanebuf[1]);
Oct 21, 1999
Oct 21, 1999
524
525
}
Jul 7, 2015
Jul 7, 2015
526
static SDL_bool LoadAIFFStream(WAVStream *wave)
Oct 21, 1999
Oct 21, 1999
527
{
Jul 7, 2015
Jul 7, 2015
528
529
530
531
SDL_RWops *src = wave->src;
SDL_AudioSpec *spec = &wave->spec;
SDL_bool found_SSND = SDL_FALSE;
SDL_bool found_COMM = SDL_FALSE;
May 22, 2013
May 22, 2013
532
533
534
Uint32 chunk_type;
Uint32 chunk_length;
Jun 1, 2013
Jun 1, 2013
535
Sint64 next_chunk;
May 22, 2013
May 22, 2013
536
537
538
539
540
541
542
543
544
545
546
547
548
549
/* AIFF magic header */
Uint32 AIFFmagic;
/* SSND chunk */
Uint32 offset;
Uint32 blocksize;
/* COMM format chunk */
Uint16 channels = 0;
Uint32 numsamples = 0;
Uint16 samplesize = 0;
Uint8 sane_freq[10];
Uint32 frequency = 0;
/* Check the magic header */
Jul 7, 2015
Jul 7, 2015
550
551
552
chunk_length = SDL_ReadBE32(src);
AIFFmagic = SDL_ReadLE32(src);
if (AIFFmagic != AIFF) {
May 22, 2013
May 22, 2013
553
Mix_SetError("Unrecognized file type (not AIFF)");
Jul 7, 2015
Jul 7, 2015
554
return SDL_FALSE;
May 22, 2013
May 22, 2013
555
556
557
}
/* From what I understand of the specification, chunks may appear in
Jul 7, 2015
Jul 7, 2015
558
* any order, and we should just ignore unknown ones.
May 22, 2013
May 22, 2013
559
560
561
*
* TODO: Better sanity-checking. E.g. what happens if the AIFF file
* contains compressed sound data?
Jun 2, 2013
Jun 2, 2013
562
*/
May 22, 2013
May 22, 2013
563
564
565
566
do {
chunk_type = SDL_ReadLE32(src);
chunk_length = SDL_ReadBE32(src);
next_chunk = SDL_RWtell(src) + chunk_length;
Aug 19, 2001
Aug 19, 2001
567
May 22, 2013
May 22, 2013
568
569
/* Paranoia to avoid infinite loops */
if (chunk_length == 0)
Jul 7, 2015
Jul 7, 2015
570
break;
Aug 19, 2001
Aug 19, 2001
571
Jun 2, 2013
Jun 2, 2013
572
switch (chunk_type) {
May 22, 2013
May 22, 2013
573
case SSND:
Jul 7, 2015
Jul 7, 2015
574
575
576
577
found_SSND = SDL_TRUE;
offset = SDL_ReadBE32(src);
blocksize = SDL_ReadBE32(src);
wave->start = SDL_RWtell(src) + offset;
May 22, 2013
May 22, 2013
578
579
580
break;
case COMM:
Jul 7, 2015
Jul 7, 2015
581
found_COMM = SDL_TRUE;
May 22, 2013
May 22, 2013
582
583
/* Read the audio data format chunk */
Jul 7, 2015
Jul 7, 2015
584
585
586
channels = SDL_ReadBE16(src);
numsamples = SDL_ReadBE32(src);
samplesize = SDL_ReadBE16(src);
May 22, 2013
May 22, 2013
587
SDL_RWread(src, sane_freq, sizeof(sane_freq), 1);
Jul 7, 2015
Jul 7, 2015
588
frequency = SANE_to_Uint32(sane_freq);
May 22, 2013
May 22, 2013
589
590
591
592
593
594
595
596
597
598
break;
default:
break;
}
} while ((!found_SSND || !found_COMM)
&& SDL_RWseek(src, next_chunk, RW_SEEK_SET) != -1);
if (!found_SSND) {
Mix_SetError("Bad AIFF file (no SSND chunk)");
Jul 7, 2015
Jul 7, 2015
599
return SDL_FALSE;
May 22, 2013
May 22, 2013
600
601
602
603
}
if (!found_COMM) {
Mix_SetError("Bad AIFF file (no COMM chunk)");
Jul 7, 2015
Jul 7, 2015
604
return SDL_FALSE;
May 22, 2013
May 22, 2013
605
606
}
Jul 7, 2015
Jul 7, 2015
607
wave->stop = wave->start + channels * numsamples * (samplesize / 8);
May 22, 2013
May 22, 2013
608
609
/* Decode the audio data format */
Jun 1, 2013
Jun 1, 2013
610
SDL_memset(spec, 0, (sizeof *spec));
May 22, 2013
May 22, 2013
611
612
613
614
615
616
617
618
619
620
spec->freq = frequency;
switch (samplesize) {
case 8:
spec->format = AUDIO_S8;
break;
case 16:
spec->format = AUDIO_S16MSB;
break;
default:
Mix_SetError("Unknown samplesize in data format");
Jul 7, 2015
Jul 7, 2015
621
return SDL_FALSE;
May 22, 2013
May 22, 2013
622
623
624
}
spec->channels = (Uint8) channels;
spec->samples = 4096; /* Good default buffer size */
Oct 21, 1999
Oct 21, 1999
625
Jul 7, 2015
Jul 7, 2015
626
return SDL_TRUE;
Oct 21, 1999
Oct 21, 1999
627
}