diff options
-rw-r--r-- | apps/codecs/aac.c | 18 | ||||
-rw-r--r-- | apps/codecs/libm4a/m4a.c | 61 | ||||
-rw-r--r-- | apps/codecs/libm4a/m4a.h | 4 | ||||
-rw-r--r-- | apps/playback.c | 1 |
4 files changed, 81 insertions, 3 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c index 532082ff05..6c86f38372 100644 --- a/apps/codecs/aac.c +++ b/apps/codecs/aac.c | |||
@@ -75,9 +75,11 @@ next_track: | |||
75 | goto exit; | 75 | goto exit; |
76 | } | 76 | } |
77 | 77 | ||
78 | while (!rb->taginfo_ready) | 78 | while (!*ci->taginfo_ready && !ci->stop_codec) |
79 | rb->yield(); | 79 | ci->sleep(1); |
80 | 80 | ||
81 | samplesdone = ci->id3->offset; | ||
82 | |||
81 | ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); | 83 | ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); |
82 | 84 | ||
83 | stream_create(&input_stream,ci); | 85 | stream_create(&input_stream,ci); |
@@ -117,7 +119,17 @@ next_track: | |||
117 | ci->id3->frequency=s; | 119 | ci->id3->frequency=s; |
118 | 120 | ||
119 | i=0; | 121 | i=0; |
120 | samplesdone=0; | 122 | |
123 | if (samplesdone > 0) { | ||
124 | if (alac_seek_raw(&demux_res, &input_stream, samplesdone, | ||
125 | &samplesdone, (int *)&i)) { | ||
126 | elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); | ||
127 | ci->set_elapsed(elapsedtime); | ||
128 | } else { | ||
129 | samplesdone=0; | ||
130 | } | ||
131 | } | ||
132 | |||
121 | /* The main decoding loop */ | 133 | /* The main decoding loop */ |
122 | while (i < demux_res.num_sample_byte_sizes) { | 134 | while (i < demux_res.num_sample_byte_sizes) { |
123 | rb->yield(); | 135 | rb->yield(); |
diff --git a/apps/codecs/libm4a/m4a.c b/apps/codecs/libm4a/m4a.c index c90fc2b85a..f914f4e4d1 100644 --- a/apps/codecs/libm4a/m4a.c +++ b/apps/codecs/libm4a/m4a.c | |||
@@ -230,3 +230,64 @@ unsigned int alac_seek (demux_res_t* demux_res, | |||
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | } | 232 | } |
233 | |||
234 | /* Seek to file_loc (or close to it). Return 1 on success (and | ||
235 | modify samplesdone and currentblock), 0 if failed | ||
236 | |||
237 | Seeking uses the following array: | ||
238 | |||
239 | the sample_byte_size array contains the length in bytes of | ||
240 | each block ("sample" in Applespeak). | ||
241 | |||
242 | So we just find the last block before (or at) the requested position. | ||
243 | |||
244 | Each ALAC block seems to be independent of all the others. | ||
245 | */ | ||
246 | |||
247 | unsigned int alac_seek_raw (demux_res_t* demux_res, | ||
248 | stream_t* stream, | ||
249 | unsigned int file_loc, | ||
250 | uint32_t* samplesdone, int* currentblock) | ||
251 | { | ||
252 | unsigned int i; | ||
253 | unsigned int j; | ||
254 | unsigned int newblock; | ||
255 | unsigned int newsample; | ||
256 | unsigned int newpos; | ||
257 | |||
258 | /* First check we have the appropriate metadata - we should always | ||
259 | have it. */ | ||
260 | if ((demux_res->num_time_to_samples==0) || | ||
261 | (demux_res->num_sample_byte_sizes==0)) { return 0; } | ||
262 | |||
263 | /* Find the destination block from the sample_byte_size array. */ | ||
264 | newpos=demux_res->mdat_offset; | ||
265 | for (i=0;(i<demux_res->num_sample_byte_sizes) && | ||
266 | (newpos+demux_res->sample_byte_size[i]<=file_loc);i++) { | ||
267 | newpos+=demux_res->sample_byte_size[i]; | ||
268 | } | ||
269 | |||
270 | newblock=i; | ||
271 | newsample=0; | ||
272 | |||
273 | /* Get the sample offset of the block */ | ||
274 | for (i=0,j=0;(i<demux_res->num_time_to_samples) && (j<newblock); | ||
275 | i++,j+=demux_res->time_to_sample[i].sample_count) { | ||
276 | if (newblock-j < demux_res->time_to_sample[i].sample_count) { | ||
277 | newsample+=(newblock-j)*demux_res->time_to_sample[i].sample_duration; | ||
278 | break; | ||
279 | } else { | ||
280 | newsample+=(demux_res->time_to_sample[i].sample_duration | ||
281 | * demux_res->time_to_sample[i].sample_count); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | /* We know the new file position, so let's try to seek to it */ | ||
286 | if (stream->ci->seek_buffer(newpos)) { | ||
287 | *samplesdone=newsample; | ||
288 | *currentblock=newblock; | ||
289 | return 1; | ||
290 | } else { | ||
291 | return 0; | ||
292 | } | ||
293 | } | ||
diff --git a/apps/codecs/libm4a/m4a.h b/apps/codecs/libm4a/m4a.h index 98cf8d6acb..7fea37513d 100644 --- a/apps/codecs/libm4a/m4a.h +++ b/apps/codecs/libm4a/m4a.h | |||
@@ -100,5 +100,9 @@ unsigned int alac_seek (demux_res_t* demux_res, | |||
100 | stream_t* stream, | 100 | stream_t* stream, |
101 | unsigned int sample_loc, | 101 | unsigned int sample_loc, |
102 | uint32_t* samplesdone, int* currentblock); | 102 | uint32_t* samplesdone, int* currentblock); |
103 | unsigned int alac_seek_raw (demux_res_t* demux_res, | ||
104 | stream_t* stream, | ||
105 | unsigned int file_loc, | ||
106 | uint32_t* samplesdone, int* currentblock); | ||
103 | 107 | ||
104 | #endif /* STREAM_H */ | 108 | #endif /* STREAM_H */ |
diff --git a/apps/playback.c b/apps/playback.c index 845fb5c7ff..8d211cfc7c 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -1876,6 +1876,7 @@ static bool audio_load_track(int offset, bool start_play, bool rebuffer) | |||
1876 | case AFMT_FLAC: | 1876 | case AFMT_FLAC: |
1877 | case AFMT_PCM_WAV: | 1877 | case AFMT_PCM_WAV: |
1878 | case AFMT_A52: | 1878 | case AFMT_A52: |
1879 | case AFMT_AAC: | ||
1879 | tracks[track_widx].id3.offset = offset; | 1880 | tracks[track_widx].id3.offset = offset; |
1880 | break; | 1881 | break; |
1881 | } | 1882 | } |