diff options
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r-- | firmware/mpeg.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index ab2fefc872..4c75345f66 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #define MPEG_RESUME 4 | 47 | #define MPEG_RESUME 4 |
48 | #define MPEG_NEXT 5 | 48 | #define MPEG_NEXT 5 |
49 | #define MPEG_PREV 6 | 49 | #define MPEG_PREV 6 |
50 | #define MPEG_FF_REWIND 7 | ||
50 | #define MPEG_NEED_DATA 100 | 51 | #define MPEG_NEED_DATA 100 |
51 | #define MPEG_SWAP_DATA 101 | 52 | #define MPEG_SWAP_DATA 101 |
52 | #define MPEG_TRACK_CHANGE 102 | 53 | #define MPEG_TRACK_CHANGE 102 |
@@ -216,6 +217,22 @@ static void remove_current_tag(void) | |||
216 | } | 217 | } |
217 | } | 218 | } |
218 | 219 | ||
220 | static void remove_all_non_current_tags(void) | ||
221 | { | ||
222 | int i = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; | ||
223 | |||
224 | while (i != tag_write_idx) | ||
225 | { | ||
226 | id3tags[i]->used = false; | ||
227 | id3tags[i] = NULL; | ||
228 | |||
229 | i = (i+1) & MAX_ID3_TAGS_MASK; | ||
230 | } | ||
231 | |||
232 | tag_write_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; | ||
233 | debug_tags(); | ||
234 | } | ||
235 | |||
219 | static void remove_all_tags(void) | 236 | static void remove_all_tags(void) |
220 | { | 237 | { |
221 | int i; | 238 | int i; |
@@ -823,6 +840,112 @@ static void mpeg_thread(void) | |||
823 | break; | 840 | break; |
824 | } | 841 | } |
825 | 842 | ||
843 | case MPEG_FF_REWIND: { | ||
844 | struct mp3entry *id3 = mpeg_current_track(); | ||
845 | int newtime = id3->elapsed + (int)ev.data; | ||
846 | int curpos, newpos, diffpos; | ||
847 | DEBUGF("MPEG_FF_REWIND\n"); | ||
848 | |||
849 | if (id3->vbr && (id3->vbrflags & VBR_TOC_FLAG)) | ||
850 | { | ||
851 | /* Use the TOC to find the new position */ | ||
852 | int percent = (newtime*100)/id3->length; | ||
853 | int curtoc, nexttoc, nextpos, remainder; | ||
854 | |||
855 | if (percent > 99) | ||
856 | percent = 99; | ||
857 | |||
858 | curtoc = id3->toc[percent]; | ||
859 | |||
860 | if (percent < 99) | ||
861 | nexttoc = id3->toc[percent+1]; | ||
862 | else | ||
863 | nexttoc = 256; | ||
864 | |||
865 | newpos = (curtoc*id3->filesize)/256; | ||
866 | |||
867 | /* Use the remainder to get a more accurate position */ | ||
868 | nextpos = (nexttoc*id3->filesize)/256; | ||
869 | remainder = (newtime*10000)/id3->length - (percent*100); | ||
870 | newpos += ((nextpos-newpos)*remainder)/100; | ||
871 | } | ||
872 | else if (id3->bpf && id3->tpf) | ||
873 | newpos = (newtime*id3->bpf)/id3->tpf; | ||
874 | else | ||
875 | /* Not enough information to FF/Rewind */ | ||
876 | break; | ||
877 | |||
878 | newpos = newpos & ~1; | ||
879 | curpos = lseek(mpeg_file, 0, SEEK_CUR); | ||
880 | |||
881 | if (num_tracks_in_memory() > 1) | ||
882 | { | ||
883 | /* We have started loading other tracks that need to be | ||
884 | accounted for */ | ||
885 | int i = tag_read_idx; | ||
886 | int j = tag_write_idx - 1; | ||
887 | |||
888 | if (j < 0) | ||
889 | j = MAX_ID3_TAGS - 1; | ||
890 | |||
891 | while (i != j) | ||
892 | { | ||
893 | curpos += id3tags[i]->id3.filesize; | ||
894 | i = (i+1) & MAX_ID3_TAGS_MASK; | ||
895 | } | ||
896 | } | ||
897 | |||
898 | diffpos = curpos - newpos; | ||
899 | |||
900 | #warning "Borde inte mp3buflen vara mp3buf_write?" | ||
901 | if(diffpos >= 0 && diffpos < mp3buflen) | ||
902 | { | ||
903 | /* We are changing to a position that's already in | ||
904 | memory */ | ||
905 | mp3buf_read = mp3buf_write - diffpos; | ||
906 | if (mp3buf_read < 0) | ||
907 | { | ||
908 | mp3buf_read += mp3buflen; | ||
909 | } | ||
910 | |||
911 | playing = true; | ||
912 | last_dma_tick = current_tick; | ||
913 | init_dma(); | ||
914 | start_dma(); | ||
915 | } | ||
916 | else | ||
917 | { | ||
918 | /* Move to the new position in the file and start | ||
919 | loading data */ | ||
920 | reset_mp3_buffer(); | ||
921 | |||
922 | if (num_tracks_in_memory() > 1) | ||
923 | { | ||
924 | /* We have to reload the current track */ | ||
925 | close(mpeg_file); | ||
926 | remove_all_non_current_tags(); | ||
927 | |||
928 | mpeg_file = open(id3->path, O_RDONLY); | ||
929 | if (mpeg_file < 0) | ||
930 | break; | ||
931 | } | ||
932 | |||
933 | if(-1 == lseek(mpeg_file, newpos, SEEK_SET)) | ||
934 | break; | ||
935 | |||
936 | filling = true; | ||
937 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); | ||
938 | |||
939 | /* Tell the file loading code that we want to start playing | ||
940 | as soon as we have some data */ | ||
941 | play_pending = true; | ||
942 | } | ||
943 | |||
944 | id3->elapsed = newtime; | ||
945 | |||
946 | break; | ||
947 | } | ||
948 | |||
826 | case MPEG_SWAP_DATA: | 949 | case MPEG_SWAP_DATA: |
827 | free_space_left = mp3buf_write - mp3buf_swapwrite; | 950 | free_space_left = mp3buf_write - mp3buf_swapwrite; |
828 | 951 | ||
@@ -1128,6 +1251,15 @@ void mpeg_prev(void) | |||
1128 | #endif | 1251 | #endif |
1129 | } | 1252 | } |
1130 | 1253 | ||
1254 | void mpeg_ff_rewind(int change) | ||
1255 | { | ||
1256 | #ifndef SIMULATOR | ||
1257 | queue_post(&mpeg_queue, MPEG_FF_REWIND, (void *)change); | ||
1258 | #else | ||
1259 | (void)change; | ||
1260 | #endif | ||
1261 | } | ||
1262 | |||
1131 | bool mpeg_is_playing(void) | 1263 | bool mpeg_is_playing(void) |
1132 | { | 1264 | { |
1133 | return playing || play_pending; | 1265 | return playing || play_pending; |