Mercurial > SDL_sound_CoreAudio
annotate decoders/mpglib.c @ 561:f2985e08589c
Fixed spacing on Speex --help text in configure script.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 30 Jan 2009 01:54:03 -0500 |
parents | 2e8907ff98e9 |
children |
rev | line source |
---|---|
261 | 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 * MPGLIB decoder for SDL_sound. This is a very lightweight MP3 decoder, | |
22 * which is included with the SDL_sound source, so that it doesn't rely on | |
23 * unnecessary external libraries. | |
24 * | |
25 * The SMPEG decoder plays back more forms of MPEGs, and may behave better or | |
26 * worse under various conditions. mpglib is (apparently) more efficient than | |
27 * SMPEG, and, again, doesn't need an external library. You should test both | |
28 * decoders and use what you find works best for you. | |
29 * | |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
30 * mpglib is an LGPL'd portion of mpg123, which can be found in its original |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
31 * form at: http://www.mpg123.de/ |
261 | 32 * |
552
2e8907ff98e9
Replaced references to COPYING with references to LICENSE.txt ...
Ryan C. Gordon <icculus@icculus.org>
parents:
526
diff
changeset
|
33 * Please see the file LICENSE.txt in the source's root directory. The included |
261 | 34 * source code for mpglib falls under the LGPL, which is the same license as |
35 * SDL_sound (so you can consider it a single work). | |
36 * | |
526
2df1f5c62d38
Updated my email address.
Ryan C. Gordon <icculus@icculus.org>
parents:
513
diff
changeset
|
37 * This file written by Ryan C. Gordon. (icculus@icculus.org) |
261 | 38 */ |
39 | |
40 #if HAVE_CONFIG_H | |
41 # include <config.h> | |
42 #endif | |
43 | |
44 #ifdef SOUND_SUPPORTS_MPGLIB | |
45 | |
46 #include <stdio.h> | |
47 #include <stdlib.h> | |
48 #include <string.h> | |
49 #include "mpglib/mpg123_sdlsound.h" | |
50 #include "mpglib/mpglib_sdlsound.h" | |
51 | |
52 #include "SDL_sound.h" | |
53 | |
54 #define __SDL_SOUND_INTERNAL__ | |
55 #include "SDL_sound_internal.h" | |
56 | |
57 static int MPGLIB_init(void); | |
58 static void MPGLIB_quit(void); | |
59 static int MPGLIB_open(Sound_Sample *sample, const char *ext); | |
60 static void MPGLIB_close(Sound_Sample *sample); | |
61 static Uint32 MPGLIB_read(Sound_Sample *sample); | |
62 static int MPGLIB_rewind(Sound_Sample *sample); | |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
63 static int MPGLIB_seek(Sound_Sample *sample, Uint32 ms); |
261 | 64 |
65 static const char *extensions_mpglib[] = { "MP3", NULL }; | |
66 const Sound_DecoderFunctions __Sound_DecoderFunctions_MPGLIB = | |
67 { | |
68 { | |
69 extensions_mpglib, | |
70 "MP3 decoding via internal mpglib", | |
526
2df1f5c62d38
Updated my email address.
Ryan C. Gordon <icculus@icculus.org>
parents:
513
diff
changeset
|
71 "Ryan C. Gordon <icculus@icculus.org>", |
261 | 72 "http://www.icculus.org/SDL_sound/" |
73 }, | |
74 | |
75 MPGLIB_init, /* init() method */ | |
76 MPGLIB_quit, /* quit() method */ | |
77 MPGLIB_open, /* open() method */ | |
78 MPGLIB_close, /* close() method */ | |
79 MPGLIB_read, /* read() method */ | |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
80 MPGLIB_rewind, /* rewind() method */ |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
81 MPGLIB_seek /* seek() method */ |
261 | 82 }; |
83 | |
84 | |
85 /* this is what we store in our internal->decoder_private field... */ | |
86 typedef struct | |
87 { | |
88 struct mpstr mp; | |
89 Uint8 inbuf[16384]; | |
90 Uint8 outbuf[8192]; | |
91 int outleft; | |
92 int outpos; | |
93 } mpglib_t; | |
94 | |
95 | |
96 | |
97 static int MPGLIB_init(void) | |
98 { | |
99 return(1); /* always succeeds. */ | |
100 } /* MPGLIB_init */ | |
101 | |
102 | |
103 static void MPGLIB_quit(void) | |
104 { | |
105 /* it's a no-op. */ | |
106 } /* MPGLIB_quit */ | |
107 | |
108 | |
109 static int MPGLIB_open(Sound_Sample *sample, const char *ext) | |
110 { | |
111 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
112 mpglib_t *mpg = NULL; | |
293
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
113 int rc; |
261 | 114 |
115 /* | |
116 * If I understand things correctly, MP3 files don't really have any | |
117 * magic header we can check for. The MP3 player is expected to just | |
118 * pick the first thing that looks like a valid frame and start | |
119 * playing from there. | |
120 * | |
121 * So here's what we do: If the caller insists that this is really | |
122 * MP3 we'll take his word for it. Otherwise, use the same test as | |
123 * SDL_mixer does and check if the stream starts with something that | |
124 * looks like a frame. | |
125 * | |
126 * A frame begins with 11 bits of frame sync (all bits must be set), | |
127 * followed by a two-bit MPEG Audio version ID: | |
128 * | |
129 * 00 - MPEG Version 2.5 (later extension of MPEG 2) | |
130 * 01 - reserved | |
131 * 10 - MPEG Version 2 (ISO/IEC 13818-3) | |
132 * 11 - MPEG Version 1 (ISO/IEC 11172-3) | |
133 * | |
134 * Apparently we don't handle MPEG Version 2.5. | |
135 */ | |
136 if (__Sound_strcasecmp(ext, "MP3") != 0) | |
137 { | |
138 Uint8 mp3_magic[2]; | |
139 | |
140 if (SDL_RWread(internal->rw, mp3_magic, sizeof (mp3_magic), 1) != 1) | |
358
f11c10ffa31a
Fixed some debug messages.
Ryan C. Gordon <icculus@icculus.org>
parents:
351
diff
changeset
|
141 BAIL_MACRO("MPGLIB: Could not read MP3 magic.", 0); |
261 | 142 |
143 if (mp3_magic[0] != 0xFF || (mp3_magic[1] & 0xF0) != 0xF0) | |
358
f11c10ffa31a
Fixed some debug messages.
Ryan C. Gordon <icculus@icculus.org>
parents:
351
diff
changeset
|
144 BAIL_MACRO("MPGLIB: Not an MP3 stream.", 0); |
261 | 145 |
351 | 146 /* If the seek fails, we'll probably miss a frame, but oh well. */ |
261 | 147 SDL_RWseek(internal->rw, -sizeof (mp3_magic), SEEK_CUR); |
148 } /* if */ | |
149 | |
150 mpg = (mpglib_t *) malloc(sizeof (mpglib_t)); | |
151 BAIL_IF_MACRO(mpg == NULL, ERR_OUT_OF_MEMORY, 0); | |
293
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
152 memset(mpg, '\0', sizeof (mpglib_t)); |
261 | 153 InitMP3(&mpg->mp); |
154 | |
293
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
155 rc = SDL_RWread(internal->rw, mpg->inbuf, 1, sizeof (mpg->inbuf)); |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
156 if (rc <= 0) |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
157 { |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
158 free(mpg); |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
159 BAIL_MACRO("MPGLIB: Failed to read any data at all", 0); |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
160 } /* if */ |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
161 |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
162 if (decodeMP3(&mpg->mp, mpg->inbuf, rc, |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
163 mpg->outbuf, sizeof (mpg->outbuf), |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
164 &mpg->outleft) == MP3_ERR) |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
165 { |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
166 free(mpg); |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
167 BAIL_MACRO("MPGLIB: Not an MP3 stream?", 0); |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
168 } /* if */ |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
169 |
261 | 170 SNDDBG(("MPGLIB: Accepting data stream.\n")); |
171 | |
172 internal->decoder_private = mpg; | |
293
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
173 sample->actual.rate = mpglib_freqs[mpg->mp.fr.sampling_frequency]; |
ee6e1f8bfae9
Can determine audio format correctly (mostly correctly?) now. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents:
271
diff
changeset
|
174 sample->actual.channels = mpg->mp.fr.stereo; |
351 | 175 sample->actual.format = AUDIO_S16SYS; |
261 | 176 sample->flags = SOUND_SAMPLEFLAG_NONE; |
177 | |
474
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
178 { |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
179 /* Finds approximate length of the song. */ |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
180 Uint32 pos, total_byte_size; |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
181 char tag_buffer[4]; |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
182 memset(tag_buffer, '\0', sizeof(tag_buffer)); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
183 |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
184 /* Get size of file first */ |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
185 pos = SDL_RWtell(internal->rw); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
186 total_byte_size = SDL_RWseek(internal->rw, -128, SEEK_END); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
187 if( total_byte_size <= 0 ) { |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
188 BAIL_MACRO("MPGLIB: Not an MP3 stream.", 0); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
189 } |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
190 if ( SDL_RWread(internal->rw, tag_buffer, 1, 3) != 3) { |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
191 BAIL_MACRO("MPGLIB: Cannot identify TAG section.", 0); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
192 } |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
193 if ( strncmp(tag_buffer, "TAG", 3) != 0 ) { |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
194 /* ENDING TAG NOT FOUND */ |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
195 total_byte_size = SDL_RWseek(internal->rw,0, SEEK_END); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
196 } |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
197 if (SDL_RWseek(internal->rw, pos, SEEK_SET) != pos) { |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
198 BAIL_MACRO("MPGLIB: Cannot go back to save spot in file.", 0); |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
199 } |
477
3e705c9180e5
Fixed binary compatibility, added Sound_GetDuration().
Ryan C. Gordon <icculus@icculus.org>
parents:
474
diff
changeset
|
200 internal->total_time = total_byte_size / mpg->mp.fr.bitrate * 8.0; |
3e705c9180e5
Fixed binary compatibility, added Sound_GetDuration().
Ryan C. Gordon <icculus@icculus.org>
parents:
474
diff
changeset
|
201 internal->total_time += (total_byte_size % mpg->mp.fr.bitrate) * 8.0 |
474
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
202 / mpg->mp.fr.bitrate; |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
203 } |
c66080364dff
Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents:
377
diff
changeset
|
204 |
261 | 205 return(1); /* we'll handle this data. */ |
206 } /* MPGLIB_open */ | |
207 | |
208 | |
209 static void MPGLIB_close(Sound_Sample *sample) | |
210 { | |
211 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
212 mpglib_t *mpg = ((mpglib_t *) internal->decoder_private); | |
213 ExitMP3(&mpg->mp); | |
214 free(mpg); | |
215 } /* MPGLIB_close */ | |
216 | |
217 | |
218 static Uint32 MPGLIB_read(Sound_Sample *sample) | |
219 { | |
220 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
221 mpglib_t *mpg = ((mpglib_t *) internal->decoder_private); | |
222 Uint32 bw = 0; | |
223 int rc; | |
224 | |
225 while (bw < internal->buffer_size) | |
226 { | |
227 if (mpg->outleft > 0) | |
228 { | |
513
006e3d6cd2fe
Patch to get mpglib going again, from Sam.
Ryan C. Gordon <icculus@icculus.org>
parents:
477
diff
changeset
|
229 size_t cpysize = internal->buffer_size - bw; |
261 | 230 if (cpysize > mpg->outleft) |
231 cpysize = mpg->outleft; | |
232 memcpy(((Uint8 *) internal->buffer) + bw, | |
233 mpg->outbuf + mpg->outpos, cpysize); | |
234 bw += cpysize; | |
235 mpg->outpos += cpysize; | |
236 mpg->outleft -= cpysize; | |
237 continue; | |
238 } /* if */ | |
239 | |
240 /* need to decode more from the MP3 stream... */ | |
241 mpg->outpos = 0; | |
242 rc = decodeMP3(&mpg->mp, NULL, 0, mpg->outbuf, | |
243 sizeof (mpg->outbuf), &mpg->outleft); | |
244 if (rc == MP3_ERR) | |
245 { | |
246 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
247 return(bw); | |
248 } /* if */ | |
249 | |
250 else if (rc == MP3_NEED_MORE) | |
251 { | |
252 rc = SDL_RWread(internal->rw, mpg->inbuf, 1, sizeof (mpg->inbuf)); | |
253 if (rc == -1) | |
254 { | |
255 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
256 return(bw); | |
257 } /* if */ | |
268
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
258 |
261 | 259 else if (rc == 0) |
260 { | |
261 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
262 return(bw); | |
263 } /* else if */ | |
264 | |
268
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
265 /* make sure there isn't an ID3 tag. */ |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
266 /* |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
267 * !!! FIXME: This can fail under the following circumstances: |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
268 * First, if there's the sequence "TAG" 128 bytes from the end |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
269 * of a read that isn't the EOF. This is unlikely. |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
270 * Second, if the TAG sequence is split between two reads (ie, |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
271 * the last byte of a read is 'T', and the next read is the |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
272 * final 127 bytes of the stream, being the rest of the ID3 tag). |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
273 * While this is more likely, it's still not very likely at all. |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
274 * Still, something SHOULD be done about this. |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
275 * ID3v2 tags are more complex, too, not to mention LYRICS tags, |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
276 * etc, which aren't handled, either. Hey, this IS meant to be |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
277 * a lightweight decoder. Use SMPEG if you need an all-purpose |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
278 * decoder. mpglib really assumes you control all your assets. |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
279 */ |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
280 if (rc >= 128) |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
281 { |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
282 Uint8 *ptr = &mpg->inbuf[rc - 128]; |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
283 if ((ptr[0] == 'T') && (ptr[1] == 'A') && (ptr[2] == 'G')) |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
284 rc -= 128; /* disregard it. */ |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
285 } /* if */ |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
286 |
263 | 287 rc = decodeMP3(&mpg->mp, mpg->inbuf, rc, |
268
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
288 mpg->outbuf, sizeof (mpg->outbuf), |
9b89bb587f8f
Detect and discard ID3 tags.
Ryan C. Gordon <icculus@icculus.org>
parents:
263
diff
changeset
|
289 &mpg->outleft); |
261 | 290 if (rc == MP3_ERR) |
291 { | |
292 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
293 return(bw); | |
294 } /* if */ | |
295 } /* else if */ | |
296 } /* while */ | |
297 | |
298 return(bw); | |
299 } /* MPGLIB_read */ | |
300 | |
301 | |
302 static int MPGLIB_rewind(Sound_Sample *sample) | |
303 { | |
304 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
305 mpglib_t *mpg = ((mpglib_t *) internal->decoder_private); | |
306 BAIL_IF_MACRO(SDL_RWseek(internal->rw, 0, SEEK_SET) != 0, ERR_IO_ERROR, 0); | |
307 | |
308 /* this is just resetting some fields in a structure; it's very fast. */ | |
309 ExitMP3(&mpg->mp); | |
310 InitMP3(&mpg->mp); | |
311 mpg->outpos = mpg->outleft = 0; | |
312 return(1); | |
313 } /* MPGLIB_rewind */ | |
314 | |
315 | |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
316 static int MPGLIB_seek(Sound_Sample *sample, Uint32 ms) |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
317 { |
351 | 318 BAIL_MACRO("MPGLIB: Seeking not implemented", 0); |
306
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
319 } /* MPGLIB_seek */ |
c97be6e1bd27
Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents:
293
diff
changeset
|
320 |
261 | 321 #endif /* SOUND_SUPPORTS_MPGLIB */ |
322 | |
323 | |
324 /* end of mpglib.c ... */ | |
325 |