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)
46 FLAC__bool
EasyFLAC__is_oggflac(EasyFLAC__StreamDecoder
*decoder
)
48 return decoder
->is_oggflac
;
52 EasyFLAC__StreamDecoder
*EasyFLAC__stream_decoder_new(FLAC__bool is_oggflac
)
54 EasyFLAC__StreamDecoder
*decoder
= malloc(sizeof(EasyFLAC__StreamDecoder
));
58 decoder
->is_oggflac
= is_oggflac
;
60 if (decoder
->is_oggflac
)
61 decoder
->oggflac
= OggFLAC__stream_decoder_new();
63 decoder
->flac
= FLAC__stream_decoder_new();
65 if ( (decoder
->is_oggflac
&& decoder
->oggflac
== NULL
)
66 ||(!decoder
->is_oggflac
&& decoder
->flac
== NULL
) )
77 void EasyFLAC__stream_decoder_delete(EasyFLAC__StreamDecoder
*decoder
)
79 if (decoder
->is_oggflac
)
80 OggFLAC__stream_decoder_delete(decoder
->oggflac
);
82 FLAC__stream_decoder_delete(decoder
->flac
);
88 /* Wrappers around the callbacks for OggFLAC */
90 FLAC__StreamDecoderReadStatus
oggflac_read_callback(const OggFLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], unsigned *bytes
, void *client_data
)
92 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
94 return (*e_decoder
->callbacks
.read
)(e_decoder
, buffer
, bytes
, e_decoder
->callbacks
.client_data
);
98 FLAC__StreamDecoderWriteStatus
oggflac_write_callback(const OggFLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
100 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
102 return (*(e_decoder
->callbacks
.write
))(e_decoder
, frame
, buffer
, e_decoder
->callbacks
.client_data
);
106 void oggflac_metadata_callback(const OggFLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
108 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
110 (*e_decoder
->callbacks
.metadata
)(e_decoder
, metadata
, e_decoder
->callbacks
.client_data
);
114 void oggflac_error_callback(const OggFLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
116 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
118 (*e_decoder
->callbacks
.error
)(e_decoder
, status
, e_decoder
->callbacks
.client_data
);
122 /* Wrappers around the callbacks for FLAC */
124 FLAC__StreamDecoderReadStatus
flac_read_callback(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], unsigned *bytes
, void *client_data
)
126 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
128 return (*e_decoder
->callbacks
.read
)(e_decoder
, buffer
, bytes
, e_decoder
->callbacks
.client_data
);
132 FLAC__StreamDecoderWriteStatus
flac_write_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
134 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
136 return (*e_decoder
->callbacks
.write
)(e_decoder
, frame
, buffer
, e_decoder
->callbacks
.client_data
);
140 void flac_metadata_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
142 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
144 (*e_decoder
->callbacks
.metadata
)(e_decoder
, metadata
, e_decoder
->callbacks
.client_data
);
148 void flac_error_callback(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
150 EasyFLAC__StreamDecoder
*e_decoder
= (EasyFLAC__StreamDecoder
*) client_data
;
152 (*e_decoder
->callbacks
.error
)(e_decoder
, status
, e_decoder
->callbacks
.client_data
);
156 FLAC__bool
EasyFLAC__set_read_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderReadCallback value
)
158 decoder
->callbacks
.read
= value
;
160 if (decoder
->is_oggflac
)
161 return OggFLAC__stream_decoder_set_read_callback(decoder
->oggflac
, &oggflac_read_callback
);
163 return FLAC__stream_decoder_set_read_callback(decoder
->flac
, &flac_read_callback
);
167 FLAC__bool
EasyFLAC__set_write_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderWriteCallback value
)
169 decoder
->callbacks
.write
= value
;
171 if (decoder
->is_oggflac
)
172 return OggFLAC__stream_decoder_set_write_callback(decoder
->oggflac
, &oggflac_write_callback
);
174 return FLAC__stream_decoder_set_write_callback(decoder
->flac
, &flac_write_callback
);
178 FLAC__bool
EasyFLAC__set_metadata_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderMetadataCallback value
)
180 decoder
->callbacks
.metadata
= value
;
182 if (decoder
->is_oggflac
)
183 return OggFLAC__stream_decoder_set_metadata_callback(decoder
->oggflac
, &oggflac_metadata_callback
);
185 return FLAC__stream_decoder_set_metadata_callback(decoder
->flac
, &flac_metadata_callback
);
189 FLAC__bool
EasyFLAC__set_error_callback(EasyFLAC__StreamDecoder
*decoder
, EasyFLAC__StreamDecoderErrorCallback value
)
191 decoder
->callbacks
.error
= value
;
193 if (decoder
->is_oggflac
)
194 return OggFLAC__stream_decoder_set_error_callback(decoder
->oggflac
, &oggflac_error_callback
);
196 return FLAC__stream_decoder_set_error_callback(decoder
->flac
, &flac_error_callback
);
200 FLAC__bool
EasyFLAC__set_client_data(EasyFLAC__StreamDecoder
*decoder
, void *value
)
202 decoder
->callbacks
.client_data
= value
;
204 if (decoder
->is_oggflac
)
205 return OggFLAC__stream_decoder_set_client_data(decoder
->oggflac
, decoder
);
207 return FLAC__stream_decoder_set_client_data(decoder
->flac
, decoder
);
211 FLAC__bool
EasyFLAC__set_metadata_respond(EasyFLAC__StreamDecoder
*decoder
, FLAC__MetadataType type
)
213 if (decoder
->is_oggflac
)
214 return OggFLAC__stream_decoder_set_metadata_respond(decoder
->oggflac
, type
);
216 return FLAC__stream_decoder_set_metadata_respond(decoder
->flac
, type
);
220 FLAC__bool
EasyFLAC__set_metadata_respond_application(EasyFLAC__StreamDecoder
*decoder
, const FLAC__byte id
[4])
222 if (decoder
->is_oggflac
)
223 return OggFLAC__stream_decoder_set_metadata_respond_application(decoder
->oggflac
, id
);
225 return FLAC__stream_decoder_set_metadata_respond_application(decoder
->flac
, id
);
229 FLAC__bool
EasyFLAC__set_metadata_respond_all(EasyFLAC__StreamDecoder
*decoder
)
231 if (decoder
->is_oggflac
)
232 return OggFLAC__stream_decoder_set_metadata_respond_all(decoder
->oggflac
);
234 return FLAC__stream_decoder_set_metadata_respond_all(decoder
->flac
);
238 FLAC__bool
EasyFLAC__set_metadata_ignore(EasyFLAC__StreamDecoder
*decoder
, FLAC__MetadataType type
)
240 if (decoder
->is_oggflac
)
241 return OggFLAC__stream_decoder_set_metadata_ignore(decoder
->oggflac
, type
);
243 return FLAC__stream_decoder_set_metadata_ignore(decoder
->flac
, type
);
247 FLAC__bool
EasyFLAC__set_metadata_ignore_application(EasyFLAC__StreamDecoder
*decoder
, const FLAC__byte id
[4])
249 if (decoder
->is_oggflac
)
250 return OggFLAC__stream_decoder_set_metadata_ignore_application(decoder
->oggflac
, id
);
252 return FLAC__stream_decoder_set_metadata_ignore_application(decoder
->flac
, id
);
255 FLAC__bool
EasyFLAC__set_metadata_ignore_all(EasyFLAC__StreamDecoder
*decoder
)
257 if (decoder
->is_oggflac
)
258 return OggFLAC__stream_decoder_set_metadata_ignore_all(decoder
->oggflac
);
260 return FLAC__stream_decoder_set_metadata_ignore_all(decoder
->flac
);
264 FLAC__StreamDecoderState
EasyFLAC__get_state(const EasyFLAC__StreamDecoder
*decoder
)
266 if (decoder
->is_oggflac
)
267 return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder
->oggflac
);
269 return FLAC__stream_decoder_get_state(decoder
->flac
);
273 unsigned EasyFLAC__get_channels(const EasyFLAC__StreamDecoder
*decoder
)
275 if (decoder
->is_oggflac
)
276 return OggFLAC__stream_decoder_get_channels(decoder
->oggflac
);
278 return FLAC__stream_decoder_get_channels(decoder
->flac
);
282 FLAC__ChannelAssignment
EasyFLAC__get_channel_assignment(const EasyFLAC__StreamDecoder
*decoder
)
284 if (decoder
->is_oggflac
)
285 return OggFLAC__stream_decoder_get_channel_assignment(decoder
->oggflac
);
287 return FLAC__stream_decoder_get_channel_assignment(decoder
->flac
);
291 unsigned EasyFLAC__get_bits_per_sample(const EasyFLAC__StreamDecoder
*decoder
)
293 if (decoder
->is_oggflac
)
294 return OggFLAC__stream_decoder_get_bits_per_sample(decoder
->oggflac
);
296 return FLAC__stream_decoder_get_bits_per_sample(decoder
->flac
);
300 unsigned EasyFLAC__get_sample_rate(const EasyFLAC__StreamDecoder
*decoder
)
302 if (decoder
->is_oggflac
)
303 return OggFLAC__stream_decoder_get_sample_rate(decoder
->oggflac
);
305 return FLAC__stream_decoder_get_sample_rate(decoder
->flac
);
309 unsigned EasyFLAC__get_blocksize(const EasyFLAC__StreamDecoder
*decoder
)
311 if (decoder
->is_oggflac
)
312 return OggFLAC__stream_decoder_get_blocksize(decoder
->oggflac
);
314 return FLAC__stream_decoder_get_blocksize(decoder
->flac
);
318 FLAC__StreamDecoderState
EasyFLAC__init(EasyFLAC__StreamDecoder
*decoder
)
320 if (decoder
->is_oggflac
)
322 OggFLAC__stream_decoder_init(decoder
->oggflac
);
323 return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder
->oggflac
);
326 return FLAC__stream_decoder_init(decoder
->flac
);
330 void EasyFLAC__finish(EasyFLAC__StreamDecoder
*decoder
)
332 if (decoder
->is_oggflac
)
333 OggFLAC__stream_decoder_finish(decoder
->oggflac
);
335 FLAC__stream_decoder_finish(decoder
->flac
);
339 FLAC__bool
EasyFLAC__flush(EasyFLAC__StreamDecoder
*decoder
)
341 if (decoder
->is_oggflac
)
342 return OggFLAC__stream_decoder_flush(decoder
->oggflac
);
344 return FLAC__stream_decoder_flush(decoder
->flac
);
348 FLAC__bool
EasyFLAC__reset(EasyFLAC__StreamDecoder
*decoder
)
350 if (decoder
->is_oggflac
)
351 return OggFLAC__stream_decoder_reset(decoder
->oggflac
);
353 return FLAC__stream_decoder_reset(decoder
->flac
);
357 FLAC__bool
EasyFLAC__process_single(EasyFLAC__StreamDecoder
*decoder
)
359 if (decoder
->is_oggflac
)
360 return OggFLAC__stream_decoder_process_single(decoder
->oggflac
);
362 return FLAC__stream_decoder_process_single(decoder
->flac
);
366 FLAC__bool
EasyFLAC__process_until_end_of_metadata(EasyFLAC__StreamDecoder
*decoder
)
368 if (decoder
->is_oggflac
)
369 return OggFLAC__stream_decoder_process_until_end_of_metadata(decoder
->oggflac
);
371 return FLAC__stream_decoder_process_until_end_of_metadata(decoder
->flac
);
375 FLAC__bool
EasyFLAC__process_until_end_of_stream(EasyFLAC__StreamDecoder
*decoder
)
377 if (decoder
->is_oggflac
)
378 return OggFLAC__stream_decoder_process_until_end_of_stream(decoder
->oggflac
);
380 return FLAC__stream_decoder_process_until_end_of_stream(decoder
->flac
);