summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-02 15:12:55 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-02 15:12:55 +0000
commit35bcdef1441519bb66a77b675013309ef39e9eec (patch)
tree62a3ebcfecb0a4a582d5bd1998e29be066e090e0
parent0f4dfc4e9d4c2cbae69442e415639476c73478b2 (diff)
downloadrockbox-35bcdef1441519bb66a77b675013309ef39e9eec.tar.gz
rockbox-35bcdef1441519bb66a77b675013309ef39e9eec.zip
Find a more consistent and resilient way to handle SBR upsampled files. The detection is only done in one place (the metadata parser) and takes into account that the m4a header might already report corrected frame/sample sizes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29188 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/aac.c4
-rw-r--r--apps/metadata.h4
-rw-r--r--apps/metadata/mp4.c27
3 files changed, 25 insertions, 10 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index 37e525e61a..0b27eed472 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -145,8 +145,8 @@ next_track:
145 } 145 }
146 146
147#ifdef SBR_DEC 147#ifdef SBR_DEC
148 /* The file uses SBR. */ 148 /* Check for need of special handling for seek/resume and elapsed time. */
149 if (decoder->forceUpSampling) { 149 if (ci->id3->needs_upsampling_correction) {
150 sbr_fac = 2; 150 sbr_fac = 2;
151 } else { 151 } else {
152 sbr_fac = 1; 152 sbr_fac = 1;
diff --git a/apps/metadata.h b/apps/metadata.h
index f366aea61c..93b9891763 100644
--- a/apps/metadata.h
+++ b/apps/metadata.h
@@ -240,6 +240,10 @@ struct mp3entry {
240 /* Added for ATRAC3 */ 240 /* Added for ATRAC3 */
241 unsigned int channels; /* Number of channels in the stream */ 241 unsigned int channels; /* Number of channels in the stream */
242 unsigned int extradata_size; /* Size (in bytes) of the codec's extradata from the container */ 242 unsigned int extradata_size; /* Size (in bytes) of the codec's extradata from the container */
243
244 /* Added for AAC HE SBR */
245 bool needs_upsampling_correction; /* flag used by aac codec */
246
243 /* these following two fields are used for local buffering */ 247 /* these following two fields are used for local buffering */
244 char id3v2buf[ID3V2_BUF_SIZE]; 248 char id3v2buf[ID3V2_BUF_SIZE];
245 char id3v1buf[4][92]; 249 char id3v1buf[4][92];
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index c9c691f0c4..a3721f0e9a 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -639,7 +639,10 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
639 { 639 {
640 uint32_t entries; 640 uint32_t entries;
641 unsigned int i; 641 unsigned int i;
642 642
643 /* Reset to false. */
644 id3->needs_upsampling_correction = true;
645
643 lseek(fd, 4, SEEK_CUR); 646 lseek(fd, 4, SEEK_CUR);
644 read_uint32be(fd, &entries); 647 read_uint32be(fd, &entries);
645 id3->samples = 0; 648 id3->samples = 0;
@@ -651,7 +654,21 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
651 654
652 read_uint32be(fd, &n); 655 read_uint32be(fd, &n);
653 read_uint32be(fd, &l); 656 read_uint32be(fd, &l);
654 id3->samples += n * l; 657
658 /* Some SBR files use upsampling. In this case the number
659 * of output samples is doubled to a maximum of 2048
660 * samples per frame. This means that files which already
661 * report a frame size of 2048 in their header will not
662 * need any further special handling. */
663 if (SBR_upsampling_used && l<=1024)
664 {
665 id3->samples += n * l * 2;
666 id3->needs_upsampling_correction = true;
667 }
668 else
669 {
670 id3->samples += n * l;
671 }
655 } 672 }
656 673
657 size = 0; 674 size = 0;
@@ -760,12 +777,6 @@ bool get_mp4_metadata(int fd, struct mp3entry* id3)
760 logf("Not an ALAC or AAC file"); 777 logf("Not an ALAC or AAC file");
761 return false; 778 return false;
762 } 779 }
763
764 /* SBR upsampling will output double amount of samples per frame. */
765 if (SBR_upsampling_used)
766 {
767 id3->samples *= 2;
768 }
769 780
770 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency; 781 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
771 782