From 6f392693b8f1d00513c48dc6e797e174dafb2448 Mon Sep 17 00:00:00 2001 From: Magnus Holmgren Date: Sun, 17 Jul 2011 13:00:53 +0000 Subject: 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 --- apps/codecs/aac.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c index 3d43837c99..52e08c7b56 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); -- cgit v1.2.3