diff options
Diffstat (limited to 'apps/mpeg.c')
-rw-r--r-- | apps/mpeg.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/apps/mpeg.c b/apps/mpeg.c index c0b2ae0c0e..d3e0e5c137 100644 --- a/apps/mpeg.c +++ b/apps/mpeg.c | |||
@@ -177,6 +177,13 @@ static long low_watermark; /* Dynamic low watermark level */ | |||
177 | static long low_watermark_margin = 0; /* Extra time in seconds for watermark */ | 177 | static long low_watermark_margin = 0; /* Extra time in seconds for watermark */ |
178 | static long lowest_watermark_level; /* Debug value to observe the buffer | 178 | static long lowest_watermark_level; /* Debug value to observe the buffer |
179 | usage */ | 179 | usage */ |
180 | |||
181 | struct audio_resume_info | ||
182 | { | ||
183 | unsigned long elapsed; | ||
184 | unsigned long offset; | ||
185 | }; | ||
186 | |||
180 | #if CONFIG_CODEC == MAS3587F | 187 | #if CONFIG_CODEC == MAS3587F |
181 | static char recording_filename[MAX_PATH]; /* argument to thread */ | 188 | static char recording_filename[MAX_PATH]; /* argument to thread */ |
182 | static char delayed_filename[MAX_PATH]; /* internal copy of above */ | 189 | static char delayed_filename[MAX_PATH]; /* internal copy of above */ |
@@ -430,10 +437,9 @@ static void set_elapsed(struct mp3entry* id3) | |||
430 | id3->elapsed = id3->offset / (id3->bitrate / 8); | 437 | id3->elapsed = id3->offset / (id3->bitrate / 8); |
431 | } | 438 | } |
432 | 439 | ||
433 | int audio_get_file_pos(void) | 440 | static int audio_get_file_pos_int(struct mp3entry *id3) |
434 | { | 441 | { |
435 | int pos = -1; | 442 | int pos = -1; |
436 | struct mp3entry *id3 = audio_current_track(); | ||
437 | 443 | ||
438 | if (id3->vbr) | 444 | if (id3->vbr) |
439 | { | 445 | { |
@@ -490,6 +496,12 @@ int audio_get_file_pos(void) | |||
490 | return pos; | 496 | return pos; |
491 | } | 497 | } |
492 | 498 | ||
499 | int audio_get_file_pos(void) | ||
500 | { | ||
501 | struct mp3entry *id3 = audio_current_track(); | ||
502 | return id3 ? audio_get_file_pos_int(id3) : 0; | ||
503 | } | ||
504 | |||
493 | unsigned long mpeg_get_last_header(void) | 505 | unsigned long mpeg_get_last_header(void) |
494 | { | 506 | { |
495 | #ifdef SIMULATOR | 507 | #ifdef SIMULATOR |
@@ -545,7 +557,13 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s | |||
545 | } | 557 | } |
546 | /* TODO: Do it without stopping playback, if possible */ | 558 | /* TODO: Do it without stopping playback, if possible */ |
547 | bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY; | 559 | bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY; |
548 | long offset = audio_current_track()->offset; | 560 | struct mp3entry *id3 = audio_current_track(); |
561 | unsigned long elapsed = 0, offset = 0; | ||
562 | if (id3) | ||
563 | { | ||
564 | elapsed = id3->elapsed; | ||
565 | offset = id3->offset; | ||
566 | } | ||
549 | /* don't call audio_hard_stop() as it frees this handle */ | 567 | /* don't call audio_hard_stop() as it frees this handle */ |
550 | if (thread_self() == audio_thread_id) | 568 | if (thread_self() == audio_thread_id) |
551 | { /* inline case MPEG_STOP (audio_stop()) response | 569 | { /* inline case MPEG_STOP (audio_stop()) response |
@@ -574,7 +592,7 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s | |||
574 | } | 592 | } |
575 | if (playing) | 593 | if (playing) |
576 | { /* safe to call even from the audio thread (due to queue_post()) */ | 594 | { /* safe to call even from the audio thread (due to queue_post()) */ |
577 | audio_play(offset); | 595 | audio_play(elapsed, offset); |
578 | } | 596 | } |
579 | 597 | ||
580 | return BUFLIB_CB_OK; | 598 | return BUFLIB_CB_OK; |
@@ -1274,7 +1292,7 @@ static void mpeg_thread(void) | |||
1274 | int unplayed_space_left; | 1292 | int unplayed_space_left; |
1275 | int amount_to_read; | 1293 | int amount_to_read; |
1276 | int t1, t2; | 1294 | int t1, t2; |
1277 | int start_offset; | 1295 | unsigned long start_elapsed, start_offset; |
1278 | #if CONFIG_CODEC == MAS3587F | 1296 | #if CONFIG_CODEC == MAS3587F |
1279 | int amount_to_save; | 1297 | int amount_to_save; |
1280 | int save_endpos = 0; | 1298 | int save_endpos = 0; |
@@ -1337,9 +1355,16 @@ static void mpeg_thread(void) | |||
1337 | break; | 1355 | break; |
1338 | } | 1356 | } |
1339 | 1357 | ||
1340 | start_offset = (int)ev.data; | 1358 | start_elapsed = ((struct audio_resume_info *)ev.data)->elapsed; |
1359 | start_offset = ((struct audio_resume_info *)ev.data)->offset; | ||
1341 | 1360 | ||
1342 | /* mid-song resume? */ | 1361 | /* mid-song resume? */ |
1362 | if (!start_offset && start_elapsed) { | ||
1363 | struct mp3entry *id3 = &get_trackdata(0)->id3; | ||
1364 | id3->elapsed = start_elapsed; | ||
1365 | start_offset = audio_get_file_pos_int(id3); | ||
1366 | } | ||
1367 | |||
1343 | if (start_offset) { | 1368 | if (start_offset) { |
1344 | struct mp3entry* id3 = &get_trackdata(0)->id3; | 1369 | struct mp3entry* id3 = &get_trackdata(0)->id3; |
1345 | lseek(mpeg_file, start_offset, SEEK_SET); | 1370 | lseek(mpeg_file, start_offset, SEEK_SET); |
@@ -1506,7 +1531,7 @@ static void mpeg_thread(void) | |||
1506 | 1531 | ||
1507 | id3->elapsed = newtime; | 1532 | id3->elapsed = newtime; |
1508 | 1533 | ||
1509 | newpos = audio_get_file_pos(); | 1534 | newpos = audio_get_file_pos_int(id3); |
1510 | if(newpos < 0) | 1535 | if(newpos < 0) |
1511 | { | 1536 | { |
1512 | id3->elapsed = oldtime; | 1537 | id3->elapsed = oldtime; |
@@ -2765,7 +2790,7 @@ static void audio_reset_buffer(void) | |||
2765 | audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize); | 2790 | audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize); |
2766 | } | 2791 | } |
2767 | 2792 | ||
2768 | void audio_play(long offset) | 2793 | void audio_play(unsigned long elapsed, unsigned long offset) |
2769 | { | 2794 | { |
2770 | audio_reset_buffer(); | 2795 | audio_reset_buffer(); |
2771 | #ifdef SIMULATOR | 2796 | #ifdef SIMULATOR |
@@ -2789,15 +2814,28 @@ void audio_play(long offset) | |||
2789 | real_mpeg_play(trackname); | 2814 | real_mpeg_play(trackname); |
2790 | #endif | 2815 | #endif |
2791 | playlist_next(steps); | 2816 | playlist_next(steps); |
2792 | taginfo.offset = offset; | 2817 | if (!offset && elapsed) |
2793 | set_elapsed(&taginfo); | 2818 | { |
2819 | /* has an elapsed time but no offset; elapsed may take | ||
2820 | precedence in this case */ | ||
2821 | taginfo.elapsed = elapsed; | ||
2822 | taginfo.offset = audio_get_file_pos_int(&taginfo); | ||
2823 | } | ||
2824 | else | ||
2825 | { | ||
2826 | taginfo.offset = offset; | ||
2827 | set_elapsed(&taginfo); | ||
2828 | } | ||
2794 | is_playing = true; | 2829 | is_playing = true; |
2795 | playing = true; | 2830 | playing = true; |
2796 | break; | 2831 | break; |
2797 | } while(1); | 2832 | } while(1); |
2798 | #else /* !SIMULATOR */ | 2833 | #else /* !SIMULATOR */ |
2834 | static struct audio_resume_info resume; | ||
2799 | is_playing = true; | 2835 | is_playing = true; |
2800 | queue_post(&mpeg_queue, MPEG_PLAY, offset); | 2836 | resume.elapsed = elapsed; |
2837 | resume.offset = offset; | ||
2838 | queue_post(&mpeg_queue, MPEG_PLAY, (intptr_t)&resume); | ||
2801 | #endif /* !SIMULATOR */ | 2839 | #endif /* !SIMULATOR */ |
2802 | 2840 | ||
2803 | mpeg_errno = 0; | 2841 | mpeg_errno = 0; |