summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2006-08-23 13:10:48 +0000
committerMagnus Holmgren <magnushol@gmail.com>2006-08-23 13:10:48 +0000
commit9f09a394368a8fb2fb0da7840535ce9cd5583ee0 (patch)
tree754bc12cd648709b36cd5d5939e9753acde04633 /apps/codecs
parenta04cef7adee7e79cdafcbf8efb5ee9110a8d4ab1 (diff)
downloadrockbox-9f09a394368a8fb2fb0da7840535ce9cd5583ee0.zip
rockbox-9f09a394368a8fb2fb0da7840535ce9cd5583ee0.tar.gz
rockbox-9f09a394368a8fb2fb0da7840535ce9cd5583ee0.tar.bz2
rockbox-9f09a394368a8fb2fb0da7840535ce9cd5583ee0.tar.xz
Add resume support to AAC files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10720 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/aac.c18
-rw-r--r--apps/codecs/libm4a/m4a.c61
-rw-r--r--apps/codecs/libm4a/m4a.h4
3 files changed, 80 insertions, 3 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index 532082f..6c86f38 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -75,9 +75,11 @@ next_track:
goto exit;
}
- while (!rb->taginfo_ready)
- rb->yield();
+ while (!*ci->taginfo_ready && !ci->stop_codec)
+ ci->sleep(1);
+ samplesdone = ci->id3->offset;
+
ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency));
stream_create(&input_stream,ci);
@@ -117,7 +119,17 @@ next_track:
ci->id3->frequency=s;
i=0;
- samplesdone=0;
+
+ if (samplesdone > 0) {
+ if (alac_seek_raw(&demux_res, &input_stream, samplesdone,
+ &samplesdone, (int *)&i)) {
+ elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
+ ci->set_elapsed(elapsedtime);
+ } else {
+ samplesdone=0;
+ }
+ }
+
/* The main decoding loop */
while (i < demux_res.num_sample_byte_sizes) {
rb->yield();
diff --git a/apps/codecs/libm4a/m4a.c b/apps/codecs/libm4a/m4a.c
index c90fc2b..f914f4e 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,
return 0;
}
}
+
+/* Seek to file_loc (or close to it). Return 1 on success (and
+ modify samplesdone and currentblock), 0 if failed
+
+ Seeking uses the following array:
+
+ the sample_byte_size array contains the length in bytes of
+ each block ("sample" in Applespeak).
+
+ So we just find the last block before (or at) the requested position.
+
+ Each ALAC block seems to be independent of all the others.
+ */
+
+unsigned int alac_seek_raw (demux_res_t* demux_res,
+ stream_t* stream,
+ unsigned int file_loc,
+ uint32_t* samplesdone, int* currentblock)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int newblock;
+ unsigned int newsample;
+ unsigned int newpos;
+
+ /* First check we have the appropriate metadata - we should always
+ have it. */
+ if ((demux_res->num_time_to_samples==0) ||
+ (demux_res->num_sample_byte_sizes==0)) { return 0; }
+
+ /* Find the destination block from the sample_byte_size array. */
+ newpos=demux_res->mdat_offset;
+ for (i=0;(i<demux_res->num_sample_byte_sizes) &&
+ (newpos+demux_res->sample_byte_size[i]<=file_loc);i++) {
+ newpos+=demux_res->sample_byte_size[i];
+ }
+
+ newblock=i;
+ newsample=0;
+
+ /* Get the sample offset of the block */
+ for (i=0,j=0;(i<demux_res->num_time_to_samples) && (j<newblock);
+ i++,j+=demux_res->time_to_sample[i].sample_count) {
+ if (newblock-j < demux_res->time_to_sample[i].sample_count) {
+ newsample+=(newblock-j)*demux_res->time_to_sample[i].sample_duration;
+ break;
+ } else {
+ newsample+=(demux_res->time_to_sample[i].sample_duration
+ * demux_res->time_to_sample[i].sample_count);
+ }
+ }
+
+ /* We know the new file position, so let's try to seek to it */
+ if (stream->ci->seek_buffer(newpos)) {
+ *samplesdone=newsample;
+ *currentblock=newblock;
+ return 1;
+ } else {
+ return 0;
+ }
+}
diff --git a/apps/codecs/libm4a/m4a.h b/apps/codecs/libm4a/m4a.h
index 98cf8d6..7fea375 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,
stream_t* stream,
unsigned int sample_loc,
uint32_t* samplesdone, int* currentblock);
+unsigned int alac_seek_raw (demux_res_t* demux_res,
+ stream_t* stream,
+ unsigned int file_loc,
+ uint32_t* samplesdone, int* currentblock);
#endif /* STREAM_H */