summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c132
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
220static 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
219static void remove_all_tags(void) 236static 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
1254void 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
1131bool mpeg_is_playing(void) 1263bool mpeg_is_playing(void)
1132{ 1264{
1133 return playing || play_pending; 1265 return playing || play_pending;