diff options
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 84 |
1 files changed, 36 insertions, 48 deletions
diff --git a/apps/playback.c b/apps/playback.c index 8b498f265e..a1db82eafd 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -155,13 +155,6 @@ static struct mp3entry static_id3_entries[ID3_TYPE_NUM_STATIC]; /* (A,O) */ | |||
155 | /* Peeking functions can yield and mess us up */ | 155 | /* Peeking functions can yield and mess us up */ |
156 | static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/ | 156 | static struct mutex id3_mutex SHAREDBSS_ATTR; /* (A,O)*/ |
157 | 157 | ||
158 | |||
159 | /** For Scrobbler support **/ | ||
160 | |||
161 | /* Previous track elapsed time */ | ||
162 | static unsigned long prev_track_elapsed = 0; /* (A,O-) */ | ||
163 | |||
164 | |||
165 | /** For album art support **/ | 158 | /** For album art support **/ |
166 | #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT | 159 | #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT |
167 | #ifdef HAVE_ALBUMART | 160 | #ifdef HAVE_ALBUMART |
@@ -296,9 +289,8 @@ enum track_skip_type | |||
296 | would work as expected */ | 289 | would work as expected */ |
297 | 290 | ||
298 | /* Used to indicate status for the events. Must be separate to satisfy all | 291 | /* Used to indicate status for the events. Must be separate to satisfy all |
299 | clients so the correct metadata is read when sending the change events | 292 | clients so the correct metadata is read when sending the change events. */ |
300 | and also so that it is read correctly outside the events. */ | 293 | static unsigned int track_event_flags = TEF_NONE; /* (A, O-) */ |
301 | static bool automatic_skip = false; /* (A, O-) */ | ||
302 | 294 | ||
303 | /* Pending manual track skip offset */ | 295 | /* Pending manual track skip offset */ |
304 | static int skip_offset = 0; /* (A, O) */ | 296 | static int skip_offset = 0; /* (A, O) */ |
@@ -1056,6 +1048,16 @@ static void audio_handle_track_load_status(int trackstat) | |||
1056 | } | 1048 | } |
1057 | } | 1049 | } |
1058 | 1050 | ||
1051 | /* Send track events that use a struct track_event for data */ | ||
1052 | static void send_track_event(unsigned int id, unsigned int flags, | ||
1053 | struct mp3entry *id3) | ||
1054 | { | ||
1055 | if (id3 == id3_get(PLAYING_ID3)) | ||
1056 | flags |= TEF_CURRENT; | ||
1057 | |||
1058 | send_event(id, &(struct track_event){ .flags = flags, .id3 = id3 }); | ||
1059 | } | ||
1060 | |||
1059 | /* Announce the end of playing the current track */ | 1061 | /* Announce the end of playing the current track */ |
1060 | static void audio_playlist_track_finish(void) | 1062 | static void audio_playlist_track_finish(void) |
1061 | { | 1063 | { |
@@ -1066,12 +1068,8 @@ static void audio_playlist_track_finish(void) | |||
1066 | 1068 | ||
1067 | if (id3) | 1069 | if (id3) |
1068 | { | 1070 | { |
1069 | send_event(PLAYBACK_EVENT_TRACK_FINISH, id3); | 1071 | send_track_event(PLAYBACK_EVENT_TRACK_FINISH, |
1070 | prev_track_elapsed = id3->elapsed; | 1072 | track_event_flags, id3); |
1071 | } | ||
1072 | else | ||
1073 | { | ||
1074 | prev_track_elapsed = 0; | ||
1075 | } | 1073 | } |
1076 | } | 1074 | } |
1077 | 1075 | ||
@@ -1081,7 +1079,10 @@ static void audio_playlist_track_change(void) | |||
1081 | struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3)); | 1079 | struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3)); |
1082 | 1080 | ||
1083 | if (id3) | 1081 | if (id3) |
1084 | send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3); | 1082 | { |
1083 | send_track_event(PLAYBACK_EVENT_TRACK_CHANGE, | ||
1084 | track_event_flags, id3); | ||
1085 | } | ||
1085 | 1086 | ||
1086 | position_key = pcmbuf_get_position_key(); | 1087 | position_key = pcmbuf_get_position_key(); |
1087 | 1088 | ||
@@ -1092,8 +1093,8 @@ static void audio_playlist_track_change(void) | |||
1092 | static void audio_update_and_announce_next_track(const struct mp3entry *id3_next) | 1093 | static void audio_update_and_announce_next_track(const struct mp3entry *id3_next) |
1093 | { | 1094 | { |
1094 | id3_write_locked(NEXTTRACK_ID3, id3_next); | 1095 | id3_write_locked(NEXTTRACK_ID3, id3_next); |
1095 | send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, | 1096 | send_track_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, |
1096 | id3_get(NEXTTRACK_ID3)); | 1097 | 0, id3_get(NEXTTRACK_ID3)); |
1097 | } | 1098 | } |
1098 | 1099 | ||
1099 | /* Bring the user current mp3entry up to date and set a new offset for the | 1100 | /* Bring the user current mp3entry up to date and set a new offset for the |
@@ -1441,7 +1442,7 @@ static bool audio_start_codec(bool auto_skip) | |||
1441 | bool resume = !auto_skip; | 1442 | bool resume = !auto_skip; |
1442 | 1443 | ||
1443 | /* Send the "buffer" event to obtain the resume position for the codec */ | 1444 | /* Send the "buffer" event to obtain the resume position for the codec */ |
1444 | send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3); | 1445 | send_track_event(PLAYBACK_EVENT_TRACK_BUFFER, 0, cur_id3); |
1445 | 1446 | ||
1446 | if (!resume) | 1447 | if (!resume) |
1447 | { | 1448 | { |
@@ -1497,7 +1498,7 @@ static bool audio_start_codec(bool auto_skip) | |||
1497 | #endif | 1498 | #endif |
1498 | { | 1499 | { |
1499 | /* Send the "buffer" event now */ | 1500 | /* Send the "buffer" event now */ |
1500 | send_event(PLAYBACK_EVENT_TRACK_BUFFER, cur_id3); | 1501 | send_track_event(PLAYBACK_EVENT_TRACK_BUFFER, 0, cur_id3); |
1501 | } | 1502 | } |
1502 | 1503 | ||
1503 | buf_pin_handle(info->id3_hid, false); | 1504 | buf_pin_handle(info->id3_hid, false); |
@@ -1893,7 +1894,8 @@ static int audio_finish_load_track(struct track_info *info) | |||
1893 | /* Send only when the track handles could not all be opened ahead of | 1894 | /* Send only when the track handles could not all be opened ahead of |
1894 | time for the user's current track - otherwise everything is ready | 1895 | time for the user's current track - otherwise everything is ready |
1895 | by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */ | 1896 | by the time PLAYBACK_EVENT_TRACK_CHANGE is sent */ |
1896 | send_event(PLAYBACK_EVENT_CUR_TRACK_READY, id3_get(PLAYING_ID3)); | 1897 | send_track_event(PLAYBACK_EVENT_CUR_TRACK_READY, 0, |
1898 | id3_get(PLAYING_ID3)); | ||
1897 | } | 1899 | } |
1898 | 1900 | ||
1899 | #ifdef HAVE_CODEC_BUFFERING | 1901 | #ifdef HAVE_CODEC_BUFFERING |
@@ -2157,7 +2159,7 @@ static void audio_on_finish_load_track(int id3_hid) | |||
2157 | buf_read_cuesheet(info->cuesheet_hid); | 2159 | buf_read_cuesheet(info->cuesheet_hid); |
2158 | } | 2160 | } |
2159 | 2161 | ||
2160 | if (audio_start_codec(automatic_skip)) | 2162 | if (audio_start_codec(track_event_flags & TEF_AUTO_SKIP)) |
2161 | { | 2163 | { |
2162 | if (is_user_current) | 2164 | if (is_user_current) |
2163 | { | 2165 | { |
@@ -2356,7 +2358,7 @@ static void audio_on_codec_complete(int status) | |||
2356 | 2358 | ||
2357 | int trackstat = LOAD_TRACK_OK; | 2359 | int trackstat = LOAD_TRACK_OK; |
2358 | 2360 | ||
2359 | automatic_skip = true; | 2361 | track_event_flags = TEF_AUTO_SKIP; |
2360 | skip_pending = TRACK_SKIP_AUTO; | 2362 | skip_pending = TRACK_SKIP_AUTO; |
2361 | 2363 | ||
2362 | /* Does this track have an entry allocated? */ | 2364 | /* Does this track have an entry allocated? */ |
@@ -2471,7 +2473,7 @@ static void audio_start_playback(size_t offset, unsigned int flags) | |||
2471 | 2473 | ||
2472 | halt_decoding_track(true); | 2474 | halt_decoding_track(true); |
2473 | 2475 | ||
2474 | automatic_skip = false; | 2476 | track_event_flags = TEF_NONE; |
2475 | ff_rw_mode = false; | 2477 | ff_rw_mode = false; |
2476 | 2478 | ||
2477 | if (flags & AUDIO_START_RESTART) | 2479 | if (flags & AUDIO_START_RESTART) |
@@ -2595,7 +2597,7 @@ static void audio_stop_playback(void) | |||
2595 | audio_playlist_track_finish(); | 2597 | audio_playlist_track_finish(); |
2596 | 2598 | ||
2597 | skip_pending = TRACK_SKIP_NONE; | 2599 | skip_pending = TRACK_SKIP_NONE; |
2598 | automatic_skip = false; | 2600 | track_event_flags = TEF_NONE; |
2599 | 2601 | ||
2600 | /* Close all tracks and mark them NULL */ | 2602 | /* Close all tracks and mark them NULL */ |
2601 | remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback); | 2603 | remove_event(BUFFER_EVENT_REBUFFER, buffer_event_rebuffer_callback); |
@@ -2667,7 +2669,7 @@ static void audio_on_skip(void) | |||
2667 | ff_rw_mode = false; | 2669 | ff_rw_mode = false; |
2668 | 2670 | ||
2669 | /* Manual skip */ | 2671 | /* Manual skip */ |
2670 | automatic_skip = false; | 2672 | track_event_flags = TEF_NONE; |
2671 | 2673 | ||
2672 | /* If there was an auto skip in progress, there will be residual | 2674 | /* If there was an auto skip in progress, there will be residual |
2673 | advancement of the playlist and/or track list so compensation will be | 2675 | advancement of the playlist and/or track list so compensation will be |
@@ -2755,7 +2757,7 @@ static void audio_on_dir_skip(int direction) | |||
2755 | ff_rw_mode = false; | 2757 | ff_rw_mode = false; |
2756 | 2758 | ||
2757 | /* Manual skip */ | 2759 | /* Manual skip */ |
2758 | automatic_skip = false; | 2760 | track_event_flags = TEF_NONE; |
2759 | 2761 | ||
2760 | audio_playlist_track_finish(); | 2762 | audio_playlist_track_finish(); |
2761 | 2763 | ||
@@ -2820,14 +2822,14 @@ static void audio_on_ff_rewind(long time) | |||
2820 | struct mp3entry *id3 = id3_get(PLAYING_ID3); | 2822 | struct mp3entry *id3 = id3_get(PLAYING_ID3); |
2821 | struct mp3entry *ci_id3 = id3_get(CODEC_ID3); | 2823 | struct mp3entry *ci_id3 = id3_get(CODEC_ID3); |
2822 | 2824 | ||
2823 | automatic_skip = false; | 2825 | track_event_flags = TEF_NONE; |
2824 | 2826 | ||
2825 | /* Send event before clobbering the time */ | 2827 | /* Send event before clobbering the time if rewinding. */ |
2826 | /* FIXME: Nasty, but the tagtree expects this so that rewinding and | ||
2827 | then skipping back to this track resumes properly. Something else | ||
2828 | should be sent. We're not _really_ finishing the track are we? */ | ||
2829 | if (time == 0) | 2828 | if (time == 0) |
2830 | send_event(PLAYBACK_EVENT_TRACK_FINISH, id3); | 2829 | { |
2830 | send_track_event(PLAYBACK_EVENT_TRACK_FINISH, | ||
2831 | track_event_flags | TEF_REWIND, id3); | ||
2832 | } | ||
2831 | 2833 | ||
2832 | id3->elapsed = time; | 2834 | id3->elapsed = time; |
2833 | queue_reply(&audio_queue, 1); | 2835 | queue_reply(&audio_queue, 1); |
@@ -3662,14 +3664,6 @@ void playback_release_aa_slot(int slot) | |||
3662 | } | 3664 | } |
3663 | #endif /* HAVE_ALBUMART */ | 3665 | #endif /* HAVE_ALBUMART */ |
3664 | 3666 | ||
3665 | /* Is an automatic skip in progress? If called outside transition callbacks, | ||
3666 | indicates the last skip type at the time it was processed and isn't very | ||
3667 | meaningful. */ | ||
3668 | bool audio_automatic_skip(void) | ||
3669 | { | ||
3670 | return automatic_skip; | ||
3671 | } | ||
3672 | |||
3673 | /* Would normally calculate byte offset from an elapsed time but is not | 3667 | /* Would normally calculate byte offset from an elapsed time but is not |
3674 | used on SWCODEC */ | 3668 | used on SWCODEC */ |
3675 | int audio_get_file_pos(void) | 3669 | int audio_get_file_pos(void) |
@@ -3677,12 +3671,6 @@ int audio_get_file_pos(void) | |||
3677 | return 0; | 3671 | return 0; |
3678 | } | 3672 | } |
3679 | 3673 | ||
3680 | /* Return the elapsed time of the track previous to the current */ | ||
3681 | unsigned long audio_prev_elapsed(void) | ||
3682 | { | ||
3683 | return prev_track_elapsed; | ||
3684 | } | ||
3685 | |||
3686 | /* Return total file buffer length after accounting for the talk buf */ | 3674 | /* Return total file buffer length after accounting for the talk buf */ |
3687 | size_t audio_get_filebuflen(void) | 3675 | size_t audio_get_filebuflen(void) |
3688 | { | 3676 | { |