43 #define STATE_FILE "playlist-state"
45 #define ENTER pthread_mutex_lock (& mutex)
46 #define LEAVE pthread_mutex_unlock (& mutex)
48 #define RETURN(...) do { \
49 pthread_mutex_unlock (& mutex); \
53 #define ENTER_GET_PLAYLIST(...) ENTER; \
54 Playlist * playlist = lookup_playlist (playlist_num); \
58 #define ENTER_GET_ENTRY(...) ENTER_GET_PLAYLIST (__VA_ARGS__); \
59 Entry * entry = lookup_entry (playlist, entry_num); \
72 char * formatted, *
title, * artist, * album;
99 static pthread_mutex_t
mutex = PTHREAD_MUTEX_INITIALIZER;
100 static pthread_cond_t
cond = PTHREAD_COND_INITIALIZER;
154 entry->
tuple = tuple;
238 g_slice_free (
Entry, entry);
244 GINT_TO_POINTER (preferred),
NULL,
NULL))
294 g_list_free (playlist->
queued);
300 for (
int count = 0; count < length; count ++)
303 playlist->
number = at + count;
315 for (
int count = 0; count < length; count ++)
318 entry->
number = at + count;
350 hook_call (
"playlist update", GINT_TO_POINTER (level));
406 int level = u->
level;
415 if (playlist_num >= 0)
439 for (GList * node =
scan_list; node; node = node->next)
451 for (GList * node =
scan_list; node; node = node->next)
454 if (item->
entry == entry)
463 for (GList * node =
scan_list; node; node = node->next)
574 pthread_cond_broadcast (&
cond);
606 if (! entry || entry->
failed)
609 if ((need_decoder && ! entry->
decoder) || (need_tuple && ! entry->
tuple))
629 if (! entry || entry->
failed)
632 if ((need_decoder && ! entry->
decoder) || (need_tuple && ! entry->
tuple))
670 active_playlist = playing_playlist =
NULL;
765 playing_playlist =
NULL;
777 int unique_id =
playlist->unique_id;
786 int num = p ? p->
number : -1;
864 int list = active_playlist ? active_playlist->
number : -1;
880 if (playlist == playing_playlist)
883 if (playing_playlist)
890 if (playlist && ! playlist->
position)
893 position_changed =
TRUE;
909 if (position_changed)
910 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
924 int list = playing_playlist ? playing_playlist->
number: -1;
948 for (list = 0; list < count; list ++)
973 if (entry && update_shuffle)
1000 if (at < 0 || at > entries)
1008 for (
int i = 0; i < number; i ++)
1028 for (
int count = 0; count < number; count ++)
1047 if (at < 0 || at > entries)
1049 if (number < 0 || number > entries - at)
1050 number = entries -
at;
1053 playlist->position->number < at + number)
1055 position_changed =
TRUE;
1062 playlist->focus->number < at + number)
1064 if (at + number < entries)
1072 for (
int count = 0; count < number; count ++)
1092 if (position_changed &&
get_bool (
NULL,
"advance_on_delete"))
1098 if (position_changed)
1099 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
1126 Tuple * tuple = entry ? entry->
tuple :
NULL;
1145 char * * title,
char * * artist,
char * * album,
bool_t fast)
1166 int length = entry ? entry->
length : 0;
1183 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
1199 int first = INT_MAX;
1234 if (
entry->selected == selected)
1237 entry->selected = selected;
1264 int selected_count =
playlist->selected_count;
1273 int first = entries, last = 0;
1275 for (
int count = 0; count < entries; count ++)
1289 playlist->selected_count = entries;
1298 if (first < entries)
1308 if (!
entry->selected || ! distance)
1312 int shift = 0, center, top, bottom;
1316 for (center = entry_num; center > 0 && shift > distance; )
1319 if (!
entry->selected)
1325 for (center = entry_num + 1; center < entries && shift < distance; )
1328 if (!
entry->selected)
1333 top = bottom = center;
1335 for (
int i = 0; i < top; i ++)
1338 if (
entry->selected)
1342 for (
int i = entries; i > bottom; i --)
1345 if (
entry->selected)
1351 for (
int i = top; i < center; i ++)
1354 if (!
entry->selected)
1358 for (
int i = top; i < bottom; i ++)
1361 if (
entry->selected)
1365 for (
int i = center; i < bottom; i ++)
1368 if (!
entry->selected)
1383 return playlist->
focus;
1387 for (
int search = playlist->
focus->
number + 1; search < entries; search ++)
1394 for (
int search = playlist->
focus->
number; search --;)
1421 position_changed =
TRUE;
1429 int before = 0, after = 0;
1432 for (
int count = 0; count < entries; count++)
1467 if (position_changed &&
get_bool (
NULL,
"advance_on_delete"))
1473 if (position_changed)
1474 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
1488 for (
int count = entries; count --; )
1508 for (
int count = entries; count --; )
1516 for (
int count = 0; count < entries; count++)
1536 for (
int i = 0; i < entries; i ++)
1538 int j = i + rand () % (entries - i);
1559 for (
int count = 0; count < entries; count++)
1566 for (
int i = 0; i <
playlist->selected_count; i ++)
1568 int j = i + rand () % (
playlist->selected_count - i);
1576 for (
int count = 0; count < entries; count++)
1599 static int compare_cb (
const void * _a,
const void * _b,
void * _data)
1601 const Entry *
a = _a, *
b = _b;
1612 b->formatted ? b->formatted : b->filename);
1618 return a->
number - b->number;
1636 for (
int count = 0; count < entries; count++)
1646 for (
int count = 0; count < entries; count++)
1662 for (
int count = 0; count < entries; count ++)
1671 "metadata scanning is still in progress (or has been disabled)."));
1680 (
const char *
a,
const char *
b))
1691 (
const Tuple * a,
const Tuple * b))
1715 (
const char * a,
const char * b))
1726 (
const Tuple * a,
const Tuple * b))
1738 (
const char * a,
const char * b))
1762 for (
int count = 0; count < entries; count++)
1796 for (
int count = 0; count < entries; count ++)
1823 for (
int playlist_num = 0; playlist_num < num_playlists; playlist_num ++)
1828 for (
int entry_num = 0; entry_num < num_entries; entry_num ++)
1832 if (! strcmp (entry->
filename, filename))
1846 int64_t length =
playlist->total_length;
1853 int64_t length =
playlist->selected_length;
1860 int count = g_list_length (
playlist->queued);
1887 int first = entries, last = 0;
1889 for (
int count = 0; count < entries; count++)
1906 if (first < entries)
1916 GList * node = g_list_nth (
playlist->queued, at);
1917 int entry_num = node ? ((
Entry *) node->data)->number : -1;
1934 int first = entries, last = 0;
1938 while (
playlist->queued && number --)
1950 GList * anchor = g_list_nth (
playlist->queued, at - 1);
1954 while (anchor->next && number --)
1966 if (first < entries)
1977 int first = entries, last = 0;
1979 for (GList * node =
playlist->queued; node; )
1981 GList * next = node->next;
1995 if (first < entries)
2006 for (
int count = 0; count < entries; count ++)
2045 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
2057 for (count = 0; count < entries; count ++)
2078 choice = rand () % choice;
2080 for (count = 0; ; count ++)
2103 for (
int count = 0; count < entries; count ++)
2137 if (hint >= entries)
2163 hook_call (
"playlist position", GINT_TO_POINTER (playlist_num));
2175 int entry_num = entry ? entry->
number : -1;
2205 Tuple * tuple = entry ? entry->
tuple :
NULL;
2228 int length = entry ? entry->
length : 0;
2236 if (! playing_playlist || ! playing_playlist->
position)
2255 FILE * handle = fopen (path,
"w");
2260 fprintf (handle,
"active %d\n", active_playlist ? active_playlist->
number : -1);
2261 fprintf (handle,
"playing %d\n", playing_playlist ? playing_playlist->
number : -1);
2268 fprintf (handle,
"playlist %d\n", playlist_num);
2271 fprintf (handle,
"filename %s\n", playlist->
filename);
2275 if (playlist == playing_playlist)
2282 fprintf (handle,
"resume-time %d\n", playlist->
resume_time);
2296 if (! fgets (parse_key,
sizeof parse_key, handle))
2299 char * space = strchr (parse_key,
' ');
2304 parse_value = space + 1;
2306 char * newline = strchr (parse_value,
'\n');
2313 return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value,
"%d", value) == 1);
2318 return (parse_value && ! strcmp (parse_key, key)) ?
str_get (parse_value) :
NULL;
2327 FILE * handle = fopen (path,
"r");
2344 while (
parse_integer (
"playlist", & playlist_num) && playlist_num >= 0 &&
2364 if (position >= 0 && position < entries)