1 /* -*- linux-c -*-
2 Copyright (C) 2005 Tom Szilagyi
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 $Id: dec_flac.c 1245 2012-02-04 10:33:30Z assworth $
19 */
20
21 #include <config.h>
22
23 #include <stddef.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <FLAC/format.h>
29 #include <FLAC/metadata.h>
30
31 #include "../metadata.h"
32 #include "../metadata_api.h"
33 #include "../metadata_flac.h"
34 #include "../rb.h"
35 #include "dec_flac.h"
36
37
38 extern size_t sample_size;
39
40
41 /* FLAC write callback */
42 FLAC__StreamDecoderWriteStatus
write_callback(const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)43 write_callback(const FLAC__StreamDecoder * decoder,
44 const FLAC__Frame * frame,
45 const FLAC__int32 * const buffer[],
46 void * client_data) {
47
48 decoder_t * dec = (decoder_t *) client_data;
49 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
50 file_decoder_t * fdec = dec->fdec;
51 int i, j;
52 long int scale, blocksize;
53 FLAC__int32 buf[2];
54 float fbuf[2];
55
56
57 if (pd->probing)
58 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
59
60 blocksize = frame->header.blocksize;
61 scale = 1 << (pd->bits_per_sample - 1);
62
63 for (i = 0; i < blocksize; i++) {
64 for (j = 0; j < pd->channels; j++) {
65 buf[j] = *(buffer[j] + i);
66 fbuf[j] = (float)buf[j] * fdec->voladj_lin / scale;
67 }
68 rb_write(pd->rb, (char *)fbuf,
69 pd->channels * sample_size);
70 }
71
72 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
73 }
74
75
76 /* FLAC metadata callback */
77 void
metadata_callback(const FLAC__StreamDecoder * decoder,const FLAC__StreamMetadata * metadata,void * client_data)78 metadata_callback(const FLAC__StreamDecoder * decoder,
79 const FLAC__StreamMetadata * metadata,
80 void * client_data) {
81
82 decoder_t * dec = (decoder_t *)client_data;
83 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
84
85 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
86 pd->SR = metadata->data.stream_info.sample_rate;
87 pd->bits_per_sample = metadata->data.stream_info.bits_per_sample;
88 pd->channels = metadata->data.stream_info.channels;
89 pd->total_samples = metadata->data.stream_info.total_samples;
90 } else {
91 fprintf(stderr, "FLAC metadata callback: ignoring unexpected header\n");
92 }
93 }
94
95
96 /* FLAC error callback */
97 void
error_callback(const FLAC__StreamDecoder * decoder,FLAC__StreamDecoderErrorStatus status,void * client_data)98 error_callback(const FLAC__StreamDecoder * decoder,
99 FLAC__StreamDecoderErrorStatus status,
100 void * client_data) {
101
102 decoder_t * dec = (decoder_t *) client_data;
103 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
104
105 pd->error = 1;
106 }
107
108
109 decoder_t *
flac_decoder_init(file_decoder_t * fdec)110 flac_decoder_init(file_decoder_t * fdec) {
111
112 decoder_t * dec = NULL;
113
114 if ((dec = calloc(1, sizeof(decoder_t))) == NULL) {
115 fprintf(stderr, "dec_flac.c: flac_decoder_new() failed: calloc error\n");
116 return NULL;
117 }
118
119 dec->fdec = fdec;
120
121 if ((dec->pdata = calloc(1, sizeof(flac_pdata_t))) == NULL) {
122 fprintf(stderr, "dec_flac.c: flac_decoder_new() failed: calloc error\n");
123 return NULL;
124 }
125
126 dec->init = flac_decoder_init;
127 dec->destroy = flac_decoder_destroy;
128 dec->open = flac_decoder_open;
129 dec->send_metadata = flac_decoder_send_metadata;
130 dec->close = flac_decoder_close;
131 dec->read = flac_decoder_read;
132 dec->seek = flac_decoder_seek;
133
134 return dec;
135 }
136
137
138 void
flac_decoder_destroy(decoder_t * dec)139 flac_decoder_destroy(decoder_t * dec) {
140
141 free(dec->pdata);
142 free(dec);
143 }
144
145
146 int
flac_meta_vc_replace_or_append(file_decoder_t * fdec,FLAC__StreamMetadata * smeta)147 flac_meta_vc_replace_or_append(file_decoder_t * fdec, FLAC__StreamMetadata * smeta) {
148
149 FLAC__Metadata_SimpleIterator * iter;
150 FLAC__bool ret;
151 int found = 0;
152
153 iter = FLAC__metadata_simple_iterator_new();
154 if (iter == NULL) {
155 return META_ERROR_NOMEM;
156 }
157
158 ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, false, false);
159 if (!ret) {
160 fprintf(stderr, "dec_flac.c/flac_meta_replace_or_append: error: %s\n",
161 FLAC__Metadata_SimpleIteratorStatusString[
162 FLAC__metadata_simple_iterator_status(iter)]);
163
164 FLAC__metadata_simple_iterator_delete(iter);
165 return META_ERROR_INTERNAL;
166 }
167
168 if (FLAC__metadata_simple_iterator_is_writable(iter) == false) {
169 fprintf(stderr, "error: FLAC meta not writable!\n");
170 FLAC__metadata_simple_iterator_delete(iter);
171 return META_ERROR_NOT_WRITABLE;
172 }
173
174 do {
175 switch (FLAC__metadata_simple_iterator_get_block_type(iter)) {
176 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
177 ret = FLAC__metadata_simple_iterator_set_block(iter, smeta, true);
178 if (ret == false) {
179 fprintf(stderr, "error: FLAC metadata write failed!\n");
180 FLAC__metadata_simple_iterator_delete(iter);
181 return META_ERROR_INTERNAL;
182 }
183 found = 1;
184 break;
185 default:
186 break;
187 }
188 } while (FLAC__metadata_simple_iterator_next(iter));
189
190 if (!found) {
191 do { /* rewind to STREAMINFO and insert after that */
192 if (FLAC__metadata_simple_iterator_get_block_type(iter) ==
193 FLAC__METADATA_TYPE_STREAMINFO) {
194 break;
195 }
196 } while (FLAC__metadata_simple_iterator_prev(iter));
197
198 ret = FLAC__metadata_simple_iterator_insert_block_after(iter, smeta, true);
199 if (ret == false) {
200 fprintf(stderr, "error: FLAC metadata write failed!\n");
201 FLAC__metadata_simple_iterator_delete(iter);
202 return META_ERROR_INTERNAL;
203 }
204 }
205
206 FLAC__metadata_simple_iterator_delete(iter);
207 return META_ERROR_NONE;
208 }
209
210
211 int
flac_meta_append_pics(file_decoder_t * fdec,metadata_t * meta)212 flac_meta_append_pics(file_decoder_t * fdec, metadata_t * meta) {
213
214 FLAC__Metadata_SimpleIterator * iter;
215 FLAC__bool ret;
216 meta_frame_t * frame;
217 int found_vc = 0;
218
219 iter = FLAC__metadata_simple_iterator_new();
220 if (iter == NULL) {
221 return META_ERROR_NOMEM;
222 }
223
224 ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, false, false);
225 if (!ret) {
226 fprintf(stderr, "dec_flac.c/flac_meta_append_pics: error: %s\n",
227 FLAC__Metadata_SimpleIteratorStatusString[
228 FLAC__metadata_simple_iterator_status(iter)]);
229
230 FLAC__metadata_simple_iterator_delete(iter);
231 return META_ERROR_INTERNAL;
232 }
233
234 if (FLAC__metadata_simple_iterator_is_writable(iter) == false) {
235 fprintf(stderr, "error: FLAC meta not writable!\n");
236 FLAC__metadata_simple_iterator_delete(iter);
237 return META_ERROR_NOT_WRITABLE;
238 }
239
240 /* try to insert pictures after the Vorbis Comment, or if
241 there is none, after STREAMINFO. */
242 do {
243 if (FLAC__metadata_simple_iterator_get_block_type(iter) ==
244 FLAC__METADATA_TYPE_VORBIS_COMMENT) {
245 found_vc = 1;
246 break;
247 }
248 } while (FLAC__metadata_simple_iterator_next(iter));
249
250 if (!found_vc) {
251 do { /* rewind to STREAMINFO and insert after that */
252 if (FLAC__metadata_simple_iterator_get_block_type(iter) ==
253 FLAC__METADATA_TYPE_STREAMINFO) {
254 break;
255 }
256 } while (FLAC__metadata_simple_iterator_prev(iter));
257 }
258
259 frame = metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, NULL);
260 while (frame) {
261 FLAC__StreamMetadata * smeta = metadata_apic_frame_to_smeta(frame);
262 ret = FLAC__metadata_simple_iterator_insert_block_after(iter, smeta, true);
263 if (ret == false) {
264 fprintf(stderr, "error: FLAC metadata write failed!\n");
265 FLAC__metadata_object_delete(smeta);
266 FLAC__metadata_simple_iterator_delete(iter);
267 return META_ERROR_INTERNAL;
268 }
269
270 FLAC__metadata_object_delete(smeta);
271 frame = metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, frame);
272 }
273
274 FLAC__metadata_simple_iterator_delete(iter);
275 return META_ERROR_NONE;
276 }
277
278
279 int
flac_meta_delete(file_decoder_t * fdec,int del_vc)280 flac_meta_delete(file_decoder_t * fdec, int del_vc) {
281
282 FLAC__Metadata_SimpleIterator * iter;
283 FLAC__bool ret;
284
285 iter = FLAC__metadata_simple_iterator_new();
286 if (iter == NULL) {
287 return META_ERROR_NOMEM;
288 }
289
290 ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, false, false);
291 if (!ret) {
292 fprintf(stderr, "dec_flac.c/flac_meta_delete: error: %s\n",
293 FLAC__Metadata_SimpleIteratorStatusString[
294 FLAC__metadata_simple_iterator_status(iter)]);
295
296 FLAC__metadata_simple_iterator_delete(iter);
297 return META_ERROR_INTERNAL;
298 }
299
300 if (FLAC__metadata_simple_iterator_is_writable(iter) == false) {
301 fprintf(stderr, "error: FLAC meta not writable!\n");
302 FLAC__metadata_simple_iterator_delete(iter);
303 return META_ERROR_NOT_WRITABLE;
304 }
305
306 do {
307 switch (FLAC__metadata_simple_iterator_get_block_type(iter)) {
308 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
309 if (!del_vc)
310 break;
311 ret = FLAC__metadata_simple_iterator_delete_block(iter, true);
312 if (ret == false) {
313 fprintf(stderr, "error: FLAC metadata delete failed!\n");
314 FLAC__metadata_simple_iterator_delete(iter);
315 return META_ERROR_INTERNAL;
316 }
317 break;
318 case FLAC__METADATA_TYPE_PICTURE:
319 ret = FLAC__metadata_simple_iterator_delete_block(iter, true);
320 if (ret == false) {
321 fprintf(stderr, "error: FLAC metadata delete failed!\n");
322 FLAC__metadata_simple_iterator_delete(iter);
323 return META_ERROR_INTERNAL;
324 }
325 break;
326 default:
327 break;
328 }
329 } while (FLAC__metadata_simple_iterator_next(iter));
330 FLAC__metadata_simple_iterator_delete(iter);
331 return META_ERROR_NONE;
332 }
333
334 int
flac_write_metadata(file_decoder_t * fdec,metadata_t * meta)335 flac_write_metadata(file_decoder_t * fdec, metadata_t * meta) {
336
337 int ret;
338 int del_vc = 0;
339
340 if (metadata_get_frame_by_tag(meta, META_TAG_OXC, NULL) == NULL) {
341 /* no Ogg Xiph comment in this metablock -- remove it from file */
342 del_vc = 1;
343 }
344 ret = flac_meta_delete(fdec, del_vc);
345 if (ret != META_ERROR_NONE) {
346 return ret;
347 }
348
349 if (!del_vc) {
350 FLAC__StreamMetadata * smeta = metadata_to_flac_streammeta(meta);
351 ret = flac_meta_vc_replace_or_append(fdec, smeta);
352 if (ret != META_ERROR_NONE) {
353 return ret;
354 }
355 FLAC__metadata_object_delete(smeta);
356 }
357
358 if (metadata_get_frame_by_tag(meta, META_TAG_FLAC_APIC, NULL) != NULL) {
359 ret = flac_meta_append_pics(fdec, meta);
360 if (ret != META_ERROR_NONE) {
361 return ret;
362 }
363 }
364
365 return META_ERROR_NONE;
366 }
367
368 void
flac_send_metadata(decoder_t * dec)369 flac_send_metadata(decoder_t * dec) {
370
371 file_decoder_t * fdec = dec->fdec;
372 metadata_t * meta;
373 int found = 0;
374 int writable;
375 FLAC__Metadata_SimpleIterator * iter;
376 FLAC__bool ret;
377
378 iter = FLAC__metadata_simple_iterator_new();
379 if (iter == NULL) {
380 return;
381 }
382
383 writable = (access(fdec->filename, R_OK | W_OK) == 0) ? 1 : 0;
384 ret = FLAC__metadata_simple_iterator_init(iter, fdec->filename, writable ? false : true, false);
385 if (!ret) {
386 fprintf(stderr, "dec_flac.c/flac_send_metadata: error: %s\n",
387 FLAC__Metadata_SimpleIteratorStatusString[
388 FLAC__metadata_simple_iterator_status(iter)]);
389
390 FLAC__metadata_simple_iterator_delete(iter);
391 return;
392 }
393
394 meta = metadata_new();
395 meta->fdec = fdec;
396 fdec->meta = meta;
397 meta->valid_tags = META_TAG_OXC | META_TAG_FLAC_APIC;
398 if (writable && FLAC__metadata_simple_iterator_is_writable(iter) == true) {
399 meta->writable = 1;
400 fdec->meta_write = flac_write_metadata;
401 }
402
403 do {
404 FLAC__StreamMetadata * smeta;
405 switch (FLAC__metadata_simple_iterator_get_block_type(iter)) {
406 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
407 smeta = FLAC__metadata_simple_iterator_get_block(iter);
408 FLAC__StreamMetadata_VorbisComment vc =
409 FLAC__metadata_simple_iterator_get_block(iter)->data.vorbis_comment;
410 metadata_from_flac_streammeta_vc(meta, &vc);
411 found = 1;
412
413 FLAC__metadata_object_delete(smeta);
414 break;
415 case FLAC__METADATA_TYPE_PICTURE:
416 smeta = FLAC__metadata_simple_iterator_get_block(iter);
417 FLAC__StreamMetadata_Picture pic =
418 FLAC__metadata_simple_iterator_get_block(iter)->data.picture;
419 metadata_from_flac_streammeta_pic(meta, &pic);
420 found = 1;
421
422 FLAC__metadata_object_delete(smeta);
423 break;
424 default:
425 break;
426 }
427 } while (FLAC__metadata_simple_iterator_next(iter));
428 FLAC__metadata_simple_iterator_delete(iter);
429
430 if (!found && !meta->writable) {
431 fdec->meta = NULL;
432 metadata_free(meta);
433 }
434 }
435
436
437 int
flac_decoder_open(decoder_t * dec,char * filename)438 flac_decoder_open(decoder_t * dec, char * filename) {
439
440 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
441 file_decoder_t * fdec = dec->fdec;
442
443 int tried_flac = 0;
444
445 try_flac:
446 pd->error = 0;
447 pd->state = FLAC__STREAM_DECODER_UNINITIALIZED;
448 pd->flac_decoder = FLAC__stream_decoder_new();
449
450 if (FLAC__stream_decoder_init_file(pd->flac_decoder, filename,
451 write_callback, metadata_callback,
452 error_callback, (void *)dec)
453 != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
454
455 FLAC__stream_decoder_delete(pd->flac_decoder);
456 return DECODER_OPEN_FERROR;
457 }
458
459 pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder);
460 FLAC__stream_decoder_process_until_end_of_metadata(pd->flac_decoder);
461
462 if ((!pd->error) && (pd->channels > 0)) {
463 if ((pd->channels != 1) && (pd->channels != 2)) {
464 fprintf(stderr,
465 "flac_decoder_open: FLAC file with %d channels is "
466 "unsupported\n", pd->channels);
467 return DECODER_OPEN_FERROR;
468 } else {
469 if (!tried_flac) {
470 /* we need a real read test (some MP3's get to this point) */
471 pd->probing = 1;
472 FLAC__stream_decoder_process_single(pd->flac_decoder);
473 pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder);
474
475 if ((pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) &&
476 (pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) &&
477 (pd->state != FLAC__STREAM_DECODER_READ_METADATA) &&
478 (pd->state != FLAC__STREAM_DECODER_READ_FRAME)) {
479 return DECODER_OPEN_BADLIB;
480 }
481
482 pd->probing = 0;
483 tried_flac = 1;
484 FLAC__stream_decoder_finish(pd->flac_decoder);
485 FLAC__stream_decoder_delete(pd->flac_decoder);
486 goto try_flac;
487 }
488
489 pd->rb = rb_create(pd->channels * sample_size * RB_FLAC_SIZE);
490
491 fdec->fileinfo.channels = pd->channels;
492 fdec->fileinfo.sample_rate = pd->SR;
493 fdec->fileinfo.total_samples = pd->total_samples;
494 fdec->fileinfo.bps = pd->bits_per_sample * fdec->fileinfo.sample_rate
495 * fdec->fileinfo.channels;
496
497 fdec->file_lib = FLAC_LIB;
498 strcpy(dec->format_str, "FLAC");
499
500 flac_send_metadata(dec);
501 return DECODER_OPEN_SUCCESS;
502 }
503 } else {
504 FLAC__stream_decoder_finish(pd->flac_decoder);
505 FLAC__stream_decoder_delete(pd->flac_decoder);
506
507 return DECODER_OPEN_BADLIB;
508 }
509 }
510
511
512 void
flac_decoder_send_metadata(decoder_t * dec)513 flac_decoder_send_metadata(decoder_t * dec) {
514
515 file_decoder_t * fdec = dec->fdec;
516
517 if (fdec->meta != NULL && fdec->meta_cb != NULL) {
518 fdec->meta_cb(fdec->meta, fdec->meta_cbdata);
519 }
520 }
521
522
523 void
flac_decoder_close(decoder_t * dec)524 flac_decoder_close(decoder_t * dec) {
525
526 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
527
528 FLAC__stream_decoder_finish(pd->flac_decoder);
529 FLAC__stream_decoder_delete(pd->flac_decoder);
530 rb_free(pd->rb);
531 }
532
533
534 unsigned int
flac_decoder_read(decoder_t * dec,float * dest,int num)535 flac_decoder_read(decoder_t * dec, float * dest, int num) {
536
537 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
538
539 unsigned int numread = 0;
540 unsigned int n_avail = 0;
541
542 pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder);
543 while ((rb_read_space(pd->rb) < num * pd->channels * sample_size) &&
544 (pd->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ||
545 pd->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ||
546 pd->state == FLAC__STREAM_DECODER_READ_METADATA ||
547 pd->state == FLAC__STREAM_DECODER_READ_FRAME)) {
548 FLAC__stream_decoder_process_single(pd->flac_decoder);
549 pd->state = FLAC__stream_decoder_get_state(pd->flac_decoder);
550 }
551
552 /* Have i chosen the right conditions? */
553 if ((pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) &&
554 (pd->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) &&
555 (pd->state != FLAC__STREAM_DECODER_READ_METADATA) &&
556 (pd->state != FLAC__STREAM_DECODER_READ_FRAME) &&
557 (pd->state != FLAC__STREAM_DECODER_END_OF_STREAM)) {
558 fprintf(stderr, "file_decoder_read() / FLAC: decoder error: %s\n",
559 FLAC__StreamDecoderStateString[pd->state]);
560 return 0; /* this means that a new file will be opened */
561 }
562
563 n_avail = rb_read_space(pd->rb) /
564 (pd->channels * sample_size);
565
566 if (n_avail > num) {
567 n_avail = num;
568 }
569
570 rb_read(pd->rb, (char *)dest, n_avail * pd->channels * sample_size);
571 numread = n_avail;
572 return numread;
573 }
574
575
576 void
flac_decoder_seek(decoder_t * dec,unsigned long long seek_to_pos)577 flac_decoder_seek(decoder_t * dec, unsigned long long seek_to_pos) {
578
579 flac_pdata_t * pd = (flac_pdata_t *)dec->pdata;
580 file_decoder_t * fdec = dec->fdec;
581 char flush_dest;
582
583
584 if (seek_to_pos == fdec->fileinfo.total_samples) {
585 --seek_to_pos;
586 }
587
588 if (FLAC__stream_decoder_seek_absolute(pd->flac_decoder, seek_to_pos)) {
589 fdec->samples_left = fdec->fileinfo.total_samples - seek_to_pos;
590
591 /* empty flac decoder ringbuffer */
592 while (rb_read_space(pd->rb))
593 rb_read(pd->rb, &flush_dest, sizeof(char));
594 } else {
595 fprintf(stderr, "flac_decoder_seek: warning: "
596 "FLAC__file_decoder_seek_absolute() failed\n");
597 }
598 }
599
600
601
602 // vim: shiftwidth=8:tabstop=8:softtabstop=8 :
603