diff options
author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-12-14 18:02:57 +0000 |
---|---|---|
committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-12-14 18:02:57 +0000 |
commit | 5b8ed62922fce346dc1c92db264e7ceff8c4796e (patch) | |
tree | 6965b1d3cc0f557e8574822c371d0cfe1ce6ed9c /apps | |
parent | 6b450190774accae3bd4185b9c4329acf57b3db9 (diff) | |
download | rockbox-5b8ed62922fce346dc1c92db264e7ceff8c4796e.tar.gz rockbox-5b8ed62922fce346dc1c92db264e7ceff8c4796e.zip |
FS#12443: Implement downmixing to stereo for multichannel flac.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31253 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/flac.c | 5 | ||||
-rw-r--r-- | apps/codecs/libffmpegFLAC/decoder.c | 93 |
2 files changed, 90 insertions, 8 deletions
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c index 72bb26663a..b9f6654f92 100644 --- a/apps/codecs/flac.c +++ b/apps/codecs/flac.c | |||
@@ -27,7 +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) */ |
28 | static int32_t decoded0[MAX_BLOCKSIZE] IBSS_ATTR_FLAC_DECODED0; | 28 | static int32_t decoded0[MAX_BLOCKSIZE] IBSS_ATTR_FLAC_DECODED0; |
29 | static int32_t decoded1[MAX_BLOCKSIZE] IBSS_ATTR; | 29 | static int32_t decoded1[MAX_BLOCKSIZE] IBSS_ATTR; |
30 | static int32_t dummydec[MAX_BLOCKSIZE]; | 30 | static int32_t dummydec[4][MAX_BLOCKSIZE]; |
31 | 31 | ||
32 | #define MAX_SUPPORTED_SEEKTABLE_SIZE 5000 | 32 | #define MAX_SUPPORTED_SEEKTABLE_SIZE 5000 |
33 | 33 | ||
@@ -98,8 +98,7 @@ static bool flac_init(FLACContext* fc, int first_frame_offset) | |||
98 | fc->decoded[1] = decoded1; | 98 | fc->decoded[1] = decoded1; |
99 | for (ch=2; ch<MAX_CHANNELS; ++ch) | 99 | for (ch=2; ch<MAX_CHANNELS; ++ch) |
100 | { | 100 | { |
101 | /* Only channel 0 and 1 are used, the other are decoded to scratch */ | 101 | fc->decoded[ch] = dummydec[ch-2]; |
102 | fc->decoded[ch] = dummydec; | ||
103 | } | 102 | } |
104 | 103 | ||
105 | /* Skip any foreign tags at start of file */ | 104 | /* Skip any foreign tags at start of file */ |
diff --git a/apps/codecs/libffmpegFLAC/decoder.c b/apps/codecs/libffmpegFLAC/decoder.c index ec96307383..1be5fbb6ef 100644 --- a/apps/codecs/libffmpegFLAC/decoder.c +++ b/apps/codecs/libffmpegFLAC/decoder.c | |||
@@ -488,9 +488,87 @@ static int decode_frame(FLACContext *s, | |||
488 | return 0; | 488 | return 0; |
489 | } | 489 | } |
490 | 490 | ||
491 | static int flac_downmix(FLACContext *s) | ||
492 | { | ||
493 | int32_t *FL, *FR, *FC, *SB, *RL, *RR; | ||
494 | int32_t *outL = s->decoded[0]; | ||
495 | int32_t *outR = s->decoded[1]; | ||
496 | int i, scale=FLAC_OUTPUT_DEPTH-s->bps; | ||
497 | |||
498 | switch(s->channels) | ||
499 | { | ||
500 | case 3: /* 3.0 channel order: FL FR FC */ | ||
501 | FL = s->decoded[0]; | ||
502 | FR = s->decoded[1]; | ||
503 | FC = s->decoded[2]; | ||
504 | /* LF = 0.66 LF + 0.33 FC | ||
505 | LR = 0.66 LR + 0.33 FC */ | ||
506 | for (i=0; i<s->blocksize; ++i) { | ||
507 | int32_t a = *(FL)*2 + *(FC); | ||
508 | int32_t b = *(FR)*2 + *(FC); | ||
509 | *outL++ = ((a + (a<<2))>>4) << scale; /* 1/3 ~= 5>>4 */ | ||
510 | *outR++ = ((b + (b<<2))>>4) << scale; /* 1/3 ~= 5>>4 */ | ||
511 | FL++; FR++; FC++; | ||
512 | } | ||
513 | break; | ||
514 | case 4: /* 4.0 channel order: FL FR RL RR */ | ||
515 | FL = s->decoded[0]; | ||
516 | FR = s->decoded[1]; | ||
517 | RL = s->decoded[2]; | ||
518 | RR = s->decoded[3]; | ||
519 | /* LF = 0.50 LF + 0.50 RL + 0.00 RR | ||
520 | LR = 0.50 LR + 0.00 RL + 0.50 RR */ | ||
521 | for (i=0; i<s->blocksize; ++i) { | ||
522 | int32_t a = *(FL) + *(RL); | ||
523 | int32_t b = *(FR) + *(RR); | ||
524 | *outL++ = (a>>1) << scale; | ||
525 | *outR++ = (b>>1) << scale; | ||
526 | FL++; FR++; RL++; RR++; | ||
527 | } | ||
528 | break; | ||
529 | case 5: /* 5.0 channel order: FL FR FC RL RR */ | ||
530 | FL = s->decoded[0]; | ||
531 | FR = s->decoded[1]; | ||
532 | FC = s->decoded[2]; | ||
533 | RL = s->decoded[3]; | ||
534 | RR = s->decoded[4]; | ||
535 | /* LF = 0.40 LF + 0.20 FC + 0.40 RL + 0.00 RR | ||
536 | LR = 0.40 LR + 0.20 FC + 0.00 RL + 0.40 RR */ | ||
537 | for (i=0; i<s->blocksize; ++i) { | ||
538 | int32_t a = *(FL)*2 + *(FC) + *(RL)*2; | ||
539 | int32_t b = *(FR)*2 + *(FC) + *(RR)*2; | ||
540 | *outL++ = ((a + (a<<1))>>4) << scale; /* 3>>4 ~= 1/5 */ | ||
541 | *outR++ = ((b + (b<<1))>>4) << scale; /* 3>>4 ~= 1/5 */ | ||
542 | FL++; FR++; FC++; RL++; RR++; | ||
543 | } | ||
544 | break; | ||
545 | case 6: /* 5.1 channel order: FL FR FC SUB RL RR */ | ||
546 | FL = s->decoded[0]; | ||
547 | FR = s->decoded[1]; | ||
548 | FC = s->decoded[2]; | ||
549 | SB = s->decoded[3]; | ||
550 | RL = s->decoded[4]; | ||
551 | RR = s->decoded[5]; | ||
552 | /* LF = 0.33 LF + 0.16 SUB + 0.16 FC + 0.33 RL + 0.00 RR | ||
553 | LR = 0.33 LR + 0.16 SUB + 0.16 FC + 0.00 RL + 0.33 RR */ | ||
554 | for (i=0; i<s->blocksize; ++i) { | ||
555 | int32_t a = *(FL)*2 + *(SB) + *(FC) + *(RL)*2; | ||
556 | int32_t b = *(FR)*2 + *(SB) + *(FC) + *(RR)*2; | ||
557 | *outL++ = ((a + (a<<2))>>5) << scale; /* 5>>5 ~= 1/6 */ | ||
558 | *outR++ = ((b + (b<<2))>>5) << scale; /* 5>>5 ~= 1/6 */ | ||
559 | FL++; FR++; SB++; FC++; RL++; RR++; | ||
560 | } | ||
561 | break; | ||
562 | default: /* 1.0 and 2.0 do not need downmix, other formats unknown. */ | ||
563 | return -501; | ||
564 | break; | ||
565 | } | ||
566 | return 0; | ||
567 | } | ||
568 | |||
491 | int flac_decode_frame(FLACContext *s, | 569 | int flac_decode_frame(FLACContext *s, |
492 | uint8_t *buf, int buf_size, | 570 | uint8_t *buf, int buf_size, |
493 | void (*yield)(void)) | 571 | void (*yield)(void)) |
494 | { | 572 | { |
495 | int tmp; | 573 | int tmp; |
496 | int i; | 574 | int i; |
@@ -514,8 +592,8 @@ int flac_decode_frame(FLACContext *s, | |||
514 | 592 | ||
515 | #define DECORRELATE(left, right)\ | 593 | #define DECORRELATE(left, right)\ |
516 | for (i = 0; i < s->blocksize; i++) {\ | 594 | for (i = 0; i < s->blocksize; i++) {\ |
517 | int a = s->decoded[0][i];\ | 595 | int32_t a = s->decoded[0][i];\ |
518 | int b = s->decoded[1][i];\ | 596 | int32_t b = s->decoded[1][i];\ |
519 | s->decoded[0][i] = (left) << scale;\ | 597 | s->decoded[0][i] = (left) << scale;\ |
520 | s->decoded[1][i] = (right) << scale;\ | 598 | s->decoded[1][i] = (right) << scale;\ |
521 | }\ | 599 | }\ |
@@ -524,7 +602,12 @@ int flac_decode_frame(FLACContext *s, | |||
524 | switch(s->decorrelation) | 602 | switch(s->decorrelation) |
525 | { | 603 | { |
526 | case INDEPENDENT: | 604 | case INDEPENDENT: |
527 | DECORRELATE(a, b) /* Always decorrelate exactly the two supported channels. */ | 605 | if (s->channels <= 2) { |
606 | DECORRELATE(a, b) /* Always decorrelate exactly the two supported channels. */ | ||
607 | } else { | ||
608 | if ((tmp=flac_downmix(s)) != 0) | ||
609 | return tmp; | ||
610 | } | ||
528 | break; | 611 | break; |
529 | case LEFT_SIDE: | 612 | case LEFT_SIDE: |
530 | DECORRELATE(a, a-b) | 613 | DECORRELATE(a, a-b) |