summaryrefslogtreecommitdiff
path: root/apps/plugins/playing_time.c
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2024-08-02 22:02:05 +0200
committerChristian Soffke <christian.soffke@gmail.com>2024-08-11 17:30:19 +0200
commit8dcd781291a5fe8d8605a0e5aab2dc0dd371b33b (patch)
tree152d12e16db8492e91d2c8b3622cd14d24111f9e /apps/plugins/playing_time.c
parent1f7ea715db2341cc3da067a75a20761324489655 (diff)
downloadrockbox-8dcd781291a5fe8d8605a0e5aab2dc0dd371b33b.tar.gz
rockbox-8dcd781291a5fe8d8605a0e5aab2dc0dd371b33b.zip
plugins: Playing Time: Add 'Remaining' and 'Single Mode' options
1) Remaining: Sometimes, you may only be interested in how much time is left in a playlist, but don't care about the progress already made. The new option will disregard already played tracks, which can be much faster, depending on your position in the playlist. 2) Single Mode: When 'Single Mode' is enabled (and set to something other than 'Track'), you now have the option to see the time elapsed and remaining specifically for that section of the playlist (e.g. the playing album). Change-Id: I786eaababc537f565ab3fa4de1c46b7d5f3d1101
Diffstat (limited to 'apps/plugins/playing_time.c')
-rw-r--r--apps/plugins/playing_time.c421
1 files changed, 285 insertions, 136 deletions
diff --git a/apps/plugins/playing_time.c b/apps/plugins/playing_time.c
index 5916e4e58f..54752e987a 100644
--- a/apps/plugins/playing_time.c
+++ b/apps/plugins/playing_time.c
@@ -32,10 +32,10 @@ const unsigned char * const byte_units[] =
32}; 32};
33 33
34const int menu_items[] = { 34const int menu_items[] = {
35 LANG_PLAYTIME_ELAPSED, 35 LANG_REMAINING,
36 LANG_PLAYTIME_REMAINING, 36 LANG_ELAPSED,
37 LANG_PLAYTIME_TRK_ELAPSED,
38 LANG_PLAYTIME_TRK_REMAINING, 37 LANG_PLAYTIME_TRK_REMAINING,
38 LANG_PLAYTIME_TRK_ELAPSED,
39 LANG_PLAYTIME_TRACK, 39 LANG_PLAYTIME_TRACK,
40 LANG_PLAYTIME_STORAGE, 40 LANG_PLAYTIME_STORAGE,
41 LANG_PLAYTIME_AVG_TRACK_SIZE, 41 LANG_PLAYTIME_AVG_TRACK_SIZE,
@@ -54,14 +54,61 @@ enum ePT_SUM {
54}; 54};
55 55
56struct playing_time_info { 56struct playing_time_info {
57 int nb_tracks; /* number of tracks in playlist */ 57 char single_mode_tag[MAX_PATH]; /* Relevant tag when single mode enabled */
58 int curr_track_index; /* index of currently playing track in playlist */ 58 unsigned long long size[ePT_COUNT]; /* File size of tracks */
59 int curr_display_index; /* display index of currently playing track */ 59 unsigned long long length[ePT_COUNT]; /* Length of tracks */
60 unsigned long curr_track_length[ePT_COUNT]; /* current track length */ 60 unsigned long curr_track_length[ePT_COUNT]; /* Current track length */
61 unsigned long long length[ePT_COUNT]; /* length of all tracks */ 61 int curr_track_index; /* Index of currently playing track in playlist */
62 unsigned long long size[ePT_COUNT]; /* file size of all tracks */ 62 int curr_display_index; /* Display index of currently playing track */
63 int actual_index; /* Display index in actually counted tracks */
64 int counted; /* Number of tracks already added up */
65 int nb_tracks; /* Number of tracks in playlist */
66 int error_count; /* Number of tracks whose data couldn't be retrieved */
67 bool remaining_only; /* Whether to ignore elapsed tracks */
63}; 68};
64 69
70static int32_t single_mode_lang(void)
71{
72 switch (rb->global_settings->single_mode)
73 {
74 case SINGLE_MODE_ALBUM:
75 return LANG_ID3_ALBUM;
76 case SINGLE_MODE_ALBUM_ARTIST:
77 return LANG_ID3_ALBUMARTIST;
78 case SINGLE_MODE_ARTIST:
79 return LANG_ID3_ARTIST;
80 case SINGLE_MODE_COMPOSER:
81 return LANG_ID3_COMPOSER;
82 case SINGLE_MODE_GROUPING:
83 return LANG_ID3_GROUPING;
84 case SINGLE_MODE_GENRE:
85 return LANG_ID3_GENRE;
86 case SINGLE_MODE_TRACK:
87 return LANG_TRACK;
88 }
89 return LANG_OFF;
90}
91
92static char* single_mode_id3_tag(struct mp3entry *id3)
93{
94 switch (rb->global_settings->single_mode)
95 {
96 case SINGLE_MODE_ALBUM:
97 return id3->album;
98 case SINGLE_MODE_ALBUM_ARTIST:
99 return id3->albumartist;
100 case SINGLE_MODE_ARTIST:
101 return id3->artist;
102 case SINGLE_MODE_COMPOSER:
103 return id3->composer;
104 case SINGLE_MODE_GROUPING:
105 return id3->grouping;
106 case SINGLE_MODE_GENRE:
107 return id3->genre_string;
108 }
109 return NULL;
110}
111
65static char* get_percent_str(long percents) 112static char* get_percent_str(long percents)
66{ 113{
67 static char val[10]; 114 static char val[10];
@@ -97,7 +144,18 @@ static const char * pt_get_or_speak_info(int selected_item, void * data,
97 144
98 /* data */ 145 /* data */
99 switch(info_no) { 146 switch(info_no) {
100 case 0: { /* elapsed and total time */ 147 case 0: { /* playlist remaining time */
148 char timestr[25];
149 rb->format_time_auto(timestr, sizeof(timestr),
150 pti->length[ePT_REMAINING], UNIT_SEC, false);
151 rb->snprintf(buf, buffer_len, "%s", timestr);
152
153 if (say_it)
154 rb_talk_ids(false, menu_name_id,
155 TALK_ID(pti->length[ePT_REMAINING], UNIT_TIME));
156 break;
157 }
158 case 1: { /* elapsed and total time */
101 char timestr1[25], timestr2[25]; 159 char timestr1[25], timestr2[25];
102 rb->format_time_auto(timestr1, sizeof(timestr1), 160 rb->format_time_auto(timestr1, sizeof(timestr1),
103 pti->length[ePT_ELAPSED], UNIT_SEC, true); 161 pti->length[ePT_ELAPSED], UNIT_SEC, true);
@@ -128,18 +186,18 @@ static const char * pt_get_or_speak_info(int selected_item, void * data,
128 TALK_ID(elapsed_pct, UNIT_PERCENT)); 186 TALK_ID(elapsed_pct, UNIT_PERCENT));
129 break; 187 break;
130 } 188 }
131 case 1: { /* playlist remaining time */ 189 case 2: { /* track remaining time */
132 char timestr[25]; 190 char timestr[25];
133 rb->format_time_auto(timestr, sizeof(timestr), 191 rb->format_time_auto(timestr, sizeof(timestr),
134 pti->length[ePT_REMAINING], UNIT_SEC, false); 192 pti->curr_track_length[ePT_REMAINING], UNIT_SEC, false);
135 rb->snprintf(buf, buffer_len, "%s", timestr); 193 rb->snprintf(buf, buffer_len, "%s", timestr);
136 194
137 if (say_it) 195 if (say_it)
138 rb_talk_ids(false, menu_name_id, 196 rb_talk_ids(false, menu_name_id,
139 TALK_ID(pti->length[ePT_REMAINING], UNIT_TIME)); 197 TALK_ID(pti->curr_track_length[ePT_REMAINING], UNIT_TIME));
140 break; 198 break;
141 } 199 }
142 case 2: { /* track elapsed and duration */ 200 case 3: { /* track elapsed and duration */
143 char timestr1[25], timestr2[25]; 201 char timestr1[25], timestr2[25];
144 202
145 rb->format_time_auto(timestr1, sizeof(timestr1), 203 rb->format_time_auto(timestr1, sizeof(timestr1),
@@ -170,32 +228,21 @@ static const char * pt_get_or_speak_info(int selected_item, void * data,
170 TALK_ID(elapsed_pct, UNIT_PERCENT)); 228 TALK_ID(elapsed_pct, UNIT_PERCENT));
171 break; 229 break;
172 } 230 }
173 case 3: { /* track remaining time */
174 char timestr[25];
175 rb->format_time_auto(timestr, sizeof(timestr),
176 pti->curr_track_length[ePT_REMAINING], UNIT_SEC, false);
177 rb->snprintf(buf, buffer_len, "%s", timestr);
178
179 if (say_it)
180 rb_talk_ids(false, menu_name_id,
181 TALK_ID(pti->curr_track_length[ePT_REMAINING], UNIT_TIME));
182 break;
183 }
184 case 4: { /* track index */ 231 case 4: { /* track index */
185 int track_pct = pti->curr_display_index * 100 / pti->nb_tracks; 232 int track_pct = pti->actual_index * 100 / pti->counted;
186 233
187 if (rb->lang_is_rtl()) 234 if (rb->lang_is_rtl())
188 rb->snprintf(buf, buffer_len, "%s %d / %d", get_percent_str(track_pct), 235 rb->snprintf(buf, buffer_len, "%s %d / %d", get_percent_str(track_pct),
189 pti->nb_tracks, pti->curr_display_index); 236 pti->counted, pti->actual_index);
190 else 237 else
191 rb->snprintf(buf, buffer_len, "%d / %d %s", pti->curr_display_index, 238 rb->snprintf(buf, buffer_len, "%d / %d %s", pti->actual_index,
192 pti->nb_tracks, get_percent_str(track_pct)); 239 pti->counted, get_percent_str(track_pct));
193 240
194 if (say_it) 241 if (say_it)
195 rb_talk_ids(false, menu_name_id, 242 rb_talk_ids(false, menu_name_id,
196 TALK_ID(pti->curr_display_index, UNIT_INT), 243 TALK_ID(pti->actual_index, UNIT_INT),
197 VOICE_OF, 244 VOICE_OF,
198 TALK_ID(pti->nb_tracks, UNIT_INT), 245 TALK_ID(pti->counted, UNIT_INT),
199 VOICE_PAUSE, 246 VOICE_PAUSE,
200 TALK_ID(track_pct, UNIT_PERCENT)); 247 TALK_ID(track_pct, UNIT_PERCENT));
201 break; 248 break;
@@ -215,7 +262,7 @@ static const char * pt_get_or_speak_info(int selected_item, void * data,
215 int32_t voice_ids[ePT_COUNT]; 262 int32_t voice_ids[ePT_COUNT];
216 voice_ids[ePT_TOTAL] = menu_name_id; 263 voice_ids[ePT_TOTAL] = menu_name_id;
217 voice_ids[ePT_ELAPSED] = VOICE_PLAYTIME_DONE; 264 voice_ids[ePT_ELAPSED] = VOICE_PLAYTIME_DONE;
218 voice_ids[ePT_REMAINING] = LANG_PLAYTIME_REMAINING; 265 voice_ids[ePT_REMAINING] = LANG_REMAINING;
219 266
220 for (i = 0; i < ePT_COUNT; i++) 267 for (i = 0; i < ePT_COUNT; i++)
221 { 268 {
@@ -227,7 +274,7 @@ static const char * pt_get_or_speak_info(int selected_item, void * data,
227 } 274 }
228 case 6: { /* Average track file size */ 275 case 6: { /* Average track file size */
229 char str[20]; 276 char str[20];
230 long avg_track_size = pti->size[ePT_TOTAL] / pti->nb_tracks; 277 long avg_track_size = pti->size[ePT_TOTAL] / pti->counted;
231 rb->output_dyn_value(str, sizeof(str), avg_track_size, kibyte_units, 3, true); 278 rb->output_dyn_value(str, sizeof(str), avg_track_size, kibyte_units, 3, true);
232 rb->snprintf(buf, buffer_len, "%s", str); 279 rb->snprintf(buf, buffer_len, "%s", str);
233 280
@@ -266,138 +313,240 @@ static int pt_speak_info(int selected_item, void * data)
266 return 0; 313 return 0;
267} 314}
268 315
269/* playing time screen: shows total and elapsed playlist duration and 316static bool pt_display_stats(struct playing_time_info *pti)
270 other stats */
271static bool playing_time(void)
272{ 317{
273 struct playing_time_info pti;
274 struct playlist_track_info pl_track;
275 struct mp3entry id3;
276 struct mp3entry *curr_id3;
277 struct gui_synclist pt_lists; 318 struct gui_synclist pt_lists;
278 unsigned long talked_tick = *rb->current_tick; 319 rb->gui_synclist_init(&pt_lists, &pt_get_info, pti, true, 2, NULL);
279 int action, i, index, section, error_count = 0; 320 if (rb->global_settings->talk_menu)
321 rb->gui_synclist_set_voice_callback(&pt_lists, pt_speak_info);
322 rb->gui_synclist_set_nb_items(&pt_lists, pti->remaining_only ? 2 : 8*2);
323 rb->gui_synclist_set_title(&pt_lists, *pti->single_mode_tag ?
324 rb->str(single_mode_lang()) :
325 rb->str(LANG_PLAYLIST), NOICON);
326 rb->gui_synclist_draw(&pt_lists);
327 rb->gui_synclist_speak_item(&pt_lists);
328 while (true)
329 {
330 int action = rb->get_action(CONTEXT_LIST, HZ/2);
331 if (rb->gui_synclist_do_button(&pt_lists, &action) == 0
332 && action != ACTION_NONE && action != ACTION_UNKNOWN)
333 {
334 bool usb = rb->default_event_handler(action) == SYS_USB_CONNECTED;
280 335
281 pti.nb_tracks = rb->playlist_amount(); 336 if (!usb && IS_SYSEVENT(action))
282 rb->playlist_get_resume_info(&pti.curr_track_index); 337 continue;
283 curr_id3 = rb->audio_current_track();
284 338
285 if (pti.curr_track_index == -1 || !curr_id3) 339 rb->talk_force_shutup();
286 return false; 340 return usb;
341 }
342 }
343 return false;
344}
287 345
288 pti.curr_display_index = rb->playlist_get_display_index(); 346static const char *pt_options_name(int selected_item, void * data,
347 char *buf, size_t buf_size)
348{
349 (void) data;
350 (void) buf;
351 (void) buf_size;
352 return selected_item == 0 ? rb->str(LANG_ALL) :
353 selected_item == 1 ? rb->str(LANG_REMAINING) :
354 rb->str(single_mode_lang());
355}
289 356
290 pti.length[ePT_ELAPSED] = pti.curr_track_length[ePT_ELAPSED] 357static int pt_options_speak(int selected_item, void * data)
291 = curr_id3->elapsed; 358{
292 pti.length[ePT_REMAINING] = pti.curr_track_length[ePT_REMAINING] 359 (void) data;
293 = curr_id3->length - curr_id3->elapsed; 360 rb->talk_id(selected_item == 0 ? LANG_ALL :
361 selected_item == 1 ? LANG_REMAINING :
362 single_mode_lang(), false);
363 return 0;
364}
294 365
295 pti.size[ePT_ELAPSED] = curr_id3->offset; 366static int pt_options(struct playing_time_info *pti)
296 pti.size[ePT_REMAINING] = curr_id3->filesize - curr_id3->offset; 367{
368 struct gui_synclist pt_options;
369 rb->gui_synclist_init(&pt_options, &pt_options_name, NULL, true, 1, NULL);
370 if (rb->global_settings->talk_menu)
371 rb->gui_synclist_set_voice_callback(&pt_options, pt_options_speak);
372 rb->gui_synclist_set_nb_items(&pt_options, *pti->single_mode_tag ? 3 : 2);
373 rb->gui_synclist_set_title(&pt_options, rb->str(LANG_PLAYING_TIME), NOICON);
374 rb->gui_synclist_draw(&pt_options);
375 rb->gui_synclist_speak_item(&pt_options);
297 376
298 rb->splash_progress_set_delay(HZ/2); 377 while(true)
378 {
379 int button = rb->get_action(CONTEXT_LIST, HZ);
380 if (rb->gui_synclist_do_button(&pt_options, &button))
381 continue;
382 switch(button)
383 {
384 case ACTION_STD_OK:
385 {
386 int sel = rb->gui_synclist_get_sel_pos(&pt_options);
387 if (sel < 2)
388 *pti->single_mode_tag = 0;
389 if (sel == 1)
390 pti->remaining_only = true;
391 return -1;
392 }
393 case ACTION_STD_CANCEL:
394 return 0;
395 default:
396 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
397 return 1;
398 }
399 }
400}
299 401
300#ifdef HAVE_ADJUSTABLE_CPU_FREQ 402static void pt_store_converted_totals(struct playing_time_info *pti)
301 rb->cpu_boost(true); 403{
302#endif 404 /* convert units from ms to s */
303 /* Go through each file in the playlist and get its stats. For 405 pti->length[ePT_ELAPSED] /= 1000;
304 huge playlists this can take a while... The reference position 406 pti->length[ePT_REMAINING] /= 1000;
305 is the position at the moment this function was invoked, 407 pti->curr_track_length[ePT_ELAPSED] /= 1000;
306 although playback continues forward. */ 408 pti->curr_track_length[ePT_REMAINING] /= 1000;
307 index = rb->playlist_get_first_index(NULL); 409 /* convert units from Bytes to KiB */
308 for (i = 0; i < pti.nb_tracks; i++, index++) { 410 pti->size[ePT_ELAPSED] >>= 10;
411 pti->size[ePT_REMAINING] >>= 10;
309 412
310 if (index == pti.nb_tracks) 413 pti->length[ePT_TOTAL] = pti->length[ePT_ELAPSED] + pti->length[ePT_REMAINING];
311 index = 0; 414 pti->curr_track_length[ePT_TOTAL] = pti->curr_track_length[ePT_ELAPSED]
415 + pti->curr_track_length[ePT_REMAINING];
416 pti->size[ePT_TOTAL] = pti->size[ePT_ELAPSED] + pti->size[ePT_REMAINING];
417}
312 418
313 rb->splash_progress(i, pti.nb_tracks, "%s (%s)", 419static int pt_add_track(int i, enum ePT_SUM section, struct playing_time_info *pti)
314 rb->str(LANG_WAIT), rb->str(LANG_OFF_ABORT)); 420{
421 struct mp3entry id3;
422 struct playlist_track_info pl_track;
423 static unsigned long talked_tick;
424 int progress_total = pti->remaining_only ?
425 pti->nb_tracks - pti->curr_display_index :
426 pti->nb_tracks;
315 427
316 if (TIME_AFTER(*rb->current_tick, talked_tick + HZ*5)) 428 rb->splash_progress(pti->counted, progress_total, "%s (%s)",
317 { 429 rb->str(LANG_WAIT), rb->str(LANG_OFF_ABORT));
318 talked_tick = *rb->current_tick;
319 rb_talk_ids(false, LANG_LOADING_PERCENT,
320 TALK_ID(i * 100 / pti.nb_tracks, UNIT_PERCENT));
321 }
322 if (rb->action_userabort(TIMEOUT_NOBLOCK))
323 {
324#ifdef HAVE_ADJUSTABLE_CPU_FREQ
325 rb->cpu_boost(false);
326#endif
327 goto exit;
328 }
329 430
330 if (index == pti.curr_track_index) 431 if (TIME_AFTER(*rb->current_tick, talked_tick + HZ*5))
331 continue; 432 {
433 talked_tick = *rb->current_tick;
434 rb_talk_ids(false, LANG_LOADING_PERCENT,
435 TALK_ID(pti->counted * 100 / progress_total,
436 UNIT_PERCENT));
437 }
332 438
333 if (rb->playlist_get_track_info(NULL, index, &pl_track) < 0 439 if (rb->action_userabort(TIMEOUT_NOBLOCK))
334 || !rb->get_metadata(&id3, -1, pl_track.filename)) 440 return -1;
335 { 441 else if (rb->playlist_get_track_info(NULL, i, &pl_track) < 0
336 error_count++; 442 || !rb->get_metadata(&id3, -1, pl_track.filename))
337 continue; 443 {
338 } 444 pti->error_count++;
445 return -2;
446 }
447 else if(*pti->single_mode_tag && /* single mode tag doesn't match */
448 rb->strcmp(pti->single_mode_tag, single_mode_id3_tag(&id3) ?: ""))
449 return 1;
450
451 pti->length[section] += id3.length;
452 pti->size[section] += id3.filesize;
453 pti->counted++;
454 return 0;
455}
339 456
340 section = pl_track.display_index < pti.curr_display_index ? 457static bool pt_add_remaining(struct playing_time_info *pti)
341 ePT_ELAPSED : ePT_REMAINING; 458{
342 pti.length[section] += id3.length; 459 int display_index = pti->curr_display_index + 1;
343 pti.size[section] += id3.filesize; 460 for (int i = pti->curr_track_index + 1; display_index <= pti->nb_tracks; i++, display_index++)
461 {
462 if (i == pti->nb_tracks)
463 i = 0;
464
465 int ret = pt_add_track(i, ePT_REMAINING, pti);
466 if (ret == 1)
467 break;
468 else if (ret == -1)
469 return false;
344 } 470 }
345#ifdef HAVE_ADJUSTABLE_CPU_FREQ 471 return true;
346 rb->cpu_boost(false); 472}
347#endif
348 473
349 if (error_count > 0) 474static bool pt_add_elapsed(struct playing_time_info *pti)
350 rb->splash(HZ, ID2P(LANG_PLAYTIME_ERROR)); 475{
476 int display_index = pti->curr_display_index - 1;
477 for (int i = pti->curr_track_index - 1; display_index > 0; i--, display_index--)
478 {
479 if (i < 0)
480 i = pti->nb_tracks - 1;
481
482 int ret = pt_add_track(i, ePT_ELAPSED, pti);
483 if (ret == 1)
484 break;
485 else if (ret == -1)
486 return false;
487 else if (ret == 0)
488 pti->actual_index++;
489 }
490 return true;
491}
351 492
352 pti.nb_tracks -= error_count; 493static bool pt_add_curr_track(struct playing_time_info *pti)
494{
495 struct mp3entry *curr_id3 = rb->audio_current_track();
496 rb->playlist_get_resume_info(&pti->curr_track_index);
353 497
354 /* convert units from ms to s */ 498 if (pti->curr_track_index == -1 || !curr_id3)
355 pti.length[ePT_ELAPSED] /= 1000; 499 return false;
356 pti.length[ePT_REMAINING] /= 1000;
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 500
363 /* calculate totals */ 501 pti->curr_display_index = rb->playlist_get_display_index();
364 pti.length[ePT_TOTAL] = pti.length[ePT_ELAPSED] + pti.length[ePT_REMAINING]; 502 pti->length[ePT_ELAPSED] = pti->curr_track_length[ePT_ELAPSED]
365 pti.curr_track_length[ePT_TOTAL] = pti.curr_track_length[ePT_ELAPSED] 503 = curr_id3->elapsed;
366 + pti.curr_track_length[ePT_REMAINING]; 504 pti->length[ePT_REMAINING] = pti->curr_track_length[ePT_REMAINING]
367 pti.size[ePT_TOTAL] = pti.size[ePT_ELAPSED] + pti.size[ePT_REMAINING]; 505 = curr_id3->length - curr_id3->elapsed;
506 pti->size[ePT_ELAPSED] = curr_id3->offset;
507 pti->size[ePT_REMAINING] = curr_id3->filesize - curr_id3->offset;
508 pti->actual_index = pti->counted = 1;
509 rb->strlcpy(pti->single_mode_tag, single_mode_id3_tag(curr_id3) ?: "",
510 sizeof(pti->single_mode_tag));
511 return true;
512}
368 513
369 rb->gui_synclist_init(&pt_lists, &pt_get_info, &pti, true, 2, NULL); 514/* playing time screen: shows total and elapsed playlist duration and
370 if (rb->global_settings->talk_menu) 515 other stats */
371 rb->gui_synclist_set_voice_callback(&pt_lists, pt_speak_info); 516static bool playing_time(void)
372 rb->gui_synclist_set_nb_items(&pt_lists, 16); 517{
373 rb->gui_synclist_set_title(&pt_lists, rb->str(LANG_PLAYING_TIME), NOICON); 518 struct playing_time_info pti = {0};
374 rb->gui_synclist_draw(&pt_lists);
375 rb->gui_synclist_speak_item(&pt_lists);
376 while (true)
377 {
378 action = rb->get_action(CONTEXT_LIST, HZ/2);
379 if (rb->gui_synclist_do_button(&pt_lists, &action) == 0
380 && action != ACTION_NONE && action != ACTION_UNKNOWN)
381 {
382 bool usb = rb->default_event_handler(action) == SYS_USB_CONNECTED;
383 519
384 if (!usb && IS_SYSEVENT(action)) 520 if (!pt_add_curr_track(&pti))
385 continue; 521 return false;
386 522
387 rb->talk_force_shutup(); 523 int opt = pt_options(&pti);
388 return usb; 524 if (opt > -1)
389 } 525 return opt;
390 } 526
391 exit: 527#ifdef HAVE_ADJUSTABLE_CPU_FREQ
392 return false; 528 rb->cpu_boost(true);
529#endif
530 rb->splash_progress_set_delay(HZ/2);
531 pti.nb_tracks = rb->playlist_amount();
532 int success = (pti.remaining_only || pt_add_elapsed(&pti)) && pt_add_remaining(&pti);
533#ifdef HAVE_ADJUSTABLE_CPU_FREQ
534 rb->cpu_boost(false);
535#endif
536 if (!success)
537 return false;
538 if (pti.error_count > 0)
539 rb->splash(HZ, ID2P(LANG_PLAYTIME_ERROR));
540
541 pt_store_converted_totals(&pti);
542 return pt_display_stats(&pti);
393} 543}
394 544
395/* this is the plugin entry point */ 545/* this is the plugin entry point */
396enum plugin_status plugin_start(const void* parameter) 546enum plugin_status plugin_start(const void* parameter)
397{ 547{
398 enum plugin_status status = PLUGIN_OK;
399
400 (void)parameter; 548 (void)parameter;
549 enum plugin_status status = PLUGIN_OK;
401 550
402 if (!rb->audio_status()) 551 if (!rb->audio_status())
403 { 552 {