annotate decoders/flac.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 30f96c853462
children 3e705c9180e5
rev   line source
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 * SDL_sound -- An abstract sound format decoding API.
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3 * Copyright (C) 2001 Ryan C. Gordon.
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 *
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8 * version 2.1 of the License, or (at your option) any later version.
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 *
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 * Lesser General Public License for more details.
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 *
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 /*
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 * FLAC decoder for SDL_sound.
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 *
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23 * This driver handles FLAC audio, that is to say the Free Lossless Audio
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 * Codec. It depends on libFLAC for decoding, which can be grabbed from:
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 * http://flac.sourceforge.net
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 *
184
47cc2de2ae36 Changed reference to "LICENSE" file to "COPYING".
Ryan C. Gordon <icculus@icculus.org>
parents: 182
diff changeset
27 * Please see the file COPYING in the source's root directory.
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 *
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 * This file written by Torbjörn Andersson. (d91tan@Update.UU.SE)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32 #if HAVE_CONFIG_H
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33 # include <config.h>
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 #endif
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36 #ifdef SOUND_SUPPORTS_FLAC
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 #include <stdio.h>
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39 #include <stdlib.h>
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 #include <string.h>
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42 #include "SDL_sound.h"
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44 #define __SDL_SOUND_INTERNAL__
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 #include "SDL_sound_internal.h"
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46
443
30f96c853462 MacOS X build fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 422
diff changeset
47 #include <FLAC/seekable_stream_decoder.h>
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
48
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
49 #define D_END_OF_STREAM FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
50
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
51 #define d_new() FLAC__seekable_stream_decoder_new()
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
52 #define d_init(x) FLAC__seekable_stream_decoder_init(x)
422
5b06e23d934e Removed backwards compatible API nastiness from FLAC decoder.
Ryan C. Gordon <icculus@icculus.org>
parents: 400
diff changeset
53 #define d_process_metadata(x) FLAC__seekable_stream_decoder_process_until_end_of_metadata(x)
5b06e23d934e Removed backwards compatible API nastiness from FLAC decoder.
Ryan C. Gordon <icculus@icculus.org>
parents: 400
diff changeset
54 #define d_process_one_frame(x) FLAC__seekable_stream_decoder_process_single(x)
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
55 #define d_get_state(x) FLAC__seekable_stream_decoder_get_state(x)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
56 #define d_finish(x) FLAC__seekable_stream_decoder_finish(x)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
57 #define d_delete(x) FLAC__seekable_stream_decoder_delete(x)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
58 #define d_set_read_callback(x, y) FLAC__seekable_stream_decoder_set_read_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
59 #define d_set_write_callback(x, y) FLAC__seekable_stream_decoder_set_write_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
60 #define d_set_metadata_callback(x, y) FLAC__seekable_stream_decoder_set_metadata_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
61 #define d_set_error_callback(x, y) FLAC__seekable_stream_decoder_set_error_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
62 #define d_set_client_data(x, y) FLAC__seekable_stream_decoder_set_client_data(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
63
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
64 typedef FLAC__SeekableStreamDecoder decoder_t;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
65 typedef FLAC__SeekableStreamDecoderReadStatus d_read_status_t;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
66
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
67 #define D_SEEK_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
68 #define D_SEEK_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
69 #define D_TELL_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
70 #define D_TELL_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
71 #define D_LENGTH_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
72 #define D_LENGTH_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
73
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
74 #define d_set_seek_callback(x, y) FLAC__seekable_stream_decoder_set_seek_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
75 #define d_set_tell_callback(x, y) FLAC__seekable_stream_decoder_set_tell_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
76 #define d_set_length_callback(x, y) FLAC__seekable_stream_decoder_set_length_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
77 #define d_set_eof_callback(x, y) FLAC__seekable_stream_decoder_set_eof_callback(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
78 #define d_seek_absolute(x, y) FLAC__seekable_stream_decoder_seek_absolute(x, y)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
79
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
80 typedef FLAC__SeekableStreamDecoderSeekStatus d_seek_status_t;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
81 typedef FLAC__SeekableStreamDecoderTellStatus d_tell_status_t;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
82 typedef FLAC__SeekableStreamDecoderLengthStatus d_length_status_t;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
83
393
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
84 #define D_WRITE_CONTINUE FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
85 #define D_READ_END_OF_STREAM FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
86 #define D_READ_ABORT FLAC__STREAM_DECODER_READ_STATUS_ABORT
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
87 #define D_READ_CONTINUE FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
88
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
89 #define d_error_status_string FLAC__StreamDecoderErrorStatusString
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
90
393
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
91 typedef FLAC__StreamDecoderErrorStatus d_error_status_t;
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
92 typedef FLAC__StreamMetadata d_metadata_t;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
93 typedef FLAC__StreamDecoderWriteStatus d_write_status_t;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
94
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96 static int FLAC_init(void);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 static void FLAC_quit(void);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 static int FLAC_open(Sound_Sample *sample, const char *ext);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99 static void FLAC_close(Sound_Sample *sample);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100 static Uint32 FLAC_read(Sound_Sample *sample);
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
101 static int FLAC_rewind(Sound_Sample *sample);
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
102 static int FLAC_seek(Sound_Sample *sample, Uint32 ms);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 static const char *extensions_flac[] = { "FLAC", "FLA", NULL };
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106 const Sound_DecoderFunctions __Sound_DecoderFunctions_FLAC =
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 extensions_flac,
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 "Free Lossless Audio Codec",
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111 "Torbjörn Andersson <d91tan@Update.UU.SE>",
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 "http://flac.sourceforge.net/"
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113 },
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
114
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
115 FLAC_init, /* init() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
116 FLAC_quit, /* quit() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
117 FLAC_open, /* open() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
118 FLAC_close, /* close() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
119 FLAC_read, /* read() method */
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
120 FLAC_rewind, /* rewind() method */
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
121 FLAC_seek /* seek() method */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 };
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 /* This is what we store in our internal->decoder_private field. */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125 typedef struct
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 {
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
127 decoder_t *decoder;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128 SDL_RWops *rw;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129 Sound_Sample *sample;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130 Uint32 frame_size;
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
131 Uint8 is_flac;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
132 Uint32 stream_length;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
133 } flac_t;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
134
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
135
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
136 static void free_flac(flac_t *f)
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
137 {
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
138 d_finish(f->decoder);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
139 d_delete(f->decoder);
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
140 free(f);
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
141 } /* free_flac */
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
142
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
143
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
144 static d_read_status_t read_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
145 const decoder_t *decoder, FLAC__byte buffer[],
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
146 unsigned int *bytes, void *client_data)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
147 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
148 flac_t *f = (flac_t *) client_data;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
149 Uint32 retval;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
150
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
151 retval = SDL_RWread(f->rw, (Uint8 *) buffer, 1, *bytes);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
152
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
153 if (retval == 0)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
154 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
155 *bytes = 0;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
156 f->sample->flags |= SOUND_SAMPLEFLAG_EOF;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
157 return(D_READ_END_OF_STREAM);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
158 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
159
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
160 if (retval == -1)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
161 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
162 *bytes = 0;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
163 f->sample->flags |= SOUND_SAMPLEFLAG_ERROR;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
164 return(D_READ_ABORT);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
165 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
166
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
167 if (retval < *bytes)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
168 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
169 *bytes = retval;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
170 f->sample->flags |= SOUND_SAMPLEFLAG_EAGAIN;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
171 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
172
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
173 return(D_READ_CONTINUE);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
174 } /* read_callback */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
175
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
176
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
177 static d_write_status_t write_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
178 const decoder_t *decoder, const FLAC__Frame *frame,
393
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
179 const FLAC__int32 * const buffer[],
b12c4483815e Handles all versions of libFLAC up to version 1.0.3, now.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
180 void *client_data)
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
181 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
182 flac_t *f = (flac_t *) client_data;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
183 Uint32 i, j;
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
184 Uint32 sample;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
185 Uint8 *dst;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
186
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
187 f->frame_size = frame->header.channels * frame->header.blocksize
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
188 * frame->header.bits_per_sample / 8;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
189
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
190 if (f->frame_size > f->sample->buffer_size)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
191 Sound_SetBufferSize(f->sample, f->frame_size);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
192
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
193 dst = f->sample->buffer;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
194
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
195 /* If the sample is neither exactly 8-bit nor 16-bit, it will have to
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
196 * be converted. Unfortunately the buffer is read-only, so we either
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
197 * have to check for each sample, or make a copy of the buffer. I'm
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
198 * not sure which way is best, so I've arbitrarily picked the former.
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
199 */
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
200 if (f->sample->actual.format == AUDIO_S8)
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
201 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
202 for (i = 0; i < frame->header.blocksize; i++)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
203 for (j = 0; j < frame->header.channels; j++)
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
204 {
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
205 sample = buffer[j][i];
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
206 if (frame->header.bits_per_sample < 8)
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
207 sample <<= (8 - frame->header.bits_per_sample);
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
208 *dst++ = sample & 0x00ff;
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
209 } /* for */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
210 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
211 else
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
212 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
213 for (i = 0; i < frame->header.blocksize; i++)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
214 for (j = 0; j < frame->header.channels; j++)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
215 {
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
216 sample = buffer[j][i];
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
217 if (frame->header.bits_per_sample < 16)
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
218 sample <<= (16 - frame->header.bits_per_sample);
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
219 else if (frame->header.bits_per_sample > 16)
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
220 sample >>= (frame->header.bits_per_sample - 16);
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
221 *dst++ = (sample & 0xff00) >> 8;
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
222 *dst++ = sample & 0x00ff;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
223 } /* for */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
224 } /* else */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
225
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
226 return(D_WRITE_CONTINUE);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
227 } /* write_callback */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
228
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
229
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
230 static void metadata_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
231 const decoder_t *decoder,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
232 const d_metadata_t *metadata,
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
233 void *client_data)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
234 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
235 flac_t *f = (flac_t *) client_data;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
236
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
237 SNDDBG(("FLAC: Metadata callback.\n"));
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
238
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
239 /* There are several kinds of metadata, but STREAMINFO is the only
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
240 * one that always has to be there.
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
241 */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
242 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
243 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
244 SNDDBG(("FLAC: Metadata is streaminfo.\n"));
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
245
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
246 f->is_flac = 1;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
247 f->sample->actual.channels = metadata->data.stream_info.channels;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
248 f->sample->actual.rate = metadata->data.stream_info.sample_rate;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
249
474
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
250 if (metadata->data.stream_info.sample_rate == 0 ||
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
251 metadata->data.stream_info.total_samples == 0)
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
252 f->sample->total_time = -1;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
253 else {
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
254 f->sample->total_time = (metadata->data.stream_info.total_samples)
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
255 / metadata->data.stream_info.sample_rate * 1000;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
256 f->sample->total_time += (metadata->data.stream_info.total_samples
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
257 % metadata->data.stream_info.sample_rate) * 1000
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
258 / metadata->data.stream_info.sample_rate;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
259 }
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 443
diff changeset
260
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
261 if (metadata->data.stream_info.bits_per_sample > 8)
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
262 f->sample->actual.format = AUDIO_S16MSB;
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
263 else
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
264 f->sample->actual.format = AUDIO_S8;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
265 } /* if */
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
266 } /* metadata_callback */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
267
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
268
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
269 static void error_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
270 const decoder_t *decoder,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
271 d_error_status_t status,
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
272 void *client_data)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
273 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
274 flac_t *f = (flac_t *) client_data;
164
77482005beb6 Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
Ryan C. Gordon <icculus@icculus.org>
parents: 155
diff changeset
275
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
276 __Sound_SetError(d_error_status_string[status]);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
277 f->sample->flags |= SOUND_SAMPLEFLAG_ERROR;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
278 } /* error_callback */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
279
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
280
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
281 static d_seek_status_t seek_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
282 const decoder_t *decoder,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
283 FLAC__uint64 absolute_byte_offset,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
284 void *client_data)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
285 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
286 flac_t *f = (flac_t *) client_data;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
287
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
288 if (SDL_RWseek(f->rw, absolute_byte_offset, SEEK_SET) >= 0)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
289 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
290 return(D_SEEK_STATUS_OK);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
291 } /* if */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
292
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
293 return(D_SEEK_STATUS_ERROR);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
294 } /* seek_callback*/
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
295
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
296
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
297 static d_tell_status_t tell_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
298 const decoder_t *decoder,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
299 FLAC__uint64 *absolute_byte_offset,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
300 void *client_data)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
301 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
302 flac_t *f = (flac_t *) client_data;
400
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
303 int pos;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
304
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
305 pos = SDL_RWtell(f->rw);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
306
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
307 if (pos < 0)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
308 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
309 return(D_TELL_STATUS_ERROR);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
310 } /* if */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
311
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
312 *absolute_byte_offset = pos;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
313 return(D_TELL_STATUS_OK);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
314 } /* tell_callback */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
315
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
316
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
317 static d_length_status_t length_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
318 const decoder_t *decoder,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
319 FLAC__uint64 *stream_length,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
320 void *client_data)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
321 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
322 flac_t *f = (flac_t *) client_data;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
323
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
324 if (f->sample->flags & SOUND_SAMPLEFLAG_CANSEEK)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
325 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
326 *stream_length = f->stream_length;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
327 return(D_LENGTH_STATUS_OK);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
328 } /* if */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
329
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
330 return(D_LENGTH_STATUS_ERROR);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
331 } /* length_callback */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
332
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
333
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
334 static FLAC__bool eof_callback(
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
335 const decoder_t *decoder,
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
336 void *client_data)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
337 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
338 flac_t *f = (flac_t *) client_data;
400
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
339 int pos;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
340
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
341 /* Maybe we could check for SOUND_SAMPLEFLAG_EOF here instead? */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
342 pos = SDL_RWtell(f->rw);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
343
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
344 if (pos >= 0 && pos >= f->stream_length)
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
345 {
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
346 return(true);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
347 } /* if */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
348
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
349 return(false);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
350 } /* eof_callback */
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
351
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
352
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
353 static int FLAC_init(void)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
354 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
355 return(1); /* always succeeds. */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
356 } /* FLAC_init */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
357
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
358
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
359 static void FLAC_quit(void)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
360 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
361 /* it's a no-op. */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
362 } /* FLAC_quit */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
363
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
364
182
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
365 #define FLAC_MAGIC 0x43614C66 /* "fLaC" in ASCII. */
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
366
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
367 static int FLAC_open(Sound_Sample *sample, const char *ext)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
368 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
369 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
370 SDL_RWops *rw = internal->rw;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
371 decoder_t *decoder;
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
372 flac_t *f;
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
373 int i;
182
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
374 int has_extension = 0;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
375 Uint32 pos;
182
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
376
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
377 /*
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
378 * If the extension is "flac", we'll believe that this is really meant
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
379 * to be a FLAC stream, and will try to grok it from existing metadata.
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
380 * metadata searching can be a very expensive operation, however, so
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
381 * unless the user swears that it is a FLAC stream through the extension,
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
382 * we decide what to do based on the existance of a 32-bit magic number.
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
383 */
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
384 for (i = 0; extensions_flac[i] != NULL; i++)
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
385 {
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
386 if (__Sound_strcasecmp(ext, extensions_flac[i]) == 0)
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
387 {
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
388 has_extension = 1;
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
389 break;
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
390 } /* if */
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
391 } /* for */
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
392
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
393 if (!has_extension)
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
394 {
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
395 int rc;
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
396 Uint32 flac_magic = SDL_ReadLE32(rw);
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
397 BAIL_IF_MACRO(flac_magic != FLAC_MAGIC, "FLAC: Not a FLAC stream.", 0);
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
398
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
399 /* move back over magic number for metadata scan... */
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
400 rc = SDL_RWseek(internal->rw, -sizeof (flac_magic), SEEK_CUR);
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
401 BAIL_IF_MACRO(rc < 0, ERR_IO_ERROR, 0);
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
402 } /* if */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
403
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
404 f = (flac_t *) malloc(sizeof (flac_t));
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
405 BAIL_IF_MACRO(f == NULL, ERR_OUT_OF_MEMORY, 0);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
406
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
407 decoder = d_new();
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
408 if (decoder == NULL)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
409 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
410 free(f);
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
411 BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
412 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
413
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
414 d_set_read_callback(decoder, read_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
415 d_set_write_callback(decoder, write_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
416 d_set_metadata_callback(decoder, metadata_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
417 d_set_error_callback(decoder, error_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
418 d_set_seek_callback(decoder, seek_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
419 d_set_tell_callback(decoder, tell_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
420 d_set_length_callback(decoder, length_callback);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
421 d_set_eof_callback(decoder, eof_callback);
422
5b06e23d934e Removed backwards compatible API nastiness from FLAC decoder.
Ryan C. Gordon <icculus@icculus.org>
parents: 400
diff changeset
422
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
423 d_set_client_data(decoder, f);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
424
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
425 f->rw = internal->rw;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
426 f->sample = sample;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
427 f->decoder = decoder;
164
77482005beb6 Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
Ryan C. Gordon <icculus@icculus.org>
parents: 155
diff changeset
428 f->sample->actual.format = 0;
182
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
429 f->is_flac = 0 /* !!! FIXME: should be "has_extension", not "0". */;
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
430
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
431 internal->decoder_private = f;
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
432 d_init(decoder);
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
433
400
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
434 sample->flags = SOUND_SAMPLEFLAG_NONE;
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
435
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
436 pos = SDL_RWtell(f->rw);
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
437 if (SDL_RWseek(f->rw, 0, SEEK_END) > 0)
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
438 {
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
439 f->stream_length = SDL_RWtell(f->rw);
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
440 if (SDL_RWseek(f->rw, pos, SEEK_SET) == -1)
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
441 {
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
442 free_flac(f);
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
443 BAIL_MACRO(ERR_IO_ERROR, 0);
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
444 } /* if */
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
445 sample->flags = SOUND_SAMPLEFLAG_CANSEEK;
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
446 } /* if */
9d0b5ec9cc26 FIXME cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
447
231
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
448 /*
182
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
449 * If we are not sure this is a FLAC stream, check for the STREAMINFO
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
450 * metadata block. If not, we'd have to peek at the first audio frame
182
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
451 * and get the sound format from there, but that is not yet
3849438b735e Checks magic number again, unless the file extension is recognized.
Ryan C. Gordon <icculus@icculus.org>
parents: 166
diff changeset
452 * implemented.
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
453 */
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
454 if (!f->is_flac)
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
455 {
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
456 d_process_metadata(decoder);
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
457
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
458 /* Still not FLAC? Give up. */
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
459 if (!f->is_flac)
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
460 {
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
461 free_flac(f);
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
462 BAIL_MACRO("FLAC: No metadata found. Not a FLAC stream?", 0);
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
463 } /* if */
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
464 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
465
164
77482005beb6 Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
Ryan C. Gordon <icculus@icculus.org>
parents: 155
diff changeset
466 SNDDBG(("FLAC: Accepting data stream.\n"));
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
467 return(1);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
468 } /* FLAC_open */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
469
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
470
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
471 static void FLAC_close(Sound_Sample *sample)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
472 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
473 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
474 flac_t *f = (flac_t *) internal->decoder_private;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
475
166
d8904267d23c Cleanups, fixes and enhancements by Torbj�rn Andersson.
Ryan C. Gordon <icculus@icculus.org>
parents: 164
diff changeset
476 free_flac(f);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
477 } /* FLAC_close */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
478
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
479
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
480 static Uint32 FLAC_read(Sound_Sample *sample)
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
481 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
482 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
483 flac_t *f = (flac_t *) internal->decoder_private;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
484 Uint32 len;
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
485
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
486 if (!d_process_one_frame(f->decoder))
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
487 {
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
488 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
489 BAIL_MACRO("FLAC: Couldn't decode frame.", 0);
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
490 } /* if */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
491
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
492 if (d_get_state(f->decoder) == D_END_OF_STREAM)
231
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
493 {
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
494 sample->flags |= SOUND_SAMPLEFLAG_EOF;
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
495 return(0);
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
496 } /* if */
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
497
164
77482005beb6 Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
Ryan C. Gordon <icculus@icculus.org>
parents: 155
diff changeset
498 /* An error may have been signalled through the error callback. */
77482005beb6 Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
Ryan C. Gordon <icculus@icculus.org>
parents: 155
diff changeset
499 if (sample->flags & SOUND_SAMPLEFLAG_ERROR)
77482005beb6 Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
Ryan C. Gordon <icculus@icculus.org>
parents: 155
diff changeset
500 return(0);
231
d3dc34315ac7 Rewind method implemented by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
501
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
502 return(f->frame_size);
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
503 } /* FLAC_read */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
504
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
505
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
506 static int FLAC_rewind(Sound_Sample *sample)
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
507 {
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
508 return FLAC_seek(sample, 0);
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
509 } /* FLAC_rewind */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
510
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
511
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
512 static int FLAC_seek(Sound_Sample *sample, Uint32 ms)
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
513 {
312
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
514 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
515 flac_t *f = (flac_t *) internal->decoder_private;
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
516
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
517 d_seek_absolute(f->decoder, (ms * sample->actual.rate) / 1000);
498240aa76f1 Seek implementations.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
518 return(1);
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
519 } /* FLAC_seek */
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 231
diff changeset
520
155
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
521 #endif /* SOUND_SUPPORTS_FLAC */
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
522
72ff7d3a25b6 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
523 /* end of flac.c ... */