Mercurial > SDL_sound_CoreAudio
annotate decoders/au.c @ 562:7e08477b0fc1
MP3 decoder upgrade work.
Ripped out SMPEG and mpglib support, replaced it with "mpg123.c" and libmpg123.
libmpg123 is a much better version of mpglib, so it should solve all the
problems about MP3's not seeking, or most modern MP3's not playing at all,
etc. Since you no longer have to make a tradeoff with SMPEG for features, and
SMPEG is basically rotting, I removed it from the project.
There is still work to be done with libmpg123...there are MMX, 3DNow, SSE,
Altivec, etc decoders which we don't have enabled at the moment, and the
build system could use some work to make this compile more cleanly, etc.
Still: huge win.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 30 Jan 2009 02:44:47 -0500 |
parents | 2e8907ff98e9 |
children |
rev | line source |
---|---|
213 | 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 * Sun/NeXT .au decoder for SDL_sound. | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
22 * Formats supported: 8 and 16 bit linear PCM, 8 bit µ-law. |
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
23 * Files without valid header are assumed to be 8 bit µ-law, 8kHz, mono. |
213 | 24 * |
552
2e8907ff98e9
Replaced references to COPYING with references to LICENSE.txt ...
Ryan C. Gordon <icculus@icculus.org>
parents:
536
diff
changeset
|
25 * Please see the file LICENSE.txt in the source's root directory. |
213 | 26 * |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
27 * This file written by Mattias Engdegård. (f91-men@nada.kth.se) |
213 | 28 */ |
29 | |
30 #if HAVE_CONFIG_H | |
31 # include <config.h> | |
32 #endif | |
33 | |
34 #ifdef SOUND_SUPPORTS_AU | |
35 | |
36 #include <stdio.h> | |
37 #include <stdlib.h> | |
38 #include <string.h> | |
39 | |
40 #include "SDL_sound.h" | |
41 | |
42 #define __SDL_SOUND_INTERNAL__ | |
43 #include "SDL_sound_internal.h" | |
44 | |
45 static int AU_init(void); | |
46 static void AU_quit(void); | |
47 static int AU_open(Sound_Sample *sample, const char *ext); | |
48 static void AU_close(Sound_Sample *sample); | |
49 static Uint32 AU_read(Sound_Sample *sample); | |
221
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
50 static int AU_rewind(Sound_Sample *sample); |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
51 static int AU_seek(Sound_Sample *sample, Uint32 ms); |
213 | 52 |
53 /* | |
54 * Sometimes the extension ".snd" is used for these files (mostly on the NeXT), | |
55 * and the magic number comes from this. However it may clash with other | |
56 * formats and is somewhat of an anachronism, so only .au is used here. | |
57 */ | |
58 static const char *extensions_au[] = { "AU", NULL }; | |
59 const Sound_DecoderFunctions __Sound_DecoderFunctions_AU = | |
60 { | |
61 { | |
62 extensions_au, | |
63 "Sun/NeXT audio file format", | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
64 "Mattias Engdegård <f91-men@nada.kth.se>", |
213 | 65 "http://www.icculus.org/SDL_sound/" |
66 }, | |
67 | |
221
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
68 AU_init, /* init() method */ |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
69 AU_quit, /* quit() method */ |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
70 AU_open, /* open() method */ |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
71 AU_close, /* close() method */ |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
72 AU_read, /* read() method */ |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
73 AU_rewind, /* rewind() method */ |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
74 AU_seek /* seek() method */ |
213 | 75 }; |
76 | |
77 /* no init/deinit needed */ | |
78 static int AU_init(void) | |
79 { | |
80 return(1); | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
81 } /* AU_init */ |
213 | 82 |
83 static void AU_quit(void) | |
84 { | |
85 /* no-op. */ | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
86 } /* AU_quit */ |
213 | 87 |
88 struct au_file_hdr | |
89 { | |
90 Uint32 magic; | |
91 Uint32 hdr_size; | |
92 Uint32 data_size; | |
93 Uint32 encoding; | |
94 Uint32 sample_rate; | |
95 Uint32 channels; | |
96 }; | |
97 | |
98 #define HDR_SIZE 24 | |
99 | |
100 enum | |
101 { | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
102 AU_ENC_ULAW_8 = 1, /* 8-bit ISDN µ-law */ |
213 | 103 AU_ENC_LINEAR_8 = 2, /* 8-bit linear PCM */ |
104 AU_ENC_LINEAR_16 = 3, /* 16-bit linear PCM */ | |
105 | |
106 /* the rest are unsupported (I have never seen them in the wild) */ | |
107 AU_ENC_LINEAR_24 = 4, /* 24-bit linear PCM */ | |
108 AU_ENC_LINEAR_32 = 5, /* 32-bit linear PCM */ | |
109 AU_ENC_FLOAT = 6, /* 32-bit IEEE floating point */ | |
110 AU_ENC_DOUBLE = 7, /* 64-bit IEEE floating point */ | |
111 /* more Sun formats, not supported either */ | |
112 AU_ENC_ADPCM_G721 = 23, | |
113 AU_ENC_ADPCM_G722 = 24, | |
114 AU_ENC_ADPCM_G723_3 = 25, | |
115 AU_ENC_ADPCM_G723_5 = 26, | |
116 AU_ENC_ALAW_8 = 27 | |
117 }; | |
118 | |
119 struct audec | |
120 { | |
221
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
121 Uint32 total; |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
122 Uint32 remaining; |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
123 Uint32 start_offset; |
213 | 124 int encoding; |
125 }; | |
126 | |
127 | |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
128 /* |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
129 * Read in the AU header from disk. This makes this process safe |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
130 * regardless of the processor's byte order or how the au_file_hdr |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
131 * structure is packed. |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
132 */ |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
133 static int read_au_header(SDL_RWops *rw, struct au_file_hdr *hdr) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
134 { |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
135 if (SDL_RWread(rw, &hdr->magic, sizeof (hdr->magic), 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
136 return(0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
137 hdr->magic = SDL_SwapBE32(hdr->magic); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
138 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
139 if (SDL_RWread(rw, &hdr->hdr_size, sizeof (hdr->hdr_size), 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
140 return(0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
141 hdr->hdr_size = SDL_SwapBE32(hdr->hdr_size); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
142 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
143 if (SDL_RWread(rw, &hdr->data_size, sizeof (hdr->data_size), 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
144 return(0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
145 hdr->data_size = SDL_SwapBE32(hdr->data_size); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
146 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
147 if (SDL_RWread(rw, &hdr->encoding, sizeof (hdr->encoding), 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
148 return(0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
149 hdr->encoding = SDL_SwapBE32(hdr->encoding); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
150 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
151 if (SDL_RWread(rw, &hdr->sample_rate, sizeof (hdr->sample_rate), 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
152 return(0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
153 hdr->sample_rate = SDL_SwapBE32(hdr->sample_rate); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
154 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
155 if (SDL_RWread(rw, &hdr->channels, sizeof (hdr->channels), 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
156 return(0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
157 hdr->channels = SDL_SwapBE32(hdr->channels); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
158 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
159 return(1); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
160 } /* read_au_header */ |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
161 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
162 |
257
7c4f6ee02cd0
Changed magic number to be bigendian.
Ryan C. Gordon <icculus@icculus.org>
parents:
221
diff
changeset
|
163 #define AU_MAGIC 0x2E736E64 /* ".snd", in ASCII (bigendian number) */ |
213 | 164 |
165 static int AU_open(Sound_Sample *sample, const char *ext) | |
166 { | |
167 Sound_SampleInternal *internal = sample->opaque; | |
168 SDL_RWops *rw = internal->rw; | |
474
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
169 int skip, hsize, i, bytes_per_second; |
213 | 170 struct au_file_hdr hdr; |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
171 struct audec *dec; |
213 | 172 char c; |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
173 |
387
fb519e6028e3
Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
174 /* read_au_header() will do byte order swapping. */ |
fb519e6028e3
Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
175 BAIL_IF_MACRO(!read_au_header(rw, &hdr), "AU: bad header", 0); |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
176 |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
177 dec = malloc(sizeof *dec); |
213 | 178 BAIL_IF_MACRO(dec == NULL, ERR_OUT_OF_MEMORY, 0); |
179 internal->decoder_private = dec; | |
180 | |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
181 if (hdr.magic == AU_MAGIC) |
213 | 182 { |
183 /* valid magic */ | |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
184 dec->encoding = hdr.encoding; |
213 | 185 switch(dec->encoding) |
186 { | |
187 case AU_ENC_ULAW_8: | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
188 /* Convert 8-bit µ-law to 16-bit linear on the fly. This is |
213 | 189 slightly wasteful if the audio driver must convert them |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
190 back, but µ-law only devices are rare (mostly _old_ Suns) */ |
213 | 191 sample->actual.format = AUDIO_S16SYS; |
192 break; | |
193 | |
194 case AU_ENC_LINEAR_8: | |
195 sample->actual.format = AUDIO_S8; | |
196 break; | |
197 | |
198 case AU_ENC_LINEAR_16: | |
199 sample->actual.format = AUDIO_S16MSB; | |
200 break; | |
201 | |
202 default: | |
203 free(dec); | |
387
fb519e6028e3
Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
204 BAIL_MACRO("AU: Unsupported .au encoding", 0); |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
205 } /* switch */ |
213 | 206 |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
207 sample->actual.rate = hdr.sample_rate; |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
208 sample->actual.channels = hdr.channels; |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
209 dec->remaining = hdr.data_size; |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
210 hsize = hdr.hdr_size; |
213 | 211 |
212 /* skip remaining part of header (input may be unseekable) */ | |
213 for (i = HDR_SIZE; i < hsize; i++) | |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
214 { |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
215 if (SDL_RWread(rw, &c, 1, 1) != 1) |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
216 { |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
217 free(dec); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
218 BAIL_MACRO(ERR_IO_ERROR, 0); |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
219 } /* if */ |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
220 } /* for */ |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
221 } /* if */ |
213 | 222 |
223 else if (__Sound_strcasecmp(ext, "au") == 0) | |
224 { | |
225 /* | |
226 * A number of files in the wild have the .au extension but no valid | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
227 * header; these are traditionally assumed to be 8kHz µ-law. Handle |
213 | 228 * them here only if the extension is recognized. |
229 */ | |
230 | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
231 SNDDBG(("AU: Invalid header, assuming raw 8kHz µ-law.\n")); |
213 | 232 /* if seeking fails, we lose 24 samples. big deal */ |
233 SDL_RWseek(rw, -HDR_SIZE, SEEK_CUR); | |
234 dec->encoding = AU_ENC_ULAW_8; | |
235 dec->remaining = (Uint32)-1; /* no limit */ | |
236 sample->actual.format = AUDIO_S16SYS; | |
237 sample->actual.rate = 8000; | |
238 sample->actual.channels = 1; | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
239 } /* else if */ |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
240 |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
241 else |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
242 { |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
243 free(dec); |
387
fb519e6028e3
Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
244 BAIL_MACRO("AU: Not an .AU stream.", 0); |
474
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
245 } /* else */ |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
246 |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
247 bytes_per_second = ( ( dec->encoding == AU_ENC_LINEAR_16 ) ? 2 : 1 ) |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
248 * sample->actual.rate * sample->actual.channels ; |
477
3e705c9180e5
Fixed binary compatibility, added Sound_GetDuration().
Ryan C. Gordon <icculus@icculus.org>
parents:
474
diff
changeset
|
249 internal->total_time = ((dec->remaining == -1) ? (-1) : |
3e705c9180e5
Fixed binary compatibility, added Sound_GetDuration().
Ryan C. Gordon <icculus@icculus.org>
parents:
474
diff
changeset
|
250 ( ( dec->remaining / bytes_per_second ) * 1000 ) + |
3e705c9180e5
Fixed binary compatibility, added Sound_GetDuration().
Ryan C. Gordon <icculus@icculus.org>
parents:
474
diff
changeset
|
251 ( ( dec->remaining % bytes_per_second ) * 1000 / |
3e705c9180e5
Fixed binary compatibility, added Sound_GetDuration().
Ryan C. Gordon <icculus@icculus.org>
parents:
474
diff
changeset
|
252 bytes_per_second ) ); |
213 | 253 |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
254 sample->flags = SOUND_SAMPLEFLAG_CANSEEK; |
221
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
255 dec->total = dec->remaining; |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
256 dec->start_offset = SDL_RWtell(rw); |
213 | 257 |
258 SNDDBG(("AU: Accepting data stream.\n")); | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
259 return(1); |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
260 } /* AU_open */ |
213 | 261 |
262 | |
263 static void AU_close(Sound_Sample *sample) | |
264 { | |
265 Sound_SampleInternal *internal = sample->opaque; | |
266 free(internal->decoder_private); | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
267 } /* AU_close */ |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
268 |
213 | 269 |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
270 /* table to convert from µ-law encoding to signed 16-bit samples, |
213 | 271 generated by a throwaway perl script */ |
272 static Sint16 ulaw_to_linear[256] = { | |
273 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, | |
274 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, | |
275 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, | |
276 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, | |
277 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, | |
278 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, | |
279 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, | |
280 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, | |
281 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, | |
282 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, | |
283 -876, -844, -812, -780, -748, -716, -684, -652, | |
284 -620, -588, -556, -524, -492, -460, -428, -396, | |
285 -372, -356, -340, -324, -308, -292, -276, -260, | |
286 -244, -228, -212, -196, -180, -164, -148, -132, | |
287 -120, -112, -104, -96, -88, -80, -72, -64, | |
288 -56, -48, -40, -32, -24, -16, -8, 0, | |
289 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, | |
290 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, | |
291 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, | |
292 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, | |
293 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, | |
294 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, | |
295 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, | |
296 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, | |
297 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, | |
298 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, | |
299 876, 844, 812, 780, 748, 716, 684, 652, | |
300 620, 588, 556, 524, 492, 460, 428, 396, | |
301 372, 356, 340, 324, 308, 292, 276, 260, | |
302 244, 228, 212, 196, 180, 164, 148, 132, | |
303 120, 112, 104, 96, 88, 80, 72, 64, | |
304 56, 48, 40, 32, 24, 16, 8, 0 | |
305 }; | |
306 | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
307 |
213 | 308 static Uint32 AU_read(Sound_Sample *sample) |
309 { | |
310 int ret; | |
311 Sound_SampleInternal *internal = sample->opaque; | |
312 struct audec *dec = internal->decoder_private; | |
313 int maxlen; | |
314 Uint8 *buf; | |
315 | |
316 maxlen = internal->buffer_size; | |
317 buf = internal->buffer; | |
318 if (dec->encoding == AU_ENC_ULAW_8) | |
319 { | |
536
8a814bbbedfa
Merged r544:545 from branches/stable-1.0: converted to UTF-8 encoding.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
320 /* We read µ-law samples into the second half of the buffer, so |
213 | 321 we can expand them to 16-bit samples afterwards */ |
322 maxlen >>= 1; | |
323 buf += maxlen; | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
324 } /* if */ |
213 | 325 |
221
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
326 if (maxlen > dec->remaining) |
213 | 327 maxlen = dec->remaining; |
328 ret = SDL_RWread(internal->rw, buf, 1, maxlen); | |
329 if (ret == 0) | |
330 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
331 else if (ret == -1) | |
332 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
333 else | |
334 { | |
335 dec->remaining -= ret; | |
336 if (ret < maxlen) | |
337 sample->flags |= SOUND_SAMPLEFLAG_EAGAIN; | |
338 | |
339 if (dec->encoding == AU_ENC_ULAW_8) | |
340 { | |
341 int i; | |
342 Sint16 *dst = internal->buffer; | |
343 for (i = 0; i < ret; i++) | |
344 dst[i] = ulaw_to_linear[buf[i]]; | |
345 ret <<= 1; /* return twice as much as read */ | |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
346 } /* if */ |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
347 } /* else */ |
213 | 348 |
217
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
349 return(ret); |
9bab949e2318
Fixed memory leak I introduced, mangled coding style some more. :)
Ryan C. Gordon <icculus@icculus.org>
parents:
213
diff
changeset
|
350 } /* AU_read */ |
213 | 351 |
221
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
352 |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
353 static int AU_rewind(Sound_Sample *sample) |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
354 { |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
355 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
356 struct audec *dec = (struct audec *) internal->decoder_private; |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
357 int rc = SDL_RWseek(internal->rw, dec->start_offset, SEEK_SET); |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
358 BAIL_IF_MACRO(rc != dec->start_offset, ERR_IO_ERROR, 0); |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
359 dec->remaining = dec->total; |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
360 return(1); |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
361 } /* AU_rewind */ |
c9772a9f5271
Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
217
diff
changeset
|
362 |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
363 |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
364 static int AU_seek(Sound_Sample *sample, Uint32 ms) |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
365 { |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
366 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
367 struct audec *dec = (struct audec *) internal->decoder_private; |
331
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
368 int offset = __Sound_convertMsToBytePos(&sample->actual, ms); |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
369 int rc; |
331
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
370 int pos; |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
371 |
331
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
372 if (dec->encoding == AU_ENC_ULAW_8) |
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
373 offset >>= 1; /* halve the byte offset for compression. */ |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
374 |
331
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
375 pos = (int) (dec->start_offset + offset); |
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
376 rc = SDL_RWseek(internal->rw, pos, SEEK_SET); |
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
377 BAIL_IF_MACRO(rc != pos, ERR_IO_ERROR, 0); |
e683cb99f88f
Fixed seek implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
330
diff
changeset
|
378 dec->remaining = dec->total - offset; |
330
a81976ed5df7
Cleanups for robustness, potentially buggy seek method implementation.
Ryan C. Gordon <icculus@icculus.org>
parents:
306
diff
changeset
|
379 return(1); |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
380 } /* AU_seek */ |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
294
diff
changeset
|
381 |
213 | 382 #endif /* SOUND_SUPPORTS_AU */ |
383 |