diff options
-rw-r--r-- | firmware/mpeg.c | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 8e9b008e11..7f736b42e7 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -251,21 +251,40 @@ static void set_elapsed(struct mp3entry* id3) | |||
251 | if ( id3->vbr ) { | 251 | if ( id3->vbr ) { |
252 | if ( id3->vbrflags & VBR_TOC_FLAG ) { | 252 | if ( id3->vbrflags & VBR_TOC_FLAG ) { |
253 | /* calculate elapsed time using TOC */ | 253 | /* calculate elapsed time using TOC */ |
254 | int i, remainder, plen, relpos; | 254 | int i; |
255 | 255 | unsigned int remainder, plen, relpos, nextpos; | |
256 | relpos = id3->offset * 256 / id3->filesize; | ||
257 | remainder = id3->offset - (relpos * id3->filesize / 256); | ||
258 | 256 | ||
259 | /* find wich percent we're at */ | 257 | /* find wich percent we're at */ |
260 | for (i=0; i<100; i++ ) | 258 | for (i=0; i<100; i++ ) |
261 | if ( relpos < id3->toc[i] ) | 259 | { |
260 | if ( id3->offset < (int)(id3->toc[i] * (id3->filesize / 256)) ) | ||
261 | { | ||
262 | break; | 262 | break; |
263 | 263 | } | |
264 | } | ||
265 | |||
266 | i--; | ||
267 | if (i < 0) | ||
268 | i = 0; | ||
269 | |||
270 | relpos = id3->toc[i]; | ||
271 | |||
272 | if (i < 99) | ||
273 | { | ||
274 | nextpos = id3->toc[i+1]; | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | nextpos = 256; | ||
279 | } | ||
280 | |||
281 | remainder = id3->offset - (relpos * (id3->filesize / 256)); | ||
282 | |||
264 | /* set time for this percent */ | 283 | /* set time for this percent */ |
265 | id3->elapsed = (i-1) * id3->length / 100; | 284 | id3->elapsed = i * id3->length / 100; |
266 | 285 | ||
267 | /* calculate remainder time */ | 286 | /* calculate remainder time */ |
268 | plen = (id3->toc[i] - id3->toc[i-1]) * id3->filesize / 256; | 287 | plen = (nextpos - relpos) * (id3->filesize / 256); |
269 | id3->elapsed += remainder * 1000 / plen ; | 288 | id3->elapsed += remainder * 1000 / plen ; |
270 | } | 289 | } |
271 | else { | 290 | else { |
@@ -881,10 +900,13 @@ static void mpeg_thread(void) | |||
881 | 900 | ||
882 | case MPEG_FF_REWIND: { | 901 | case MPEG_FF_REWIND: { |
883 | struct mp3entry *id3 = mpeg_current_track(); | 902 | struct mp3entry *id3 = mpeg_current_track(); |
884 | int newtime = id3->elapsed + (int)ev.data; | 903 | int oldtime = id3->elapsed; |
904 | int newtime = oldtime + (int)ev.data; | ||
885 | int curpos, newpos, diffpos; | 905 | int curpos, newpos, diffpos; |
886 | DEBUGF("MPEG_FF_REWIND\n"); | 906 | DEBUGF("MPEG_FF_REWIND\n"); |
887 | 907 | ||
908 | id3->elapsed = newtime; | ||
909 | |||
888 | if (id3->vbr && (id3->vbrflags & VBR_TOC_FLAG)) | 910 | if (id3->vbr && (id3->vbrflags & VBR_TOC_FLAG)) |
889 | { | 911 | { |
890 | /* Use the TOC to find the new position */ | 912 | /* Use the TOC to find the new position */ |
@@ -913,13 +935,23 @@ static void mpeg_thread(void) | |||
913 | else if (id3->bpf && id3->tpf) | 935 | else if (id3->bpf && id3->tpf) |
914 | newpos = (newtime*id3->bpf)/id3->tpf; | 936 | newpos = (newtime*id3->bpf)/id3->tpf; |
915 | else | 937 | else |
938 | { | ||
916 | /* Not enough information to FF/Rewind */ | 939 | /* Not enough information to FF/Rewind */ |
940 | id3->elapsed = oldtime; | ||
917 | break; | 941 | break; |
942 | } | ||
918 | 943 | ||
919 | /* Don't seek right to the end of the file so that we can | ||
920 | transition properly to the next song */ | ||
921 | if (newpos >= (int)(id3->filesize - id3->id3v1len)) | 944 | if (newpos >= (int)(id3->filesize - id3->id3v1len)) |
945 | { | ||
946 | /* Don't seek right to the end of the file so that we can | ||
947 | transition properly to the next song */ | ||
922 | newpos = id3->filesize - id3->id3v1len - 1; | 948 | newpos = id3->filesize - id3->id3v1len - 1; |
949 | } | ||
950 | else if (newpos < (int)id3->id3v2len) | ||
951 | { | ||
952 | /* skip past id3v2 tag */ | ||
953 | newpos = id3->id3v2len; | ||
954 | } | ||
923 | 955 | ||
924 | newpos = newpos & ~1; | 956 | newpos = newpos & ~1; |
925 | curpos = lseek(mpeg_file, 0, SEEK_CUR); | 957 | curpos = lseek(mpeg_file, 0, SEEK_CUR); |
@@ -980,11 +1012,17 @@ static void mpeg_thread(void) | |||
980 | 1012 | ||
981 | mpeg_file = open(id3->path, O_RDONLY); | 1013 | mpeg_file = open(id3->path, O_RDONLY); |
982 | if (mpeg_file < 0) | 1014 | if (mpeg_file < 0) |
1015 | { | ||
1016 | id3->elapsed = oldtime; | ||
983 | break; | 1017 | break; |
1018 | } | ||
984 | } | 1019 | } |
985 | 1020 | ||
986 | if(-1 == lseek(mpeg_file, newpos, SEEK_SET)) | 1021 | if(-1 == lseek(mpeg_file, newpos, SEEK_SET)) |
1022 | { | ||
1023 | id3->elapsed = oldtime; | ||
987 | break; | 1024 | break; |
1025 | } | ||
988 | 1026 | ||
989 | filling = true; | 1027 | filling = true; |
990 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); | 1028 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); |
@@ -995,7 +1033,6 @@ static void mpeg_thread(void) | |||
995 | } | 1033 | } |
996 | 1034 | ||
997 | id3->offset = newpos; | 1035 | id3->offset = newpos; |
998 | id3->elapsed = newtime; | ||
999 | 1036 | ||
1000 | break; | 1037 | break; |
1001 | } | 1038 | } |