Mercurial > SDL_sound_CoreAudio
annotate decoders/wav.c @ 124:e46e31fdecfd
Restructured to handle multiple formats.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Mon, 08 Oct 2001 19:13:16 +0000 |
parents | 40de367eb59e |
children | 1df5c106504e |
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 | |
53 const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV = | |
54 { | |
55 { | |
56 "WAV", | |
57 "Microsoft WAVE audio format", | |
58 "Ryan C. Gordon <icculus@clutteredmind.org>", | |
59 "http://www.icculus.org/SDL_sound/" | |
60 }, | |
61 | |
47
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
62 WAV_init, /* init() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
63 WAV_quit, /* quit() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
64 WAV_open, /* open() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
65 WAV_close, /* close() method */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
66 WAV_read /* read() method */ |
17 | 67 }; |
68 | |
47
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
69 static int WAV_init(void) |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
70 { |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
71 return(1); /* always succeeds. */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
72 } /* WAV_init */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
73 |
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 static void WAV_quit(void) |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
76 { |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
77 /* it's a no-op. */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
78 } /* WAV_quit */ |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
79 |
ea58bc3b15d7
Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents:
40
diff
changeset
|
80 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
81 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
82 /* Chunk management code... */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
83 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
84 #define riffID 0x46464952 /* "RIFF", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
85 #define waveID 0x45564157 /* "WAVE", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
86 |
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 * The FORMAT chunk... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
90 *****************************************************************************/ |
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 #define fmtID 0x20746D66 /* "fmt ", in ascii. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
93 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
94 #define FMT_NORMAL 0x0001 /* Uncompressed waveform data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
95 #define FMT_ADPCM 0x0002 /* ADPCM compressed waveform data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
96 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
97 typedef struct { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
98 Uint16 iCoef1; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
99 Uint16 iCoef2; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
100 } ADPCMCOEFSET; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
101 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
102 typedef struct S_FMT_T |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
103 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
104 Uint32 chunkID; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
105 Sint32 chunkSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
106 Sint16 wFormatTag; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
107 Uint16 wChannels; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
108 Uint32 dwSamplesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
109 Uint32 dwAvgBytesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
110 Uint16 wBlockAlign; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
111 Uint16 wBitsPerSample; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
112 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
113 void (*free)(struct S_FMT_T *fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
114 Uint32(*read_sample)(Sound_Sample *sample); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
115 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
116 union |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
117 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
118 struct |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
119 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
120 Uint16 cbSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
121 Uint16 wSamplesPerBlock; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
122 Uint16 wNumCoef; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
123 ADPCMCOEFSET *aCoeff; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
124 } adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
125 } fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
126 } fmt_t; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
127 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
128 |
17 | 129 /* |
130 * Read in a fmt_t from disk. This makes this process safe regardless of | |
131 * 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
|
132 * 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
|
133 * needed in the read_fmt_* functions. |
17 | 134 */ |
135 static int read_fmt_chunk(SDL_RWops *rw, fmt_t *fmt) | |
136 { | |
137 /* skip reading the chunk ID, since it was already read at this point... */ | |
138 fmt->chunkID = fmtID; | |
139 | |
140 if (SDL_RWread(rw, &fmt->chunkSize, sizeof (fmt->chunkSize), 1) != 1) | |
141 return(0); | |
142 fmt->chunkSize = SDL_SwapLE32(fmt->chunkSize); | |
143 | |
144 if (SDL_RWread(rw, &fmt->wFormatTag, sizeof (fmt->wFormatTag), 1) != 1) | |
145 return(0); | |
146 fmt->wFormatTag = SDL_SwapLE16(fmt->wFormatTag); | |
147 | |
148 if (SDL_RWread(rw, &fmt->wChannels, sizeof (fmt->wChannels), 1) != 1) | |
149 return(0); | |
150 fmt->wChannels = SDL_SwapLE16(fmt->wChannels); | |
151 | |
152 if (SDL_RWread(rw, &fmt->dwSamplesPerSec, | |
153 sizeof (fmt->dwSamplesPerSec), 1) != 1) | |
154 return(0); | |
155 fmt->dwSamplesPerSec = SDL_SwapLE32(fmt->dwSamplesPerSec); | |
156 | |
157 if (SDL_RWread(rw, &fmt->dwAvgBytesPerSec, | |
158 sizeof (fmt->dwAvgBytesPerSec), 1) != 1) | |
159 return(0); | |
160 fmt->dwAvgBytesPerSec = SDL_SwapLE32(fmt->dwAvgBytesPerSec); | |
161 | |
162 if (SDL_RWread(rw, &fmt->wBlockAlign, sizeof (fmt->wBlockAlign), 1) != 1) | |
163 return(0); | |
164 fmt->wBlockAlign = SDL_SwapLE16(fmt->wBlockAlign); | |
165 | |
166 if (SDL_RWread(rw, &fmt->wBitsPerSample, | |
167 sizeof (fmt->wBitsPerSample), 1) != 1) | |
168 return(0); | |
169 fmt->wBitsPerSample = SDL_SwapLE16(fmt->wBitsPerSample); | |
170 | |
171 return(1); | |
172 } /* read_fmt_chunk */ | |
173 | |
174 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
175 |
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 * The DATA chunk... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
178 *****************************************************************************/ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
179 |
17 | 180 #define dataID 0x61746164 /* "data", in ascii. */ |
181 | |
182 typedef struct | |
183 { | |
184 Uint32 chunkID; | |
185 Sint32 chunkSize; | |
186 /* Then, (chunkSize) bytes of waveform data... */ | |
187 } data_t; | |
188 | |
189 | |
190 /* | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
191 * Read in a data_t from disk. This makes this process safe regardless of |
17 | 192 * the processor's byte order or how the fmt_t structure is packed. |
193 */ | |
194 static int read_data_chunk(SDL_RWops *rw, data_t *data) | |
195 { | |
196 /* skip reading the chunk ID, since it was already read at this point... */ | |
197 data->chunkID = dataID; | |
198 | |
199 if (SDL_RWread(rw, &data->chunkSize, sizeof (data->chunkSize), 1) != 1) | |
200 return(0); | |
201 data->chunkSize = SDL_SwapLE32(data->chunkSize); | |
202 | |
203 return(1); | |
40
c15396fc0e55
Fixed incorrect comment, by Torbj�rn Andersson. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
17
diff
changeset
|
204 } /* read_data_chunk */ |
17 | 205 |
206 | |
207 | |
208 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
209 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
210 * 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
|
211 *****************************************************************************/ |
17 | 212 |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
213 typedef struct |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
214 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
215 fmt_t *fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
216 Sint32 bytesLeft; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
217 } wav_t; |
17 | 218 |
219 | |
220 | |
221 | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
222 /***************************************************************************** |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
223 * Normal, uncompressed waveform handler... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
224 *****************************************************************************/ |
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 static Uint32 read_sample_fmt_normal(Sound_Sample *sample) |
17 | 227 { |
228 Uint32 retval; | |
229 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
230 wav_t *w = (wav_t *) internal->decoder_private; | |
231 Uint32 max = (internal->buffer_size < (Uint32) w->bytesLeft) ? | |
232 internal->buffer_size : (Uint32) w->bytesLeft; | |
233 | |
234 assert(max > 0); | |
235 | |
236 /* | |
237 * We don't actually do any decoding, so we read the wav data | |
238 * directly into the internal buffer... | |
239 */ | |
240 retval = SDL_RWread(internal->rw, internal->buffer, 1, max); | |
241 | |
242 w->bytesLeft -= retval; | |
243 | |
244 /* Make sure the read went smoothly... */ | |
245 if ((retval == 0) || (w->bytesLeft == 0)) | |
246 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
247 | |
248 else if (retval == -1) | |
249 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
250 | |
251 /* (next call this EAGAIN may turn into an EOF or error.) */ | |
252 else if (retval < internal->buffer_size) | |
253 sample->flags |= SOUND_SAMPLEFLAG_EAGAIN; | |
254 | |
255 return(retval); | |
124
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
256 } /* read_sample_fmt_normal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
257 |
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 static void free_fmt_normal(fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
260 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
261 /* it's a no-op. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
262 } /* free_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 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
|
266 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
267 fmt->free = free_fmt_normal; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
268 fmt->read_sample = read_sample_fmt_normal; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
269 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
270 } /* read_fmt_normal */ |
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 |
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 * ADPCM compression handler... * |
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 Uint32 read_sample_fmt_adpcm(Sound_Sample *sample) |
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 /* !!! FIXME: Write this. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
281 sample->flags | SOUND_SAMPLEFLAG_ERROR; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
282 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
283 } /* read_sample_fmt_adpcm */ |
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 static void free_fmt_adpcm(fmt_t *fmt) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
287 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
288 if (fmt->fmt.adpcm.aCoeff != NULL) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
289 free(fmt->fmt.adpcm.aCoeff); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
290 } /* free_fmt_adpcm */ |
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 |
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 * 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
|
295 * 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
|
296 * structure is packed. |
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 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
|
299 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
300 size_t i; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
301 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
302 fmt->fmt.adpcm.aCoeff = NULL; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
303 fmt->free = free_fmt_adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
304 fmt->read_sample = read_sample_fmt_adpcm; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
305 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
306 if (SDL_RWread(rw, &fmt->fmt.adpcm.cbSize, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
307 sizeof (fmt->fmt.adpcm.cbSize), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
308 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
309 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
310 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
311 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
|
312 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
313 if (SDL_RWread(rw, &fmt->fmt.adpcm.wSamplesPerBlock, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
314 sizeof (fmt->fmt.adpcm.wSamplesPerBlock), 1) != 1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
315 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
316 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
317 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
318 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
|
319 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
320 if (SDL_RWread(rw, &fmt->fmt.adpcm.wNumCoef, |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
321 sizeof (fmt->fmt.adpcm.wNumCoef), 1) != 1) |
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 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
324 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
325 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
|
326 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
327 i = sizeof (ADPCMCOEFSET) * fmt->fmt.adpcm.wNumCoef; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
328 fmt->fmt.adpcm.aCoeff = (ADPCMCOEFSET *) malloc(i); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
329 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
|
330 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
331 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
|
332 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
333 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
|
334 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
|
335 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
336 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
337 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
338 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
339 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
|
340 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
|
341 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
342 return(0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
343 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
344 } /* for */ |
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 return(1); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
347 } /* read_fmt_adpcm */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
348 |
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 * Everything else... * |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
352 *****************************************************************************/ |
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 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
|
356 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
357 /* 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
|
358 switch (fmt->wFormatTag) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
359 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
360 case FMT_NORMAL: |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
361 return(read_fmt_normal(rw, fmt)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
362 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
363 case FMT_ADPCM: |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
364 return(read_fmt_adpcm(rw, fmt)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
365 } /* switch */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
366 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
367 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
|
368 Sound_SetError("WAV: Unsupported format"); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
369 return(0); /* not supported whatsoever. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
370 } /* read_fmt */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
371 |
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 * 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
|
375 */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
376 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
|
377 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
378 Sint32 siz = 0; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
379 Uint32 _id = 0; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
380 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
381 while (1) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
382 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
383 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
|
384 if (SDL_SwapLE32(_id) == id) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
385 return(1); |
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 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
|
388 siz = SDL_SwapLE32(siz); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
389 assert(siz > 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
390 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
|
391 } /* while */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
392 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
393 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
|
394 } /* find_chunk */ |
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 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
397 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
|
398 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
399 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
400 SDL_RWops *rw = internal->rw; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
401 data_t d; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
402 wav_t *w; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
403 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
404 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
|
405 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
|
406 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
|
407 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
|
408 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
|
409 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
410 sample->actual.channels = (Uint8) fmt->wChannels; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
411 sample->actual.rate = fmt->dwSamplesPerSec; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
412 if (fmt->wBitsPerSample <= 8) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
413 sample->actual.format = AUDIO_U8; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
414 else if (fmt->wBitsPerSample <= 16) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
415 sample->actual.format = AUDIO_S16LSB; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
416 else |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
417 BAIL_MACRO("WAV: Unsupported sample size.", 0); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
418 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
419 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
|
420 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
|
421 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
|
422 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
423 w = (wav_t *) malloc(sizeof(wav_t)); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
424 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
|
425 w->fmt = fmt; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
426 w->bytesLeft = d.chunkSize; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
427 internal->decoder_private = (void *) w; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
428 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
429 sample->flags = SOUND_SAMPLEFLAG_NONE; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
430 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
431 SNDDBG(("WAV: Accepting data stream.\n")); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
432 return(1); /* we'll handle this data. */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
433 } /* WAV_open_internal */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
434 |
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 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
|
437 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
438 int rc; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
439 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
440 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
|
441 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
|
442 memset(fmt, '\0', sizeof (fmt_t)); |
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 rc = WAV_open_internal(sample, ext, fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
445 if (!rc) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
446 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
447 if (fmt->free != NULL) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
448 fmt->free(fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
449 free(fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
450 } /* if */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
451 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
452 return(rc); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
453 } /* WAV_open */ |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
454 |
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 static void WAV_close(Sound_Sample *sample) |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
457 { |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
458 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
459 wav_t *w = (wav_t *) internal->decoder_private; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
460 w->fmt->free(w->fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
461 free(w->fmt); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
462 free(w); |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
463 } /* WAV_close */ |
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 |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
466 static Uint32 WAV_read(Sound_Sample *sample) |
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 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
469 wav_t *w = (wav_t *) internal->decoder_private; |
e46e31fdecfd
Restructured to handle multiple formats.
Ryan C. Gordon <icculus@icculus.org>
parents:
106
diff
changeset
|
470 return(w->fmt->read_sample(sample)); |
17 | 471 } /* WAV_read */ |
472 | |
64
40006625142a
Changes in preparation of autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents:
62
diff
changeset
|
473 #endif /* SOUND_SUPPORTS_WAV */ |
17 | 474 |
475 /* end of wav.c ... */ | |
476 |