summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/aac.c29
-rw-r--r--apps/metadata/mp4.c27
2 files changed, 51 insertions, 5 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++;
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index a59b3f9819..c9c691f0c4 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -73,6 +73,9 @@
73#define MP4_udta FOURCC('u', 'd', 't', 'a') 73#define MP4_udta FOURCC('u', 'd', 't', 'a')
74#define MP4_extra FOURCC('-', '-', '-', '-') 74#define MP4_extra FOURCC('-', '-', '-', '-')
75 75
76/* Used to correct id3->samples, if SBR upsampling was detected in esds atom. */
77static bool SBR_upsampling_used = false;
78
76/* Read the tag data from an MP4 file, storing up to buffer_size bytes in 79/* Read the tag data from an MP4 file, storing up to buffer_size bytes in
77 * buffer. 80 * buffer.
78 */ 81 */
@@ -272,7 +275,6 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
272 275
273 if (type == 5) 276 if (type == 5)
274 { 277 {
275 DEBUGF("MP4: SBR\n");
276 unsigned int old_index = index; 278 unsigned int old_index = index;
277 279
278 sbr = true; 280 sbr = true;
@@ -342,6 +344,12 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
342 * decoding (parts of) the file. 344 * decoding (parts of) the file.
343 */ 345 */
344 id3->frequency *= 2; 346 id3->frequency *= 2;
347
348 /* Set this to true to be able to calculate the correct runtime
349 * and bitrate. */
350 SBR_upsampling_used = true;
351
352 sbr = true;
345 } 353 }
346 } 354 }
347 355
@@ -665,6 +673,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
665 { 673 {
666 uint32_t subsize; 674 uint32_t subsize;
667 uint32_t subtype; 675 uint32_t subtype;
676 bool sbr_used;
668 677
669 /* Get frequency from the decoder info tag, if possible. */ 678 /* Get frequency from the decoder info tag, if possible. */
670 lseek(fd, 2, SEEK_CUR); 679 lseek(fd, 2, SEEK_CUR);
@@ -676,7 +685,14 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
676 685
677 if (subtype == MP4_esds) 686 if (subtype == MP4_esds)
678 { 687 {
679 read_mp4_esds(fd, id3, &size); 688 sbr_used = read_mp4_esds(fd, id3, &size);
689 if (sbr_used)
690 {
691 if (SBR_upsampling_used)
692 DEBUGF("MP4: AAC-HE, SBR upsampling\n");
693 else
694 DEBUGF("MP4: AAC-HE, SBR\n");
695 }
680 } 696 }
681 } 697 }
682 } 698 }
@@ -730,6 +746,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
730 746
731bool get_mp4_metadata(int fd, struct mp3entry* id3) 747bool get_mp4_metadata(int fd, struct mp3entry* id3)
732{ 748{
749 SBR_upsampling_used = false;
733 id3->codectype = AFMT_UNKNOWN; 750 id3->codectype = AFMT_UNKNOWN;
734 id3->filesize = 0; 751 id3->filesize = 0;
735 errno = 0; 752 errno = 0;
@@ -743,6 +760,12 @@ bool get_mp4_metadata(int fd, struct mp3entry* id3)
743 logf("Not an ALAC or AAC file"); 760 logf("Not an ALAC or AAC file");
744 return false; 761 return false;
745 } 762 }
763
764 /* SBR upsampling will output double amount of samples per frame. */
765 if (SBR_upsampling_used)
766 {
767 id3->samples *= 2;
768 }
746 769
747 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency; 770 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
748 771