From 35bcdef1441519bb66a77b675013309ef39e9eec Mon Sep 17 00:00:00 2001 From: Andree Buschmann Date: Wed, 2 Feb 2011 15:12:55 +0000 Subject: 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 --- apps/codecs/aac.c | 4 ++-- apps/metadata.h | 4 ++++ apps/metadata/mp4.c | 27 +++++++++++++++++++-------- 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: } #ifdef SBR_DEC - /* The file uses SBR. */ - if (decoder->forceUpSampling) { + /* Check for need of special handling for seek/resume and elapsed time. */ + if (ci->id3->needs_upsampling_correction) { sbr_fac = 2; } else { 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 { /* Added for ATRAC3 */ unsigned int channels; /* Number of channels in the stream */ unsigned int extradata_size; /* Size (in bytes) of the codec's extradata from the container */ + + /* Added for AAC HE SBR */ + bool needs_upsampling_correction; /* flag used by aac codec */ + /* these following two fields are used for local buffering */ char id3v2buf[ID3V2_BUF_SIZE]; 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, { uint32_t entries; unsigned int i; - + + /* Reset to false. */ + id3->needs_upsampling_correction = true; + lseek(fd, 4, SEEK_CUR); read_uint32be(fd, &entries); id3->samples = 0; @@ -651,7 +654,21 @@ static bool read_mp4_container(int fd, struct mp3entry* id3, read_uint32be(fd, &n); read_uint32be(fd, &l); - id3->samples += n * l; + + /* Some SBR files use upsampling. In this case the number + * of output samples is doubled to a maximum of 2048 + * samples per frame. This means that files which already + * report a frame size of 2048 in their header will not + * need any further special handling. */ + if (SBR_upsampling_used && l<=1024) + { + id3->samples += n * l * 2; + id3->needs_upsampling_correction = true; + } + else + { + id3->samples += n * l; + } } size = 0; @@ -760,12 +777,6 @@ bool get_mp4_metadata(int fd, struct mp3entry* id3) logf("Not an ALAC or AAC file"); return false; } - - /* SBR upsampling will output double amount of samples per frame. */ - if (SBR_upsampling_used) - { - id3->samples *= 2; - } id3->length = ((int64_t) id3->samples * 1000) / id3->frequency; -- cgit v1.2.3