Mercurial > SDL_sound_CoreAudio
annotate SDL_sound.c @ 223:249186e31431
Sound_Rewind() support code.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 17 Jan 2002 20:55:46 +0000 |
parents | ca3483f4cfec |
children | 57e16a6d244f |
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 * | |
184
47cc2de2ae36
Changed reference to "LICENSE" file to "COPYING".
Ryan C. Gordon <icculus@icculus.org>
parents:
172
diff
changeset
|
26 * Please see the file COPYING in the source's root directory. |
4 | 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 |
209
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
54 #if (defined SOUND_SUPPORTS_MIKMOD) |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
55 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MIKMOD; |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
56 #endif |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
57 |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
58 #if (defined SOUND_SUPPORTS_MODPLUG) |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
59 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MODPLUG; |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
60 #endif |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
61 |
20 | 62 #if (defined SOUND_SUPPORTS_WAV) |
63 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV; | |
64 #endif | |
65 | |
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
|
66 #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
|
67 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
|
68 #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
|
69 |
216
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
70 #if (defined SOUND_SUPPORTS_AU) |
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
71 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_AU; |
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
72 #endif |
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
73 |
26
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
74 #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
|
75 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
|
76 #endif |
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
77 |
4 | 78 #if (defined SOUND_SUPPORTS_VOC) |
79 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_VOC; | |
80 #endif | |
81 | |
82 #if (defined SOUND_SUPPORTS_RAW) | |
83 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_RAW; | |
84 #endif | |
85 | |
102 | 86 #if (defined SOUND_SUPPORTS_SHN) |
87 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_SHN; | |
88 #endif | |
89 | |
110 | 90 #if (defined SOUND_SUPPORTS_MIDI) |
91 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MIDI; | |
92 #endif | |
93 | |
157 | 94 #if (defined SOUND_SUPPORTS_FLAC) |
95 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_FLAC; | |
96 #endif | |
97 | |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
98 |
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 typedef struct |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
101 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
102 int available; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
103 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
|
104 } decoder_element; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
105 |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
106 static decoder_element decoders[] = |
4 | 107 { |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
108 #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
|
109 { 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
|
110 #endif |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
111 |
209
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
112 #if (defined SOUND_SUPPORTS_MIKMOD) |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
113 { 0, &__Sound_DecoderFunctions_MIKMOD }, |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
114 #endif |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
115 |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
116 #if (defined SOUND_SUPPORTS_MODPLUG) |
e63b9393f6ce
Added ModPlug support.
Ryan C. Gordon <icculus@icculus.org>
parents:
184
diff
changeset
|
117 { 0, &__Sound_DecoderFunctions_MODPLUG }, |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
118 #endif |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
119 |
20 | 120 #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
|
121 { 0, &__Sound_DecoderFunctions_WAV }, |
20 | 122 #endif |
123 | |
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
|
124 #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
|
125 { 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
|
126 #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
|
127 |
216
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
128 #if (defined SOUND_SUPPORTS_AU) |
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
129 { 0, &__Sound_DecoderFunctions_AU }, |
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
130 #endif |
07d0939d40e7
Support for .AU files added.
Ryan C. Gordon <icculus@icculus.org>
parents:
209
diff
changeset
|
131 |
26
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
132 #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
|
133 { 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
|
134 #endif |
ddc3614c9042
Bugfix (thanks Tsuyoshi Iguchi!), and Ogg Vorbis decoder entry.
Ryan C. Gordon <icculus@icculus.org>
parents:
20
diff
changeset
|
135 |
4 | 136 #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
|
137 { 0, &__Sound_DecoderFunctions_VOC }, |
4 | 138 #endif |
139 | |
140 #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
|
141 { 0, &__Sound_DecoderFunctions_RAW }, |
4 | 142 #endif |
102 | 143 |
144 #if (defined SOUND_SUPPORTS_SHN) | |
145 { 0, &__Sound_DecoderFunctions_SHN }, | |
146 #endif | |
110 | 147 |
163
b6d6f994e970
Moved MIDI decoder to end of array. Fixed Sound_SetError() so that it
Ryan C. Gordon <icculus@icculus.org>
parents:
157
diff
changeset
|
148 #if (defined SOUND_SUPPORTS_FLAC) |
b6d6f994e970
Moved MIDI decoder to end of array. Fixed Sound_SetError() so that it
Ryan C. Gordon <icculus@icculus.org>
parents:
157
diff
changeset
|
149 { 0, &__Sound_DecoderFunctions_FLAC }, |
b6d6f994e970
Moved MIDI decoder to end of array. Fixed Sound_SetError() so that it
Ryan C. Gordon <icculus@icculus.org>
parents:
157
diff
changeset
|
150 #endif |
b6d6f994e970
Moved MIDI decoder to end of array. Fixed Sound_SetError() so that it
Ryan C. Gordon <icculus@icculus.org>
parents:
157
diff
changeset
|
151 |
110 | 152 #if (defined SOUND_SUPPORTS_MIDI) |
153 { 0, &__Sound_DecoderFunctions_MIDI }, | |
154 #endif | |
118
fd942c1433f8
Fixed for win32 compile.
Ryan C. Gordon <icculus@icculus.org>
parents:
110
diff
changeset
|
155 |
fd942c1433f8
Fixed for win32 compile.
Ryan C. Gordon <icculus@icculus.org>
parents:
110
diff
changeset
|
156 { 0, NULL } |
4 | 157 }; |
158 | |
159 | |
160 | |
161 /* General SDL_sound state ... */ | |
162 | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
163 typedef struct __SOUND_ERRMSGTYPE__ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
164 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
165 Uint32 tid; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
166 int errorAvailable; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
167 char errorString[128]; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
168 struct __SOUND_ERRMSGTYPE__ *next; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
169 } ErrMsg; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
170 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
171 static ErrMsg *errorMessages = NULL; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
172 static SDL_mutex *errorlist_mutex = NULL; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
173 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
174 /* !!! FIXME: This needs a mutex. */ |
4 | 175 static Sound_Sample *samplesList = NULL; /* this is a linked list. */ |
176 static const Sound_DecoderInfo **available_decoders = NULL; | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
177 static int initialized = 0; |
4 | 178 |
179 | |
180 /* functions ... */ | |
181 | |
182 void Sound_GetLinkedVersion(Sound_Version *ver) | |
183 { | |
184 if (ver != NULL) | |
185 { | |
186 ver->major = SOUND_VER_MAJOR; | |
187 ver->minor = SOUND_VER_MINOR; | |
188 ver->patch = SOUND_VER_PATCH; | |
189 } /* if */ | |
190 } /* Sound_GetLinkedVersion */ | |
191 | |
192 | |
193 int Sound_Init(void) | |
194 { | |
195 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
|
196 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
|
197 size_t total = sizeof (decoders) / sizeof (decoders[0]); |
4 | 198 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
199 |
4 | 200 samplesList = NULL; |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
201 errorMessages = NULL; |
4 | 202 |
203 SDL_Init(SDL_INIT_AUDIO); | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
204 errorlist_mutex = SDL_CreateMutex(); |
4 | 205 |
206 available_decoders = (const Sound_DecoderInfo **) | |
118
fd942c1433f8
Fixed for win32 compile.
Ryan C. Gordon <icculus@icculus.org>
parents:
110
diff
changeset
|
207 malloc((total) * sizeof (Sound_DecoderInfo *)); |
4 | 208 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); |
209 | |
118
fd942c1433f8
Fixed for win32 compile.
Ryan C. Gordon <icculus@icculus.org>
parents:
110
diff
changeset
|
210 for (i = 0; decoders[i].funcs != NULL; i++) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
211 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
212 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
|
213 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
|
214 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
215 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
|
216 pos++; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
217 } /* if */ |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
218 } /* for */ |
4 | 219 |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
220 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
|
221 |
4 | 222 initialized = 1; |
223 return(1); | |
224 } /* Sound_Init */ | |
225 | |
226 | |
227 int Sound_Quit(void) | |
228 { | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
229 ErrMsg *err; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
230 ErrMsg *nexterr = NULL; |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
231 size_t i; |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
232 |
4 | 233 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); |
234 | |
235 while (((volatile Sound_Sample *) samplesList) != NULL) | |
236 Sound_FreeSample(samplesList); | |
237 | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
238 samplesList = NULL; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
239 |
118
fd942c1433f8
Fixed for win32 compile.
Ryan C. Gordon <icculus@icculus.org>
parents:
110
diff
changeset
|
240 for (i = 0; decoders[i].funcs != NULL; i++) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
241 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
242 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
|
243 { |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
244 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
|
245 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
|
246 } /* if */ |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
247 } /* for */ |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
248 |
4 | 249 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
|
250 free((void *) available_decoders); |
4 | 251 available_decoders = NULL; |
252 | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
253 /* clean up error state for each thread... */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
254 SDL_LockMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
255 for (err = errorMessages; err != NULL; err = nexterr) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
256 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
257 nexterr = err->next; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
258 free(err); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
259 } /* for */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
260 SDL_UnlockMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
261 SDL_DestroyMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
262 errorMessages = NULL; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
263 errorlist_mutex = NULL; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
264 |
4 | 265 initialized = 0; |
266 return(1); | |
267 } /* Sound_Quit */ | |
268 | |
269 | |
270 const Sound_DecoderInfo **Sound_AvailableDecoders(void) | |
271 { | |
272 return(available_decoders); /* READ. ONLY. */ | |
273 } /* Sound_AvailableDecoders */ | |
274 | |
275 | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
276 static ErrMsg *findErrorForCurrentThread(void) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
277 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
278 ErrMsg *i; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
279 Uint32 tid; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
280 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
281 if (errorMessages != NULL) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
282 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
283 tid = SDL_ThreadID(); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
284 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
285 SDL_LockMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
286 for (i = errorMessages; i != NULL; i = i->next) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
287 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
288 if (i->tid == tid) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
289 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
290 SDL_UnlockMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
291 return(i); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
292 } /* if */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
293 } /* for */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
294 SDL_UnlockMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
295 } /* if */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
296 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
297 return(NULL); /* no error available. */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
298 } /* findErrorForCurrentThread */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
299 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
300 |
4 | 301 const char *Sound_GetError(void) |
302 { | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
303 const char *retval = NULL; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
304 ErrMsg *err = findErrorForCurrentThread(); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
305 if ((err != NULL) && (err->errorAvailable)) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
306 { |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
307 retval = err->errorString; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
308 err->errorAvailable = 0; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
309 } /* if */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
310 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
311 return(retval); |
4 | 312 } /* Sound_GetError */ |
313 | |
314 | |
315 void Sound_ClearError(void) | |
316 { | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
317 ErrMsg *err = findErrorForCurrentThread(); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
318 if (err != NULL) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
319 err->errorAvailable = 0; |
4 | 320 } /* Sound_ClearError */ |
321 | |
322 | |
323 /* | |
324 * This is declared in the internal header. | |
325 */ | |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
326 void Sound_SetError(const char *str) |
4 | 327 { |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
328 ErrMsg *err; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
329 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
330 if (str == NULL) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
331 return; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
332 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
333 SNDDBG(("Sound_SetError(\"%s\");\n", str)); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
334 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
335 err = findErrorForCurrentThread(); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
336 if (err == NULL) |
165
9b26ed9eaf04
Whoops; I should read the code before I change it next time; regressing
Ryan C. Gordon <icculus@icculus.org>
parents:
163
diff
changeset
|
337 { |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
338 err = (ErrMsg *) malloc(sizeof (ErrMsg)); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
339 if (err == NULL) |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
340 return; /* uhh...? */ |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
341 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
342 memset((void *) err, '\0', sizeof (ErrMsg)); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
343 err->tid = SDL_ThreadID(); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
344 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
345 SDL_LockMutex(errorlist_mutex); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
346 err->next = errorMessages; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
347 errorMessages = err; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
348 SDL_UnlockMutex(errorlist_mutex); |
165
9b26ed9eaf04
Whoops; I should read the code before I change it next time; regressing
Ryan C. Gordon <icculus@icculus.org>
parents:
163
diff
changeset
|
349 } /* if */ |
219
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
350 |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
351 err->errorAvailable = 1; |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
352 strncpy(err->errorString, str, sizeof (err->errorString)); |
ca3483f4cfec
Error message management now keeps state per-thread, and does not use
Ryan C. Gordon <icculus@icculus.org>
parents:
216
diff
changeset
|
353 err->errorString[sizeof (err->errorString) - 1] = '\0'; |
4 | 354 } /* Sound_SetError */ |
355 | |
356 | |
357 /* | |
358 * -ansi and -pedantic flags prevent use of strcasecmp() on Linux, and | |
359 * I honestly don't want to mess around with figuring out if a given | |
360 * platform has "strcasecmp", "stricmp", or | |
361 * "compare_two_damned_strings_case_insensitive", which I hear is in the | |
362 * next release of Carbon. :) This is exported so decoders may use it if | |
363 * they like. | |
364 */ | |
365 int __Sound_strcasecmp(const char *x, const char *y) | |
366 { | |
367 int ux, uy; | |
368 | |
98
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
369 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
|
370 return(0); |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
371 |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
372 if (x == NULL) |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
373 return(-1); |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
374 |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
375 if (y == NULL) |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
376 return(1); |
dfdf7b4e05bd
Changed __Sound_strcasecmp() to handle NULL strings gracefully.
Ryan C. Gordon <icculus@icculus.org>
parents:
80
diff
changeset
|
377 |
4 | 378 do |
379 { | |
380 ux = toupper((int) *x); | |
381 uy = toupper((int) *y); | |
382 if (ux > uy) | |
383 return(1); | |
384 else if (ux < uy) | |
385 return(-1); | |
386 x++; | |
387 y++; | |
388 } while ((ux) && (uy)); | |
389 | |
390 return(0); | |
391 } /* __Sound_strcasecmp */ | |
392 | |
393 | |
394 /* | |
395 * Allocate a Sound_Sample, and fill in most of its fields. Those that need | |
396 * to be filled in later, by a decoder, will be initialized to zero. | |
397 */ | |
398 static Sound_Sample *alloc_sample(SDL_RWops *rw, Sound_AudioInfo *desired, | |
399 Uint32 bufferSize) | |
400 { | |
401 Sound_Sample *retval = malloc(sizeof (Sound_Sample)); | |
402 Sound_SampleInternal *internal = malloc(sizeof (Sound_SampleInternal)); | |
403 if ((retval == NULL) || (internal == NULL)) | |
404 { | |
405 Sound_SetError(ERR_OUT_OF_MEMORY); | |
406 if (retval) | |
407 free(retval); | |
408 if (internal) | |
409 free(internal); | |
410 | |
411 return(NULL); | |
412 } /* if */ | |
413 | |
414 memset(retval, '\0', sizeof (Sound_Sample)); | |
415 memset(internal, '\0', sizeof (Sound_SampleInternal)); | |
416 | |
417 assert(bufferSize > 0); | |
418 retval->buffer = malloc(bufferSize); /* pure ugly. */ | |
419 if (!retval->buffer) | |
420 { | |
421 Sound_SetError(ERR_OUT_OF_MEMORY); | |
422 free(internal); | |
423 free(retval); | |
424 return(NULL); | |
425 } /* if */ | |
426 memset(retval->buffer, '\0', bufferSize); | |
427 retval->buffer_size = bufferSize; | |
428 | |
429 if (desired != NULL) | |
430 memcpy(&retval->desired, desired, sizeof (Sound_AudioInfo)); | |
431 | |
432 internal->rw = rw; | |
433 retval->opaque = internal; | |
434 return(retval); | |
435 } /* alloc_sample */ | |
436 | |
437 | |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
438 #if (defined DEBUG_CHATTER) |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
439 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
|
440 { |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
441 switch(fmt) |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
442 { |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
443 case AUDIO_U8: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
444 return("U8"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
445 case AUDIO_S8: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
446 return("S8"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
447 case AUDIO_U16LSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
448 return("U16LSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
449 case AUDIO_S16LSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
450 return("S16LSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
451 case AUDIO_U16MSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
452 return("U16MSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
453 case AUDIO_S16MSB: |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
454 return("S16MSB"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
455 } /* switch */ |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
456 |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
457 return("Unknown"); |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
458 } /* fmt_to_str */ |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
459 #endif |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
460 |
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
461 |
4 | 462 /* |
463 * The bulk of the Sound_NewSample() work is done here... | |
464 * Ask the specified decoder to handle the data in (rw), and if | |
465 * so, construct the Sound_Sample. Otherwise, try to wind (rw)'s stream | |
466 * back to where it was, and return false. | |
467 * | |
468 * !!! FIXME: This is big, ugly, nasty, and smelly. | |
469 */ | |
470 static int init_sample(const Sound_DecoderFunctions *funcs, | |
471 Sound_Sample *sample, const char *ext, | |
472 Sound_AudioInfo *_desired) | |
473 { | |
474 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
|
475 Sound_AudioInfo desired; |
4 | 476 int pos = SDL_RWtell(internal->rw); /* !!! FIXME: Int? Really? */ |
477 | |
478 /* fill in the funcs for this decoder... */ | |
479 sample->decoder = &funcs->info; | |
480 internal->funcs = funcs; | |
481 if (!funcs->open(sample, ext)) | |
482 { | |
483 SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */ | |
484 return(0); | |
485 } /* if */ | |
486 | |
487 /* success; we've got a decoder! */ | |
488 | |
489 /* Now we need to set up the conversion buffer... */ | |
490 | |
491 memcpy(&desired, (_desired != NULL) ? _desired : &sample->actual, | |
492 sizeof (Sound_AudioInfo)); | |
493 | |
143
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
494 if (Sound_BuildAudioCVT(&internal->sdlcvt, |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
495 sample->actual.format, |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
496 sample->actual.channels, |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
497 sample->actual.rate, |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
498 desired.format, |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
499 desired.channels, |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
500 desired.rate) == -1) |
4 | 501 { |
502 Sound_SetError(SDL_GetError()); | |
503 funcs->close(sample); | |
504 SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */ | |
505 return(0); | |
506 } /* if */ | |
507 | |
508 if (internal->sdlcvt.len_mult > 1) | |
509 { | |
510 void *rc = realloc(sample->buffer, | |
143
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
511 sample->buffer_size * internal->sdlcvt.len_mult); |
4 | 512 if (rc == NULL) |
513 { | |
514 funcs->close(sample); | |
515 SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */ | |
516 return(0); | |
517 } /* if */ | |
518 | |
519 sample->buffer = rc; | |
520 } /* if */ | |
521 | |
522 /* these pointers are all one and the same. */ | |
523 memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo)); | |
524 internal->sdlcvt.buf = internal->buffer = sample->buffer; | |
525 internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult; | |
526 internal->sdlcvt.len = internal->buffer_size; | |
527 | |
528 /* Prepend our new Sound_Sample to the samplesList... */ | |
529 if (samplesList != NULL) | |
530 { | |
531 internal->next = samplesList; | |
532 if (samplesList != NULL) | |
533 internal->prev = sample; | |
534 } /* if */ | |
535 samplesList = sample; | |
536 | |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
537 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
|
538 fmt_to_str(sample->desired.format), |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
539 sample->desired.rate, |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
540 sample->desired.channels)); |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
541 |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
542 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
|
543 fmt_to_str(sample->actual.format), |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
544 sample->actual.rate, |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
545 sample->actual.channels)); |
10
cc2c32349380
Some debugging output, and MP3 and VOC entries, added.
Ryan C. Gordon <icculus@icculus.org>
parents:
4
diff
changeset
|
546 |
62
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
547 SNDDBG(("On-the-fly conversion: %s.\n", |
b13fafb976be
Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents:
48
diff
changeset
|
548 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
|
549 |
4 | 550 return(1); |
551 } /* init_sample */ | |
552 | |
553 | |
554 Sound_Sample *Sound_NewSample(SDL_RWops *rw, const char *ext, | |
555 Sound_AudioInfo *desired, Uint32 bSize) | |
556 { | |
557 Sound_Sample *retval; | |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
558 decoder_element *decoder; |
4 | 559 |
560 /* sanity checks. */ | |
561 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL); | |
562 BAIL_IF_MACRO(rw == NULL, ERR_INVALID_ARGUMENT, NULL); | |
563 | |
564 retval = alloc_sample(rw, desired, bSize); | |
565 if (!retval) | |
566 return(NULL); /* alloc_sample() sets error message... */ | |
567 | |
568 if (ext != NULL) | |
569 { | |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
570 for (decoder = &decoders[0]; decoder->funcs != NULL; decoder++) |
4 | 571 { |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
572 if (decoder->available) |
4 | 573 { |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
574 const char **decoderExt = decoder->funcs->info.extensions; |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
575 while (*decoderExt) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
576 { |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
577 if (__Sound_strcasecmp(*decoderExt, ext) == 0) |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
578 { |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
579 if (init_sample(decoder->funcs, retval, ext, desired)) |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
580 return(retval); |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
581 } /* if */ |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
582 decoderExt++; |
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
583 } /* while */ |
4 | 584 } /* if */ |
585 } /* for */ | |
586 } /* if */ | |
587 | |
588 /* no direct extension match? Try everything we've got... */ | |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
589 for (decoder = &decoders[0]; decoder->funcs != NULL; decoder++) |
4 | 590 { |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
591 if (decoder->available) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
592 { |
149
1df5c106504e
Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents:
143
diff
changeset
|
593 if (init_sample(decoder->funcs, retval, ext, desired)) |
48
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
594 return(retval); |
c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
Ryan C. Gordon <icculus@icculus.org>
parents:
37
diff
changeset
|
595 } /* if */ |
4 | 596 } /* for */ |
597 | |
598 /* nothing could handle the sound data... */ | |
599 free(retval->opaque); | |
600 if (retval->buffer != NULL) | |
601 free(retval->buffer); | |
602 free(retval); | |
603 SDL_RWclose(rw); | |
604 Sound_SetError(ERR_UNSUPPORTED_FORMAT); | |
605 return(NULL); | |
606 } /* Sound_NewSample */ | |
607 | |
608 | |
609 Sound_Sample *Sound_NewSampleFromFile(const char *filename, | |
610 Sound_AudioInfo *desired, | |
611 Uint32 bufferSize) | |
612 { | |
613 const char *ext; | |
614 SDL_RWops *rw; | |
615 | |
616 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL); | |
617 BAIL_IF_MACRO(filename == NULL, ERR_INVALID_ARGUMENT, NULL); | |
618 | |
619 ext = strrchr(filename, '.'); | |
620 rw = SDL_RWFromFile(filename, "rb"); | |
621 BAIL_IF_MACRO(rw == NULL, SDL_GetError(), NULL); | |
622 | |
623 if (ext != NULL) | |
624 ext++; | |
625 | |
626 return(Sound_NewSample(rw, ext, desired, bufferSize)); | |
627 } /* Sound_NewSampleFromFile */ | |
628 | |
629 | |
630 void Sound_FreeSample(Sound_Sample *sample) | |
631 { | |
632 Sound_SampleInternal *internal; | |
633 | |
634 if (!initialized) | |
635 { | |
636 Sound_SetError(ERR_NOT_INITIALIZED); | |
637 return; | |
638 } /* if */ | |
639 | |
640 if (sample == NULL) | |
641 { | |
642 Sound_SetError(ERR_INVALID_ARGUMENT); | |
643 return; | |
644 } /* if */ | |
645 | |
646 internal = (Sound_SampleInternal *) sample->opaque; | |
647 | |
648 internal->funcs->close(sample); | |
649 | |
650 /* update the samplesList... */ | |
651 if (internal->prev != NULL) | |
652 { | |
653 Sound_SampleInternal *prevInternal; | |
654 prevInternal = (Sound_SampleInternal *) internal->prev->opaque; | |
655 prevInternal->next = internal->next; | |
656 } /* if */ | |
657 else | |
658 { | |
659 assert(samplesList == sample); | |
660 samplesList = internal->next; | |
661 } /* else */ | |
662 | |
663 if (internal->next != NULL) | |
664 { | |
665 Sound_SampleInternal *nextInternal; | |
666 nextInternal = (Sound_SampleInternal *) internal->next->opaque; | |
667 nextInternal->prev = internal->prev; | |
668 } /* if */ | |
669 | |
670 /* nuke it... */ | |
671 if (internal->rw != NULL) /* this condition is a "just in case" thing. */ | |
672 SDL_RWclose(internal->rw); | |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
673 |
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
674 if ((internal->buffer != NULL) && (internal->buffer != sample->buffer)) |
4 | 675 free(internal->buffer); |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
676 |
4 | 677 free(internal); |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
678 |
4 | 679 if (sample->buffer != NULL) |
680 free(sample->buffer); | |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
681 |
4 | 682 free(sample); |
683 } /* Sound_FreeSample */ | |
684 | |
685 | |
686 int Sound_SetBufferSize(Sound_Sample *sample, Uint32 newSize) | |
687 { | |
688 void *newBuf = NULL; | |
689 Sound_SampleInternal *internal = NULL; | |
690 | |
691 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | |
692 BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0); | |
693 internal = ((Sound_SampleInternal *) sample->opaque); | |
694 newBuf = realloc(sample->buffer, newSize * internal->sdlcvt.len_mult); | |
695 BAIL_IF_MACRO(newBuf == NULL, ERR_OUT_OF_MEMORY, 0); | |
696 | |
697 internal->sdlcvt.buf = internal->buffer = sample->buffer = newBuf; | |
698 sample->buffer_size = newSize; | |
699 internal->buffer_size = newSize / internal->sdlcvt.len_mult; | |
700 internal->sdlcvt.len = internal->buffer_size; | |
701 | |
702 return(1); | |
703 } /* Sound_SetBufferSize */ | |
704 | |
705 | |
706 Uint32 Sound_Decode(Sound_Sample *sample) | |
707 { | |
708 Sound_SampleInternal *internal = NULL; | |
709 Uint32 retval = 0; | |
710 | |
711 /* a boatload of sanity checks... */ | |
712 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | |
713 BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0); | |
714 BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_ERROR, ERR_PREV_ERROR, 0); | |
715 BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_EOF, ERR_PREV_EOF, 0); | |
716 | |
717 internal = (Sound_SampleInternal *) sample->opaque; | |
718 | |
719 assert(sample->buffer != NULL); | |
720 assert(sample->buffer_size > 0); | |
721 assert(internal->buffer != NULL); | |
722 assert(internal->buffer_size > 0); | |
723 | |
724 /* reset EAGAIN. Decoder can flip it back on if it needs to. */ | |
725 sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; | |
726 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
|
727 |
163
b6d6f994e970
Moved MIDI decoder to end of array. Fixed Sound_SetError() so that it
Ryan C. Gordon <icculus@icculus.org>
parents:
157
diff
changeset
|
728 if (retval > 0 && internal->sdlcvt.needed) |
4 | 729 { |
730 internal->sdlcvt.len = retval; | |
143
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
731 Sound_ConvertAudio(&internal->sdlcvt); |
3e60862fbd76
Start of audio converter work.
Ryan C. Gordon <icculus@icculus.org>
parents:
118
diff
changeset
|
732 retval = internal->sdlcvt.len_cvt; |
4 | 733 } /* if */ |
734 | |
735 return(retval); | |
736 } /* Sound_Decode */ | |
737 | |
738 | |
739 Uint32 Sound_DecodeAll(Sound_Sample *sample) | |
740 { | |
741 Sound_SampleInternal *internal = NULL; | |
742 void *buf = NULL; | |
743 Uint32 newBufSize = 0; | |
744 | |
745 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | |
172
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
746 BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_EOF, ERR_PREV_EOF, 0); |
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
747 BAIL_IF_MACRO(sample->flags & SOUND_SAMPLEFLAG_ERROR, ERR_PREV_ERROR, 0); |
4 | 748 |
749 internal = (Sound_SampleInternal *) sample->opaque; | |
750 | |
751 while ( ((sample->flags & SOUND_SAMPLEFLAG_EOF) == 0) && | |
752 ((sample->flags & SOUND_SAMPLEFLAG_ERROR) == 0) ) | |
753 { | |
172
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
754 Uint32 br = Sound_Decode(sample); |
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
755 void *ptr = realloc(buf, newBufSize + br); |
4 | 756 if (ptr == NULL) |
757 { | |
758 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
759 Sound_SetError(ERR_OUT_OF_MEMORY); | |
760 } /* if */ | |
761 else | |
762 { | |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
763 buf = ptr; |
4 | 764 memcpy( ((char *) buf) + newBufSize, sample->buffer, br ); |
765 newBufSize += br; | |
766 } /* else */ | |
767 } /* while */ | |
768 | |
172
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
769 if (buf == NULL) /* ...in case first call to realloc() fails... */ |
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
770 return(sample->buffer_size); |
705dcbf94639
Sound_DecodeAll() is now more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
167
diff
changeset
|
771 |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
772 if (internal->buffer != sample->buffer) |
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
773 free(internal->buffer); |
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
774 |
4 | 775 free(sample->buffer); |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
776 |
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
777 internal->sdlcvt.buf = internal->buffer = sample->buffer = buf; |
4 | 778 sample->buffer_size = newBufSize; |
779 internal->buffer_size = newBufSize / internal->sdlcvt.len_mult; | |
167
82acaa7107c2
Fixed Sound_DecodeAll(), and made Sound_FreeSample() a little more robust.
Ryan C. Gordon <icculus@icculus.org>
parents:
165
diff
changeset
|
780 internal->sdlcvt.len = internal->buffer_size; |
4 | 781 |
782 return(newBufSize); | |
783 } /* Sound_DecodeAll */ | |
784 | |
223
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
785 |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
786 int Sound_Rewind(Sound_Sample *sample) |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
787 { |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
788 Sound_SampleInternal *internal; |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
789 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
790 |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
791 internal = (Sound_SampleInternal *) sample->opaque; |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
792 if (!internal->funcs->rewind(sample)) |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
793 { |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
794 sample->flags |= SOUND_SAMPLEFLAG_ERROR; |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
795 return(0); |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
796 } /* if */ |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
797 |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
798 sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
799 sample->flags &= !SOUND_SAMPLEFLAG_ERROR; |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
800 sample->flags &= !SOUND_SAMPLEFLAG_EOF; |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
801 return(1); |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
802 } /* Sound_Rewind */ |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
803 |
249186e31431
Sound_Rewind() support code.
Ryan C. Gordon <icculus@icculus.org>
parents:
219
diff
changeset
|
804 |
4 | 805 /* end of SDL_sound.c ... */ |
806 |