summaryrefslogtreecommitdiff
path: root/apps/playlist_viewer.c
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-07-05 17:13:10 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2024-07-09 01:40:02 -0400
commitfdbaf7df597b404be04cecbdc83dbc0551a5b996 (patch)
treef4254d2ed63ce1174d9710a315678aeaf921399b /apps/playlist_viewer.c
parent07cf87419189f8730eff53bb74669856a42a2016 (diff)
downloadrockbox-fdbaf7df597b404be04cecbdc83dbc0551a5b996.tar.gz
rockbox-fdbaf7df597b404be04cecbdc83dbc0551a5b996.zip
[Feature] playlist_viewer id3 title display
Not sure this is a great idea from disk and battery standpoint but there is no reason you can't.. using the name buffer to fill title data prevent hitting the disk for each screen scroll add get_metadata_ex to allow flags METADATA_EXCLUDE_ID3_PATH prevent copying the filename to the ID3 struct METADATA_CLOSE_FD_ON_EXIT instead of seeking to the beginning the file is closed before get_metadata returns add logic to allow a invalid fd to signal that get_metadata should open and close the file within its call bugfix per Chris_s don't use the tagcache for the trackinfo Change-Id: Ic7a595b39a8d7a57f975312bc9c8bb4111f22a88
Diffstat (limited to 'apps/playlist_viewer.c')
-rw-r--r--apps/playlist_viewer.c122
1 files changed, 87 insertions, 35 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index 579eba5a61..d06a3f3df6 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -51,6 +51,10 @@
51#include "menus/exported_menus.h" 51#include "menus/exported_menus.h"
52#include "yesno.h" 52#include "yesno.h"
53 53
54#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
55#include "tagcache.h"
56#endif
57
54/* Maximum number of tracks we can have loaded at one time */ 58/* Maximum number of tracks we can have loaded at one time */
55#define MAX_PLAYLIST_ENTRIES 200 59#define MAX_PLAYLIST_ENTRIES 200
56 60
@@ -60,11 +64,11 @@
60 64
61/* Information about a specific track */ 65/* Information about a specific track */
62struct playlist_entry { 66struct playlist_entry {
63 char *name; /* Formatted track name */ 67 char *name; /* track path */
68 char *title; /* Formatted track name */
64 int index; /* Playlist index */ 69 int index; /* Playlist index */
65 int display_index; /* Display index */ 70 int display_index; /* Display index */
66 bool queued; /* Is track queued? */ 71 int attr; /* Is track queued?; Is track marked as bad?*/
67 bool skipped; /* Is track marked as bad? */
68}; 72};
69 73
70enum direction 74enum direction
@@ -86,6 +90,8 @@ enum pv_onplay_result {
86 90
87struct playlist_buffer 91struct playlist_buffer
88{ 92{
93 struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];
94
89 char *name_buffer; /* Buffer used to store track names */ 95 char *name_buffer; /* Buffer used to store track names */
90 int buffer_size; /* Size of name buffer */ 96 int buffer_size; /* Size of name buffer */
91 97
@@ -97,7 +103,6 @@ struct playlist_buffer
97 the buffer has a real index < to the 103 the buffer has a real index < to the
98 real index of the the first track)*/ 104 real index of the the first track)*/
99 105
100 struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];
101 int num_loaded; /* Number of track entries loaded in buffer */ 106 int num_loaded; /* Number of track entries loaded in buffer */
102}; 107};
103 108
@@ -136,7 +141,6 @@ static bool playlist_viewer_init(struct playlist_viewer * viewer,
136 const char* filename, bool reload, 141 const char* filename, bool reload,
137 int *most_recent_selection); 142 int *most_recent_selection);
138 143
139static void format_name(char* dest, const char* src);
140static void format_line(const struct playlist_entry* track, char* str, 144static void format_line(const struct playlist_entry* track, char* str,
141 int len); 145 int len);
142 146
@@ -221,6 +225,40 @@ static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb,
221 } 225 }
222} 226}
223 227
228static bool retrieve_track_metadata(struct mp3entry *id3, const char *filename, int flags)
229{
230 bool success = true;
231#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
232 /* try to get the id3 data from the database */
233 /* the database, doesn't store frequency, file size or codec (g4470) ChrisS*/
234 if ((flags & METADATA_EXCLUDE_ID3_PATH) || !tagcache_fill_tags(id3, filename))
235#endif
236 /* fall back to reading the file from disk */
237 {
238 success = get_metadata_ex(id3, -1, filename, flags);
239 }
240 return success;
241}
242
243static int load_track_title(char* buffer, size_t bufsz, char *filename)
244{
245 struct mp3entry id3;
246 if (retrieve_track_metadata(&id3, filename, METADATA_EXCLUDE_ID3_PATH)
247 && id3.title && id3.title[0] != '\0')
248 {
249 const char *artist = id3.artist;
250 if (!artist)
251 artist = id3.albumartist;
252 if(!artist)
253 artist = str(LANG_TAGNAVI_UNTAGGED);
254
255 size_t len = snprintf(buffer, bufsz, "%s - %s", artist, id3.title) + 1;
256 if (len < bufsz)
257 return len;
258 }
259 return 0; /*Failure*/
260}
261
224static int playlist_entry_load(struct playlist_entry *entry, int index, 262static int playlist_entry_load(struct playlist_entry *entry, int index,
225 char* name_buffer, int remaining_size) 263 char* name_buffer, int remaining_size)
226{ 264{
@@ -234,17 +272,29 @@ static int playlist_entry_load(struct playlist_entry *entry, int index,
234 if (playlist_get_track_info(viewer.playlist, index, &info) < 0) 272 if (playlist_get_track_info(viewer.playlist, index, &info) < 0)
235 return -1; 273 return -1;
236 274
237 len = strlen(info.filename) + 1; 275 len = strlcpy(name_buffer, info.filename, remaining_size) + 1;
238 276
239 if (len <= remaining_size) 277 if (len <= remaining_size)
240 { 278 {
241 strcpy(name_buffer, info.filename);
242
243 entry->name = name_buffer; 279 entry->name = name_buffer;
280 entry->title = name_buffer;
244 entry->index = info.index; 281 entry->index = info.index;
245 entry->display_index = info.display_index; 282 entry->display_index = info.display_index;
246 entry->queued = info.attr & PLAYLIST_ATTR_QUEUED; 283 entry->attr = info.attr & (PLAYLIST_ATTR_SKIPPED | PLAYLIST_ATTR_QUEUED);
247 entry->skipped = info.attr & PLAYLIST_ATTR_SKIPPED; 284
285 if (global_settings.playlist_viewer_track_display == 2) /* title */
286 {
287 /* advance buffer position past filename, adjust length remaining */
288 name_buffer += len;
289 remaining_size -= len;
290 int tlen = load_track_title(name_buffer, remaining_size, info.filename);
291 if (tlen > 0)
292 {
293 entry->title = name_buffer;
294 len += tlen;
295 }
296 }
297
248 return len; 298 return len;
249 } 299 }
250 return -1; 300 return -1;
@@ -433,7 +483,7 @@ static bool playlist_viewer_init(struct playlist_viewer * viewer,
433} 483}
434 484
435/* Format trackname for display purposes */ 485/* Format trackname for display purposes */
436static void format_name(char* dest, const char* src) 486static void format_name(char* dest, const char* src, size_t bufsz)
437{ 487{
438 switch (global_settings.playlist_viewer_track_display) 488 switch (global_settings.playlist_viewer_track_display)
439 { 489 {
@@ -442,17 +492,16 @@ static void format_name(char* dest, const char* src)
442 { 492 {
443 /* Only display the filename */ 493 /* Only display the filename */
444 char* p = strrchr(src, '/'); 494 char* p = strrchr(src, '/');
445 495 strlcpy(dest, p+1, bufsz);
446 strcpy(dest, p+1);
447
448 /* Remove the extension */ 496 /* Remove the extension */
449 strrsplt(dest, '.'); 497 strrsplt(dest, '.');
450
451 break; 498 break;
452 } 499 }
500 case 2: /* Artist - Title */
501 /*fall-through*/
453 case 1: 502 case 1:
454 /* Full path */ 503 /* Full path */
455 strcpy(dest, src); 504 strlcpy(dest, src, bufsz);
456 break; 505 break;
457 } 506 }
458} 507}
@@ -463,10 +512,9 @@ static void format_line(const struct playlist_entry* track, char* str,
463{ 512{
464 char name[MAX_PATH]; 513 char name[MAX_PATH];
465 char *skipped = ""; 514 char *skipped = "";
515 format_name(name, track->title, sizeof(name));
466 516
467 format_name(name, track->name); 517 if (track->attr & PLAYLIST_ATTR_SKIPPED)
468
469 if (track->skipped)
470 skipped = "(ERR) "; 518 skipped = "(ERR) ";
471 519
472 if (global_settings.playlist_viewer_indices) 520 if (global_settings.playlist_viewer_indices)
@@ -524,13 +572,7 @@ static enum pv_onplay_result show_track_info(const struct playlist_entry *curren
524 } 572 }
525 else 573 else
526 { 574 {
527 int fd = open(current_track->name, O_RDONLY); 575 id3_retrieval_successful = retrieve_track_metadata(&id3, current_track->name, 0);
528 if (fd >= 0)
529 {
530 if (get_metadata(&id3, fd, current_track->name))
531 id3_retrieval_successful = true;
532 close(fd);
533 }
534 } 576 }
535 577
536 return id3_retrieval_successful && 578 return id3_retrieval_successful &&
@@ -755,7 +797,7 @@ static enum themable_icons playlist_callback_icons(int selected_item,
755 /* Track we are moving */ 797 /* Track we are moving */
756 return Icon_Moving; 798 return Icon_Moving;
757 } 799 }
758 else if (track->queued) 800 else if (track->attr & PLAYLIST_ATTR_QUEUED)
759 { 801 {
760 /* Queued track */ 802 /* Queued track */
761 return Icon_Queued; 803 return Icon_Queued;
@@ -776,17 +818,27 @@ static int playlist_callback_voice(int selected_item, void *data)
776 talk_id(LANG_NOW_PLAYING, true); 818 talk_id(LANG_NOW_PLAYING, true);
777 if (track->index == local_viewer->moving_track) 819 if (track->index == local_viewer->moving_track)
778 talk_id(VOICE_TRACK_TO_MOVE, true); 820 talk_id(VOICE_TRACK_TO_MOVE, true);
779 if (track->queued) 821 if (track->attr & PLAYLIST_ATTR_QUEUED)
780 talk_id(VOICE_QUEUED, true); 822 talk_id(VOICE_QUEUED, true);
781 } 823 }
782 if (track->skipped) 824 if (track->attr & PLAYLIST_ATTR_SKIPPED)
783 talk_id(VOICE_BAD_TRACK, true); 825 talk_id(VOICE_BAD_TRACK, true);
784 if (global_settings.playlist_viewer_indices) 826 if (global_settings.playlist_viewer_indices)
785 talk_number(track->display_index, true); 827 talk_number(track->display_index, true);
786 828
787 if(global_settings.playlist_viewer_track_display) 829 switch(global_settings.playlist_viewer_track_display)
788 talk_fullpath(track->name, true); 830 {
789 else talk_file_or_spell(NULL, track->name, NULL, true); 831 case 1: /*full path*/
832 talk_fullpath(track->name, true);
833 break;
834 case 2: /*title*/
835 talk_spell(track->title, true);
836 break;
837 default:
838 case 0: /*filename only*/
839 talk_file_or_spell(NULL, track->name, NULL, true);
840 break;
841 }
790 if (viewer.moving_track != -1) 842 if (viewer.moving_track != -1)
791 talk_ids(true,VOICE_PAUSE, VOICE_MOVING_TRACK); 843 talk_ids(true,VOICE_PAUSE, VOICE_MOVING_TRACK);
792 844
@@ -1132,11 +1184,11 @@ static void close_playlist_viewer(void)
1132static const char* playlist_search_callback_name(int selected_item, void * data, 1184static const char* playlist_search_callback_name(int selected_item, void * data,
1133 char *buffer, size_t buffer_len) 1185 char *buffer, size_t buffer_len)
1134{ 1186{
1135 (void)buffer_len; /* this should probably be used */
1136 int *found_indicies = (int*)data; 1187 int *found_indicies = (int*)data;
1137 static struct playlist_track_info track; 1188 static struct playlist_track_info track;
1138 playlist_get_track_info(viewer.playlist, found_indicies[selected_item], &track); 1189 playlist_get_track_info(viewer.playlist, found_indicies[selected_item], &track);
1139 format_name(buffer, track.filename); 1190
1191 format_name(buffer, track.filename, buffer_len);
1140 return buffer; 1192 return buffer;
1141} 1193}
1142 1194
@@ -1145,7 +1197,7 @@ static int say_search_item(int selected_item, void *data)
1145 int *found_indicies = (int*)data; 1197 int *found_indicies = (int*)data;
1146 static struct playlist_track_info track; 1198 static struct playlist_track_info track;
1147 playlist_get_track_info(viewer.playlist,found_indicies[selected_item],&track); 1199 playlist_get_track_info(viewer.playlist,found_indicies[selected_item],&track);
1148 if(global_settings.playlist_viewer_track_display) 1200 if(global_settings.playlist_viewer_track_display == 1)
1149 talk_fullpath(track.filename, false); 1201 talk_fullpath(track.filename, false);
1150 else talk_file_or_spell(NULL, track.filename, NULL, false); 1202 else talk_file_or_spell(NULL, track.filename, NULL, false);
1151 return 0; 1203 return 0;