42 #define SCAN_THREADS 2
43 #define STATE_FILE "playlist-state"
45 #define ENTER pthread_mutex_lock (& mutex)
46 #define LEAVE pthread_mutex_unlock (& mutex)
48 #define LEAVE_RET_VOID do { \
49 pthread_mutex_unlock (& mutex); \
53 #define LEAVE_RET(ret) do { \
54 pthread_mutex_unlock (& mutex); \
58 #define DECLARE_PLAYLIST \
61 #define DECLARE_PLAYLIST_ENTRY \
62 Playlist * playlist; \
65 #define LOOKUP_PLAYLIST do { \
66 if (! (playlist = lookup_playlist (playlist_num))) \
70 #define LOOKUP_PLAYLIST_RET(ret) do { \
71 if (! (playlist = lookup_playlist (playlist_num))) \
75 #define LOOKUP_PLAYLIST_ENTRY do { \
77 if (! (entry = lookup_entry (playlist, entry_num))) \
81 #define LOOKUP_PLAYLIST_ENTRY_RET(ret) do { \
82 LOOKUP_PLAYLIST_RET(ret); \
83 if (! (entry = lookup_entry (playlist, entry_num))) \
96 char * formatted, *
title, * artist, * album;
124 static pthread_mutex_t
mutex = PTHREAD_MUTEX_INITIALIZER;
125 static pthread_cond_t
cond = PTHREAD_COND_INITIALIZER;
149 static void *
scanner (
void * unused);
175 entry->
tuple = tuple;
242 for (GList * node =
scan_queue.head; node; node = next)
247 if (item->
entry == entry)
256 if (scan_items[i] && scan_items[i]->entry == entry)
258 g_slice_free (
ScanItem, scan_items[i]);
259 scan_items[i] =
NULL;
300 g_slice_free (
Entry, entry);
306 GINT_TO_POINTER (preferred),
NULL,
NULL))
355 g_list_free (playlist->
queued);
361 for (
int count = 0; count < length; count ++)
364 playlist->
number = at + count;
376 for (
int count = 0; count < length; count ++)
379 entry->
number = at + count;
411 hook_call (
"playlist update", GINT_TO_POINTER (level));
469 int level = u->
level;
489 for (GList * node =
scan_queue.head; node; node = node->next)
492 if (item->
entry == entry)
498 if (scan_items[i] && scan_items[i]->entry == entry)
515 pthread_cond_broadcast (&
cond);
523 for (GList * node =
scan_queue.head; node; node = node->next)
532 if (scan_items[i] && scan_items[i]->
playlist == p)
585 int i = GPOINTER_TO_INT (data);
629 else if (need_tuple || ! decoder)
635 g_slice_free (
ScanItem, scan_items[i]);
636 scan_items[i] =
NULL;
638 pthread_cond_broadcast (&
cond);
649 pthread_cond_broadcast (&
cond);
661 if (! entry || entry->
failed)
664 if ((need_decoder && ! entry->
decoder) || (need_tuple && ! entry->
tuple))
682 if (! entry || entry->
failed)
685 if ((need_decoder && ! entry->
decoder) || (need_tuple && ! entry->
tuple))
741 pthread_cond_broadcast (&
cond);
756 active_playlist = playing_playlist =
NULL;
853 playing_playlist =
NULL;
865 int unique_id =
playlist->unique_id;
875 int num = p ? p->
number : -1;
975 int list = active_playlist ? active_playlist->
number : -1;
993 if (playing_playlist)
1001 if (playlist_num < 0)
1030 int list = playing_playlist ? playing_playlist->
number: -1;
1054 for (list = 0; list < count; list ++)
1080 if (entry && update_shuffle)
1104 if (at < 0 || at > entries)
1112 for (
int i = 0; i < number; i ++)
1132 for (
int count = 0; count < number; count ++)
1147 (playlist_num) < at + number)
1156 if (at < 0 || at > entries)
1158 if (number < 0 || number > entries - at)
1159 number = entries -
at;
1162 playlist->position->number < at + number)
1165 for (
int count = 0; count < number; count ++)
1215 Tuple * tuple = entry ? entry->
tuple :
NULL;
1234 char * * title,
char * * artist,
char * * album,
bool_t fast)
1255 int length = entry ? entry->
length : 0;
1269 if (entry_num == -1)
1280 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
1301 if (
entry->selected == selected)
1304 entry->selected = selected;
1338 int selected_count =
playlist->selected_count;
1350 int first = entries, last = 0;
1352 for (
int count = 0; count < entries; count ++)
1366 playlist->selected_count = entries;
1375 if (first < entries)
1387 if (!
entry->selected || ! distance)
1391 int shift = 0, center, top, bottom;
1395 for (center = entry_num; center > 0 && shift > distance; )
1398 if (!
entry->selected)
1404 for (center = entry_num + 1; center < entries && shift < distance; )
1407 if (!
entry->selected)
1412 top = bottom = center;
1414 for (
int i = 0; i < top; i ++)
1417 if (
entry->selected)
1421 for (
int i = entries; i > bottom; i --)
1424 if (
entry->selected)
1430 for (
int i = top; i < center; i ++)
1433 if (!
entry->selected)
1437 for (
int i = top; i < bottom; i ++)
1440 if (
entry->selected)
1444 for (
int i = center; i < bottom; i ++)
1447 if (!
entry->selected)
1482 int before = 0, after = 0;
1485 for (
int count = 0; count < entries; count++)
1534 for (
int count = entries; count --; )
1553 for (
int i = 0; i < entries; i ++)
1555 int j = i + rand () % (entries - i);
1579 static int compare_cb (
const void * _a,
const void * _b,
void * _data)
1581 const Entry *
a = _a, *
b = _b;
1592 b->formatted ? b->formatted : b->filename);
1598 return a->
number - b->number;
1616 for (
int count = 0; count < entries; count++)
1626 for (
int count = 0; count < entries; count++)
1642 for (
int count = 0; count < entries; count ++)
1651 "metadata scanning is still in progress (or has been disabled)."));
1660 (
const char *
a,
const char *
b))
1673 (
const Tuple * a,
const Tuple * b))
1701 (
const char * a,
const char * b))
1714 (
const Tuple * a,
const Tuple * b))
1728 (
const char * a,
const char * b))
1754 for (
int count = 0; count < entries; count++)
1790 for (
int count = 0; count < entries; count ++)
1820 for (
int playlist_num = 0; playlist_num < num_playlists; playlist_num ++)
1825 for (
int entry_num = 0; entry_num < num_entries; entry_num ++)
1829 if (! strcmp (entry->
filename, filename))
1848 int64_t length =
playlist->total_length;
1859 int64_t length =
playlist->selected_length;
1870 int count = g_list_length (
playlist->queued);
1902 int first = entries, last = 0;
1904 for (
int count = 0; count < entries; count++)
1921 if (first < entries)
1933 GList * node = g_list_nth (
playlist->queued, at);
1934 int entry_num = node ? ((
Entry *) node->data)->number : -1;
1957 int first = entries, last = 0;
1961 while (
playlist->queued && number --)
1973 GList * anchor = g_list_nth (
playlist->queued, at - 1);
1977 while (anchor->next && number --)
1989 if (first < entries)
2002 int first = entries, last = 0;
2004 for (GList * node =
playlist->queued; node; )
2006 GList * next = node->next;
2020 if (first < entries)
2031 for (
int count = 0; count < entries; count ++)
2074 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
2083 for (count = 0; count < entries; count ++)
2104 choice = rand () % choice;
2106 for (count = 0; ; count ++)
2129 for (
int count = 0; count < entries; count ++)
2174 else if (
playlist->position->number == entries - 1)
2188 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
2197 int entry_num = entry ? entry->
number : -1;
2217 Tuple * tuple = entry ? entry->
tuple :
NULL;
2240 int length = entry->
length;
2248 if (! playing_playlist || ! playing_playlist->
position)
2262 if (! playing_playlist || ! playing_playlist->
position)
2272 if (! playing_playlist || ! playing_playlist->
position)
2288 FILE * handle = fopen (path,
"w");
2293 fprintf (handle,
"active %d\n", active_playlist ? active_playlist->
number : -1);
2294 fprintf (handle,
"playing %d\n", playing_playlist ? playing_playlist->
number : -1);
2301 fprintf (handle,
"playlist %d\n", playlist_num);
2304 fprintf (handle,
"filename %s\n", playlist->
filename);
2308 if (playlist == playing_playlist)
2314 fprintf (handle,
"resume-state %d\n", playlist->
resume_state);
2315 fprintf (handle,
"resume-time %d\n", playlist->
resume_time);
2329 if (! fgets (parse_key,
sizeof parse_key, handle))
2332 char * space = strchr (parse_key,
' ');
2337 parse_value = space + 1;
2339 char * newline = strchr (parse_value,
'\n');
2346 return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value,
"%d", value) == 1);
2351 return (parse_value && ! strcmp (parse_key, key)) ?
str_get (parse_value) :
NULL;
2360 FILE * handle = fopen (path,
"r");
2380 while (
parse_integer (
"playlist", & playlist_num) && playlist_num >= 0 &&
2399 if (position >= 0 && position < entries)
2436 if (playing_playlist)