summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-12-10 22:28:16 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-12-10 22:28:16 +0000
commita6653a9bb6c35e01dc44365b51f816198656acf7 (patch)
tree4a271828aa91694403a4e3688b9106b062084dcd
parent09722dd28db02bf7cb34d1a7d42729ce66ebe302 (diff)
downloadrockbox-a6653a9bb6c35e01dc44365b51f816198656acf7.tar.gz
rockbox-a6653a9bb6c35e01dc44365b51f816198656acf7.zip
Fix decoding of multichannel flac, refactor sample buffer handling and decorrelation (taken from ffmpeg sources) and add some flac details to the manual. Solves FS#12371.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31207 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/flac.c22
-rw-r--r--apps/codecs/libffmpegFLAC/decoder.c80
-rw-r--r--apps/codecs/libffmpegFLAC/decoder.h8
-rw-r--r--manual/appendix/file_formats.tex2
4 files changed, 42 insertions, 70 deletions
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c
index c91a173f4a..72bb26663a 100644
--- a/apps/codecs/flac.c
+++ b/apps/codecs/flac.c
@@ -27,6 +27,7 @@ CODEC_HEADER
27/* The output buffers containing the decoded samples (channels 0 and 1) */ 27/* The output buffers containing the decoded samples (channels 0 and 1) */
28static int32_t decoded0[MAX_BLOCKSIZE] IBSS_ATTR_FLAC_DECODED0; 28static int32_t decoded0[MAX_BLOCKSIZE] IBSS_ATTR_FLAC_DECODED0;
29static int32_t decoded1[MAX_BLOCKSIZE] IBSS_ATTR; 29static int32_t decoded1[MAX_BLOCKSIZE] IBSS_ATTR;
30static int32_t dummydec[MAX_BLOCKSIZE];
30 31
31#define MAX_SUPPORTED_SEEKTABLE_SIZE 5000 32#define MAX_SUPPORTED_SEEKTABLE_SIZE 5000
32 33
@@ -80,11 +81,26 @@ static bool flac_init(FLACContext* fc, int first_frame_offset)
80 uint16_t blocksize; 81 uint16_t blocksize;
81 int endofmetadata=0; 82 int endofmetadata=0;
82 uint32_t blocklength; 83 uint32_t blocklength;
84 int ch;
83 85
84 ci->memset(fc,0,sizeof(FLACContext)); 86 ci->memset(fc,0,sizeof(FLACContext));
85 nseekpoints=0; 87 nseekpoints=0;
86 88
87 fc->sample_skip = 0; 89 fc->sample_skip = 0;
90
91 /* Reset sample buffers */
92 memset(decoded0, 0, sizeof(decoded0));
93 memset(decoded1, 0, sizeof(decoded1));
94 memset(dummydec, 0, sizeof(dummydec));
95
96 /* Set sample buffers in decoder structure */
97 fc->decoded[0] = decoded0;
98 fc->decoded[1] = decoded1;
99 for (ch=2; ch<MAX_CHANNELS; ++ch)
100 {
101 /* Only channel 0 and 1 are used, the other are decoded to scratch */
102 fc->decoded[ch] = dummydec;
103 }
88 104
89 /* Skip any foreign tags at start of file */ 105 /* Skip any foreign tags at start of file */
90 ci->seek_buffer(first_frame_offset); 106 ci->seek_buffer(first_frame_offset);
@@ -231,7 +247,7 @@ static bool frame_sync(FLACContext* fc) {
231 /* Decode the frame to verify the frame crc and 247 /* Decode the frame to verify the frame crc and
232 * fill fc with its metadata. 248 * fill fc with its metadata.
233 */ 249 */
234 if(flac_decode_frame(fc, decoded0, decoded1, 250 if(flac_decode_frame(fc,
235 bit_buffer, buff_size, ci->yield) < 0) { 251 bit_buffer, buff_size, ci->yield) < 0) {
236 return false; 252 return false;
237 } 253 }
@@ -485,7 +501,7 @@ enum codec_status codec_run(void)
485 ci->seek_complete(); 501 ci->seek_complete();
486 } 502 }
487 503
488 if((res=flac_decode_frame(&fc,decoded0,decoded1,buf, 504 if((res=flac_decode_frame(&fc,buf,
489 bytesleft,ci->yield)) < 0) { 505 bytesleft,ci->yield)) < 0) {
490 LOGF("FLAC: Frame %d, error %d\n",frame,res); 506 LOGF("FLAC: Frame %d, error %d\n",frame,res);
491 return CODEC_ERROR; 507 return CODEC_ERROR;
@@ -494,7 +510,7 @@ enum codec_status codec_run(void)
494 frame++; 510 frame++;
495 511
496 ci->yield(); 512 ci->yield();
497 ci->pcmbuf_insert(&decoded0[fc.sample_skip], &decoded1[fc.sample_skip], 513 ci->pcmbuf_insert(&fc.decoded[0][fc.sample_skip], &fc.decoded[1][fc.sample_skip],
498 fc.blocksize - fc.sample_skip); 514 fc.blocksize - fc.sample_skip);
499 515
500 fc.sample_skip = 0; 516 fc.sample_skip = 0;
diff --git a/apps/codecs/libffmpegFLAC/decoder.c b/apps/codecs/libffmpegFLAC/decoder.c
index 1fafec17fb..2dbedf3110 100644
--- a/apps/codecs/libffmpegFLAC/decoder.c
+++ b/apps/codecs/libffmpegFLAC/decoder.c
@@ -381,17 +381,13 @@ static inline int decode_subframe(FLACContext *s, int channel, int32_t* decoded)
381} 381}
382 382
383static int decode_frame(FLACContext *s, 383static int decode_frame(FLACContext *s,
384 int32_t* decoded0,
385 int32_t* decoded1,
386 void (*yield)(void)) ICODE_ATTR_FLAC; 384 void (*yield)(void)) ICODE_ATTR_FLAC;
387static int decode_frame(FLACContext *s, 385static int decode_frame(FLACContext *s,
388 int32_t* decoded0,
389 int32_t* decoded1,
390 void (*yield)(void)) 386 void (*yield)(void))
391{ 387{
392 int blocksize_code, sample_rate_code, sample_size_code, assignment, crc8; 388 int blocksize_code, sample_rate_code, sample_size_code, assignment, crc8;
393 int decorrelation, bps, blocksize, samplerate; 389 int decorrelation, bps, blocksize, samplerate;
394 int res; 390 int res, ch;
395 391
396 blocksize_code = get_bits(&s->gb, 4); 392 blocksize_code = get_bits(&s->gb, 4);
397 393
@@ -477,16 +473,10 @@ static int decode_frame(FLACContext *s,
477 s->bps = bps; 473 s->bps = bps;
478 s->decorrelation= decorrelation; 474 s->decorrelation= decorrelation;
479 475
480 yield(); 476 for (ch=0; ch<s->channels; ++ch) {
481 /* subframes */ 477 yield();
482 if ((res=decode_subframe(s, 0, decoded0)) < 0) 478 if ((res=decode_subframe(s, ch, s->decoded[ch])) < 0)
483 return res-100; 479 return res-100;
484
485 yield();
486
487 if (s->channels==2) {
488 if ((res=decode_subframe(s, 1, decoded1)) < 0)
489 return res-200;
490 } 480 }
491 481
492 yield(); 482 yield();
@@ -499,8 +489,6 @@ static int decode_frame(FLACContext *s,
499} 489}
500 490
501int flac_decode_frame(FLACContext *s, 491int flac_decode_frame(FLACContext *s,
502 int32_t* decoded0,
503 int32_t* decoded1,
504 uint8_t *buf, int buf_size, 492 uint8_t *buf, int buf_size,
505 void (*yield)(void)) 493 void (*yield)(void))
506{ 494{
@@ -516,68 +504,36 @@ int flac_decode_frame(FLACContext *s,
516 return -41; 504 return -41;
517 } 505 }
518 506
519 if ((framesize=decode_frame(s,decoded0,decoded1,yield)) < 0){ 507 if ((framesize=decode_frame(s,yield)) < 0){
520 s->bitstream_size=0; 508 s->bitstream_size=0;
521 s->bitstream_index=0; 509 s->bitstream_index=0;
522 return framesize; 510 return framesize;
523 } 511 }
524 512
525 yield(); 513 yield();
514
515#define DECORRELATE(left, right)\
516 for (i = 0; i < s->blocksize; i++) {\
517 int a = s->decoded[0][i];\
518 int b = s->decoded[1][i];\
519 s->decoded[0][i] = (left) << scale;\
520 s->decoded[1][i] = (right) << scale;\
521 }\
526 522
527 scale=FLAC_OUTPUT_DEPTH-s->bps; 523 scale=FLAC_OUTPUT_DEPTH-s->bps;
528 switch(s->decorrelation) 524 switch(s->decorrelation)
529 { 525 {
530 case INDEPENDENT: 526 case INDEPENDENT:
531 if (s->channels==1) {; 527 DECORRELATE(a, b) /* Always decorrelate exactly the two supported channels. */
532 for (i = 0; i < s->blocksize; i++)
533 {
534 decoded0[i] = decoded0[i] << scale;
535 }
536 } else {
537 for (i = 0; i < s->blocksize; i++)
538 {
539 decoded0[i] = decoded0[i] << scale;
540 decoded1[i] = decoded1[i] << scale;
541 }
542 }
543 break; 528 break;
544 case LEFT_SIDE: 529 case LEFT_SIDE:
545 //assert(s->channels == 2); 530 DECORRELATE(a, a-b)
546 for (i = 0; i < s->blocksize; i++)
547 {
548 decoded1[i] = (decoded0[i] - decoded1[i]) << scale;
549 decoded0[i] = decoded0[i] << scale;
550 }
551 break; 531 break;
552 case RIGHT_SIDE: 532 case RIGHT_SIDE:
553 //assert(s->channels == 2); 533 DECORRELATE(a+b, a)
554 for (i = 0; i < s->blocksize; i++)
555 {
556 decoded0[i] = (decoded0[i] + decoded1[i]) << scale;
557 decoded1[i] = decoded1[i] << scale;
558 }
559 break; 534 break;
560 case MID_SIDE: 535 case MID_SIDE:
561 //assert(s->channels == 2); 536 DECORRELATE( (a-=b>>1) + b, a)
562 for (i = 0; i < s->blocksize; i++)
563 {
564 int mid, side;
565 mid = decoded0[i];
566 side = decoded1[i];
567
568#if 1 //needs to be checked but IMHO it should be binary identical
569 mid -= side>>1;
570 decoded0[i] = (mid + side) << scale;
571 decoded1[i] = mid << scale;
572#else
573
574 mid <<= 1;
575 if (side & 1)
576 mid++;
577 decoded0[i] = ((mid + side) >> 1) << scale;
578 decoded1[i] = ((mid - side) >> 1) << scale;
579#endif
580 }
581 break; 537 break;
582 } 538 }
583 539
diff --git a/apps/codecs/libffmpegFLAC/decoder.h b/apps/codecs/libffmpegFLAC/decoder.h
index 0b148df916..677a21ac98 100644
--- a/apps/codecs/libffmpegFLAC/decoder.h
+++ b/apps/codecs/libffmpegFLAC/decoder.h
@@ -3,9 +3,9 @@
3 3
4#include "bitstream.h" 4#include "bitstream.h"
5 5
6#define MAX_CHANNELS 2 /* Maximum supported channels */ 6#define MAX_CHANNELS 6 /* Maximum supported channels, only left/right will be played back */
7#define MAX_BLOCKSIZE 4608 /* Maxsize in samples of one uncompressed frame */ 7#define MAX_BLOCKSIZE 4608 /* Maxsize in samples of one uncompressed frame */
8#define MAX_FRAMESIZE 32768 /* Maxsize in bytes of one compressed frame */ 8#define MAX_FRAMESIZE 65536 /* Maxsize in bytes of one compressed frame */
9 9
10#define FLAC_OUTPUT_DEPTH 29 /* Provide samples left-shifted to 28 bits+sign */ 10#define FLAC_OUTPUT_DEPTH 29 /* Provide samples left-shifted to 28 bits+sign */
11 11
@@ -38,11 +38,11 @@ typedef struct FLACContext {
38 38
39 int sample_skip; 39 int sample_skip;
40 int framesize; 40 int framesize;
41
42 int32_t *decoded[MAX_CHANNELS];
41} FLACContext; 43} FLACContext;
42 44
43int flac_decode_frame(FLACContext *s, 45int flac_decode_frame(FLACContext *s,
44 int32_t* decoded0,
45 int32_t* decoded1,
46 uint8_t *buf, int buf_size, 46 uint8_t *buf, int buf_size,
47 void (*yield)(void)) ICODE_ATTR_FLAC; 47 void (*yield)(void)) ICODE_ATTR_FLAC;
48 48
diff --git a/manual/appendix/file_formats.tex b/manual/appendix/file_formats.tex
index 3c361f7996..f9f2e0a020 100644
--- a/manual/appendix/file_formats.tex
+++ b/manual/appendix/file_formats.tex
@@ -176,7 +176,7 @@
176 & Linear PCM 8/16/24/32 bit, IEEE float 32/64 bit, ITU-T G.711 a-law/$\mu$-law\\ 176 & Linear PCM 8/16/24/32 bit, IEEE float 32/64 bit, ITU-T G.711 a-law/$\mu$-law\\
177 Free Lossless Audio 177 Free Lossless Audio
178 & \fname{.flac} 178 & \fname{.flac}
179 & \\ 179 & Supports multichannel tracks w/o downmixing (only left/right is played).\\
180 Apple Lossless 180 Apple Lossless
181 & \fname{.m4a}, \fname{.mp4} 181 & \fname{.m4a}, \fname{.mp4}
182 & \\ 182 & \\