summaryrefslogtreecommitdiff
path: root/apps/codecs/libffmpegFLAC/decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libffmpegFLAC/decoder.c')
-rw-r--r--apps/codecs/libffmpegFLAC/decoder.c93
1 files changed, 88 insertions, 5 deletions
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
491static 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
491int flac_decode_frame(FLACContext *s, 569int 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)