diff options
-rw-r--r-- | apps/codecs/aac.c | 29 | ||||
-rw-r--r-- | apps/metadata/mp4.c | 27 |
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. */ | ||
77 | static 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 | ||
731 | bool get_mp4_metadata(int fd, struct mp3entry* id3) | 747 | bool 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 | ||