Fix Lancer-patched libvorbis-aoTuV so it builds with GCC.
[vorbis-lancer-gcc.git] / vorbis-tools-1.2.0 / ogg123 / flac_format.c
blobfe6dbe5011d0d15abba5d492b6e80c9a6df27912
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2005 *
9 * by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS *
10 * http://www.xiph.org/ *
11 * *
12 ********************************************************************
14 last mod: $Id: flac_format.c,v 1.3 2003/01/14 00:19:05 volsung Exp $
16 ********************************************************************/
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <math.h>
27 #include <FLAC/all.h>
28 #include <ao/ao.h>
29 #include "audio.h"
30 #include "format.h"
31 #include "i18n.h"
32 #if !defined(FLAC_API_VERSION_CURRENT) || (FLAC_API_VERSION_CURRENT < 8)
33 #define NEED_EASYFLAC 1
34 #endif
35 #if NEED_EASYFLAC
36 #include "easyflac.h"
37 #endif
38 #include "vorbis_comments.h"
40 typedef struct {
41 #if NEED_EASYFLAC
42 EasyFLAC__StreamDecoder *decoder;
43 #else
44 FLAC__StreamDecoder *decoder;
45 int is_oggflac;
46 #endif
47 short channels;
48 int rate;
49 int bits_per_sample;
50 long totalsamples; /* per channel, of course */
51 long currentsample; /* number of samples played, (not decoded,
52 as those may still be buffered in buf) */
54 /* For calculating bitrate stats */
55 long samples_decoded;
56 long samples_decoded_previous;
57 long bytes_read;
58 long bytes_read_previous;
60 FLAC__StreamMetadata *comments;
62 int bos; /* At beginning of stream */
63 int eos; /* End of stream read */
66 /* Buffer for decoded audio */
67 FLAC__int32 **buf; /* channels by buf_len array */
68 int buf_len;
69 int buf_start; /* Offset to start of audio data */
70 int buf_fill; /* Number of bytes of audio data in buffer */
72 decoder_stats_t stats;
74 } flac_private_t;
76 /* Forward declarations */
77 format_t flac_format;
78 format_t oggflac_format;
81 /* Private functions declarations */
82 #if NEED_EASYFLAC
83 static FLAC__StreamDecoderReadStatus easyflac_read_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
84 static FLAC__StreamDecoderWriteStatus easyflac_write_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
85 static void easyflac_metadata_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
86 static void easyflac_error_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
87 #else
88 static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
89 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
90 static void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
91 static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
92 static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
93 #endif
95 void resize_buffer(flac_private_t *flac, int newchannels, int newsamples);
96 /*void copy_comments (vorbis_comment *v_comments, FLAC__StreamMetadata_VorbisComment *f_comments);*/
97 void print_flac_stream_info (decoder_t *decoder);
98 void print_flac_comments (FLAC__StreamMetadata_VorbisComment *comments,
99 decoder_callbacks_t *cb, void *callback_arg);
103 int flac_can_decode (data_source_t *source)
105 char buf[4];
106 int len;
108 len = source->transport->peek(source, buf, sizeof(char), 4);
110 if (len >= 4 && memcmp(buf, "fLaC", 4) == 0)
111 return 1; /* Naked FLAC */
112 else
113 return 0;
117 int oggflac_can_decode (data_source_t *source)
119 char buf[36];
120 int len;
122 len = source->transport->peek(source, buf, sizeof(char), 36);
124 if (len >= 36 && memcmp(buf, "OggS", 4) == 0
125 && memcmp(buf+28, "fLaC", 4) == 0) {
126 /* old Ogg FLAC , pre flac 1.1.1 */
127 return 1;
130 if (len >= 36 && memcmp(buf, "OggS", 4) == 0
131 && buf[28] == 0x7F
132 && memcmp(buf+29, "FLAC", 4) == 0
133 && buf[33] == 1
134 && buf[34] == 0) {
135 /* Ogg FLAC >= 1.1.1, according to OggFlac mapping 1.0 */
136 return 1;
139 return 0;
143 decoder_t* flac_init (data_source_t *source, ogg123_options_t *ogg123_opts,
144 audio_format_t *audio_fmt,
145 decoder_callbacks_t *callbacks, void *callback_arg)
147 decoder_t *decoder;
148 flac_private_t *private;
149 FLAC__bool ret;
152 /* Allocate data source structures */
153 decoder = malloc(sizeof(decoder_t));
154 private = malloc(sizeof(flac_private_t));
156 if (decoder != NULL && private != NULL) {
157 decoder->source = source;
158 decoder->actual_fmt = decoder->request_fmt = *audio_fmt;
159 /* Set format below when we distinguish which we are doing */
160 decoder->callbacks = callbacks;
161 decoder->callback_arg = callback_arg;
162 decoder->private = private;
164 private->stats.total_time = 0.0;
165 private->stats.current_time = 0.0;
166 private->stats.instant_bitrate = 0;
167 private->stats.avg_bitrate = 0;
168 } else {
169 fprintf(stderr, _("Error: Out of memory.\n"));
170 exit(1);
173 private->bos = 1;
174 private->eos = 0;
175 private->comments = NULL;
176 private->samples_decoded = private->samples_decoded_previous = 0;
177 private->bytes_read = private->bytes_read_previous = 0;
178 private->currentsample = 0;
180 /* Setup empty audio buffer that will be resized on first frame
181 callback */
182 private->channels = 0;
183 private->buf = NULL;
184 private->buf_len = 0;
185 private->buf_fill = 0;
186 private->buf_start = 0;
188 /* Setup FLAC decoder */
189 #if NEED_EASYFLAC
190 if (oggflac_can_decode(source)) {
191 decoder->format = &oggflac_format;
192 private->decoder = EasyFLAC__stream_decoder_new(1);
193 } else {
194 decoder->format = &flac_format;
195 private->decoder = EasyFLAC__stream_decoder_new(0);
199 EasyFLAC__set_client_data(private->decoder, decoder);
200 EasyFLAC__set_read_callback(private->decoder, &easyflac_read_callback);
201 EasyFLAC__set_write_callback(private->decoder, &easyflac_write_callback);
202 EasyFLAC__set_metadata_callback(private->decoder, &easyflac_metadata_callback);
203 EasyFLAC__set_error_callback(private->decoder, &easyflac_error_callback);
204 EasyFLAC__set_metadata_respond(private->decoder, FLAC__METADATA_TYPE_STREAMINFO);
205 EasyFLAC__set_metadata_respond(private->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
206 EasyFLAC__init(private->decoder);
207 #else
208 if (oggflac_can_decode(source)) {
209 private->is_oggflac = 1;
210 decoder->format = &oggflac_format;
211 } else {
212 private->is_oggflac = 0;
213 decoder->format = &flac_format;
215 private->decoder = FLAC__stream_decoder_new();
217 FLAC__stream_decoder_set_md5_checking(private->decoder, false);
218 FLAC__stream_decoder_set_metadata_respond(private->decoder, FLAC__METADATA_TYPE_STREAMINFO);
219 FLAC__stream_decoder_set_metadata_respond(private->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
220 /*FLAC__stream_decoder_init(private->decoder);*/
221 if(private->is_oggflac)
222 FLAC__stream_decoder_init_ogg_stream(private->decoder, read_callback, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, eof_callback, write_callback, metadata_callback, error_callback, decoder);
223 else
224 FLAC__stream_decoder_init_stream(private->decoder, read_callback, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, eof_callback, write_callback, metadata_callback, error_callback, decoder);
225 #endif
227 /* Callback will set the total samples and sample rate */
228 #if NEED_EASYFLAC
229 EasyFLAC__process_until_end_of_metadata(private->decoder);
230 #else
231 FLAC__stream_decoder_process_until_end_of_metadata(private->decoder);
232 #endif
234 /* Callback will set the number of channels and resize the
235 audio buffer */
236 #if NEED_EASYFLAC
237 EasyFLAC__process_single(private->decoder);
238 #else
239 FLAC__stream_decoder_process_single(private->decoder);
240 #endif
242 /* FLAC API returns signed samples on all streams */
243 decoder->actual_fmt.signed_sample = 1;
244 decoder->actual_fmt.big_endian = ao_is_big_endian();
246 return decoder;
250 int flac_read (decoder_t *decoder, void *ptr, int nbytes, int *eos,
251 audio_format_t *audio_fmt)
253 flac_private_t *priv = decoder->private;
254 decoder_callbacks_t *cb = decoder->callbacks;
255 FLAC__int8 *buf8 = (FLAC__int8 *) ptr;
256 FLAC__int16 *buf16 = (FLAC__int16 *) ptr;
257 long samples, realsamples = 0;
258 FLAC__bool ret;
259 int i,j;
261 /* Read comments and audio info at the start of a logical bitstream */
262 if (priv->bos) {
263 decoder->actual_fmt.rate = priv->rate;
264 decoder->actual_fmt.channels = priv->channels;
265 decoder->actual_fmt.word_size = ((priv->bits_per_sample + 7) / 8);
267 print_flac_stream_info(decoder);
268 if (priv->comments != NULL)
269 print_flac_comments(&priv->comments->data.vorbis_comment, cb,
270 decoder->callback_arg);
272 priv->bos = 0;
275 *audio_fmt = decoder->actual_fmt;
277 /* Validate channels and word_size to avoid div by zero */
278 if(!(audio_fmt->channels && audio_fmt->word_size)) {
279 fprintf(stderr, _("Error: Corrupt input.\n"));
280 exit(1);
283 /* Only return whole samples (no channel splitting) */
284 samples = nbytes / (audio_fmt->channels * audio_fmt->word_size);
286 while (realsamples < samples) {
287 if (priv->buf_fill > 0) {
288 int copy = priv->buf_fill < (samples - realsamples) ?
289 priv->buf_fill : (samples - realsamples);
291 /* Need sample mangling code here! */
293 if (audio_fmt->word_size == 1) {
294 for (i = 0; i < priv->channels; i++)
295 for (j = 0; j < copy; j++)
296 buf8[(j+realsamples)*audio_fmt->channels+i] = (FLAC__int8) (0xFF & priv->buf[i][j+priv->buf_start]);
297 } else if (audio_fmt->word_size == 2) {
298 for (i = 0; i < priv->channels; i++)
299 for (j = 0; j < copy; j++)
300 buf16[(j+realsamples)*audio_fmt->channels+i] = (FLAC__int16) (0xFFFF & priv->buf[i][j+priv->buf_start]);
303 priv->buf_start += copy;
304 priv->buf_fill -= copy;
305 realsamples += copy;
307 else if (!priv->eos) {
308 #if NEED_EASYFLAC
309 ret = EasyFLAC__process_single(priv->decoder);
310 if (!ret ||
311 EasyFLAC__get_state(priv->decoder)
312 == FLAC__STREAM_DECODER_END_OF_STREAM)
313 priv->eos = 1; /* Bail out! */
314 #else
315 ret = FLAC__stream_decoder_process_single(priv->decoder);
316 if (!ret ||
317 FLAC__stream_decoder_get_state(priv->decoder)
318 == FLAC__STREAM_DECODER_END_OF_STREAM)
319 priv->eos = 1; /* Bail out! */
320 #endif
321 } else
322 break;
325 priv->currentsample += realsamples;
327 return realsamples * audio_fmt->channels * audio_fmt->word_size;
331 int flac_seek (decoder_t *decoder, double offset, int whence)
333 return 0; /* No seeking at this time */
337 #define AVG_FACTOR 0.5
339 decoder_stats_t *flac_statistics (decoder_t *decoder)
341 flac_private_t *priv = decoder->private;
342 long instant_bitrate;
344 /* ov_time_tell() doesn't work on non-seekable streams, so we use
345 ov_pcm_tell() */
346 priv->stats.total_time = (double) priv->totalsamples /
347 (double) decoder->actual_fmt.rate;
348 priv->stats.current_time = (double) priv->currentsample /
349 (double) decoder->actual_fmt.rate;
351 /* Need this test to prevent averaging in false zeros. */
352 if ((priv->bytes_read - priv->bytes_read_previous) != 0 &&
353 (priv->samples_decoded - priv->samples_decoded_previous) != 0) {
355 instant_bitrate = 8.0 * (priv->bytes_read - priv->bytes_read_previous)
356 * decoder->actual_fmt.rate
357 / (double) (priv->samples_decoded - priv->samples_decoded_previous);
359 /* A little exponential averaging to smooth things out */
360 priv->stats.instant_bitrate = AVG_FACTOR * instant_bitrate
361 + (1.0 - AVG_FACTOR) * priv->stats.instant_bitrate;
363 priv->bytes_read_previous = priv->bytes_read;
364 priv->samples_decoded_previous = priv->samples_decoded;
367 // priv->stats.instant_bitrate = 8.0 * priv->bytes_read * decoder->actual_fmt.rate / (double) priv->samples_decoded;
369 /* Don't know unless we seek the stream */
370 priv->stats.avg_bitrate = 0;
373 return malloc_decoder_stats(&priv->stats);
377 void flac_cleanup (decoder_t *decoder)
379 flac_private_t *priv = decoder->private;
380 int i;
382 for (i = 0; i < priv->channels; i++)
383 free(priv->buf[i]);
385 free(priv->buf);
386 #if NEED_EASYFLAC
387 EasyFLAC__finish(priv->decoder);
388 EasyFLAC__stream_decoder_delete(priv->decoder);
389 #else
390 FLAC__stream_decoder_finish(priv->decoder);
391 FLAC__stream_decoder_delete(priv->decoder);
392 #endif
394 free(decoder->private);
395 free(decoder);
399 format_t flac_format = {
400 "flac",
401 &flac_can_decode,
402 &flac_init,
403 &flac_read,
404 &flac_seek,
405 &flac_statistics,
406 &flac_cleanup,
410 format_t oggflac_format = {
411 "oggflac",
412 &oggflac_can_decode,
413 &flac_init,
414 &flac_read,
415 &flac_seek,
416 &flac_statistics,
417 &flac_cleanup,
422 #if NEED_EASYFLAC
423 FLAC__StreamDecoderReadStatus easyflac_read_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
424 #else
425 FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
426 #endif
428 decoder_t *e_decoder = client_data;
429 flac_private_t *priv = e_decoder->private;
431 int read = 0;
433 read = e_decoder->source->transport->read(e_decoder->source, buffer,
434 sizeof(FLAC__byte), *bytes);
436 *bytes = read;
437 priv->bytes_read += read;
439 /* Immediately return if errors occured */
440 if(read == 0)
441 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
442 else
443 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
447 #if NEED_EASYFLAC
448 FLAC__StreamDecoderWriteStatus easyflac_write_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
449 #else
450 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
451 #endif
453 decoder_t *e_decoder = client_data;
454 flac_private_t *priv = e_decoder->private;
456 int samples = frame->header.blocksize;
457 int channels = frame->header.channels;
458 int bits_per_sample = priv->bits_per_sample = frame->header.bits_per_sample;
459 int i, j;
461 resize_buffer(priv, channels, samples);
463 for (i = 0; i < channels; i++)
464 for (j = 0; j < samples; j++)
465 priv->buf[i][j] = buffer[i][j];
467 priv->buf_start = 0;
468 priv->buf_fill = samples;
471 priv->samples_decoded += samples;
473 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
477 #if NEED_EASYFLAC
478 void easyflac_metadata_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
479 #else
480 void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
481 #endif
483 decoder_t *e_decoder = client_data;
484 flac_private_t *priv = e_decoder->private;
486 switch (metadata->type) {
487 case FLAC__METADATA_TYPE_STREAMINFO:
488 priv->totalsamples = metadata->data.stream_info.total_samples;
489 priv->rate = metadata->data.stream_info.sample_rate;
490 break;
492 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
493 priv->comments = FLAC__metadata_object_clone(metadata);
494 break;
495 default:
496 break;
501 #if NEED_EASYFLAC
502 void easyflac_error_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
503 #else
504 void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
505 #endif
511 #if !NEED_EASYFLAC
512 FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
514 decoder_t *e_decoder = client_data;
515 flac_private_t *priv = e_decoder->private;
517 return priv->eos;
519 #endif
522 void resize_buffer(flac_private_t *flac, int newchannels, int newsamples)
524 int i;
526 if (newchannels == flac->channels && newsamples == flac->buf_len) {
527 flac->buf_start = 0;
528 flac->buf_fill = 0;
529 return;
533 /* Not the most efficient approach, but it is easy to follow */
534 if(newchannels != flac->channels) {
535 /* Deallocate all of the sample vectors */
536 for (i = 0; i < flac->channels; i++)
537 free(flac->buf[i]);
539 flac->buf = realloc(flac->buf, sizeof(FLAC__int32*) * newchannels);
540 flac->channels = newchannels;
543 for (i = 0; i < newchannels; i++)
544 flac->buf[i] = malloc(sizeof(FLAC__int32) * newsamples);
546 flac->buf_len = newsamples;
547 flac->buf_start = 0;
548 flac->buf_fill = 0;
552 void print_flac_stream_info (decoder_t *decoder)
554 flac_private_t *priv = decoder->private;
555 decoder_callbacks_t *cb = decoder->callbacks;
558 if (cb == NULL || cb->printf_metadata == NULL)
559 return;
563 #if NEED_EASYFLAC
564 if (EasyFLAC__is_oggflac(priv->decoder))
565 #else
566 if (priv->is_oggflac)
567 #endif
568 cb->printf_metadata(decoder->callback_arg, 2,
569 _("Ogg FLAC stream: %d bits, %d channel, %ld Hz"),
570 priv->bits_per_sample,
571 priv->channels,
572 priv->rate);
573 else
574 cb->printf_metadata(decoder->callback_arg, 2,
575 _("FLAC stream: %d bits, %d channel, %ld Hz"),
576 priv->bits_per_sample,
577 priv->channels,
578 priv->rate);
581 void print_flac_comments (FLAC__StreamMetadata_VorbisComment *f_comments,
582 decoder_callbacks_t *cb, void *callback_arg)
584 int i;
585 char *temp = NULL;
586 int temp_len = 0;
588 for (i = 0; i < f_comments->num_comments; i++) {
590 /* Gotta null terminate these things */
591 if (temp_len < f_comments->comments[i].length + 1) {
592 temp_len = f_comments->comments[i].length + 1;
593 temp = realloc(temp, sizeof(char) * temp_len);
596 strncpy(temp, f_comments->comments[i].entry,
597 f_comments->comments[i].length);
598 temp[f_comments->comments[i].length] = '\0';
600 print_vorbis_comment(temp, cb, callback_arg);
603 free(temp);