summaryrefslogtreecommitdiff
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
parent3a7291020b12d986173aa6d9e91f8fb7c0d35bc9 (diff)
downloadrockbox-6f392693b8f1d00513c48dc6e797e174dafb2448.tar.gz
rockbox-6f392693b8f1d00513c48dc6e797e174dafb2448.zip
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
-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 3d43837c99..52e08c7b56 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -61,6 +61,7 @@ enum codec_status codec_run(void)
61 int file_offset; 61 int file_offset;
62 int framelength; 62 int framelength;
63 int lead_trim = 0; 63 int lead_trim = 0;
64 unsigned int frame_samples;
64 unsigned int i; 65 unsigned int i;
65 unsigned char* buffer; 66 unsigned char* buffer;
66 NeAACDecFrameInfo frame_info; 67 NeAACDecFrameInfo frame_info;
@@ -214,13 +215,15 @@ enum codec_status codec_run(void)
214 /* Output the audio */ 215 /* Output the audio */
215 ci->yield(); 216 ci->yield();
216 217
218 frame_samples = frame_info.samples >> 1;
219
217 if (empty_first_frame) 220 if (empty_first_frame)
218 { 221 {
219 /* Remove the first frame from lead_trim, under the assumption 222 /* Remove the first frame from lead_trim, under the assumption
220 * that it had the same size as this frame 223 * that it had the same size as this frame
221 */ 224 */
222 empty_first_frame = false; 225 empty_first_frame = false;
223 lead_trim -= (frame_info.samples >> 1); 226 lead_trim -= frame_samples;
224 227
225 if (lead_trim < 0) 228 if (lead_trim < 0)
226 { 229 {
@@ -229,11 +232,30 @@ enum codec_status codec_run(void)
229 } 232 }
230 233
231 /* Gather number of samples for the decoded frame. */ 234 /* Gather number of samples for the decoded frame. */
232 framelength = (frame_info.samples >> 1) - lead_trim; 235 framelength = frame_samples - lead_trim;
233 236
234 if (i == demux_res.num_sample_byte_sizes - 1) 237 if (i == demux_res.num_sample_byte_sizes - 1)
235 { 238 {
236 framelength -= ci->id3->tail_trim; 239 // Size of the last frame
240 const uint32_t sample_duration = (demux_res.num_time_to_samples > 0) ?
241 demux_res.time_to_sample[demux_res.num_time_to_samples - 1].sample_duration :
242 frame_samples;
243
244 /* Currently limited to at most one frame of tail_trim.
245 * Seems to be enough.
246 */
247 if (ci->id3->tail_trim == 0 && sample_duration < frame_samples)
248 {
249 /* Subtract lead_trim just in case we decode a file with only
250 * one audio frame with actual data (lead_trim is usually zero
251 * here).
252 */
253 framelength = sample_duration - lead_trim;
254 }
255 else
256 {
257 framelength -= ci->id3->tail_trim;
258 }
237 } 259 }
238 260
239 if (framelength > 0) 261 if (framelength > 0)
@@ -241,6 +263,10 @@ enum codec_status codec_run(void)
241 ci->pcmbuf_insert(&decoder->time_out[0][lead_trim], 263 ci->pcmbuf_insert(&decoder->time_out[0][lead_trim],
242 &decoder->time_out[1][lead_trim], 264 &decoder->time_out[1][lead_trim],
243 framelength); 265 framelength);
266 sound_samples_done += framelength;
267 /* Update the elapsed-time indicator */
268 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
269 ci->set_elapsed(elapsed_time);
244 } 270 }
245 271
246 if (lead_trim > 0) 272 if (lead_trim > 0)
@@ -253,7 +279,7 @@ enum codec_status codec_run(void)
253 empty_first_frame = true; 279 empty_first_frame = true;
254 } 280 }
255 281
256 lead_trim -= (frame_info.samples >> 1); 282 lead_trim -= frame_samples;
257 283
258 if (lead_trim < 0) 284 if (lead_trim < 0)
259 { 285 {
@@ -261,11 +287,7 @@ enum codec_status codec_run(void)
261 } 287 }
262 } 288 }
263 289
264 /* Update the elapsed-time indicator */ 290 ++i;
265 sound_samples_done += framelength;
266 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
267 ci->set_elapsed(elapsed_time);
268 i++;
269 } 291 }
270 292
271 LOGF("AAC: Decoded %lu samples\n", (unsigned long)sound_samples_done); 293 LOGF("AAC: Decoded %lu samples\n", (unsigned long)sound_samples_done);