diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-08-16 14:41:47 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-08-16 14:41:47 +0000 |
commit | 6224cdb16677cae7b65b0598eec3381a6fb6a4aa (patch) | |
tree | 9ad9b39557492606c853e7f14c359bca5e0a3b65 /firmware/mpeg.c | |
parent | 085e77467565aba251c31721e92bc7ebd7baa61f (diff) | |
download | rockbox-6224cdb16677cae7b65b0598eec3381a6fb6a4aa.tar.gz rockbox-6224cdb16677cae7b65b0598eec3381a6fb6a4aa.zip |
Added resume. Works in dirs and playlists, shuffled or not. Resumes mid-song, but press pause on players before you shutdown so they get a chance to store the position on disk. Recorders use RTC ram. Todo: Time display is wrong after mid-track resume and ffd/rew is not handled.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1787 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r-- | firmware/mpeg.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index a8442f2e85..13562190ce 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -52,7 +52,8 @@ | |||
52 | #define MPEG_SWAP_DATA 101 | 52 | #define MPEG_SWAP_DATA 101 |
53 | #define MPEG_TRACK_CHANGE 102 | 53 | #define MPEG_TRACK_CHANGE 102 |
54 | 54 | ||
55 | extern char* playlist_next(int steps); | 55 | extern char* playlist_next(int steps, int* id); |
56 | extern void update_file_pos( int id, int pos ); | ||
56 | 57 | ||
57 | static char *units[] = | 58 | static char *units[] = |
58 | { | 59 | { |
@@ -243,6 +244,7 @@ static void remove_all_tags(void) | |||
243 | } | 244 | } |
244 | #endif | 245 | #endif |
245 | 246 | ||
247 | static bool paused; /* playback is paused */ | ||
246 | #ifdef SIMULATOR | 248 | #ifdef SIMULATOR |
247 | static bool playing = false; | 249 | static bool playing = false; |
248 | static bool play_pending = false; | 250 | static bool play_pending = false; |
@@ -502,7 +504,7 @@ static void stop_dma(void) | |||
502 | 504 | ||
503 | static void dma_tick(void) | 505 | static void dma_tick(void) |
504 | { | 506 | { |
505 | if(playing) | 507 | if(playing && !paused) |
506 | { | 508 | { |
507 | /* Start DMA if it is disabled and the DEMAND pin is high */ | 509 | /* Start DMA if it is disabled and the DEMAND pin is high */ |
508 | if(!dma_on && (PBDR & 0x4000)) | 510 | if(!dma_on && (PBDR & 0x4000)) |
@@ -594,6 +596,7 @@ void DEI3(void) | |||
594 | 596 | ||
595 | DTCR3 = last_dma_chunk_size & 0xffff; | 597 | DTCR3 = last_dma_chunk_size & 0xffff; |
596 | SAR3 = (unsigned int)mp3buf + mp3buf_read; | 598 | SAR3 = (unsigned int)mp3buf + mp3buf_read; |
599 | id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size; | ||
597 | } | 600 | } |
598 | else | 601 | else |
599 | { | 602 | { |
@@ -646,10 +649,11 @@ static void add_track_to_tag_list(char *filename) | |||
646 | /* If next_track is true, opens the next track, if false, opens prev track */ | 649 | /* If next_track is true, opens the next track, if false, opens prev track */ |
647 | static int new_file(int steps) | 650 | static int new_file(int steps) |
648 | { | 651 | { |
649 | char *trackname; | ||
650 | |||
651 | do { | 652 | do { |
652 | trackname = playlist_next( steps ); | 653 | char *trackname; |
654 | int index; | ||
655 | |||
656 | trackname = playlist_next( steps, &index ); | ||
653 | if ( !trackname ) | 657 | if ( !trackname ) |
654 | return -1; | 658 | return -1; |
655 | 659 | ||
@@ -666,6 +670,8 @@ static int new_file(int steps) | |||
666 | lseek(mpeg_file, | 670 | lseek(mpeg_file, |
667 | id3tags[tag_read_idx]->id3.id3v2len & ~1, | 671 | id3tags[tag_read_idx]->id3.id3v2len & ~1, |
668 | SEEK_SET); | 672 | SEEK_SET); |
673 | id3tags[tag_read_idx]->id3.index = index; | ||
674 | id3tags[tag_read_idx]->id3.offset = 0; | ||
669 | } | 675 | } |
670 | } while ( mpeg_file < 0 ); | 676 | } while ( mpeg_file < 0 ); |
671 | 677 | ||
@@ -706,6 +712,7 @@ static void mpeg_thread(void) | |||
706 | int amount_to_read; | 712 | int amount_to_read; |
707 | int amount_to_swap; | 713 | int amount_to_swap; |
708 | int t1, t2; | 714 | int t1, t2; |
715 | int start_offset; | ||
709 | 716 | ||
710 | play_pending = false; | 717 | play_pending = false; |
711 | playing = false; | 718 | playing = false; |
@@ -720,7 +727,7 @@ static void mpeg_thread(void) | |||
720 | switch(ev.id) | 727 | switch(ev.id) |
721 | { | 728 | { |
722 | case MPEG_PLAY: | 729 | case MPEG_PLAY: |
723 | DEBUGF("MPEG_PLAY %s\n",ev.data); | 730 | DEBUGF("MPEG_PLAY\n"); |
724 | /* Stop the current stream */ | 731 | /* Stop the current stream */ |
725 | play_pending = false; | 732 | play_pending = false; |
726 | playing = false; | 733 | playing = false; |
@@ -732,18 +739,21 @@ static void mpeg_thread(void) | |||
732 | if(mpeg_file >= 0) | 739 | if(mpeg_file >= 0) |
733 | close(mpeg_file); | 740 | close(mpeg_file); |
734 | 741 | ||
735 | mpeg_file = open((char*)ev.data, O_RDONLY); | 742 | if ( new_file(0) == -1 ) |
736 | while (mpeg_file < 0) { | 743 | return; |
737 | DEBUGF("Couldn't open file: %s\n",ev.data); | 744 | |
738 | if ( new_file(1) == -1 ) | 745 | start_offset = (int)ev.data; |
739 | return; | 746 | if (start_offset) { |
747 | lseek(mpeg_file, start_offset, SEEK_SET); | ||
748 | id3tags[tag_read_idx]->id3.offset = start_offset; | ||
740 | } | 749 | } |
750 | else { | ||
751 | /* skip past id3v2 tag (to an even byte) */ | ||
752 | lseek(mpeg_file, | ||
753 | id3tags[tag_read_idx]->id3.id3v2len & ~1, | ||
754 | SEEK_SET); | ||
741 | 755 | ||
742 | add_track_to_tag_list((char *)ev.data); | 756 | } |
743 | /* skip past id3v2 tag (to an even byte) */ | ||
744 | lseek(mpeg_file, | ||
745 | id3tags[tag_read_idx]->id3.id3v2len & ~1, | ||
746 | SEEK_SET); | ||
747 | 757 | ||
748 | /* Make it read more data */ | 758 | /* Make it read more data */ |
749 | filling = true; | 759 | filling = true; |
@@ -752,6 +762,7 @@ static void mpeg_thread(void) | |||
752 | /* Tell the file loading code that we want to start playing | 762 | /* Tell the file loading code that we want to start playing |
753 | as soon as we have some data */ | 763 | as soon as we have some data */ |
754 | play_pending = true; | 764 | play_pending = true; |
765 | paused = false; | ||
755 | 766 | ||
756 | current_track_counter++; | 767 | current_track_counter++; |
757 | break; | 768 | break; |
@@ -764,6 +775,7 @@ static void mpeg_thread(void) | |||
764 | case MPEG_PAUSE: | 775 | case MPEG_PAUSE: |
765 | DEBUGF("MPEG_PAUSE\n"); | 776 | DEBUGF("MPEG_PAUSE\n"); |
766 | /* Stop the current stream */ | 777 | /* Stop the current stream */ |
778 | paused = true; | ||
767 | playing = false; | 779 | playing = false; |
768 | pause_tick = current_tick; | 780 | pause_tick = current_tick; |
769 | stop_dma(); | 781 | stop_dma(); |
@@ -775,6 +787,7 @@ static void mpeg_thread(void) | |||
775 | playing = true; | 787 | playing = true; |
776 | last_dma_tick += current_tick - pause_tick; | 788 | last_dma_tick += current_tick - pause_tick; |
777 | pause_tick = 0; | 789 | pause_tick = 0; |
790 | paused = false; | ||
778 | start_dma(); | 791 | start_dma(); |
779 | break; | 792 | break; |
780 | 793 | ||
@@ -799,7 +812,8 @@ static void mpeg_thread(void) | |||
799 | play_pending = true; | 812 | play_pending = true; |
800 | } else { | 813 | } else { |
801 | playing = true; | 814 | playing = true; |
802 | start_dma(); | 815 | if (!paused) |
816 | start_dma(); | ||
803 | } | 817 | } |
804 | 818 | ||
805 | track_change(); | 819 | track_change(); |
@@ -931,7 +945,8 @@ static void mpeg_thread(void) | |||
931 | playing = true; | 945 | playing = true; |
932 | last_dma_tick = current_tick; | 946 | last_dma_tick = current_tick; |
933 | init_dma(); | 947 | init_dma(); |
934 | start_dma(); | 948 | if (!paused) |
949 | start_dma(); | ||
935 | } | 950 | } |
936 | else | 951 | else |
937 | { | 952 | { |
@@ -1016,7 +1031,8 @@ static void mpeg_thread(void) | |||
1016 | 1031 | ||
1017 | last_dma_tick = current_tick; | 1032 | last_dma_tick = current_tick; |
1018 | init_dma(); | 1033 | init_dma(); |
1019 | start_dma(); | 1034 | if (!paused) |
1035 | start_dma(); | ||
1020 | 1036 | ||
1021 | /* Tell ourselves that we need more data */ | 1037 | /* Tell ourselves that we need more data */ |
1022 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); | 1038 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); |
@@ -1188,7 +1204,7 @@ static void setup_sci0(void) | |||
1188 | static struct mp3entry taginfo; | 1204 | static struct mp3entry taginfo; |
1189 | #endif | 1205 | #endif |
1190 | 1206 | ||
1191 | struct mp3entry* mpeg_current_track(void) | 1207 | struct mp3entry* mpeg_current_track() |
1192 | { | 1208 | { |
1193 | #ifdef SIMULATOR | 1209 | #ifdef SIMULATOR |
1194 | return &taginfo; | 1210 | return &taginfo; |
@@ -1210,13 +1226,17 @@ bool mpeg_has_changed_track(void) | |||
1210 | return false; | 1226 | return false; |
1211 | } | 1227 | } |
1212 | 1228 | ||
1213 | void mpeg_play(char* trackname) | 1229 | void mpeg_play(int offset) |
1214 | { | 1230 | { |
1215 | #ifdef SIMULATOR | 1231 | #ifdef SIMULATOR |
1216 | mp3info(&taginfo, trackname); | 1232 | char* trackname = playlist_next( 0, NULL ); |
1217 | playing = true; | 1233 | if ( trackname ) { |
1234 | mp3info(&taginfo, trackname); | ||
1235 | playing = true; | ||
1236 | } | ||
1237 | (void)offset; | ||
1218 | #else | 1238 | #else |
1219 | queue_post(&mpeg_queue, MPEG_PLAY, trackname); | 1239 | queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset); |
1220 | #endif | 1240 | #endif |
1221 | } | 1241 | } |
1222 | 1242 | ||
@@ -1252,7 +1272,7 @@ void mpeg_next(void) | |||
1252 | #ifndef SIMULATOR | 1272 | #ifndef SIMULATOR |
1253 | queue_post(&mpeg_queue, MPEG_NEXT, NULL); | 1273 | queue_post(&mpeg_queue, MPEG_NEXT, NULL); |
1254 | #else | 1274 | #else |
1255 | char* file = playlist_next(1); | 1275 | char* file = playlist_next(1,NULL); |
1256 | mp3info(&taginfo, file); | 1276 | mp3info(&taginfo, file); |
1257 | current_track_counter++; | 1277 | current_track_counter++; |
1258 | playing = true; | 1278 | playing = true; |
@@ -1264,7 +1284,7 @@ void mpeg_prev(void) | |||
1264 | #ifndef SIMULATOR | 1284 | #ifndef SIMULATOR |
1265 | queue_post(&mpeg_queue, MPEG_PREV, NULL); | 1285 | queue_post(&mpeg_queue, MPEG_PREV, NULL); |
1266 | #else | 1286 | #else |
1267 | char* file = playlist_next(-1); | 1287 | char* file = playlist_next(-1,NULL); |
1268 | mp3info(&taginfo, file); | 1288 | mp3info(&taginfo, file); |
1269 | current_track_counter--; | 1289 | current_track_counter--; |
1270 | playing = true; | 1290 | playing = true; |
@@ -1282,7 +1302,7 @@ void mpeg_ff_rewind(int change) | |||
1282 | 1302 | ||
1283 | bool mpeg_is_playing(void) | 1303 | bool mpeg_is_playing(void) |
1284 | { | 1304 | { |
1285 | return playing || play_pending; | 1305 | return (playing || play_pending) && (!paused) ; |
1286 | } | 1306 | } |
1287 | 1307 | ||
1288 | #ifndef SIMULATOR | 1308 | #ifndef SIMULATOR |