Mercurial > SDL_sound_CoreAudio
annotate decoders/au.c @ 474:c66080364dff
Most decoders now report total sample play time, now. Technically, this
breaks binary compatibility with the 1.0 branch, since it extends the
Sound_Sample struct, but most (all?) programs are just passing pointers
allocated by SDL_sound around, and might be okay.
Source-level compatibility is not broken...yet! :)
--ryan.
-------- Original Message --------
Subject: SDL_sound patch: Finding total length of time of sound file.
Date: Sun, 26 Jan 2003 09:31:17 -0800 (PST)
Hi Ryan,
I am working with Eric Wing and helping him modify
SDL_sound. AS part of our efforts in improving and
enhancing SDL_sound, we like to submit this patch. We
modified the codecs to find the total time of a sound
file. Below is the explanation of the patch. The
patch is appended as an attachment to this email.
* MOTIVATION:
We needed the ability to get the total play time of a
sample (And we noticed that we're not the only ones).
Since SDL_sound blocks direct access to the specific
decoders, there is no way for a user to know this
information short of decoding the whole thing.
Because of this, we believe this will be a useful
addition, even though the accuracy may not be perfect
(subject to each decoder) or the information may not
always be available.
* CONTRIBUTORS:
Wesley Leong (modified the majority of the codecs and
verified the results)
Eric Wing (showed everyone how to do modify codec,
modified mikmod)
Wang Lam (modified a handful of codecs, researched
into specs and int overflow)
Ahilan Anantha (modified a few codecs and helped with
integer math)
* GENERAL ISSUES:
We chose the value to be milliseconds as an Sint32.
Milliseconds because that's what Sound_Seek takes as a
parameter and -1 to allow for instances/codecs where
the value could not be determined. We are
not sure if this is the final convention you want, so
we are willing to work with you on this.
We also expect the total_time field to be set on open
and never again modified by SDL_sound. Users may
access it directly much like the sample buffer and
buffer_size. We thought about recomputing the time
on DecodeAll, but since users may seek or decode small
chunks first, not all the data may be there. So this
is better done by the user. This may be good
information to document.
Currently, all the main codecs are implemented except
for QuickTime.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 08 May 2004 08:19:50 +0000 |
parents | fb519e6028e3 |
children | 3e705c9180e5 |
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. | |
22 * Formats supported: 8 and 16 bit linear PCM, 8 bit µ-law. | |
23 * Files without valid header are assumed to be 8 bit µ-law, 8kHz, mono. | |
24 * | |
25 * Please see the file COPYING in the source's root directory. | |
26 * | |
27 * This file written by Mattias Engdegård. (f91-men@nada.kth.se) | |
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", | |
64 "Mattias Engdegård <f91-men@nada.kth.se>", | |
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 { | |
102 AU_ENC_ULAW_8 = 1, /* 8-bit ISDN µ-law */ | |
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: | |
188 /* Convert 8-bit µ-law to 16-bit linear on the fly. This is | |
189 slightly wasteful if the audio driver must convert them | |
190 back, but µ-law only devices are rare (mostly _old_ Suns) */ | |
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 | |
227 * header; these are traditionally assumed to be 8kHz µ-law. Handle | |
228 * them here only if the extension is recognized. | |
229 */ | |
230 | |
231 SNDDBG(("AU: Invalid header, assuming raw 8kHz µ-law.\n")); | |
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 ; |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
249 sample->total_time = ((dec->remaining == -1) ? (-1) : |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
250 ( ( dec->remaining / bytes_per_second ) * 1000 ) + |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
diff
changeset
|
251 ( ( dec->remaining % bytes_per_second ) * 1000 / |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
387
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 |
270 /* table to convert from µ-law encoding to signed 16-bit samples, | |
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 { | |
320 /* We read µ-law samples into the second half of the buffer, so | |
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 |