1 /* EasyFLAC - A thin decoding wrapper around libFLAC and libOggFLAC to
2 * make your code less ugly. See easyflac.h for explanation.
4 * Copyright 2003 - Stan Seibert <volsung@xiph.org>
5 * This code is licensed under a BSD style license:
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * - Neither the name of the Xiph.org Foundation nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <FLAC/export.h>
41 #if !defined(FLAC_API_VERSION_CURRENT) || (FLAC_API_VERSION_CURRENT < 8)
47 FLAC__bool
EasyFLAC__is_oggflac(EasyFLAC__StreamDecoder
*decoder
)
49 return decoder
->is_oggflac
;
53 EasyFLAC__StreamDecoder
*EasyFLAC__stream_decoder_new(FLAC__bool is_oggflac
)
55 EasyFLAC__StreamDecoder
*decoder
= malloc(sizeof(EasyFLAC__StreamDecoder
));
59 decoder
->is_oggflac
= is_oggflac
;
61 if (decoder
->is_oggflac
)
62 decoder
->oggflac
= OggFLAC__stream_decoder_new();
64 decoder
->flac
= FLAC__stream_decoder_new();
66 if ( (decoder
->is_oggflac
&& decoder
->oggflac
== NULL
)
67 ||(!decoder
->is_oggflac
&& decoder
->flac
== NULL
) )
78 void EasyFLAC__stream_decoder_delete(EasyFLAC__StreamDecoder
*decoder
)
80 if (decoder
->is_oggflac
)
81 OggFLAC__stream_decoder_delete(decoder
->oggflac
);
83 FLAC__stream_decoder_delete(decoder
->flac
);
89 /* Wrappers around the callbacks for OggFLAC */
91 FLAC__StreamDecoderReadStatus
oggflac_read_callback(const OggFLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], unsigned *bytes
, void *client_data
)
93 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
95 return (*e_decoder
->callbacks
.read
)(e_decoder
, buffer
, bytes
, e_decoder
->callbacks
.client_data
);
99 FLAC__StreamDecoderWriteStatus
oggflac_write_callback(const OggFLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
101 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
103 return (*(e_decoder
->callbacks
.write
))(e_decoder
, frame
, buffer
, e_decoder
->callbacks
.client_data
);
107 void oggflac_metadata_callback(const OggFLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
109 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
111 (*e_decoder
->callbacks
.metadata
)(e_decoder
, metadata
, e_decoder
->callbacks
.client_data
);
115 void oggflac_error_callback(const OggFLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
117 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
119 (*e_decoder
->callbacks
.error
)(e_decoder
, status
, e_decoder
->callbacks
.client_data
);
123 /* Wrappers around the callbacks for FLAC */
125 FLAC__StreamDecoderReadStatus
flac_read_callback(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], unsigned *bytes
, void *client_data
)
127 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
129 return (*e_decoder
->callbacks
.read
)(e_decoder
, buffer
, bytes
, e_decoder
->callbacks
.client_data
);
133 FLAC__StreamDecoderWriteStatus
flac_write_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
135 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
137 return (*e_decoder
->callbacks
.write
)(e_decoder
, frame
, buffer
, e_decoder
->callbacks
.client_data
);
141 void flac_metadata_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
143 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
145 (*e_decoder
->callbacks
.metadata
)(e_decoder
, metadata
, e_decoder
->callbacks
.client_data
);
149 void flac_error_callback(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
151 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
153 (*e_decoder
->callbacks
.error
)(e_decoder
, status
, e_decoder
->callbacks
.client_data
);
157 FLAC__bool
EasyFLAC__set_read_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderReadCallback value
)
159 decoder
->callbacks
.read
= value
;
161 if (decoder
->is_oggflac
)
162 return OggFLAC__stream_decoder_set_read_callback(decoder
->oggflac
, &oggflac_read_callback
);
164 return FLAC__stream_decoder_set_read_callback(decoder
->flac
, &flac_read_callback
);
168 FLAC__bool
EasyFLAC__set_write_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderWriteCallback value
)
170 decoder
->callbacks
.write
= value
;
172 if (decoder
->is_oggflac
)
173 return OggFLAC__stream_decoder_set_write_callback(decoder
->oggflac
, &oggflac_write_callback
);
175 return FLAC__stream_decoder_set_write_callback(decoder
->flac
, &flac_write_callback
);
179 FLAC__bool
EasyFLAC__set_metadata_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderMetadataCallback value
)
181 decoder
->callbacks
.metadata
= value
;
183 if (decoder
->is_oggflac
)
184 return OggFLAC__stream_decoder_set_metadata_callback(decoder
->oggflac
, &oggflac_metadata_callback
);
186 return FLAC__stream_decoder_set_metadata_callback(decoder
->flac
, &flac_metadata_callback
);
190 FLAC__bool
EasyFLAC__set_error_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderErrorCallback value
)
192 decoder
->callbacks
.error
= value
;
194 if (decoder
->is_oggflac
)
195 return OggFLAC__stream_decoder_set_error_callback(decoder
->oggflac
, &oggflac_error_callback
);
197 return FLAC__stream_decoder_set_error_callback(decoder
->flac
, &flac_error_callback
);
201 FLAC__bool
EasyFLAC__set_client_data(EasyFLAC__StreamDecoder
*decoder
, void *value
)
203 decoder
->callbacks
.client_data
= value
;
205 if (decoder
->is_oggflac
)
206 return OggFLAC__stream_decoder_set_client_data(decoder
->oggflac
, decoder
);
208 return FLAC__stream_decoder_set_client_data(decoder
->flac
, decoder
);
212 FLAC__bool
EasyFLAC__set_metadata_respond(EasyFLAC__StreamDecoder
*decoder
, FLAC__MetadataType type
)
214 if (decoder
->is_oggflac
)
215 return OggFLAC__stream_decoder_set_metadata_respond(decoder
->oggflac
, type
);
217 return FLAC__stream_decoder_set_metadata_respond(decoder
->flac
, type
);
221 FLAC__bool
EasyFLAC__set_metadata_respond_application(EasyFLAC__StreamDecoder
*decoder
, const FLAC__byte id
[4])
223 if (decoder
->is_oggflac
)
224 return OggFLAC__stream_decoder_set_metadata_respond_application(decoder
->oggflac
, id
);
226 return FLAC__stream_decoder_set_metadata_respond_application(decoder
->flac
, id
);
230 FLAC__bool
EasyFLAC__set_metadata_respond_all(EasyFLAC__StreamDecoder
*decoder
)
232 if (decoder
->is_oggflac
)
233 return OggFLAC__stream_decoder_set_metadata_respond_all(decoder
->oggflac
);
235 return FLAC__stream_decoder_set_metadata_respond_all(decoder
->flac
);
239 FLAC__bool
EasyFLAC__set_metadata_ignore(EasyFLAC__StreamDecoder
*decoder
, FLAC__MetadataType type
)
241 if (decoder
->is_oggflac
)
242 return OggFLAC__stream_decoder_set_metadata_ignore(decoder
->oggflac
, type
);
244 return FLAC__stream_decoder_set_metadata_ignore(decoder
->flac
, type
);
248 FLAC__bool
EasyFLAC__set_metadata_ignore_application(EasyFLAC__StreamDecoder
*decoder
, const FLAC__byte id
[4])
250 if (decoder
->is_oggflac
)
251 return OggFLAC__stream_decoder_set_metadata_ignore_application(decoder
->oggflac
, id
);
253 return FLAC__stream_decoder_set_metadata_ignore_application(decoder
->flac
, id
);
256 FLAC__bool
EasyFLAC__set_metadata_ignore_all(EasyFLAC__StreamDecoder
*decoder
)
258 if (decoder
->is_oggflac
)
259 return OggFLAC__stream_decoder_set_metadata_ignore_all(decoder
->oggflac
);
261 return FLAC__stream_decoder_set_metadata_ignore_all(decoder
->flac
);
265 FLAC__StreamDecoderState
EasyFLAC__get_state(const EasyFLAC__StreamDecoder
*decoder
)
267 if (decoder
->is_oggflac
)
268 return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder
->oggflac
);
270 return FLAC__stream_decoder_get_state(decoder
->flac
);
274 unsigned EasyFLAC__get_channels(const EasyFLAC__StreamDecoder
*decoder
)
276 if (decoder
->is_oggflac
)
277 return OggFLAC__stream_decoder_get_channels(decoder
->oggflac
);
279 return FLAC__stream_decoder_get_channels(decoder
->flac
);
283 FLAC__ChannelAssignment
EasyFLAC__get_channel_assignment(const EasyFLAC__StreamDecoder
*decoder
)
285 if (decoder
->is_oggflac
)
286 return OggFLAC__stream_decoder_get_channel_assignment(decoder
->oggflac
);
288 return FLAC__stream_decoder_get_channel_assignment(decoder
->flac
);
292 unsigned EasyFLAC__get_bits_per_sample(const EasyFLAC__StreamDecoder
*decoder
)
294 if (decoder
->is_oggflac
)
295 return OggFLAC__stream_decoder_get_bits_per_sample(decoder
->oggflac
);
297 return FLAC__stream_decoder_get_bits_per_sample(decoder
->flac
);
301 unsigned EasyFLAC__get_sample_rate(const EasyFLAC__StreamDecoder
*decoder
)
303 if (decoder
->is_oggflac
)
304 return OggFLAC__stream_decoder_get_sample_rate(decoder
->oggflac
);
306 return FLAC__stream_decoder_get_sample_rate(decoder
->flac
);
310 unsigned EasyFLAC__get_blocksize(const EasyFLAC__StreamDecoder
*decoder
)
312 if (decoder
->is_oggflac
)
313 return OggFLAC__stream_decoder_get_blocksize(decoder
->oggflac
);
315 return FLAC__stream_decoder_get_blocksize(decoder
->flac
);
319 FLAC__StreamDecoderState
EasyFLAC__init(EasyFLAC__StreamDecoder
*decoder
)
321 if (decoder
->is_oggflac
)
323 OggFLAC__stream_decoder_init(decoder
->oggflac
);
324 return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder
->oggflac
);
327 return FLAC__stream_decoder_init(decoder
->flac
);
331 void EasyFLAC__finish(EasyFLAC__StreamDecoder
*decoder
)
333 if (decoder
->is_oggflac
)
334 OggFLAC__stream_decoder_finish(decoder
->oggflac
);
336 FLAC__stream_decoder_finish(decoder
->flac
);
340 FLAC__bool
EasyFLAC__flush(EasyFLAC__StreamDecoder
*decoder
)
342 if (decoder
->is_oggflac
)
343 return OggFLAC__stream_decoder_flush(decoder
->oggflac
);
345 return FLAC__stream_decoder_flush(decoder
->flac
);
349 FLAC__bool
EasyFLAC__reset(EasyFLAC__StreamDecoder
*decoder
)
351 if (decoder
->is_oggflac
)
352 return OggFLAC__stream_decoder_reset(decoder
->oggflac
);
354 return FLAC__stream_decoder_reset(decoder
->flac
);
358 FLAC__bool
EasyFLAC__process_single(EasyFLAC__StreamDecoder
*decoder
)
360 if (decoder
->is_oggflac
)
361 return OggFLAC__stream_decoder_process_single(decoder
->oggflac
);
363 return FLAC__stream_decoder_process_single(decoder
->flac
);
367 FLAC__bool
EasyFLAC__process_until_end_of_metadata(EasyFLAC__StreamDecoder
*decoder
)
369 if (decoder
->is_oggflac
)
370 return OggFLAC__stream_decoder_process_until_end_of_metadata(decoder
->oggflac
);
372 return FLAC__stream_decoder_process_until_end_of_metadata(decoder
->flac
);
376 FLAC__bool
EasyFLAC__process_until_end_of_stream(EasyFLAC__StreamDecoder
*decoder
)
378 if (decoder
->is_oggflac
)
379 return OggFLAC__stream_decoder_process_until_end_of_stream(decoder
->oggflac
);
381 return FLAC__stream_decoder_process_until_end_of_stream(decoder
->flac
);