diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/aac.c | 54 | ||||
-rw-r--r-- | apps/metadata.c | 50 |
2 files changed, 102 insertions, 2 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c index 11a9d2888d..d4f051c09c 100644 --- a/apps/codecs/aac.c +++ b/apps/codecs/aac.c | |||
@@ -42,6 +42,8 @@ enum codec_status codec_main(void) | |||
42 | uint32_t sample_duration; | 42 | uint32_t sample_duration; |
43 | uint32_t sample_byte_size; | 43 | uint32_t sample_byte_size; |
44 | int file_offset; | 44 | int file_offset; |
45 | int framelength; | ||
46 | int lead_trim = 0; | ||
45 | unsigned int i; | 47 | unsigned int i; |
46 | unsigned char* buffer; | 48 | unsigned char* buffer; |
47 | static NeAACDecFrameInfo frame_info; | 49 | static NeAACDecFrameInfo frame_info; |
@@ -117,6 +119,11 @@ next_track: | |||
117 | sound_samples_done = 0; | 119 | sound_samples_done = 0; |
118 | } | 120 | } |
119 | } | 121 | } |
122 | |||
123 | if (i == 0) | ||
124 | { | ||
125 | lead_trim = ci->id3->lead_trim; | ||
126 | } | ||
120 | 127 | ||
121 | /* The main decoding loop */ | 128 | /* The main decoding loop */ |
122 | while (i < demux_res.num_sample_byte_sizes) { | 129 | while (i < demux_res.num_sample_byte_sizes) { |
@@ -133,6 +140,11 @@ next_track: | |||
133 | &sound_samples_done, (int*) &i)) { | 140 | &sound_samples_done, (int*) &i)) { |
134 | elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); | 141 | elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); |
135 | ci->set_elapsed(elapsed_time); | 142 | ci->set_elapsed(elapsed_time); |
143 | |||
144 | if (i == 0) | ||
145 | { | ||
146 | lead_trim = ci->id3->lead_trim; | ||
147 | } | ||
136 | } | 148 | } |
137 | ci->seek_complete(); | 149 | ci->seek_complete(); |
138 | } | 150 | } |
@@ -183,8 +195,46 @@ next_track: | |||
183 | 195 | ||
184 | /* Output the audio */ | 196 | /* Output the audio */ |
185 | ci->yield(); | 197 | ci->yield(); |
186 | ci->pcmbuf_insert(decoder->time_out[0], decoder->time_out[1], | 198 | |
187 | frame_info.samples >> 1); | 199 | framelength = (frame_info.samples >> 1) - lead_trim; |
200 | |||
201 | if (i == demux_res.num_sample_byte_sizes - 1 && framelength > 0) | ||
202 | { | ||
203 | /* Currently limited to at most one frame of tail_trim. | ||
204 | * Seems to be enough. | ||
205 | */ | ||
206 | if (ci->id3->tail_trim == 0 | ||
207 | && sample_duration < (frame_info.samples >> 1)) | ||
208 | { | ||
209 | /* Subtract lead_trim just in case we decode a file with | ||
210 | * only one audio frame with actual data. | ||
211 | */ | ||
212 | framelength = sample_duration - lead_trim; | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | framelength -= ci->id3->tail_trim; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | if (framelength > 0) | ||
221 | { | ||
222 | ci->pcmbuf_insert(&decoder->time_out[0][lead_trim], | ||
223 | &decoder->time_out[1][lead_trim], | ||
224 | framelength); | ||
225 | } | ||
226 | |||
227 | if (lead_trim > 0) | ||
228 | { | ||
229 | /* frame_info.samples can be 0 for the first frame */ | ||
230 | lead_trim -= (i > 0 || frame_info.samples) | ||
231 | ? (frame_info.samples >> 1) : sample_duration; | ||
232 | |||
233 | if (lead_trim < 0 || ci->id3->lead_trim == 0) | ||
234 | { | ||
235 | lead_trim = 0; | ||
236 | } | ||
237 | } | ||
188 | 238 | ||
189 | /* Update the elapsed-time indicator */ | 239 | /* Update the elapsed-time indicator */ |
190 | sound_samples_done += sample_duration; | 240 | sound_samples_done += sample_duration; |
diff --git a/apps/metadata.c b/apps/metadata.c index 357c5e649e..a0c2f31eee 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -206,6 +206,43 @@ static long get_slong(void* buf) | |||
206 | 206 | ||
207 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | 207 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
208 | } | 208 | } |
209 | |||
210 | static char* skip_space(char* str) | ||
211 | { | ||
212 | while (isspace(*str)) | ||
213 | { | ||
214 | str++; | ||
215 | } | ||
216 | |||
217 | return str; | ||
218 | } | ||
219 | |||
220 | static unsigned long get_itunes_int32(char* value, int count) | ||
221 | { | ||
222 | static const char hexdigits[] = "0123456789ABCDEF"; | ||
223 | const char* c; | ||
224 | int r = 0; | ||
225 | |||
226 | while (count-- > 0) | ||
227 | { | ||
228 | value = skip_space(value); | ||
229 | |||
230 | while (*value && !isspace(*value)) | ||
231 | { | ||
232 | value++; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | value = skip_space(value); | ||
237 | |||
238 | while (*value && ((c = strchr(hexdigits, toupper(*value))) != NULL)) | ||
239 | { | ||
240 | r = (r << 4) | (c - hexdigits); | ||
241 | value++; | ||
242 | } | ||
243 | |||
244 | return r; | ||
245 | } | ||
209 | 246 | ||
210 | /* Parse the tag (the name-value pair) and fill id3 and buffer accordingly. | 247 | /* Parse the tag (the name-value pair) and fill id3 and buffer accordingly. |
211 | * String values to keep are written to buf. Returns number of bytes written | 248 | * String values to keep are written to buf. Returns number of bytes written |
@@ -1520,6 +1557,19 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3, | |||
1520 | { | 1557 | { |
1521 | read_mp4_tag_string(fd, size, &buffer, &buffer_left, | 1558 | read_mp4_tag_string(fd, size, &buffer, &buffer_left, |
1522 | &id3->composer); | 1559 | &id3->composer); |
1560 | } | ||
1561 | else if (strcasecmp(tag_name, "iTunSMPB") == 0) | ||
1562 | { | ||
1563 | char value[TAG_VALUE_LENGTH]; | ||
1564 | char* value_p = value; | ||
1565 | char* any; | ||
1566 | unsigned int length = sizeof(value); | ||
1567 | |||
1568 | read_mp4_tag_string(fd, size, &value_p, &length, &any); | ||
1569 | id3->lead_trim = get_itunes_int32(value, 1); | ||
1570 | id3->tail_trim = get_itunes_int32(value, 2); | ||
1571 | DEBUGF("AAC: lead_trim %d, tail_trim %d\n", | ||
1572 | id3->lead_trim, id3->tail_trim); | ||
1523 | } | 1573 | } |
1524 | else | 1574 | else |
1525 | { | 1575 | { |