diff options
-rw-r--r-- | apps/codecs/flac.c | 22 | ||||
-rw-r--r-- | apps/codecs/libffmpegFLAC/decoder.c | 80 | ||||
-rw-r--r-- | apps/codecs/libffmpegFLAC/decoder.h | 8 | ||||
-rw-r--r-- | manual/appendix/file_formats.tex | 2 |
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) */ |
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 | 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 | ||
383 | static int decode_frame(FLACContext *s, | 383 | static 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; |
387 | static int decode_frame(FLACContext *s, | 385 | static 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 | ||
501 | int flac_decode_frame(FLACContext *s, | 491 | int 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 | ||
43 | int flac_decode_frame(FLACContext *s, | 45 | int 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 | & \\ |