summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2024-07-24 20:50:39 +0200
committerChristian Soffke <christian.soffke@gmail.com>2024-07-26 21:16:13 +0200
commitb52e72db36469fab813f63d0e69ced2e9d241b61 (patch)
treeb9dd4626934f15e4aef03ff763c583fe9e2e0a3e
parent23e5f77ab0c5f80de4091b365165276cfe9899dd (diff)
downloadrockbox-b52e72db36469fab813f63d0e69ced2e9d241b61.tar.gz
rockbox-b52e72db36469fab813f63d0e69ced2e9d241b61.zip
plugins: playing time: improve precision
Add up length and size of tracks in ms & Bytes, then only convert units to s & KiB at the end. Otherwise, the result can be noticeably off when dealing with a large enough number of tracks. Change-Id: I2a3e502508089830f63b24c3bbdbb0ab8f57cabe
-rw-r--r--apps/plugins/playing_time.c305
1 files changed, 143 insertions, 162 deletions
diff --git a/apps/plugins/playing_time.c b/apps/plugins/playing_time.c
index 1da0d437c0..46fa6443e5 100644
--- a/apps/plugins/playing_time.c
+++ b/apps/plugins/playing_time.c
@@ -44,212 +44,190 @@ const int menu_items[] = {
44 44
45const unsigned char * const * const kibyte_units = &byte_units[1]; 45const unsigned char * const * const kibyte_units = &byte_units[1];
46 46
47enum ePT_SECS { 47enum ePT_SUM {
48 ePT_SECS_TTL = 0,
49 ePT_SECS_BEF,
50 ePT_SECS_AFT,
51 ePT_SECS_COUNT
52};
53
54enum ePT_KBS {
55 /* Note: Order matters (voicing order of LANG_PLAYTIME_STORAGE) */ 48 /* Note: Order matters (voicing order of LANG_PLAYTIME_STORAGE) */
56 ePT_KBS_TTL = 0, 49 ePT_TOTAL = 0,
57 ePT_KBS_BEF, 50 ePT_ELAPSED,
58 ePT_KBS_AFT, 51 ePT_REMAINING,
59 ePT_KBS_COUNT 52
53 ePT_COUNT
60}; 54};
61 55
62/* playing_time screen context */
63struct playing_time_info { 56struct playing_time_info {
64 int curr_index; /* index of currently playing track in playlist */ 57 int nb_tracks; /* number of tracks in playlist */
65 int curr_display_index; /* display index of currently playing track in playlist */ 58 int curr_track_index; /* index of currently playing track in playlist */
66 int nb_tracks; /* how many tracks in playlist */ 59 int curr_display_index; /* display index of currently playing track */
67 60 unsigned long curr_track_length[ePT_COUNT]; /* current track length */
68 /* seconds total, before, and after current position. Datatype 61 unsigned long long length[ePT_COUNT]; /* length of all tracks */
69 allows for values up to 68years. If I had kept it in ms 62 unsigned long long size[ePT_COUNT]; /* file size of all tracks */
70 though, it would have overflowed at 24days, which takes
71 something like 8.5GB at 32kbps, and so we could conceivably
72 have playlists lasting longer than that. */
73 long secs[ePT_SECS_COUNT];
74 long trk_secs[ePT_SECS_COUNT];
75
76 /* kilobytes played total, before, and after current pos.
77 Kilobytes because bytes would overflow. Data type range is up
78 to 2TB. */
79 long kbs[ePT_KBS_COUNT];
80}; 63};
81 64
82static char* get_percent_str(long percents) 65static char* get_percent_str(long percents)
83{ 66{
84 static char val[10]; 67 static char val[10];
85 rb->snprintf(val, 10, rb->str(LANG_PERCENT_FORMAT), percents); 68 rb->snprintf(val, sizeof(val), rb->str(LANG_PERCENT_FORMAT), percents);
86 return val; 69 return val;
87} 70}
88 71
89static inline void prepare_time_string(char *buf, size_t buffer_len, long elapsed_pct, const char *timestr1, const char *timestr2) 72static inline void prepare_time_string(char *buf, size_t buffer_len,
73 long elapsed_pct, const char *timestr1,
74 const char *timestr2)
90{ 75{
91 if (rb->lang_is_rtl()) 76 if (rb->lang_is_rtl())
92 {
93 rb->snprintf(buf, buffer_len, "%s %s / %s", 77 rb->snprintf(buf, buffer_len, "%s %s / %s",
94 get_percent_str(elapsed_pct), timestr2, timestr1); 78 get_percent_str(elapsed_pct), timestr2, timestr1);
95 }
96 else 79 else
97 {
98 rb->snprintf(buf, buffer_len, "%s / %s %s", 80 rb->snprintf(buf, buffer_len, "%s / %s %s",
99 timestr1, timestr2, get_percent_str(elapsed_pct)); 81 timestr1, timestr2, get_percent_str(elapsed_pct));
100 }
101} 82}
102 83
103/* list callback for playing_time screen */ 84/* list callback for playing_time screen */
104static const char * playing_time_get_or_speak_info(int selected_item, void * data, 85static const char * pt_get_or_speak_info(int selected_item, void * data,
105 char *buf, size_t buffer_len, 86 char *buf, size_t buffer_len,
106 bool say_it) 87 bool say_it)
107{ 88{
108 long elapsed_pct; /* percentage of duration elapsed */ 89 long elapsed_pct; /* percentage of duration elapsed */
109 struct playing_time_info *pti = (struct playing_time_info *)data; 90 struct playing_time_info *pti = (struct playing_time_info *)data;
110 int info_no = selected_item/2; 91 int info_no = selected_item/2;
111 const int menu_name_id = menu_items[info_no]; 92 const int menu_name_id = menu_items[info_no];
112 93
113 if (!(selected_item%2)) 94 /* header */
114 {/* header */ 95 if (!(selected_item % 2))
115 return rb->str(menu_name_id); 96 return rb->str(menu_name_id);
116 }
117 97
98 /* data */
118 switch(info_no) { 99 switch(info_no) {
119 case 0: { /* elapsed and total time */ 100 case 0: { /* elapsed and total time */
120 char timestr1[25], timestr2[25]; 101 char timestr1[25], timestr2[25];
121 rb->format_time_auto(timestr1, sizeof(timestr1), 102 rb->format_time_auto(timestr1, sizeof(timestr1),
122 pti->secs[ePT_SECS_BEF], UNIT_SEC, true); 103 pti->length[ePT_ELAPSED], UNIT_SEC, true);
123 104
124 rb->format_time_auto(timestr2, sizeof(timestr2), 105 rb->format_time_auto(timestr2, sizeof(timestr2),
125 pti->secs[ePT_SECS_TTL], UNIT_SEC, true); 106 pti->length[ePT_TOTAL], UNIT_SEC, true);
126 107
127 if (pti->secs[ePT_SECS_TTL] == 0) 108 if (pti->length[ePT_TOTAL] == 0)
128 elapsed_pct = 0; 109 elapsed_pct = 0;
129 else if (pti->secs[ePT_SECS_TTL] <= 0xFFFFFF) 110 else if (pti->length[ePT_TOTAL] <= 0xFFFFFF)
130 { 111 {
131 elapsed_pct = (pti->secs[ePT_SECS_BEF] * 100 112 elapsed_pct = (pti->length[ePT_ELAPSED] * 100
132 / pti->secs[ePT_SECS_TTL]); 113 / pti->length[ePT_TOTAL]);
133 } 114 }
134 else /* sacrifice some precision to avoid overflow */ 115 else /* sacrifice some precision to avoid overflow */
135 { 116 {
136 elapsed_pct = (pti->secs[ePT_SECS_BEF] >> 7) * 100 117 elapsed_pct = (pti->length[ePT_ELAPSED] >> 7) * 100
137 / (pti->secs[ePT_SECS_TTL] >> 7); 118 / (pti->length[ePT_TOTAL] >> 7);
138 } 119 }
139 prepare_time_string(buf, buffer_len, elapsed_pct, timestr1, timestr2); 120 prepare_time_string(buf, buffer_len, elapsed_pct, timestr1, timestr2);
140 121
141 if (say_it) 122 if (say_it)
142 rb_talk_ids(false, menu_name_id, 123 rb_talk_ids(false, menu_name_id,
143 TALK_ID(pti->secs[ePT_SECS_BEF], UNIT_TIME), 124 TALK_ID(pti->length[ePT_ELAPSED], UNIT_TIME),
144 VOICE_OF, 125 VOICE_OF,
145 TALK_ID(pti->secs[ePT_SECS_TTL], UNIT_TIME), 126 TALK_ID(pti->length[ePT_TOTAL], UNIT_TIME),
146 VOICE_PAUSE, 127 VOICE_PAUSE,
147 TALK_ID(elapsed_pct, UNIT_PERCENT)); 128 TALK_ID(elapsed_pct, UNIT_PERCENT));
148 break; 129 break;
149 } 130 }
150 case 1: { /* playlist remaining time */ 131 case 1: { /* playlist remaining time */
151 char timestr[25]; 132 char timestr[25];
152 rb->format_time_auto(timestr, sizeof(timestr), pti->secs[ePT_SECS_AFT], 133 rb->format_time_auto(timestr, sizeof(timestr),
153 UNIT_SEC, false); 134 pti->length[ePT_REMAINING], UNIT_SEC, false);
154 rb->snprintf(buf, buffer_len, "%s", timestr); 135 rb->snprintf(buf, buffer_len, "%s", timestr);
155 136
156 if (say_it) 137 if (say_it)
157 rb_talk_ids(false, menu_name_id, 138 rb_talk_ids(false, menu_name_id,
158 TALK_ID(pti->secs[ePT_SECS_AFT], UNIT_TIME)); 139 TALK_ID(pti->length[ePT_REMAINING], UNIT_TIME));
159 break; 140 break;
160 } 141 }
161 case 2: { /* track elapsed and duration */ 142 case 2: { /* track elapsed and duration */
162 char timestr1[25], timestr2[25]; 143 char timestr1[25], timestr2[25];
163 144
164 rb->format_time_auto(timestr1, sizeof(timestr1), pti->trk_secs[ePT_SECS_BEF], 145 rb->format_time_auto(timestr1, sizeof(timestr1),
165 UNIT_SEC, true); 146 pti->curr_track_length[ePT_ELAPSED], UNIT_SEC, true);
166 rb->format_time_auto(timestr2, sizeof(timestr2), pti->trk_secs[ePT_SECS_TTL], 147 rb->format_time_auto(timestr2, sizeof(timestr2),
167 UNIT_SEC, true); 148 pti->curr_track_length[ePT_TOTAL], UNIT_SEC, true);
168 149
169 if (pti->trk_secs[ePT_SECS_TTL] == 0) 150 if (pti->curr_track_length[ePT_TOTAL] == 0)
170 elapsed_pct = 0; 151 elapsed_pct = 0;
171 else if (pti->trk_secs[ePT_SECS_TTL] <= 0xFFFFFF) 152 else if (pti->curr_track_length[ePT_TOTAL] <= 0xFFFFFF)
172 { 153 {
173 elapsed_pct = (pti->trk_secs[ePT_SECS_BEF] * 100 154 elapsed_pct = (pti->curr_track_length[ePT_ELAPSED] * 100
174 / pti->trk_secs[ePT_SECS_TTL]); 155 / pti->curr_track_length[ePT_TOTAL]);
175 } 156 }
176 else /* sacrifice some precision to avoid overflow */ 157 else /* sacrifice some precision to avoid overflow */
177 { 158 {
178 elapsed_pct = (pti->trk_secs[ePT_SECS_BEF] >> 7) * 100 159 elapsed_pct = (pti->curr_track_length[ePT_ELAPSED] >> 7) * 100
179 / (pti->trk_secs[ePT_SECS_TTL] >> 7); 160 / (pti->curr_track_length[ePT_TOTAL] >> 7);
180 } 161 }
181 prepare_time_string(buf, buffer_len, elapsed_pct, timestr1, timestr2); 162 prepare_time_string(buf, buffer_len, elapsed_pct, timestr1, timestr2);
182 163
183 if (say_it) 164 if (say_it)
184 rb_talk_ids(false, menu_name_id, 165 rb_talk_ids(false, menu_name_id,
185 TALK_ID(pti->trk_secs[ePT_SECS_BEF], UNIT_TIME), 166 TALK_ID(pti->curr_track_length[ePT_ELAPSED], UNIT_TIME),
186 VOICE_OF, 167 VOICE_OF,
187 TALK_ID(pti->trk_secs[ePT_SECS_TTL], UNIT_TIME), 168 TALK_ID(pti->curr_track_length[ePT_TOTAL], UNIT_TIME),
188 VOICE_PAUSE, 169 VOICE_PAUSE,
189 TALK_ID(elapsed_pct, UNIT_PERCENT)); 170 TALK_ID(elapsed_pct, UNIT_PERCENT));
190 break; 171 break;
191 } 172 }
192 case 3: { /* track remaining time */ 173 case 3: { /* track remaining time */
193 char timestr[25]; 174 char timestr[25];
194 rb->format_time_auto(timestr, sizeof(timestr), pti->trk_secs[ePT_SECS_AFT], 175 rb->format_time_auto(timestr, sizeof(timestr),
195 UNIT_SEC, false); 176 pti->curr_track_length[ePT_REMAINING], UNIT_SEC, false);
196 rb->snprintf(buf, buffer_len, "%s", timestr); 177 rb->snprintf(buf, buffer_len, "%s", timestr);
197 178
198 if (say_it) 179 if (say_it)
199 rb_talk_ids(false, menu_name_id, 180 rb_talk_ids(false, menu_name_id,
200 TALK_ID(pti->trk_secs[ePT_SECS_AFT], UNIT_TIME)); 181 TALK_ID(pti->curr_track_length[ePT_REMAINING], UNIT_TIME));
201 break; 182 break;
202 } 183 }
203 case 4: { /* track index */ 184 case 4: { /* track index */
204 int track_pct = pti->curr_display_index * 100 / pti->nb_tracks; 185 int track_pct = pti->curr_display_index * 100 / pti->nb_tracks;
205 186
206 if (rb->lang_is_rtl()) 187 if (rb->lang_is_rtl())
207 { 188 rb->snprintf(buf, buffer_len, "%s %d / %d", get_percent_str(track_pct),
208 rb->snprintf(buf, buffer_len, "%s %d / %d", 189 pti->nb_tracks, pti->curr_display_index);
209 get_percent_str(track_pct), pti->nb_tracks, pti->curr_display_index);
210 }
211 else 190 else
212 { 191 rb->snprintf(buf, buffer_len, "%d / %d %s", pti->curr_display_index,
213 rb->snprintf(buf, buffer_len, "%d / %d %s", 192 pti->nb_tracks, get_percent_str(track_pct));
214 pti->curr_display_index, pti->nb_tracks, get_percent_str(track_pct));
215 }
216 193
217 if (say_it) 194 if (say_it)
218 rb_talk_ids(false, menu_name_id, 195 rb_talk_ids(false, menu_name_id,
219 TALK_ID(pti->curr_display_index, UNIT_INT), 196 TALK_ID(pti->curr_display_index, UNIT_INT),
220 VOICE_OF, 197 VOICE_OF,
221 TALK_ID(pti->nb_tracks, UNIT_INT), 198 TALK_ID(pti->nb_tracks, UNIT_INT),
222 VOICE_PAUSE, 199 VOICE_PAUSE,
223 TALK_ID(track_pct, UNIT_PERCENT)); 200 TALK_ID(track_pct, UNIT_PERCENT));
224 break; 201 break;
225 } 202 }
226 case 5: { /* storage size */ 203 case 5: { /* storage size */
227 int i; 204 int i;
228 char kbstr[ePT_KBS_COUNT][20]; 205 char kbstr[ePT_COUNT][20];
229 206
230 for (i = 0; i < ePT_KBS_COUNT; i++) { 207 for (i = 0; i < ePT_COUNT; i++) {
231 rb->output_dyn_value(kbstr[i], sizeof(kbstr[i]), 208 rb->output_dyn_value(kbstr[i], sizeof(kbstr[i]),
232 pti->kbs[i], kibyte_units, 3, true); 209 pti->size[i], kibyte_units, 3, true);
233 } 210 }
234 rb->snprintf(buf, buffer_len, "%s (%s / %s)", 211 rb->snprintf(buf, buffer_len, "%s (%s / %s)", kbstr[ePT_TOTAL],
235 kbstr[ePT_KBS_TTL], kbstr[ePT_KBS_BEF],kbstr[ePT_KBS_AFT]); 212 kbstr[ePT_ELAPSED], kbstr[ePT_REMAINING]);
236 213
237 if (say_it) { 214 if (say_it) {
238 int32_t voice_ids[ePT_KBS_COUNT]; 215 int32_t voice_ids[ePT_COUNT];
239 voice_ids[ePT_KBS_TTL] = menu_name_id; 216 voice_ids[ePT_TOTAL] = menu_name_id;
240 voice_ids[ePT_KBS_BEF] = VOICE_PLAYTIME_DONE; 217 voice_ids[ePT_ELAPSED] = VOICE_PLAYTIME_DONE;
241 voice_ids[ePT_KBS_AFT] = LANG_PLAYTIME_REMAINING; 218 voice_ids[ePT_REMAINING] = LANG_PLAYTIME_REMAINING;
242 219
243 for (i = 0; i < ePT_KBS_COUNT; i++) { 220 for (i = 0; i < ePT_COUNT; i++)
221 {
244 rb_talk_ids(i > 0, VOICE_PAUSE, voice_ids[i]); 222 rb_talk_ids(i > 0, VOICE_PAUSE, voice_ids[i]);
245 rb->output_dyn_value(NULL, 0, pti->kbs[i], kibyte_units, 3, true); 223 rb->output_dyn_value(NULL, 0, pti->size[i], kibyte_units, 3, true);
246 } 224 }
247 } 225 }
248 break; 226 break;
249 } 227 }
250 case 6: { /* Average track file size */ 228 case 6: { /* Average track file size */
251 char str[20]; 229 char str[20];
252 long avg_track_size = pti->kbs[ePT_KBS_TTL] / pti->nb_tracks; 230 long avg_track_size = pti->size[ePT_TOTAL] / pti->nb_tracks;
253 rb->output_dyn_value(str, sizeof(str), avg_track_size, kibyte_units, 3, true); 231 rb->output_dyn_value(str, sizeof(str), avg_track_size, kibyte_units, 3, true);
254 rb->snprintf(buf, buffer_len, "%s", str); 232 rb->snprintf(buf, buffer_len, "%s", str);
255 233
@@ -261,31 +239,30 @@ static const char * playing_time_get_or_speak_info(int selected_item, void * dat
261 } 239 }
262 case 7: { /* Average bitrate */ 240 case 7: { /* Average bitrate */
263 /* Convert power of 2 kilobytes to power of 10 kilobits */ 241 /* Convert power of 2 kilobytes to power of 10 kilobits */
264 long avg_bitrate = (pti->kbs[ePT_KBS_TTL] / pti->secs[ePT_SECS_TTL] 242 long avg_bitrate = (pti->size[ePT_TOTAL] / pti->length[ePT_TOTAL]
265 * 1024 * 8 / 1000); 243 * 1024 * 8 / 1000);
266 rb->snprintf(buf, buffer_len, "%ld kbps", avg_bitrate); 244 rb->snprintf(buf, buffer_len, "%ld kbps", avg_bitrate);
267 245
268 if (say_it) 246 if (say_it)
269 rb_talk_ids(false, menu_name_id, 247 rb_talk_ids(false, menu_name_id,
270 TALK_ID(avg_bitrate, UNIT_KBIT)); 248 TALK_ID(avg_bitrate, UNIT_KBIT));
271 break; 249 break;
272 } 250 }
273 } 251 }
274 return buf; 252 return buf;
275} 253}
276 254
277static const char * playing_time_get_info(int selected_item, void * data, 255static const char * pt_get_info(int selected_item, void * data,
278 char *buffer, size_t buffer_len) 256 char *buffer, size_t buffer_len)
279{ 257{
280 return playing_time_get_or_speak_info(selected_item, data, 258 return pt_get_or_speak_info(selected_item, data,
281 buffer, buffer_len, false); 259 buffer, buffer_len, false);
282} 260}
283 261
284static int playing_time_speak_info(int selected_item, void * data) 262static int pt_speak_info(int selected_item, void * data)
285{ 263{
286 static char buffer[MAX_PATH]; 264 static char buffer[MAX_PATH];
287 playing_time_get_or_speak_info(selected_item, data, 265 pt_get_or_speak_info(selected_item, data, buffer, sizeof(buffer), true);
288 buffer, MAX_PATH, true);
289 return 0; 266 return 0;
290} 267}
291 268
@@ -293,25 +270,30 @@ static int playing_time_speak_info(int selected_item, void * data)
293 other stats */ 270 other stats */
294static bool playing_time(void) 271static bool playing_time(void)
295{ 272{
296 int error_count = 0;
297 unsigned long talked_tick = *rb->current_tick;
298 struct playing_time_info pti; 273 struct playing_time_info pti;
299 struct playlist_track_info pltrack; 274 struct playlist_track_info pl_track;
300 struct mp3entry id3; 275 struct mp3entry id3;
301 int i, index; 276 struct mp3entry *curr_id3;
277 struct gui_synclist pt_lists;
278 unsigned long talked_tick = *rb->current_tick;
279 int action, i, index, section, error_count = 0;
302 280
303 pti.nb_tracks = rb->playlist_amount(); 281 pti.nb_tracks = rb->playlist_amount();
304 rb->playlist_get_resume_info(&pti.curr_index); 282 rb->playlist_get_resume_info(&pti.curr_track_index);
305 struct mp3entry *curr_id3 = rb->audio_current_track(); 283 curr_id3 = rb->audio_current_track();
306 if (pti.curr_index == -1 || !curr_id3) 284
285 if (pti.curr_track_index == -1 || !curr_id3)
307 return false; 286 return false;
287
308 pti.curr_display_index = rb->playlist_get_display_index(); 288 pti.curr_display_index = rb->playlist_get_display_index();
309 289
310 pti.secs[ePT_SECS_BEF] = pti.trk_secs[ePT_SECS_BEF] = curr_id3->elapsed / 1000; 290 pti.length[ePT_ELAPSED] = pti.curr_track_length[ePT_ELAPSED]
311 pti.secs[ePT_SECS_AFT] = pti.trk_secs[ePT_SECS_AFT] 291 = curr_id3->elapsed;
312 = (curr_id3->length -curr_id3->elapsed) / 1000; 292 pti.length[ePT_REMAINING] = pti.curr_track_length[ePT_REMAINING]
313 pti.kbs[ePT_KBS_BEF] = curr_id3->offset / 1024; 293 = curr_id3->length - curr_id3->elapsed;
314 pti.kbs[ePT_KBS_AFT] = (curr_id3->filesize -curr_id3->offset) / 1024; 294
295 pti.size[ePT_ELAPSED] = curr_id3->offset;
296 pti.size[ePT_REMAINING] = curr_id3->filesize - curr_id3->offset;
315 297
316 rb->splash_progress_set_delay(HZ/2); 298 rb->splash_progress_set_delay(HZ/2);
317 299
@@ -328,15 +310,14 @@ static bool playing_time(void)
328 if (index == pti.nb_tracks) 310 if (index == pti.nb_tracks)
329 index = 0; 311 index = 0;
330 312
331 /* Show a splash while we are loading. */
332 rb->splash_progress(i, pti.nb_tracks, "%s (%s)", 313 rb->splash_progress(i, pti.nb_tracks, "%s (%s)",
333 rb->str(LANG_WAIT), rb->str(LANG_OFF_ABORT)); 314 rb->str(LANG_WAIT), rb->str(LANG_OFF_ABORT));
334 315
335 /* Voice equivalent */ 316 if (TIME_AFTER(*rb->current_tick, talked_tick + HZ*5))
336 if (TIME_AFTER(*rb->current_tick, talked_tick + 5 * HZ)) { 317 {
337 talked_tick = *rb->current_tick; 318 talked_tick = *rb->current_tick;
338 rb_talk_ids(false, LANG_LOADING_PERCENT, 319 rb_talk_ids(false, LANG_LOADING_PERCENT,
339 TALK_ID(i * 100 / pti.nb_tracks, UNIT_PERCENT)); 320 TALK_ID(i * 100 / pti.nb_tracks, UNIT_PERCENT));
340 } 321 }
341 if (rb->action_userabort(TIMEOUT_NOBLOCK)) 322 if (rb->action_userabort(TIMEOUT_NOBLOCK))
342 { 323 {
@@ -346,67 +327,67 @@ static bool playing_time(void)
346 goto exit; 327 goto exit;
347 } 328 }
348 329
349 if (index == pti.curr_index) 330 if (index == pti.curr_track_index)
350 continue; 331 continue;
351 332
352 if (rb->playlist_get_track_info(NULL, index, &pltrack) < 0 333 if (rb->playlist_get_track_info(NULL, index, &pl_track) < 0
353 || !rb->get_metadata(&id3, -1, pltrack.filename)) 334 || !rb->get_metadata(&id3, -1, pl_track.filename))
354 { 335 {
355 error_count++; 336 error_count++;
356 continue; 337 continue;
357 } 338 }
358 339
359 if (pltrack.display_index < pti.curr_display_index) /* preceding tracks */ 340 section = pl_track.display_index < pti.curr_display_index ?
360 { 341 ePT_ELAPSED : ePT_REMAINING;
361 pti.secs[ePT_SECS_BEF] += id3.length / 1000; 342 pti.length[section] += id3.length;
362 pti.kbs[ePT_KBS_BEF] += id3.filesize / 1024; 343 pti.size[section] += id3.filesize;
363 }
364 else
365 {
366 pti.secs[ePT_SECS_AFT] += id3.length / 1000;
367 pti.kbs[ePT_KBS_AFT] += id3.filesize / 1024;
368 }
369 } 344 }
370#ifdef HAVE_ADJUSTABLE_CPU_FREQ 345#ifdef HAVE_ADJUSTABLE_CPU_FREQ
371 rb->cpu_boost(false); 346 rb->cpu_boost(false);
372#endif 347#endif
373 348
374 if (error_count > 0) 349 if (error_count > 0)
375 {
376 rb->splash(HZ, ID2P(LANG_PLAYTIME_ERROR)); 350 rb->splash(HZ, ID2P(LANG_PLAYTIME_ERROR));
377 }
378 351
379 pti.nb_tracks -= error_count; 352 pti.nb_tracks -= error_count;
380 pti.secs[ePT_SECS_TTL] = pti.secs[ePT_SECS_BEF] + pti.secs[ePT_SECS_AFT];
381 pti.trk_secs[ePT_SECS_TTL] = pti.trk_secs[ePT_SECS_BEF] + pti.trk_secs[ePT_SECS_AFT];
382 pti.kbs[ePT_KBS_TTL] = pti.kbs[ePT_KBS_BEF] + pti.kbs[ePT_KBS_AFT];
383 353
384 struct gui_synclist pt_lists; 354 /* convert units from ms to s */
385 int key; 355 pti.length[ePT_ELAPSED] /= 1000;
386 356 pti.length[ePT_REMAINING] /= 1000;
387 rb->gui_synclist_init(&pt_lists, &playing_time_get_info, &pti, true, 2, NULL); 357 pti.curr_track_length[ePT_ELAPSED] /= 1000;
358 pti.curr_track_length[ePT_REMAINING] /= 1000;
359 /* convert units from Bytes to KiB */
360 pti.size[ePT_ELAPSED] >>= 10;
361 pti.size[ePT_REMAINING] >>= 10;
362
363 /* calculate totals */
364 pti.length[ePT_TOTAL] = pti.length[ePT_ELAPSED] + pti.length[ePT_REMAINING];
365 pti.curr_track_length[ePT_TOTAL] = pti.curr_track_length[ePT_ELAPSED]
366 + pti.curr_track_length[ePT_REMAINING];
367 pti.size[ePT_TOTAL] = pti.size[ePT_ELAPSED] + pti.size[ePT_REMAINING];
368
369 rb->gui_synclist_init(&pt_lists, &pt_get_info, &pti, true, 2, NULL);
388 if (rb->global_settings->talk_menu) 370 if (rb->global_settings->talk_menu)
389 rb->gui_synclist_set_voice_callback(&pt_lists, playing_time_speak_info); 371 rb->gui_synclist_set_voice_callback(&pt_lists, pt_speak_info);
390 rb->gui_synclist_set_nb_items(&pt_lists, 16); 372 rb->gui_synclist_set_nb_items(&pt_lists, 16);
391 rb->gui_synclist_set_title(&pt_lists, rb->str(LANG_PLAYING_TIME), NOICON); 373 rb->gui_synclist_set_title(&pt_lists, rb->str(LANG_PLAYING_TIME), NOICON);
392 rb->gui_synclist_draw(&pt_lists); 374 rb->gui_synclist_draw(&pt_lists);
393 rb->gui_synclist_speak_item(&pt_lists); 375 rb->gui_synclist_speak_item(&pt_lists);
394 while (true) { 376 while (true)
395 key = rb->get_action(CONTEXT_LIST, HZ/2); 377 {
396 if (rb->gui_synclist_do_button(&pt_lists, &key) == 0 378 action = rb->get_action(CONTEXT_LIST, HZ/2);
397 && key!=ACTION_NONE && key!=ACTION_UNKNOWN) 379 if (rb->gui_synclist_do_button(&pt_lists, &action) == 0
380 && action != ACTION_NONE && action != ACTION_UNKNOWN)
398 { 381 {
399 bool usb = rb->default_event_handler(key) == SYS_USB_CONNECTED; 382 bool usb = rb->default_event_handler(action) == SYS_USB_CONNECTED;
400 383
401 if (!usb && IS_SYSEVENT(key)) 384 if (!usb && IS_SYSEVENT(action))
402 continue; 385 continue;
403 386
404 rb->talk_force_shutup(); 387 rb->talk_force_shutup();
405 return usb; 388 return usb;
406 } 389 }
407
408 } 390 }
409
410 exit: 391 exit:
411 return false; 392 return false;
412} 393}