diff options
author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-02-02 09:38:24 +0000 |
---|---|---|
committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-02-02 09:38:24 +0000 |
commit | 4343399473929fd5e746ceee23350d5c6cb264cf (patch) | |
tree | eb2f2306ada36dd7fdb755cfb03a800e45efe0c3 /apps/codecs/aac.c | |
parent | 0a93396cdeab4eb96c7e21531a2d9e2dfde15a2b (diff) | |
download | rockbox-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.c | 29 |
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++; |