Mercurial > SDL_sound_CoreAudio
annotate decoders/wav.c @ 149:1df5c106504e
Decoders can now list multiple file extensions.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 01 Nov 2001 19:13:17 +0000 |
parents | e46e31fdecfd |
children | bdbe09014724 |
rev | line source |
---|---|
17 | 1 /* |
2 * SDL_sound -- An abstract sound format decoding API. | |
3 * Copyright (C) 2001 Ryan C. Gordon. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2.1 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 | |
20 /* | |
21 * WAV decoder for SDL_sound. | |
22 * | |
23 * This driver handles Microsoft .WAVs, in as many of the thousands of | |
24 * variations as we can. | |
25 * | |
26 * Please see the file LICENSE in the source's root directory. | |
27 * | |
28 * This file written by Ryan C. Gordon. (icculus@clutteredmind.org) | |
29 */ | |
30 | |
106
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
31 #if HAVE_CONFIG_H |
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
32 # include <config.h> |
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
33 #endif |
100
6d9fdec2f708
added config.h, added --enable-debug flag, various other changes to the build system
fingolfin
parents:
64
diff
changeset
|
34 |
104
103cfcb3c014
Updated to fix build system problem.
Ryan C. Gordon <icculus@icculus.org>
parents:
100
diff
changeset
|
35 #ifdef SOUND_SUPPORTS_WAV |
103cfcb3c014
Updated to fix build system problem.
Ryan C. Gordon <icculus@icculus.org>
parents:
100
diff
changeset
|
36 |
17 | 37 #include <stdio.h> |
38 #include <stdlib.h> | |
39 #include <string.h> | |
40 #include <assert.h> | |
41 | |
106
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
42 #include "SDL_sound.h" |
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
43 |
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
44 #define __SDL_SOUND_INTERNAL__ |
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
45 #include "SDL_sound_internal.h" |
40de367eb59e
Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents:
104
diff
changeset
|
46 |
47
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
47 static int WAV_init(void); |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
48 static void WAV_quit(void); |
17 | 49 static int WAV_open(Sound_Sample *sample, const char *ext); |
50 static void WAV_close(Sound_Sample *sample); | |
51 static Uint32 WAV_read(Sound_Sample *sample); | |
52 | |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
124
diff
changeset
|
53 static const char *extensions_wav[] = { "WAV", NULL }; |
17 | 54 const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV = |
55 { | |
56 { | |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
124
diff
changeset
|
57 extensions_wav, |
17 | 58 "Microsoft WAVE audio format", |
59 "Ryan C. Gordon <icculus@clutteredmind.org>", | |
60 "http://www.icculus.org/SDL_sound/" | |
61 }, | |
62 | |
47
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
63 WAV_init, /* init() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
64 WAV_quit, /* quit() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
65 WAV_open, /* open() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
66 WAV_close, /* close() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
67 WAV_read /* read() method */ |
17 | 68 }; |
69 | |
47
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
70 static int WAV_init(void) |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
71 { |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
72 return(1); /* always succeeds. */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
73 } /* WAV_init */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
74 |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
75 |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
76 static void WAV_quit(void) |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
77 { |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
78 /* it's a no-op. */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
79 } /* WAV_quit */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
80 |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
81 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
82 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
83 /* Chunk management code... */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
84 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
85 #define riffID 0x46464952 /* "RIFF", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
86 #define waveID 0x45564157 /* "WAVE", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
87 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
88 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
89 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
90 * The FORMAT chunk... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
91 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
92 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
93 #define fmtID 0x20746D66 /* "fmt ", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
94 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
95 #define FMT_NORMAL 0x0001 /* Uncompressed waveform data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
96 #define FMT_ADPCM 0x0002 /* ADPCM compressed waveform data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
97 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
98 typedef struct { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
99 Uint16 iCoef1; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
100 Uint16 iCoef2; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
101 } ADPCMCOEFSET; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
102 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
103 typedef struct S_FMT_T |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
104 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
105 Uint32 chunkID; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
106 Sint32 chunkSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
107 Sint16 wFormatTag; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
108 Uint16 wChannels; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
109 Uint32 dwSamplesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
110 Uint32 dwAvgBytesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
111 Uint16 wBlockAlign; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
112 Uint16 wBitsPerSample; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
113 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
114 void (*free)(struct S_FMT_T *fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
115 Uint32(*read_sample)(Sound_Sample *sample); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
116 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
117 union |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
118 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
119 struct |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
120 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
121 Uint16 cbSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
122 Uint16 wSamplesPerBlock; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
123 Uint16 wNumCoef; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
124 ADPCMCOEFSET *aCoeff; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
125 } adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
126 } fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
127 } fmt_t; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
128 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
129 |
17 | 130 /* |
131 * Read in a fmt_t from disk. This makes this process safe regardless of | |
132 * the processor's byte order or how the fmt_t structure is packed. | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
133 * Note that the union "fmt" is not read in here; that is handled as |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
134 * needed in the read_fmt_* functions. |
17 | 135 */ |
136 static int read_fmt_chunk(SDL_RWops *rw, fmt_t *fmt) | |
137 { | |
138 /* skip reading the chunk ID, since it was already read at this point... */ | |
139 fmt->chunkID = fmtID; | |
140 | |
141 if (SDL_RWread(rw, &fmt->chunkSize, sizeof (fmt->chunkSize), 1) != 1) | |
142 return(0); | |
143 fmt->chunkSize = SDL_SwapLE32(fmt->chunkSize); | |
144 | |
145 if (SDL_RWread(rw, &fmt->wFormatTag, sizeof (fmt->wFormatTag), 1) != 1) | |
146 return(0); | |
147 fmt->wFormatTag = SDL_SwapLE16(fmt->wFormatTag); | |
148 | |
149 if (SDL_RWread(rw, &fmt->wChannels, sizeof (fmt->wChannels), 1) != 1) | |
150 return(0); | |
151 fmt->wChannels = SDL_SwapLE16(fmt->wChannels); | |
152 | |
153 if (SDL_RWread(rw, &fmt->dwSamplesPerSec, | |
154 sizeof (fmt->dwSamplesPerSec), 1) != 1) | |
155 return(0); | |
156 fmt->dwSamplesPerSec = SDL_SwapLE32(fmt->dwSamplesPerSec); | |
157 | |
158 if (SDL_RWread(rw, &fmt->dwAvgBytesPerSec, | |
159 sizeof (fmt->dwAvgBytesPerSec), 1) != 1) | |
160 return(0); | |
161 fmt->dwAvgBytesPerSec = SDL_SwapLE32(fmt->dwAvgBytesPerSec); | |
162 | |
163 if (SDL_RWread(rw, &fmt->wBlockAlign, sizeof (fmt->wBlockAlign), 1) != 1) | |
164 return(0); | |
165 fmt->wBlockAlign = SDL_SwapLE16(fmt->wBlockAlign); | |
166 | |
167 if (SDL_RWread(rw, &fmt->wBitsPerSample, | |
168 sizeof (fmt->wBitsPerSample), 1) != 1) | |
169 return(0); | |
170 fmt->wBitsPerSample = SDL_SwapLE16(fmt->wBitsPerSample); | |
171 | |
172 return(1); | |
173 } /* read_fmt_chunk */ | |
174 | |
175 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
176 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
177 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
178 * The DATA chunk... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
179 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
180 |
17 | 181 #define dataID 0x61746164 /* "data", in ascii. */ |
182 | |
183 typedef struct | |
184 { | |
185 Uint32 chunkID; | |
186 Sint32 chunkSize; | |
187 /* Then, (chunkSize) bytes of waveform data... */ | |
188 } data_t; | |
189 | |
190 | |
191 /* | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
192 * Read in a data_t from disk. This makes this process safe regardless of |
17 | 193 * the processor's byte order or how the fmt_t structure is packed. |
194 */ | |
195 static int read_data_chunk(SDL_RWops *rw, data_t *data) | |
196 { | |
197 /* skip reading the chunk ID, since it was already read at this point... */ | |
198 data->chunkID = dataID; | |
199 | |
200 if (SDL_RWread(rw, &data->chunkSize, sizeof (data->chunkSize), 1) != 1) | |
201 return(0); | |
202 data->chunkSize = SDL_SwapLE32(data->chunkSize); | |
203 | |
204 return(1); | |
40
c15396fc0e55
Fixed incorrect comment, by Torbj�rn Andersson. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
17
diff
changeset
|
205 } /* read_data_chunk */ |
17 | 206 |
207 | |
208 | |
209 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
210 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
211 * this is what we store in our internal->decoder_private field... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
212 *****************************************************************************/ |
17 | 213 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
214 typedef struct |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
215 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
216 fmt_t *fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
217 Sint32 bytesLeft; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
218 } wav_t; |
17 | 219 |
220 | |
221 | |
222 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
223 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
224 * Normal, uncompressed waveform handler... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
225 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
226 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
227 static Uint32 read_sample_fmt_normal(Sound_Sample *sample) |
17 | 228 { |
229 Uint32 retval; | |
230 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
231 wav_t *w = (wav_t *) internal->decoder_private; | |
232 Uint32 max = (internal->buffer_size < (Uint32) w->bytesLeft) ? | |
233 internal->buffer_size : (Uint32) w->bytesLeft; | |
234 | |
235 assert(max > 0); | |
236 | |
237 /* | |
238 * We don't actually do any decoding, so we read the wav data | |
239 * directly into the internal buffer... | |
240 */ | |
241 retval = SDL_RWread(internal->rw, internal->buffer, 1, max); | |
242 | |
243 w->bytesLeft -= retval; | |
244 | |
245 /* Make sure the read went smoothly... */ | |
246 if ((retval == 0) || (w->bytesLeft == 0)) | |
247 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
248 | |
249 else if (retval == -1) | |
250 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
251 | |
252 /* (next call this EAGAIN may turn into an EOF or error.) */ | |
253 else if (retval < internal->buffer_size) | |
254 sample->flags |= SOUND_SAMPLEFLAG_EAGAIN; | |
255 | |
256 return(retval); | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
257 } /* read_sample_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
258 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
259 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
260 static void free_fmt_normal(fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
261 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
262 /* it's a no-op. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
263 } /* free_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
264 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
265 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
266 static int read_fmt_normal(SDL_RWops *rw, fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
267 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
268 fmt->free = free_fmt_normal; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
269 fmt->read_sample = read_sample_fmt_normal; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
270 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
271 } /* read_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
272 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
273 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
274 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
275 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
276 * ADPCM compression handler... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
277 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
278 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
279 static Uint32 read_sample_fmt_adpcm(Sound_Sample *sample) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
280 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
281 /* !!! FIXME: Write this. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
282 sample->flags | SOUND_SAMPLEFLAG_ERROR; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
283 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
284 } /* read_sample_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
285 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
286 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
287 static void free_fmt_adpcm(fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
288 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
289 if (fmt->fmt.adpcm.aCoeff != NULL) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
290 free(fmt->fmt.adpcm.aCoeff); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
291 } /* free_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
292 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
293 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
294 /* |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
295 * Read in a the adpcm-specific info from disk. This makes this process |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
296 * safe regardless of the processor's byte order or how the fmt_t |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
297 * structure is packed. |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
298 */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
299 static int read_fmt_adpcm(SDL_RWops *rw, fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
300 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
301 size_t i; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
302 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
303 fmt->fmt.adpcm.aCoeff = NULL; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
304 fmt->free = free_fmt_adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
305 fmt->read_sample = read_sample_fmt_adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
306 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
307 if (SDL_RWread(rw, &fmt->fmt.adpcm.cbSize, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
308 sizeof (fmt->fmt.adpcm.cbSize), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
309 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
310 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
311 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
312 fmt->fmt.adpcm.cbSize = SDL_SwapLE16(fmt->fmt.adpcm.cbSize); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
313 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
314 if (SDL_RWread(rw, &fmt->fmt.adpcm.wSamplesPerBlock, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
315 sizeof (fmt->fmt.adpcm.wSamplesPerBlock), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
316 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
317 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
318 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
319 fmt->fmt.adpcm.wSamplesPerBlock = SDL_SwapLE16(fmt->fmt.adpcm.wSamplesPerBlock); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
320 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
321 if (SDL_RWread(rw, &fmt->fmt.adpcm.wNumCoef, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
322 sizeof (fmt->fmt.adpcm.wNumCoef), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
323 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
324 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
325 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
326 fmt->fmt.adpcm.wNumCoef = SDL_SwapLE16(fmt->fmt.adpcm.wNumCoef); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
327 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
328 i = sizeof (ADPCMCOEFSET) * fmt->fmt.adpcm.wNumCoef; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
329 fmt->fmt.adpcm.aCoeff = (ADPCMCOEFSET *) malloc(i); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
330 BAIL_IF_MACRO(fmt->fmt.adpcm.aCoeff == NULL, ERR_OUT_OF_MEMORY, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
331 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
332 for (i = 0; i < fmt->fmt.adpcm.wNumCoef; i++) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
333 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
334 if (SDL_RWread(rw, &fmt->fmt.adpcm.aCoeff[i].iCoef1, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
335 sizeof (fmt->fmt.adpcm.aCoeff[i].iCoef1), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
336 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
337 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
338 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
339 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
340 if (SDL_RWread(rw, &fmt->fmt.adpcm.aCoeff[i].iCoef2, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
341 sizeof (fmt->fmt.adpcm.aCoeff[i].iCoef2), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
342 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
343 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
344 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
345 } /* for */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
346 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
347 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
348 } /* read_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
349 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
350 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
351 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
352 * Everything else... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
353 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
354 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
355 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
356 static int read_fmt(SDL_RWops *rw, fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
357 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
358 /* if it's in this switch statement, we support the format. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
359 switch (fmt->wFormatTag) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
360 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
361 case FMT_NORMAL: |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
362 return(read_fmt_normal(rw, fmt)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
363 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
364 case FMT_ADPCM: |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
365 return(read_fmt_adpcm(rw, fmt)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
366 } /* switch */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
367 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
368 SNDDBG(("WAV: Format %d is unknown.\n", (int) fmt->wFormatTag)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
369 Sound_SetError("WAV: Unsupported format"); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
370 return(0); /* not supported whatsoever. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
371 } /* read_fmt */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
372 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
373 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
374 /* |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
375 * Locate a specific chunk in the WAVE file by ID... |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
376 */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
377 static int find_chunk(SDL_RWops *rw, Uint32 id) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
378 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
379 Sint32 siz = 0; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
380 Uint32 _id = 0; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
381 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
382 while (1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
383 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
384 BAIL_IF_MACRO(SDL_RWread(rw, &_id, sizeof (_id), 1) != 1, NULL, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
385 if (SDL_SwapLE32(_id) == id) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
386 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
387 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
388 BAIL_IF_MACRO(SDL_RWread(rw, &siz, sizeof (siz), 1) != 1, NULL, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
389 siz = SDL_SwapLE32(siz); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
390 assert(siz > 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
391 BAIL_IF_MACRO(SDL_RWseek(rw, siz, SEEK_SET) != siz, NULL, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
392 } /* while */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
393 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
394 return(0); /* shouldn't hit this, but just in case... */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
395 } /* find_chunk */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
396 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
397 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
398 static int WAV_open_internal(Sound_Sample *sample, const char *ext, fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
399 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
400 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
401 SDL_RWops *rw = internal->rw; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
402 data_t d; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
403 wav_t *w; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
404 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
405 BAIL_IF_MACRO(SDL_ReadLE32(rw) != riffID, "WAV: Not a RIFF file.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
406 SDL_ReadLE32(rw); /* throw the length away; we get this info later. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
407 BAIL_IF_MACRO(SDL_ReadLE32(rw) != waveID, "WAV: Not a WAVE file.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
408 BAIL_IF_MACRO(!find_chunk(rw, fmtID), "WAV: No format chunk.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
409 BAIL_IF_MACRO(!read_fmt_chunk(rw, fmt), "WAV: Can't read format chunk.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
410 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
411 sample->actual.channels = (Uint8) fmt->wChannels; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
412 sample->actual.rate = fmt->dwSamplesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
413 if (fmt->wBitsPerSample <= 8) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
414 sample->actual.format = AUDIO_U8; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
415 else if (fmt->wBitsPerSample <= 16) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
416 sample->actual.format = AUDIO_S16LSB; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
417 else |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
418 BAIL_MACRO("WAV: Unsupported sample size.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
419 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
420 BAIL_IF_MACRO(!read_fmt(rw, fmt), NULL, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
421 BAIL_IF_MACRO(!find_chunk(rw, dataID), "WAV: No data chunk.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
422 BAIL_IF_MACRO(!read_data_chunk(rw, &d), "WAV: Can't read data chunk.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
423 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
424 w = (wav_t *) malloc(sizeof(wav_t)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
425 BAIL_IF_MACRO(w == NULL, ERR_OUT_OF_MEMORY, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
426 w->fmt = fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
427 w->bytesLeft = d.chunkSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
428 internal->decoder_private = (void *) w; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
429 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
430 sample->flags = SOUND_SAMPLEFLAG_NONE; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
431 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
432 SNDDBG(("WAV: Accepting data stream.\n")); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
433 return(1); /* we'll handle this data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
434 } /* WAV_open_internal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
435 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
436 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
437 static int WAV_open(Sound_Sample *sample, const char *ext) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
438 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
439 int rc; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
440 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
441 fmt_t *fmt = (fmt_t *) malloc(sizeof (fmt_t)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
442 BAIL_IF_MACRO(fmt == NULL, ERR_OUT_OF_MEMORY, 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
443 memset(fmt, '\0', sizeof (fmt_t)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
444 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
445 rc = WAV_open_internal(sample, ext, fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
446 if (!rc) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
447 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
448 if (fmt->free != NULL) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
449 fmt->free(fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
450 free(fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
451 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
452 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
453 return(rc); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
454 } /* WAV_open */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
455 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
456 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
457 static void WAV_close(Sound_Sample *sample) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
458 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
459 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
460 wav_t *w = (wav_t *) internal->decoder_private; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
461 w->fmt->free(w->fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
462 free(w->fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
463 free(w); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
464 } /* WAV_close */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
465 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
466 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
467 static Uint32 WAV_read(Sound_Sample *sample) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
468 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
469 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
470 wav_t *w = (wav_t *) internal->decoder_private; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
471 return(w->fmt->read_sample(sample)); |
17 | 472 } /* WAV_read */ |
473 | |
64
40006625142a
Changes in preparation of autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents:
62
diff
changeset
|
474 #endif /* SOUND_SUPPORTS_WAV */ |
17 | 475 |
476 /* end of wav.c ... */ | |
477 |