summaryrefslogtreecommitdiff
path: root/apps/codecs/aac.c
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-02 09:38:24 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-02 09:38:24 +0000
commit4343399473929fd5e746ceee23350d5c6cb264cf (patch)
treeeb2f2306ada36dd7fdb755cfb03a800e45efe0c3 /apps/codecs/aac.c
parent0a93396cdeab4eb96c7e21531a2d9e2dfde15a2b (diff)
downloadrockbox-4343399473929fd5e746ceee23350d5c6cb264cf.tar.gz
rockbox-4343399473929fd5e746ceee23350d5c6cb264cf.zip
Recognize AAC-HE SBR with upsampling and correct duration, bitrate, seek and resume behaviour for such files. When SBR upsampling is used the decoder outputs the double amount of samples per frame. As the seek and resume functions do not know about this fact a special handling is introduced. Fixes issues reported in FS#11916.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29186 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/aac.c')
-rw-r--r--apps/codecs/aac.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index af403852fb..37e525e61a 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -59,6 +59,7 @@ enum codec_status codec_main(void)
59 NeAACDecHandle decoder; 59 NeAACDecHandle decoder;
60 int err; 60 int err;
61 uint32_t s = 0; 61 uint32_t s = 0;
62 uint32_t sbr_fac = 1;
62 unsigned char c = 0; 63 unsigned char c = 0;
63 void *ret; 64 void *ret;
64 65
@@ -143,13 +144,26 @@ next_track:
143 decoder->fb_intermed[1] = &gb_fb_intermed[1][0]; 144 decoder->fb_intermed[1] = &gb_fb_intermed[1][0];
144 } 145 }
145 146
147#ifdef SBR_DEC
148 /* The file uses SBR. */
149 if (decoder->forceUpSampling) {
150 sbr_fac = 2;
151 } else {
152 sbr_fac = 1;
153 }
154#endif
155
146 ci->id3->frequency = s; 156 ci->id3->frequency = s;
147 157
148 i = 0; 158 i = 0;
149 159
150 if (file_offset > 0) { 160 if (file_offset > 0) {
161 /* Resume the desired (byte) position. Important: When resuming SBR
162 * upsampling files the resulting sound_samples_done must be expanded
163 * by a factor of 2. This is done via using sbr_fac. */
151 if (alac_seek_raw(&demux_res, &input_stream, file_offset, 164 if (alac_seek_raw(&demux_res, &input_stream, file_offset,
152 &sound_samples_done, (int*) &i)) { 165 &sound_samples_done, (int*) &i)) {
166 sound_samples_done *= sbr_fac;
153 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); 167 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
154 ci->set_elapsed(elapsed_time); 168 ci->set_elapsed(elapsed_time);
155 } else { 169 } else {
@@ -174,9 +188,14 @@ next_track:
174 188
175 /* Deal with any pending seek requests */ 189 /* Deal with any pending seek requests */
176 if (ci->seek_time) { 190 if (ci->seek_time) {
191 /* Seek to the desired time position. Important: When seeking in SBR
192 * upsampling files the seek_time must be divided by 2 when calling
193 * alac_seek and the resulting sound_samples_done must be expanded
194 * by a factor 2. This is done via using sbr_fac. */
177 if (alac_seek(&demux_res, &input_stream, 195 if (alac_seek(&demux_res, &input_stream,
178 ((ci->seek_time-1)/10)*(ci->id3->frequency/100), 196 ((ci->seek_time-1)/10/sbr_fac)*(ci->id3->frequency/100),
179 &sound_samples_done, (int*) &i)) { 197 &sound_samples_done, (int*) &i)) {
198 sound_samples_done *= sbr_fac;
180 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); 199 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
181 ci->set_elapsed(elapsed_time); 200 ci->set_elapsed(elapsed_time);
182 201
@@ -234,6 +253,10 @@ next_track:
234 /* Output the audio */ 253 /* Output the audio */
235 ci->yield(); 254 ci->yield();
236 255
256 /* Ensure correct sample_duration is used. For SBR upsampling files
257 * sample_duration is only half the size of real output frame size. */
258 sample_duration *= sbr_fac;
259
237 framelength = (frame_info.samples >> 1) - lead_trim; 260 framelength = (frame_info.samples >> 1) - lead_trim;
238 261
239 if (i == demux_res.num_sample_byte_sizes - 1 && framelength > 0) 262 if (i == demux_res.num_sample_byte_sizes - 1 && framelength > 0)
@@ -266,7 +289,7 @@ next_track:
266 { 289 {
267 /* frame_info.samples can be 0 for the first frame */ 290 /* frame_info.samples can be 0 for the first frame */
268 lead_trim -= (i > 0 || frame_info.samples) 291 lead_trim -= (i > 0 || frame_info.samples)
269 ? (frame_info.samples >> 1) : sample_duration; 292 ? (frame_info.samples >> 1) : (uint32_t)framelength;
270 293
271 if (lead_trim < 0 || ci->id3->lead_trim == 0) 294 if (lead_trim < 0 || ci->id3->lead_trim == 0)
272 { 295 {
@@ -275,7 +298,7 @@ next_track:
275 } 298 }
276 299
277 /* Update the elapsed-time indicator */ 300 /* Update the elapsed-time indicator */
278 sound_samples_done += sample_duration; 301 sound_samples_done += framelength;
279 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); 302 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
280 ci->set_elapsed(elapsed_time); 303 ci->set_elapsed(elapsed_time);
281 i++; 304 i++;