Mercurial > SDL_sound_CoreAudio
annotate decoders/wav.c @ 178:bdbe09014724
Minor tweaks and such.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 05 Dec 2001 22:24:28 +0000 |
parents | 1df5c106504e |
children | 26996236d790 |
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 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
70 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
71 /* Chunk management code... */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
72 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
73 #define riffID 0x46464952 /* "RIFF", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
74 #define waveID 0x45564157 /* "WAVE", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
75 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
76 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
77 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
78 * The FORMAT chunk... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
79 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
80 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
81 #define fmtID 0x20746D66 /* "fmt ", in ascii. */ |
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 #define FMT_NORMAL 0x0001 /* Uncompressed waveform data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
84 #define FMT_ADPCM 0x0002 /* ADPCM compressed waveform data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
85 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
86 typedef struct { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
87 Uint16 iCoef1; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
88 Uint16 iCoef2; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
89 } ADPCMCOEFSET; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
90 |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
91 typedef struct S_WAV_FMT_T |
124
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 Uint32 chunkID; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
94 Sint32 chunkSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
95 Sint16 wFormatTag; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
96 Uint16 wChannels; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
97 Uint32 dwSamplesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
98 Uint32 dwAvgBytesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
99 Uint16 wBlockAlign; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
100 Uint16 wBitsPerSample; |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
101 |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
102 void (*free)(struct S_WAV_FMT_T *fmt); |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
103 Uint32(*read_sample)(Sound_Sample *sample); |
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 union |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
106 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
107 struct |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
108 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
109 Uint16 cbSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
110 Uint16 wSamplesPerBlock; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
111 Uint16 wNumCoef; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
112 ADPCMCOEFSET *aCoeff; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
113 } adpcm; |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
114 |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
115 /* put other format-specific data here... */ |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
116 } fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
117 } fmt_t; |
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 |
17 | 120 /* |
121 * Read in a fmt_t from disk. This makes this process safe regardless of | |
122 * 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
|
123 * 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
|
124 * needed in the read_fmt_* functions. |
17 | 125 */ |
126 static int read_fmt_chunk(SDL_RWops *rw, fmt_t *fmt) | |
127 { | |
128 /* skip reading the chunk ID, since it was already read at this point... */ | |
129 fmt->chunkID = fmtID; | |
130 | |
131 if (SDL_RWread(rw, &fmt->chunkSize, sizeof (fmt->chunkSize), 1) != 1) | |
132 return(0); | |
133 fmt->chunkSize = SDL_SwapLE32(fmt->chunkSize); | |
134 | |
135 if (SDL_RWread(rw, &fmt->wFormatTag, sizeof (fmt->wFormatTag), 1) != 1) | |
136 return(0); | |
137 fmt->wFormatTag = SDL_SwapLE16(fmt->wFormatTag); | |
138 | |
139 if (SDL_RWread(rw, &fmt->wChannels, sizeof (fmt->wChannels), 1) != 1) | |
140 return(0); | |
141 fmt->wChannels = SDL_SwapLE16(fmt->wChannels); | |
142 | |
143 if (SDL_RWread(rw, &fmt->dwSamplesPerSec, | |
144 sizeof (fmt->dwSamplesPerSec), 1) != 1) | |
145 return(0); | |
146 fmt->dwSamplesPerSec = SDL_SwapLE32(fmt->dwSamplesPerSec); | |
147 | |
148 if (SDL_RWread(rw, &fmt->dwAvgBytesPerSec, | |
149 sizeof (fmt->dwAvgBytesPerSec), 1) != 1) | |
150 return(0); | |
151 fmt->dwAvgBytesPerSec = SDL_SwapLE32(fmt->dwAvgBytesPerSec); | |
152 | |
153 if (SDL_RWread(rw, &fmt->wBlockAlign, sizeof (fmt->wBlockAlign), 1) != 1) | |
154 return(0); | |
155 fmt->wBlockAlign = SDL_SwapLE16(fmt->wBlockAlign); | |
156 | |
157 if (SDL_RWread(rw, &fmt->wBitsPerSample, | |
158 sizeof (fmt->wBitsPerSample), 1) != 1) | |
159 return(0); | |
160 fmt->wBitsPerSample = SDL_SwapLE16(fmt->wBitsPerSample); | |
161 | |
162 return(1); | |
163 } /* read_fmt_chunk */ | |
164 | |
165 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
166 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
167 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
168 * The DATA chunk... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
169 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
170 |
17 | 171 #define dataID 0x61746164 /* "data", in ascii. */ |
172 | |
173 typedef struct | |
174 { | |
175 Uint32 chunkID; | |
176 Sint32 chunkSize; | |
177 /* Then, (chunkSize) bytes of waveform data... */ | |
178 } data_t; | |
179 | |
180 | |
181 /* | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
182 * Read in a data_t from disk. This makes this process safe regardless of |
17 | 183 * the processor's byte order or how the fmt_t structure is packed. |
184 */ | |
185 static int read_data_chunk(SDL_RWops *rw, data_t *data) | |
186 { | |
187 /* skip reading the chunk ID, since it was already read at this point... */ | |
188 data->chunkID = dataID; | |
189 | |
190 if (SDL_RWread(rw, &data->chunkSize, sizeof (data->chunkSize), 1) != 1) | |
191 return(0); | |
192 data->chunkSize = SDL_SwapLE32(data->chunkSize); | |
193 | |
194 return(1); | |
40
c15396fc0e55
Fixed incorrect comment, by Torbj�rn Andersson. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
17
diff
changeset
|
195 } /* read_data_chunk */ |
17 | 196 |
197 | |
198 | |
199 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
200 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
201 * 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
|
202 *****************************************************************************/ |
17 | 203 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
204 typedef struct |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
205 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
206 fmt_t *fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
207 Sint32 bytesLeft; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
208 } wav_t; |
17 | 209 |
210 | |
211 | |
212 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
213 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
214 * Normal, uncompressed waveform handler... * |
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 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
217 static Uint32 read_sample_fmt_normal(Sound_Sample *sample) |
17 | 218 { |
219 Uint32 retval; | |
220 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
221 wav_t *w = (wav_t *) internal->decoder_private; | |
222 Uint32 max = (internal->buffer_size < (Uint32) w->bytesLeft) ? | |
223 internal->buffer_size : (Uint32) w->bytesLeft; | |
224 | |
225 assert(max > 0); | |
226 | |
227 /* | |
228 * We don't actually do any decoding, so we read the wav data | |
229 * directly into the internal buffer... | |
230 */ | |
231 retval = SDL_RWread(internal->rw, internal->buffer, 1, max); | |
232 | |
233 w->bytesLeft -= retval; | |
234 | |
235 /* Make sure the read went smoothly... */ | |
236 if ((retval == 0) || (w->bytesLeft == 0)) | |
237 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
238 | |
239 else if (retval == -1) | |
240 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
241 | |
242 /* (next call this EAGAIN may turn into an EOF or error.) */ | |
243 else if (retval < internal->buffer_size) | |
244 sample->flags |= SOUND_SAMPLEFLAG_EAGAIN; | |
245 | |
246 return(retval); | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
247 } /* read_sample_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
248 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
249 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
250 static void free_fmt_normal(fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
251 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
252 /* it's a no-op. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
253 } /* free_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
254 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
255 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
256 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
|
257 { |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
258 /* (don't need to read more from the RWops...) */ |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
259 fmt->free = free_fmt_normal; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
260 fmt->read_sample = read_sample_fmt_normal; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
261 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
262 } /* read_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
263 |
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 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
267 * ADPCM compression handler... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
268 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
269 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
270 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
|
271 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
272 /* !!! FIXME: Write this. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
273 sample->flags | SOUND_SAMPLEFLAG_ERROR; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
274 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
275 } /* read_sample_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
276 |
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 static void free_fmt_adpcm(fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
279 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
280 if (fmt->fmt.adpcm.aCoeff != NULL) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
281 free(fmt->fmt.adpcm.aCoeff); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
282 } /* free_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
283 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
284 |
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 * 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
|
287 * 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
|
288 * structure is packed. |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
289 */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
290 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
|
291 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
292 size_t i; |
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 fmt->fmt.adpcm.aCoeff = NULL; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
295 fmt->free = free_fmt_adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
296 fmt->read_sample = read_sample_fmt_adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
297 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
298 if (SDL_RWread(rw, &fmt->fmt.adpcm.cbSize, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
299 sizeof (fmt->fmt.adpcm.cbSize), 1) != 1) |
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 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
302 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
303 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
|
304 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
305 if (SDL_RWread(rw, &fmt->fmt.adpcm.wSamplesPerBlock, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
306 sizeof (fmt->fmt.adpcm.wSamplesPerBlock), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
307 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
308 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
309 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
310 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
|
311 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
312 if (SDL_RWread(rw, &fmt->fmt.adpcm.wNumCoef, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
313 sizeof (fmt->fmt.adpcm.wNumCoef), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
314 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
315 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
316 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
317 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
|
318 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
319 i = sizeof (ADPCMCOEFSET) * fmt->fmt.adpcm.wNumCoef; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
320 fmt->fmt.adpcm.aCoeff = (ADPCMCOEFSET *) malloc(i); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
321 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
|
322 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
323 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
|
324 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
325 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
|
326 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
|
327 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
328 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
329 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
330 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
331 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
|
332 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
|
333 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
334 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
335 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
336 } /* for */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
337 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
338 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
339 } /* read_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
340 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
341 |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
342 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
343 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
344 * Everything else... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
345 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
346 |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
347 static int WAV_init(void) |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
348 { |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
349 return(1); /* always succeeds. */ |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
350 } /* WAV_init */ |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
351 |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
352 |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
353 static void WAV_quit(void) |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
354 { |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
355 /* it's a no-op. */ |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
356 } /* WAV_quit */ |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
357 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
358 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
359 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
|
360 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
361 /* 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
|
362 switch (fmt->wFormatTag) |
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_NORMAL: |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
365 SNDDBG(("WAV: Appears to be uncompressed audio.\n")); |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
366 return(read_fmt_normal(rw, fmt)); |
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 case FMT_ADPCM: |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
369 SNDDBG(("WAV: Appears to be ADPCM compressed audio.\n")); |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
370 return(read_fmt_adpcm(rw, fmt)); |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
371 |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
372 /* add other types here. */ |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
373 |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
374 default: |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
375 SNDDBG(("WAV: Format %lu is unknown.\n", |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
376 (unsigned int) fmt->wFormatTag)); |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
377 Sound_SetError("WAV: Unsupported format"); |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
378 return(0); /* not supported whatsoever. */ |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
379 } /* switch */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
380 |
178
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
381 assert(0); /* shouldn't hit this point. */ |
bdbe09014724
Minor tweaks and such.
Ryan C. Gordon <icculus@icculus.org>
parents:
149
diff
changeset
|
382 return(0); |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
383 } /* read_fmt */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
384 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
385 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
386 /* |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
387 * 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
|
388 */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
389 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
|
390 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
391 Sint32 siz = 0; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
392 Uint32 _id = 0; |
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 while (1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
395 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
396 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
|
397 if (SDL_SwapLE32(_id) == id) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
398 return(1); |
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 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
|
401 siz = SDL_SwapLE32(siz); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
402 assert(siz > 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
403 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
|
404 } /* while */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
405 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
406 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
|
407 } /* find_chunk */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
408 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
409 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
410 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
|
411 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
412 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
413 SDL_RWops *rw = internal->rw; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
414 data_t d; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
415 wav_t *w; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
416 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
417 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
|
418 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
|
419 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
|
420 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
|
421 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
|
422 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
423 sample->actual.channels = (Uint8) fmt->wChannels; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
424 sample->actual.rate = fmt->dwSamplesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
425 if (fmt->wBitsPerSample <= 8) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
426 sample->actual.format = AUDIO_U8; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
427 else if (fmt->wBitsPerSample <= 16) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
428 sample->actual.format = AUDIO_S16LSB; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
429 else |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
430 BAIL_MACRO("WAV: Unsupported sample size.", 0); |
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 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
|
433 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
|
434 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
|
435 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
436 w = (wav_t *) malloc(sizeof(wav_t)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
437 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
|
438 w->fmt = fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
439 w->bytesLeft = d.chunkSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
440 internal->decoder_private = (void *) w; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
441 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
442 sample->flags = SOUND_SAMPLEFLAG_NONE; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
443 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
444 SNDDBG(("WAV: Accepting data stream.\n")); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
445 return(1); /* we'll handle this data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
446 } /* WAV_open_internal */ |
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 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
449 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
|
450 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
451 int rc; |
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 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
|
454 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
|
455 memset(fmt, '\0', sizeof (fmt_t)); |
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 rc = WAV_open_internal(sample, ext, fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
458 if (!rc) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
459 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
460 if (fmt->free != NULL) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
461 fmt->free(fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
462 free(fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
463 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
464 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
465 return(rc); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
466 } /* WAV_open */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
467 |
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 static void WAV_close(Sound_Sample *sample) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
470 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
471 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
472 wav_t *w = (wav_t *) internal->decoder_private; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
473 w->fmt->free(w->fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
474 free(w->fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
475 free(w); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
476 } /* WAV_close */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
477 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
478 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
479 static Uint32 WAV_read(Sound_Sample *sample) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
480 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
481 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
482 wav_t *w = (wav_t *) internal->decoder_private; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
483 return(w->fmt->read_sample(sample)); |
17 | 484 } /* WAV_read */ |
485 | |
64
40006625142a
Changes in preparation of autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents:
62
diff
changeset
|
486 #endif /* SOUND_SUPPORTS_WAV */ |
17 | 487 |
488 /* end of wav.c ... */ | |
489 |