diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-08-28 07:45:35 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-08-28 07:45:35 +0000 |
commit | 7ad2cad173ffa094bb285112582afee1c9aea4e5 (patch) | |
tree | ce23e816cfdffb1767ebe44f4f960c304d8a5fb9 /apps/playback.c | |
parent | 463b3ed8b2630d1b9d656dd2a52bbcbd429b4c08 (diff) | |
download | rockbox-7ad2cad173ffa094bb285112582afee1c9aea4e5.tar.gz rockbox-7ad2cad173ffa094bb285112582afee1c9aea4e5.zip |
Commit work started in FS#12153 to put timing/position information in PCM
buffer chunks.
* Samples and position indication is closely associated with audio data
instead of compensating by a latency constant. Alleviates problems with
using the elapsed as a track indicator where it could be off by several
steps.
* Timing is accurate throughout track even if resampling for pitch shift,
whereas before it updated during transition latency at the normal 1:1 rate.
* Simpler PCM buffer with a constant chunk size, no linked lists.
In converting crossfade, a minor change was made to not change the WPS until
the fade-in of the incoming track, whereas before it would change upon the
start of the fade-out of the outgoing track possibly having the WPS change
with far too much lead time.
Codec changes are to set elapsed times *before* writing next PCM frame because
time and position data last set are saved in the next committed PCM chunk.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30366 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 211 |
1 files changed, 90 insertions, 121 deletions
diff --git a/apps/playback.c b/apps/playback.c index 65783414fe..7dad08644a 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -330,7 +330,7 @@ static struct | |||
330 | static bool codec_skip_pending = false; | 330 | static bool codec_skip_pending = false; |
331 | static int codec_skip_status; | 331 | static int codec_skip_status; |
332 | static bool codec_seeking = false; /* Codec seeking ack expected? */ | 332 | static bool codec_seeking = false; /* Codec seeking ack expected? */ |
333 | 333 | static unsigned int position_key = 0; | |
334 | 334 | ||
335 | /* Event queues */ | 335 | /* Event queues */ |
336 | static struct event_queue audio_queue SHAREDBSS_ATTR; | 336 | static struct event_queue audio_queue SHAREDBSS_ATTR; |
@@ -353,14 +353,13 @@ static void audio_stop_playback(void); | |||
353 | static void buffer_event_buffer_low_callback(void *data); | 353 | static void buffer_event_buffer_low_callback(void *data); |
354 | static void buffer_event_rebuffer_callback(void *data); | 354 | static void buffer_event_rebuffer_callback(void *data); |
355 | static void buffer_event_finished_callback(void *data); | 355 | static void buffer_event_finished_callback(void *data); |
356 | void audio_pcmbuf_sync_position(void); | ||
356 | 357 | ||
357 | 358 | ||
358 | /**************************************/ | 359 | /**************************************/ |
359 | 360 | ||
360 | /** --- audio_queue helpers --- **/ | 361 | /** --- audio_queue helpers --- **/ |
361 | 362 | static void audio_queue_post(long id, intptr_t data) | |
362 | /* codec thread needs access */ | ||
363 | void audio_queue_post(long id, intptr_t data) | ||
364 | { | 363 | { |
365 | queue_post(&audio_queue, id, data); | 364 | queue_post(&audio_queue, id, data); |
366 | } | 365 | } |
@@ -805,14 +804,10 @@ static void audio_reset_buffer(void) | |||
805 | aids viewing and the summation of certain variables should add up to | 804 | aids viewing and the summation of certain variables should add up to |
806 | the location of others. */ | 805 | the location of others. */ |
807 | { | 806 | { |
808 | size_t pcmbufsize; | ||
809 | const unsigned char *pcmbuf = pcmbuf_get_meminfo(&pcmbufsize); | ||
810 | logf("fbuf: %08X", (unsigned)filebuf); | 807 | logf("fbuf: %08X", (unsigned)filebuf); |
811 | logf("fbufe: %08X", (unsigned)(filebuf + filebuflen)); | 808 | logf("fbufe: %08X", (unsigned)(filebuf + filebuflen)); |
812 | logf("sbuf: %08X", (unsigned)audio_scratch_memory); | 809 | logf("sbuf: %08X", (unsigned)audio_scratch_memory); |
813 | logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize)); | 810 | logf("sbufe: %08X", (unsigned)(audio_scratch_memory + allocsize)); |
814 | logf("pcmb: %08X", (unsigned)pcmbuf); | ||
815 | logf("pcmbe: %08X", (unsigned)(pcmbuf + pcmbufsize)); | ||
816 | } | 811 | } |
817 | #endif | 812 | #endif |
818 | 813 | ||
@@ -978,7 +973,8 @@ static void audio_handle_track_load_status(int trackstat) | |||
978 | /* Announce the end of playing the current track */ | 973 | /* Announce the end of playing the current track */ |
979 | static void audio_playlist_track_finish(void) | 974 | static void audio_playlist_track_finish(void) |
980 | { | 975 | { |
981 | struct mp3entry *id3 = valid_mp3entry(id3_get(PLAYING_ID3)); | 976 | struct mp3entry *ply_id3 = id3_get(PLAYING_ID3); |
977 | struct mp3entry *id3 = valid_mp3entry(ply_id3); | ||
982 | 978 | ||
983 | playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3); | 979 | playlist_update_resume_info(filling == STATE_ENDED ? NULL : id3); |
984 | 980 | ||
@@ -1001,6 +997,8 @@ static void audio_playlist_track_change(void) | |||
1001 | if (id3) | 997 | if (id3) |
1002 | send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3); | 998 | send_event(PLAYBACK_EVENT_TRACK_CHANGE, id3); |
1003 | 999 | ||
1000 | position_key = pcmbuf_get_position_key(); | ||
1001 | |||
1004 | playlist_update_resume_info(id3); | 1002 | playlist_update_resume_info(id3); |
1005 | } | 1003 | } |
1006 | 1004 | ||
@@ -1014,26 +1012,28 @@ static void audio_update_and_announce_next_track(const struct mp3entry *id3_next | |||
1014 | 1012 | ||
1015 | /* Bring the user current mp3entry up to date and set a new offset for the | 1013 | /* Bring the user current mp3entry up to date and set a new offset for the |
1016 | buffered metadata */ | 1014 | buffered metadata */ |
1017 | static void playing_id3_sync(struct track_info *user_info, size_t offset) | 1015 | static void playing_id3_sync(struct track_info *user_info, off_t offset) |
1018 | { | 1016 | { |
1019 | id3_mutex_lock(); | 1017 | id3_mutex_lock(); |
1020 | 1018 | ||
1021 | struct mp3entry *id3 = bufgetid3(user_info->id3_hid); | 1019 | struct mp3entry *id3 = bufgetid3(user_info->id3_hid); |
1020 | struct mp3entry *playing_id3 = id3_get(PLAYING_ID3); | ||
1022 | 1021 | ||
1023 | if (offset == (size_t)-1) | 1022 | pcm_play_lock(); |
1023 | |||
1024 | unsigned long e = playing_id3->elapsed; | ||
1025 | unsigned long o = playing_id3->offset; | ||
1026 | |||
1027 | id3_write(PLAYING_ID3, id3); | ||
1028 | |||
1029 | if (offset < 0) | ||
1024 | { | 1030 | { |
1025 | struct mp3entry *ply_id3 = id3_get(PLAYING_ID3); | 1031 | playing_id3->elapsed = e; |
1026 | size_t play_offset = ply_id3->offset; | 1032 | playing_id3->offset = o; |
1027 | long play_elapsed = ply_id3->elapsed; | ||
1028 | id3_write(PLAYING_ID3, id3); | ||
1029 | ply_id3->offset = play_offset; | ||
1030 | ply_id3->elapsed = play_elapsed; | ||
1031 | offset = 0; | 1033 | offset = 0; |
1032 | } | 1034 | } |
1033 | else | 1035 | |
1034 | { | 1036 | pcm_play_unlock(); |
1035 | id3_write(PLAYING_ID3, id3); | ||
1036 | } | ||
1037 | 1037 | ||
1038 | if (id3) | 1038 | if (id3) |
1039 | id3->offset = offset; | 1039 | id3->offset = offset; |
@@ -1093,13 +1093,6 @@ static bool halt_decoding_track(bool stop) | |||
1093 | return retval; | 1093 | return retval; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | /* Clear the PCM on a manual skip */ | ||
1097 | static void audio_clear_paused_pcm(void) | ||
1098 | { | ||
1099 | if (play_status == PLAY_PAUSED && !pcmbuf_is_crossfade_active()) | ||
1100 | pcmbuf_play_stop(); | ||
1101 | } | ||
1102 | |||
1103 | /* Wait for any in-progress fade to complete */ | 1096 | /* Wait for any in-progress fade to complete */ |
1104 | static void audio_wait_fade_complete(void) | 1097 | static void audio_wait_fade_complete(void) |
1105 | { | 1098 | { |
@@ -1121,6 +1114,7 @@ static void audio_ff_rewind_end(void) | |||
1121 | { | 1114 | { |
1122 | /* Clear the buffer */ | 1115 | /* Clear the buffer */ |
1123 | pcmbuf_play_stop(); | 1116 | pcmbuf_play_stop(); |
1117 | audio_pcmbuf_sync_position(); | ||
1124 | } | 1118 | } |
1125 | 1119 | ||
1126 | if (play_status != PLAY_PAUSED) | 1120 | if (play_status != PLAY_PAUSED) |
@@ -2063,7 +2057,7 @@ static void audio_on_handle_finished(int hid) | |||
2063 | 2057 | ||
2064 | /* Called to make an outstanding track skip the current track and to send the | 2058 | /* Called to make an outstanding track skip the current track and to send the |
2065 | transition events */ | 2059 | transition events */ |
2066 | static void audio_finalise_track_change(bool delayed) | 2060 | static void audio_finalise_track_change(void) |
2067 | { | 2061 | { |
2068 | switch (skip_pending) | 2062 | switch (skip_pending) |
2069 | { | 2063 | { |
@@ -2117,15 +2111,6 @@ static void audio_finalise_track_change(bool delayed) | |||
2117 | 2111 | ||
2118 | id3_write(PLAYING_ID3, track_id3); | 2112 | id3_write(PLAYING_ID3, track_id3); |
2119 | 2113 | ||
2120 | if (delayed) | ||
2121 | { | ||
2122 | /* Delayed skip where codec is ahead of user's current track */ | ||
2123 | struct mp3entry *ci_id3 = id3_get(CODEC_ID3); | ||
2124 | struct mp3entry *ply_id3 = id3_get(PLAYING_ID3); | ||
2125 | ply_id3->elapsed = ci_id3->elapsed; | ||
2126 | ply_id3->offset = ci_id3->offset; | ||
2127 | } | ||
2128 | |||
2129 | /* The skip is technically over */ | 2114 | /* The skip is technically over */ |
2130 | skip_pending = TRACK_SKIP_NONE; | 2115 | skip_pending = TRACK_SKIP_NONE; |
2131 | 2116 | ||
@@ -2141,25 +2126,25 @@ static void audio_finalise_track_change(bool delayed) | |||
2141 | } | 2126 | } |
2142 | 2127 | ||
2143 | /* Actually begin a transition and take care of the codec change - may complete | 2128 | /* Actually begin a transition and take care of the codec change - may complete |
2144 | it now or ask pcmbuf for notification depending on the type and what pcmbuf | 2129 | it now or ask pcmbuf for notification depending on the type */ |
2145 | has to say */ | 2130 | static void audio_begin_track_change(enum pcm_track_change_type type, |
2146 | static void audio_begin_track_change(bool auto_skip, int trackstat) | 2131 | int trackstat) |
2147 | { | 2132 | { |
2148 | /* Even if the new track is bad, the old track must be finished off */ | 2133 | /* Even if the new track is bad, the old track must be finished off */ |
2149 | bool finalised = pcmbuf_start_track_change(auto_skip); | 2134 | pcmbuf_start_track_change(type); |
2135 | |||
2136 | bool auto_skip = type != TRACK_CHANGE_MANUAL; | ||
2150 | 2137 | ||
2151 | if (finalised) | 2138 | if (!auto_skip) |
2152 | { | 2139 | { |
2153 | /* pcmbuf says that the transition happens now - complete it */ | 2140 | /* Manual track change happens now */ |
2154 | audio_finalise_track_change(false); | 2141 | audio_finalise_track_change(); |
2142 | pcmbuf_sync_position_update(); | ||
2155 | 2143 | ||
2156 | if (play_status == PLAY_STOPPED) | 2144 | if (play_status == PLAY_STOPPED) |
2157 | return; /* Stopped us */ | 2145 | return; /* Stopped us */ |
2158 | } | 2146 | } |
2159 | 2147 | ||
2160 | if (!auto_skip) | ||
2161 | audio_clear_paused_pcm(); | ||
2162 | |||
2163 | if (trackstat >= LOAD_TRACK_OK) | 2148 | if (trackstat >= LOAD_TRACK_OK) |
2164 | { | 2149 | { |
2165 | struct track_info *info = track_list_current(0); | 2150 | struct track_info *info = track_list_current(0); |
@@ -2170,7 +2155,7 @@ static void audio_begin_track_change(bool auto_skip, int trackstat) | |||
2170 | /* Everything needed for the codec is ready - start it */ | 2155 | /* Everything needed for the codec is ready - start it */ |
2171 | if (audio_start_codec(auto_skip)) | 2156 | if (audio_start_codec(auto_skip)) |
2172 | { | 2157 | { |
2173 | if (finalised) | 2158 | if (!auto_skip) |
2174 | playing_id3_sync(info, -1); | 2159 | playing_id3_sync(info, -1); |
2175 | return; | 2160 | return; |
2176 | } | 2161 | } |
@@ -2186,7 +2171,7 @@ static void audio_monitor_end_of_playlist(void) | |||
2186 | { | 2171 | { |
2187 | skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST; | 2172 | skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST; |
2188 | filling = STATE_ENDING; | 2173 | filling = STATE_ENDING; |
2189 | pcmbuf_monitor_track_change(true); | 2174 | pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA); |
2190 | } | 2175 | } |
2191 | 2176 | ||
2192 | /* Codec has completed decoding the track | 2177 | /* Codec has completed decoding the track |
@@ -2221,14 +2206,6 @@ static void audio_on_codec_complete(int status) | |||
2221 | 2206 | ||
2222 | codec_skip_pending = false; | 2207 | codec_skip_pending = false; |
2223 | 2208 | ||
2224 | #ifdef AB_REPEAT_ENABLE | ||
2225 | if (status >= 0) | ||
2226 | { | ||
2227 | /* Normal automatic skip */ | ||
2228 | ab_end_of_track_report(); | ||
2229 | } | ||
2230 | #endif | ||
2231 | |||
2232 | int trackstat = LOAD_TRACK_OK; | 2209 | int trackstat = LOAD_TRACK_OK; |
2233 | 2210 | ||
2234 | automatic_skip = true; | 2211 | automatic_skip = true; |
@@ -2263,7 +2240,7 @@ static void audio_on_codec_complete(int status) | |||
2263 | { | 2240 | { |
2264 | /* Continue filling after this track */ | 2241 | /* Continue filling after this track */ |
2265 | audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1); | 2242 | audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1); |
2266 | audio_begin_track_change(true, trackstat); | 2243 | audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat); |
2267 | return; | 2244 | return; |
2268 | } | 2245 | } |
2269 | /* else rebuffer at this track; status applies to the track we | 2246 | /* else rebuffer at this track; status applies to the track we |
@@ -2299,7 +2276,7 @@ static void audio_on_codec_complete(int status) | |||
2299 | } | 2276 | } |
2300 | } | 2277 | } |
2301 | 2278 | ||
2302 | audio_begin_track_change(true, trackstat); | 2279 | audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat); |
2303 | } | 2280 | } |
2304 | 2281 | ||
2305 | /* Called when codec completes seek operation | 2282 | /* Called when codec completes seek operation |
@@ -2316,7 +2293,7 @@ static void audio_on_codec_seek_complete(void) | |||
2316 | static void audio_on_track_changed(void) | 2293 | static void audio_on_track_changed(void) |
2317 | { | 2294 | { |
2318 | /* Finish whatever is pending so that the WPS is in sync */ | 2295 | /* Finish whatever is pending so that the WPS is in sync */ |
2319 | audio_finalise_track_change(true); | 2296 | audio_finalise_track_change(); |
2320 | 2297 | ||
2321 | if (codec_skip_pending) | 2298 | if (codec_skip_pending) |
2322 | { | 2299 | { |
@@ -2367,8 +2344,7 @@ static void audio_start_playback(size_t offset, unsigned int flags) | |||
2367 | track_list_clear(TRACK_LIST_CLEAR_ALL); | 2344 | track_list_clear(TRACK_LIST_CLEAR_ALL); |
2368 | 2345 | ||
2369 | /* Indicate manual track change */ | 2346 | /* Indicate manual track change */ |
2370 | pcmbuf_start_track_change(false); | 2347 | pcmbuf_start_track_change(TRACK_CHANGE_MANUAL); |
2371 | audio_clear_paused_pcm(); | ||
2372 | wipe_track_metadata(true); | 2348 | wipe_track_metadata(true); |
2373 | } | 2349 | } |
2374 | 2350 | ||
@@ -2398,6 +2374,10 @@ static void audio_start_playback(size_t offset, unsigned int flags) | |||
2398 | play_status = PLAY_PLAYING; | 2374 | play_status = PLAY_PLAYING; |
2399 | } | 2375 | } |
2400 | 2376 | ||
2377 | /* Codec's position should be available as soon as it knows it */ | ||
2378 | position_key = pcmbuf_get_position_key(); | ||
2379 | pcmbuf_sync_position_update(); | ||
2380 | |||
2401 | /* Start fill from beginning of playlist */ | 2381 | /* Start fill from beginning of playlist */ |
2402 | playlist_peek_offset = -1; | 2382 | playlist_peek_offset = -1; |
2403 | buf_set_base_handle(-1); | 2383 | buf_set_base_handle(-1); |
@@ -2592,7 +2572,7 @@ static void audio_on_skip(void) | |||
2592 | trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1); | 2572 | trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, -1); |
2593 | } | 2573 | } |
2594 | 2574 | ||
2595 | audio_begin_track_change(false, trackstat); | 2575 | audio_begin_track_change(TRACK_CHANGE_MANUAL, trackstat); |
2596 | } | 2576 | } |
2597 | 2577 | ||
2598 | /* Skip to the next/previous directory | 2578 | /* Skip to the next/previous directory |
@@ -2638,7 +2618,7 @@ static void audio_on_dir_skip(int direction) | |||
2638 | return; | 2618 | return; |
2639 | } | 2619 | } |
2640 | 2620 | ||
2641 | audio_begin_track_change(false, trackstat); | 2621 | audio_begin_track_change(TRACK_CHANGE_MANUAL, trackstat); |
2642 | } | 2622 | } |
2643 | 2623 | ||
2644 | /* Enter seek mode in order to start a seek | 2624 | /* Enter seek mode in order to start a seek |
@@ -2689,11 +2669,6 @@ static void audio_on_ff_rewind(long time) | |||
2689 | if (time == 0) | 2669 | if (time == 0) |
2690 | send_event(PLAYBACK_EVENT_TRACK_FINISH, id3); | 2670 | send_event(PLAYBACK_EVENT_TRACK_FINISH, id3); |
2691 | 2671 | ||
2692 | /* Prevent user codec time update - coerce to something that is | ||
2693 | innocuous concerning lookaheads */ | ||
2694 | if (pending == TRACK_SKIP_NONE) | ||
2695 | skip_pending = TRACK_SKIP_AUTO_END_PLAYLIST; | ||
2696 | |||
2697 | id3->elapsed = time; | 2672 | id3->elapsed = time; |
2698 | queue_reply(&audio_queue, 1); | 2673 | queue_reply(&audio_queue, 1); |
2699 | 2674 | ||
@@ -2703,6 +2678,9 @@ static void audio_on_ff_rewind(long time) | |||
2703 | halt that will reset it */ | 2678 | halt that will reset it */ |
2704 | codec_seeking = true; | 2679 | codec_seeking = true; |
2705 | 2680 | ||
2681 | /* If in transition, key will have changed - sync to it */ | ||
2682 | position_key = pcmbuf_get_position_key(); | ||
2683 | |||
2706 | if (pending == TRACK_SKIP_AUTO) | 2684 | if (pending == TRACK_SKIP_AUTO) |
2707 | { | 2685 | { |
2708 | if (!track_list_advance_current(-1)) | 2686 | if (!track_list_advance_current(-1)) |
@@ -3124,75 +3102,66 @@ static void buffer_event_finished_callback(void *data) | |||
3124 | 3102 | ||
3125 | /** -- Codec callbacks -- **/ | 3103 | /** -- Codec callbacks -- **/ |
3126 | 3104 | ||
3127 | /* Update elapsed times with latency-adjusted values */ | 3105 | /* Update elapsed time for next PCM insert */ |
3128 | void audio_codec_update_elapsed(unsigned long value) | 3106 | void audio_codec_update_elapsed(unsigned long elapsed) |
3129 | { | 3107 | { |
3130 | #ifdef AB_REPEAT_ENABLE | 3108 | #ifdef AB_REPEAT_ENABLE |
3131 | ab_position_report(value); | 3109 | ab_position_report(elapsed); |
3132 | #endif | 3110 | #endif |
3133 | 3111 | /* Save in codec's id3 where it is used at next pcm insert */ | |
3134 | unsigned long latency = pcmbuf_get_latency(); | 3112 | id3_get(CODEC_ID3)->elapsed = elapsed; |
3135 | |||
3136 | if (LIKELY(value >= latency)) | ||
3137 | { | ||
3138 | unsigned long elapsed = value - latency; | ||
3139 | |||
3140 | if (elapsed > value || elapsed < value - 2) | ||
3141 | value = elapsed; | ||
3142 | } | ||
3143 | else | ||
3144 | { | ||
3145 | value = 0; | ||
3146 | } | ||
3147 | |||
3148 | /* Track codec: used later when updating the playing at the user | ||
3149 | transition */ | ||
3150 | id3_get(CODEC_ID3)->elapsed = value; | ||
3151 | |||
3152 | /* If a skip is pending, the PCM buffer is updating the time on the | ||
3153 | previous song */ | ||
3154 | if (LIKELY(skip_pending == TRACK_SKIP_NONE)) | ||
3155 | id3_get(PLAYING_ID3)->elapsed = value; | ||
3156 | } | 3113 | } |
3157 | 3114 | ||
3158 | /* Update offsets with latency-adjusted values */ | 3115 | /* Update offset for next PCM insert */ |
3159 | void audio_codec_update_offset(size_t value) | 3116 | void audio_codec_update_offset(size_t offset) |
3160 | { | 3117 | { |
3161 | struct mp3entry *ci_id3 = id3_get(CODEC_ID3); | 3118 | /* Save in codec's id3 where it is used at next pcm insert */ |
3162 | unsigned long latency = pcmbuf_get_latency() * ci_id3->bitrate / 8; | 3119 | id3_get(CODEC_ID3)->offset = offset; |
3120 | } | ||
3163 | 3121 | ||
3164 | if (LIKELY(value >= latency)) | 3122 | /* Codec has finished running */ |
3165 | { | 3123 | void audio_codec_complete(int status) |
3166 | value -= latency; | 3124 | { |
3167 | } | 3125 | #ifdef AB_REPEAT_ENABLE |
3168 | else | 3126 | if (status >= CODEC_OK) |
3169 | { | 3127 | { |
3170 | value = 0; | 3128 | /* Normal automatic skip */ |
3129 | ab_end_of_track_report(); | ||
3171 | } | 3130 | } |
3131 | #endif | ||
3172 | 3132 | ||
3173 | /* Track codec: used later when updating the playing id3 at the user | 3133 | LOGFQUEUE("codec > audio Q_AUDIO_CODEC_COMPLETE: %d", status); |
3174 | transition */ | 3134 | audio_queue_post(Q_AUDIO_CODEC_COMPLETE, status); |
3175 | ci_id3->offset = value; | 3135 | } |
3176 | 3136 | ||
3177 | /* If a skip is pending, the PCM buffer is updating the time on the | 3137 | /* Codec has finished seeking */ |
3178 | previous song */ | 3138 | void audio_codec_seek_complete(void) |
3179 | if (LIKELY(skip_pending == TRACK_SKIP_NONE)) | 3139 | { |
3180 | id3_get(PLAYING_ID3)->offset = value; | 3140 | LOGFQUEUE("codec > audio Q_AUDIO_CODEC_SEEK_COMPLETE"); |
3141 | audio_queue_post(Q_AUDIO_CODEC_SEEK_COMPLETE, 0); | ||
3181 | } | 3142 | } |
3182 | 3143 | ||
3183 | 3144 | ||
3184 | /** --- Pcmbuf callbacks --- **/ | 3145 | /** --- Pcmbuf callbacks --- **/ |
3185 | 3146 | ||
3186 | /* Between the codec and PCM track change, we need to keep updating the | 3147 | /* Update the elapsed and offset from the information cached during the |
3187 | * "elapsed" value of the previous (to the codec, but current to the | 3148 | PCM buffer insert */ |
3188 | * user/PCM/WPS) track, so that the progressbar reaches the end. */ | 3149 | void audio_pcmbuf_position_callback(unsigned long elapsed, off_t offset, |
3189 | void audio_pcmbuf_position_callback(unsigned int time) | 3150 | unsigned int key) |
3190 | { | 3151 | { |
3191 | struct mp3entry *id3 = id3_get(PLAYING_ID3); | 3152 | if (key == position_key) |
3192 | 3153 | { | |
3193 | time += id3->elapsed; | 3154 | struct mp3entry *id3 = id3_get(PLAYING_ID3); |
3155 | id3->elapsed = elapsed; | ||
3156 | id3->offset = offset; | ||
3157 | } | ||
3158 | } | ||
3194 | 3159 | ||
3195 | id3->elapsed = MIN(time, id3->length); | 3160 | /* Synchronize position info to the codec's */ |
3161 | void audio_pcmbuf_sync_position(void) | ||
3162 | { | ||
3163 | audio_pcmbuf_position_callback(ci.id3->elapsed, ci.id3->offset, | ||
3164 | pcmbuf_get_position_key()); | ||
3196 | } | 3165 | } |
3197 | 3166 | ||
3198 | /* Post message from pcmbuf that the end of the previous track has just | 3167 | /* Post message from pcmbuf that the end of the previous track has just |