summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2011-07-17 13:00:53 +0000
committerMagnus Holmgren <magnushol@gmail.com>2011-07-17 13:00:53 +0000
commit6f392693b8f1d00513c48dc6e797e174dafb2448 (patch)
tree774b80fa8e759758c70596d95585d98e285c6786 /apps/codecs
parent3a7291020b12d986173aa6d9e91f8fb7c0d35bc9 (diff)
downloadrockbox-6f392693b8f1d00513c48dc6e797e174dafb2448.zip
rockbox-6f392693b8f1d00513c48dc6e797e174dafb2448.tar.gz
rockbox-6f392693b8f1d00513c48dc6e797e174dafb2448.tar.bz2
rockbox-6f392693b8f1d00513c48dc6e797e174dafb2448.tar.xz
AAC: Another gapless fix, this one for the end of the file. The real size of the last frame was lost in r29727, as indicated by Yusaku Inui in FS#12185, so bring it back. Now the decoded length of test1_nero.m4a (in FS#12185) only differs by one sample compared to Foobar2000 (Rockbox has one more leading sample, for some reason). Also moved a few lines to a better place.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30149 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/aac.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index 3d43837..52e08c7 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -61,6 +61,7 @@ enum codec_status codec_run(void)
int file_offset;
int framelength;
int lead_trim = 0;
+ unsigned int frame_samples;
unsigned int i;
unsigned char* buffer;
NeAACDecFrameInfo frame_info;
@@ -214,13 +215,15 @@ enum codec_status codec_run(void)
/* Output the audio */
ci->yield();
+ frame_samples = frame_info.samples >> 1;
+
if (empty_first_frame)
{
/* Remove the first frame from lead_trim, under the assumption
* that it had the same size as this frame
*/
empty_first_frame = false;
- lead_trim -= (frame_info.samples >> 1);
+ lead_trim -= frame_samples;
if (lead_trim < 0)
{
@@ -229,11 +232,30 @@ enum codec_status codec_run(void)
}
/* Gather number of samples for the decoded frame. */
- framelength = (frame_info.samples >> 1) - lead_trim;
+ framelength = frame_samples - lead_trim;
if (i == demux_res.num_sample_byte_sizes - 1)
{
- framelength -= ci->id3->tail_trim;
+ // Size of the last frame
+ const uint32_t sample_duration = (demux_res.num_time_to_samples > 0) ?
+ demux_res.time_to_sample[demux_res.num_time_to_samples - 1].sample_duration :
+ frame_samples;
+
+ /* Currently limited to at most one frame of tail_trim.
+ * Seems to be enough.
+ */
+ if (ci->id3->tail_trim == 0 && sample_duration < frame_samples)
+ {
+ /* Subtract lead_trim just in case we decode a file with only
+ * one audio frame with actual data (lead_trim is usually zero
+ * here).
+ */
+ framelength = sample_duration - lead_trim;
+ }
+ else
+ {
+ framelength -= ci->id3->tail_trim;
+ }
}
if (framelength > 0)
@@ -241,6 +263,10 @@ enum codec_status codec_run(void)
ci->pcmbuf_insert(&decoder->time_out[0][lead_trim],
&decoder->time_out[1][lead_trim],
framelength);
+ sound_samples_done += framelength;
+ /* Update the elapsed-time indicator */
+ elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
+ ci->set_elapsed(elapsed_time);
}
if (lead_trim > 0)
@@ -253,7 +279,7 @@ enum codec_status codec_run(void)
empty_first_frame = true;
}
- lead_trim -= (frame_info.samples >> 1);
+ lead_trim -= frame_samples;
if (lead_trim < 0)
{
@@ -261,11 +287,7 @@ enum codec_status codec_run(void)
}
}
- /* Update the elapsed-time indicator */
- sound_samples_done += framelength;
- elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
- ci->set_elapsed(elapsed_time);
- i++;
+ ++i;
}
LOGF("AAC: Decoded %lu samples\n", (unsigned long)sound_samples_done);