Mercurial > SDL_sound_CoreAudio
annotate SDL_sound.c @ 110:5e5adbe0f215
Added Midi decoder.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 03 Oct 2001 20:17:48 +0000 |
parents | 427541211bfd |
children | fd942c1433f8 |
rev | line source |
---|---|
4 | 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 * This file implements the core API, which is relatively simple. | |
22 * The real meat of SDL_sound is in the decoders directory. | |
23 * | |
24 * Documentation is in SDL_sound.h ... It's verbose, honest. :) | |
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 | |
107
427541211bfd
config.h management updates.
Ryan C. Gordon <icculus@icculus.org>
parents:
102
diff
changeset
|
31 #if HAVE_CONFIG_H |
427541211bfd
config.h management updates.
Ryan C. Gordon <icculus@icculus.org>
parents:
102
diff
changeset
|
32 # include <config.h> |
427541211bfd
config.h management updates.
Ryan C. Gordon <icculus@icculus.org>
parents:
102
diff
changeset
|
33 #endif |
4 | 34 |
35 #include <stdio.h> | |
36 #include <stdlib.h> | |
37 #include <string.h> | |
38 #include <assert.h> | |
39 #include <ctype.h> | |
40 | |
41 #include "SDL.h" | |
42 #include "SDL_sound.h" | |
43 | |
44 #define __SDL_SOUND_INTERNAL__ | |
45 #include "SDL_sound_internal.h" | |
46 | |
47 | |
48 /* The various decoder drivers... */ | |
49 | |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
50 #if (defined SOUND_SUPPORTS_MP3) |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
51 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MP3; |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
52 #endif |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
53 |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
54 #if (defined SOUND_SUPPORTS_MOD) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
55 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MOD; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
56 #endif |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
57 |
20 | 58 #if (defined SOUND_SUPPORTS_WAV) |
59 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV; | |
60 #endif | |
61 | |
37
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
62 #if (defined SOUND_SUPPORTS_AIFF) |
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
63 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_AIFF; |
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
64 #endif |
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
65 |
26
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
66 #if (defined SOUND_SUPPORTS_OGG) |
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
67 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_OGG; |
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
68 #endif |
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
69 |
4 | 70 #if (defined SOUND_SUPPORTS_VOC) |
71 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_VOC; | |
72 #endif | |
73 | |
74 #if (defined SOUND_SUPPORTS_RAW) | |
75 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_RAW; | |
76 #endif | |
77 | |
102 | 78 #if (defined SOUND_SUPPORTS_SHN) |
79 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_SHN; | |
80 #endif | |
81 | |
110 | 82 #if (defined SOUND_SUPPORTS_MIDI) |
83 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MIDI; | |
84 #endif | |
85 | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
86 |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
87 |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
88 typedef struct |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
89 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
90 int available; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
91 const Sound_DecoderFunctions *funcs; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
92 } decoder_element; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
93 |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
94 static decoder_element decoders[] = |
4 | 95 { |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
96 #if (defined SOUND_SUPPORTS_MP3) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
97 { 0, &__Sound_DecoderFunctions_MP3 }, |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
98 #endif |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
99 |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
100 #if (defined SOUND_SUPPORTS_MOD) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
101 { 0, &__Sound_DecoderFunctions_MOD }, |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
102 #endif |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
103 |
20 | 104 #if (defined SOUND_SUPPORTS_WAV) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
105 { 0, &__Sound_DecoderFunctions_WAV }, |
20 | 106 #endif |
107 | |
37
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
108 #if (defined SOUND_SUPPORTS_AIFF) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
109 { 0, &__Sound_DecoderFunctions_AIFF }, |
37
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
110 #endif |
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
111 |
26
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
112 #if (defined SOUND_SUPPORTS_OGG) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
113 { 0, &__Sound_DecoderFunctions_OGG }, |
26
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
114 #endif |
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
115 |
4 | 116 #if (defined SOUND_SUPPORTS_VOC) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
117 { 0, &__Sound_DecoderFunctions_VOC }, |
4 | 118 #endif |
119 | |
120 #if (defined SOUND_SUPPORTS_RAW) | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
121 { 0, &__Sound_DecoderFunctions_RAW }, |
4 | 122 #endif |
102 | 123 |
124 #if (defined SOUND_SUPPORTS_SHN) | |
125 { 0, &__Sound_DecoderFunctions_SHN }, | |
126 #endif | |
110 | 127 |
128 #if (defined SOUND_SUPPORTS_MIDI) | |
129 { 0, &__Sound_DecoderFunctions_MIDI }, | |
130 #endif | |
4 | 131 }; |
132 | |
133 | |
134 | |
135 /* General SDL_sound state ... */ | |
136 | |
137 static int initialized = 0; | |
138 static Sound_Sample *samplesList = NULL; /* this is a linked list. */ | |
139 static const Sound_DecoderInfo **available_decoders = NULL; | |
140 | |
141 | |
142 /* functions ... */ | |
143 | |
144 void Sound_GetLinkedVersion(Sound_Version *ver) | |
145 { | |
146 if (ver != NULL) | |
147 { | |
148 ver->major = SOUND_VER_MAJOR; | |
149 ver->minor = SOUND_VER_MINOR; | |
150 ver->patch = SOUND_VER_PATCH; | |
151 } /* if */ | |
152 } /* Sound_GetLinkedVersion */ | |
153 | |
154 | |
155 int Sound_Init(void) | |
156 { | |
157 size_t i; | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
158 size_t pos = 0; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
159 size_t total = sizeof (decoders) / sizeof (decoders[0]); |
4 | 160 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); |
161 samplesList = NULL; | |
162 | |
163 SDL_Init(SDL_INIT_AUDIO); | |
164 | |
165 available_decoders = (const Sound_DecoderInfo **) | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
166 malloc((total + 1) * sizeof (Sound_DecoderInfo *)); |
4 | 167 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); |
168 | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
169 for (i = 0; i < total; i++) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
170 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
171 decoders[i].available = decoders[i].funcs->init(); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
172 if (decoders[i].available) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
173 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
174 available_decoders[pos] = &(decoders[i].funcs->info); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
175 pos++; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
176 } /* if */ |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
177 } /* for */ |
4 | 178 |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
179 available_decoders[pos] = NULL; |
26
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
180 |
4 | 181 initialized = 1; |
182 return(1); | |
183 } /* Sound_Init */ | |
184 | |
185 | |
186 int Sound_Quit(void) | |
187 { | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
188 size_t total = sizeof (decoders) / sizeof (decoders[0]); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
189 size_t i; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
190 |
4 | 191 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); |
192 | |
193 while (((volatile Sound_Sample *) samplesList) != NULL) | |
194 Sound_FreeSample(samplesList); | |
195 | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
196 for (i = 0; i < total; i++) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
197 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
198 if (decoders[i].available) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
199 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
200 decoders[i].funcs->quit(); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
201 decoders[i].available = 0; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
202 } /* if */ |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
203 } /* for */ |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
204 |
4 | 205 if (available_decoders != NULL) |
80
25ee62c6b333
Fixed a const complaint from Visual C++ 6.0.
Ryan C. Gordon <icculus@icculus.org>
parents:
62
diff
changeset
|
206 free((void *) available_decoders); |
4 | 207 available_decoders = NULL; |
208 | |
209 initialized = 0; | |
210 | |
211 return(1); | |
212 } /* Sound_Quit */ | |
213 | |
214 | |
215 const Sound_DecoderInfo **Sound_AvailableDecoders(void) | |
216 { | |
217 return(available_decoders); /* READ. ONLY. */ | |
218 } /* Sound_AvailableDecoders */ | |
219 | |
220 | |
221 const char *Sound_GetError(void) | |
222 { | |
223 return(SDL_GetError()); | |
224 } /* Sound_GetError */ | |
225 | |
226 | |
227 void Sound_ClearError(void) | |
228 { | |
229 SDL_ClearError(); | |
230 } /* Sound_ClearError */ | |
231 | |
232 | |
233 /* | |
234 * This is declared in the internal header. | |
235 */ | |
236 void Sound_SetError(const char *err) | |
237 { | |
238 if (err != NULL) | |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
239 { |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
240 SNDDBG(("Sound_SetError(\"%s\");\n", err)); |
4 | 241 SDL_SetError(err); |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
242 } /* if */ |
4 | 243 } /* Sound_SetError */ |
244 | |
245 | |
246 /* | |
247 * -ansi and -pedantic flags prevent use of strcasecmp() on Linux, and | |
248 * I honestly don't want to mess around with figuring out if a given | |
249 * platform has "strcasecmp", "stricmp", or | |
250 * "compare_two_damned_strings_case_insensitive", which I hear is in the | |
251 * next release of Carbon. :) This is exported so decoders may use it if | |
252 * they like. | |
253 */ | |
254 int __Sound_strcasecmp(const char *x, const char *y) | |
255 { | |
256 int ux, uy; | |
257 | |
98
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
258 if (x == y) /* same pointer? Both NULL? */ |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
259 return(0); |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
260 |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
261 if (x == NULL) |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
262 return(-1); |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
263 |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
264 if (y == NULL) |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
265 return(1); |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
266 |
4 | 267 do |
268 { | |
269 ux = toupper((int) *x); | |
270 uy = toupper((int) *y); | |
271 if (ux > uy) | |
272 return(1); | |
273 else if (ux < uy) | |
274 return(-1); | |
275 x++; | |
276 y++; | |
277 } while ((ux) && (uy)); | |
278 | |
279 return(0); | |
280 } /* __Sound_strcasecmp */ | |
281 | |
282 | |
283 /* | |
284 * Allocate a Sound_Sample, and fill in most of its fields. Those that need | |
285 * to be filled in later, by a decoder, will be initialized to zero. | |
286 */ | |
287 static Sound_Sample *alloc_sample(SDL_RWops *rw, Sound_AudioInfo *desired, | |
288 Uint32 bufferSize) | |
289 { | |
290 Sound_Sample *retval = malloc(sizeof (Sound_Sample)); | |
291 Sound_SampleInternal *internal = malloc(sizeof (Sound_SampleInternal)); | |
292 if ((retval == NULL) || (internal == NULL)) | |
293 { | |
294 Sound_SetError(ERR_OUT_OF_MEMORY); | |
295 if (retval) | |
296 free(retval); | |
297 if (internal) | |
298 free(internal); | |
299 | |
300 return(NULL); | |
301 } /* if */ | |
302 | |
303 memset(retval, '\0', sizeof (Sound_Sample)); | |
304 memset(internal, '\0', sizeof (Sound_SampleInternal)); | |
305 | |
306 assert(bufferSize > 0); | |
307 retval->buffer = malloc(bufferSize); /* pure ugly. */ | |
308 if (!retval->buffer) | |
309 { | |
310 Sound_SetError(ERR_OUT_OF_MEMORY); | |
311 free(internal); | |
312 free(retval); | |
313 return(NULL); | |
314 } /* if */ | |
315 memset(retval->buffer, '\0', bufferSize); | |
316 retval->buffer_size = bufferSize; | |
317 | |
318 if (desired != NULL) | |
319 memcpy(&retval->desired, desired, sizeof (Sound_AudioInfo)); | |
320 | |
321 internal->rw = rw; | |
322 retval->opaque = internal; | |
323 return(retval); | |
324 } /* alloc_sample */ | |
325 | |
326 | |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
327 #if (defined DEBUG_CHATTER) |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
328 static __inline__ const char *fmt_to_str(Uint16 fmt) |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
329 { |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
330 switch(fmt) |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
331 { |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
332 case AUDIO_U8: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
333 return("U8"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
334 case AUDIO_S8: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
335 return("S8"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
336 case AUDIO_U16LSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
337 return("U16LSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
338 case AUDIO_S16LSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
339 return("S16LSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
340 case AUDIO_U16MSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
341 return("U16MSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
342 case AUDIO_S16MSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
343 return("S16MSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
344 } /* switch */ |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
345 |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
346 return("Unknown"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
347 } /* fmt_to_str */ |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
348 #endif |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
349 |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
350 |
4 | 351 /* |
352 * The bulk of the Sound_NewSample() work is done here... | |
353 * Ask the specified decoder to handle the data in (rw), and if | |
354 * so, construct the Sound_Sample. Otherwise, try to wind (rw)'s stream | |
355 * back to where it was, and return false. | |
356 * | |
357 * !!! FIXME: This is big, ugly, nasty, and smelly. | |
358 */ | |
359 static int init_sample(const Sound_DecoderFunctions *funcs, | |
360 Sound_Sample *sample, const char *ext, | |
361 Sound_AudioInfo *_desired) | |
362 { | |
363 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
37
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
364 Sound_AudioInfo desired; |
4 | 365 int pos = SDL_RWtell(internal->rw); /* !!! FIXME: Int? Really? */ |
366 | |
367 /* fill in the funcs for this decoder... */ | |
368 sample->decoder = &funcs->info; | |
369 internal->funcs = funcs; | |
370 if (!funcs->open(sample, ext)) | |
371 { | |
372 SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */ | |
373 return(0); | |
374 } /* if */ | |
375 | |
376 /* success; we've got a decoder! */ | |
377 | |
378 /* Now we need to set up the conversion buffer... */ | |
379 | |
380 memcpy(&desired, (_desired != NULL) ? _desired : &sample->actual, | |
381 sizeof (Sound_AudioInfo)); | |
382 | |
383 if (SDL_BuildAudioCVT(&internal->sdlcvt, | |
384 sample->actual.format, | |
385 sample->actual.channels, | |
386 (int) sample->actual.rate, /* !!! FIXME: Int? Really? */ | |
387 desired.format, | |
388 desired.channels, | |
389 (int) desired.rate) == -1) /* !!! FIXME: Int? Really? */ | |
390 { | |
391 Sound_SetError(SDL_GetError()); | |
392 funcs->close(sample); | |
393 SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */ | |
394 return(0); | |
395 } /* if */ | |
396 | |
397 if (internal->sdlcvt.len_mult > 1) | |
398 { | |
399 void *rc = realloc(sample->buffer, | |
400 sample->buffer_size * internal->sdlcvt.len_mult); | |
401 if (rc == NULL) | |
402 { | |
403 funcs->close(sample); | |
404 SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */ | |
405 return(0); | |
406 } /* if */ | |
407 | |
408 sample->buffer = rc; | |
409 } /* if */ | |
410 | |
411 /* these pointers are all one and the same. */ | |
412 memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo)); | |
413 internal->sdlcvt.buf = internal->buffer = sample->buffer; | |
414 internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult; | |
415 internal->sdlcvt.len = internal->buffer_size; | |
416 | |
417 /* Prepend our new Sound_Sample to the samplesList... */ | |
418 if (samplesList != NULL) | |
419 { | |
420 internal->next = samplesList; | |
421 if (samplesList != NULL) | |
422 internal->prev = sample; | |
423 } /* if */ | |
424 samplesList = sample; | |
425 | |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
426 SNDDBG(("New sample DESIRED format: %s format, %d rate, %d channels.\n", |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
427 fmt_to_str(sample->desired.format), |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
428 sample->desired.rate, |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
429 sample->desired.channels)); |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
430 |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
431 SNDDBG(("New sample ACTUAL format: %s format, %d rate, %d channels.\n", |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
432 fmt_to_str(sample->actual.format), |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
433 sample->actual.rate, |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
434 sample->actual.channels)); |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
435 |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
436 SNDDBG(("On-the-fly conversion: %s.\n", |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
437 internal->sdlcvt.needed ? "ENABLED" : "DISABLED")); |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
438 |
4 | 439 return(1); |
440 } /* init_sample */ | |
441 | |
442 | |
443 Sound_Sample *Sound_NewSample(SDL_RWops *rw, const char *ext, | |
444 Sound_AudioInfo *desired, Uint32 bSize) | |
445 { | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
446 size_t total = sizeof (decoders) / sizeof (decoders[0]); |
4 | 447 size_t i; |
448 Sound_Sample *retval; | |
449 | |
450 /* sanity checks. */ | |
451 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL); | |
452 BAIL_IF_MACRO(rw == NULL, ERR_INVALID_ARGUMENT, NULL); | |
453 | |
454 retval = alloc_sample(rw, desired, bSize); | |
455 if (!retval) | |
456 return(NULL); /* alloc_sample() sets error message... */ | |
457 | |
458 if (ext != NULL) | |
459 { | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
460 for (i = 0; i < total; i++) |
4 | 461 { |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
462 if (decoders[i].available) |
4 | 463 { |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
464 const char *decoderExt = decoders[i].funcs->info.extension; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
465 if (__Sound_strcasecmp(decoderExt, ext) == 0) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
466 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
467 if (init_sample(decoders[i].funcs, retval, ext, desired)) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
468 return(retval); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
469 } /* if */ |
4 | 470 } /* if */ |
471 } /* for */ | |
472 } /* if */ | |
473 | |
474 /* no direct extension match? Try everything we've got... */ | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
475 for (i = 0; i < total; i++) |
4 | 476 { |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
477 if (decoders[i].available) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
478 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
479 if (init_sample(decoders[i].funcs, retval, ext, desired)) |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
480 return(retval); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
481 } /* if */ |
4 | 482 } /* for */ |
483 | |
484 /* nothing could handle the sound data... */ | |
485 free(retval->opaque); | |
486 if (retval->buffer != NULL) | |
487 free(retval->buffer); | |
488 free(retval); | |
489 SDL_RWclose(rw); | |
490 Sound_SetError(ERR_UNSUPPORTED_FORMAT); | |
491 return(NULL); | |
492 } /* Sound_NewSample */ | |
493 | |
494 | |
495 Sound_Sample *Sound_NewSampleFromFile(const char *filename, | |
496 Sound_AudioInfo *desired, | |
497 Uint32 bufferSize) | |
498 { | |
499 const char *ext; | |
500 SDL_RWops *rw; | |
501 | |
502 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL); | |
503 BAIL_IF_MACRO(filename == NULL, ERR_INVALID_ARGUMENT, NULL); | |
504 | |
505 ext = strrchr(filename, '.'); | |
506 rw = SDL_RWFromFile(filename, "rb"); | |
507 BAIL_IF_MACRO(rw == NULL, SDL_GetError(), NULL); | |
508 | |
509 if (ext != NULL) | |
510 ext++; | |
511 | |
512 return(Sound_NewSample(rw, ext, desired, bufferSize)); | |
513 } /* Sound_NewSampleFromFile */ | |
514 | |
515 | |
516 void Sound_FreeSample(Sound_Sample *sample) | |
517 { | |
518 Sound_SampleInternal *internal; | |
519 | |
520 if (!initialized) | |
521 { | |
522 Sound_SetError(ERR_NOT_INITIALIZED); | |
523 return; | |
524 } /* if */ | |
525 | |
526 if (sample == NULL) | |
527 { | |
528 Sound_SetError(ERR_INVALID_ARGUMENT); | |
529 return; | |
530 } /* if */ | |
531 | |
532 internal = (Sound_SampleInternal *) sample->opaque; | |
533 | |
534 internal->funcs->close(sample); | |
535 | |
536 /* update the samplesList... */ | |
537 if (internal->prev != NULL) | |
538 { | |
539 Sound_SampleInternal *prevInternal; | |
540 prevInternal = (Sound_SampleInternal *) internal->prev->opaque; | |
541 prevInternal->next = internal->next; | |
542 } /* if */ | |
543 else | |
544 { | |
545 assert(samplesList == sample); | |
546 samplesList = internal->next; | |
547 } /* else */ | |
548 | |
549 if (internal->next != NULL) | |
550 { | |
551 Sound_SampleInternal *nextInternal; | |
552 nextInternal = (Sound_SampleInternal *) internal->next->opaque; | |
553 nextInternal->prev = internal->prev; | |
554 } /* if */ | |
555 | |
556 /* nuke it... */ | |
557 if (internal->rw != NULL) /* this condition is a "just in case" thing. */ | |
558 SDL_RWclose(internal->rw); | |
559 assert(internal->buffer != NULL); | |
560 if (internal->buffer != sample->buffer) | |
561 free(internal->buffer); | |
562 free(internal); | |
563 if (sample->buffer != NULL) | |
564 free(sample->buffer); | |
565 free(sample); | |
566 } /* Sound_FreeSample */ | |
567 | |
568 | |
569 int Sound_SetBufferSize(Sound_Sample *sample, Uint32 newSize) | |
570 { | |
571 void *newBuf = NULL; | |
572 Sound_SampleInternal *internal = NULL; | |
573 | |
574 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | |
575 BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0); | |
576 internal = ((Sound_SampleInternal *) sample->opaque); | |
577 newBuf = realloc(sample->buffer, newSize * internal->sdlcvt.len_mult); | |
578 BAIL_IF_MACRO(newBuf == NULL, ERR_OUT_OF_MEMORY, 0); | |
579 | |
580 internal->sdlcvt.buf = internal->buffer = sample->buffer = newBuf; | |
581 sample->buffer_size = newSize; | |
582 internal->buffer_size = newSize / internal->sdlcvt.len_mult; | |
583 internal->sdlcvt.len = internal->buffer_size; | |
584 | |
585 return(1); | |
586 } /* Sound_SetBufferSize */ | |
587 | |
588 | |
589 Uint32 Sound_Decode(Sound_Sample *sample) | |
590 { | |
591 Sound_SampleInternal *internal = NULL; | |
592 Uint32 retval = 0; | |
593 | |
594 /* a boatload of sanity checks... */ | |
595 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | |
596 BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0); | |
597 BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_ERROR, ERR_PREV_ERROR, 0); | |
598 BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_EOF, ERR_PREV_EOF, 0); | |
599 | |
600 internal = (Sound_SampleInternal *) sample->opaque; | |
601 | |
602 assert(sample->buffer != NULL); | |
603 assert(sample->buffer_size > 0); | |
604 assert(internal->buffer != NULL); | |
605 assert(internal->buffer_size > 0); | |
606 | |
607 /* reset EAGAIN. Decoder can flip it back on if it needs to. */ | |
608 sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; | |
609 retval = internal->funcs->read(sample); | |
37
f27bcbcaeab1
Added AIFF entry, and (for now) some multiple-streams-in-one-rwops support.
Ryan C. Gordon <icculus@icculus.org>
parents:
26
diff
changeset
|
610 |
4 | 611 if (internal->sdlcvt.needed) |
612 { | |
613 internal->sdlcvt.len = retval; | |
614 SDL_ConvertAudio(&internal->sdlcvt); | |
615 retval *= internal->sdlcvt.len_mult; | |
616 } /* if */ | |
617 | |
618 return(retval); | |
619 } /* Sound_Decode */ | |
620 | |
621 | |
622 Uint32 Sound_DecodeAll(Sound_Sample *sample) | |
623 { | |
624 Sound_SampleInternal *internal = NULL; | |
625 void *buf = NULL; | |
626 Uint32 newBufSize = 0; | |
627 | |
628 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | |
629 | |
630 internal = (Sound_SampleInternal *) sample->opaque; | |
631 | |
632 while ( ((sample->flags & SOUND_SAMPLEFLAG_EOF) == 0) && | |
633 ((sample->flags & SOUND_SAMPLEFLAG_ERROR) == 0) ) | |
634 { | |
635 void *ptr = realloc(buf, newBufSize + sample->buffer_size); | |
636 if (ptr == NULL) | |
637 { | |
638 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
639 Sound_SetError(ERR_OUT_OF_MEMORY); | |
640 } /* if */ | |
641 else | |
642 { | |
643 Uint32 br = Sound_Decode(sample); | |
644 memcpy( ((char *) buf) + newBufSize, sample->buffer, br ); | |
645 newBufSize += br; | |
646 } /* else */ | |
647 } /* while */ | |
648 | |
649 free(sample->buffer); | |
650 sample->buffer = internal->buffer = internal->sdlcvt.buf = buf; | |
651 sample->buffer_size = newBufSize; | |
652 internal->buffer_size = newBufSize / internal->sdlcvt.len_mult; | |
653 internal->sdlcvt.len_mult = internal->buffer_size; | |
654 | |
655 return(newBufSize); | |
656 } /* Sound_DecodeAll */ | |
657 | |
658 | |
659 /* end of SDL_sound.c ... */ | |
660 |