summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c171
1 files changed, 145 insertions, 26 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index f834a3d5e7..1ededb2ba9 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -146,6 +146,7 @@ static int format_track_path(char *dest, char *src, int buf_length, int max,
146static void display_playlist_count(int count, char *fmt); 146static void display_playlist_count(int count, char *fmt);
147static void display_buffer_full(void); 147static void display_buffer_full(void);
148static int flush_pending_control(void); 148static int flush_pending_control(void);
149static int rotate_index(int index);
149 150
150/* 151/*
151 * remove any files and indices associated with the playlist 152 * remove any files and indices associated with the playlist
@@ -679,11 +680,7 @@ static int get_next_index(int steps)
679 { 680 {
680 case REPEAT_OFF: 681 case REPEAT_OFF:
681 { 682 {
682 /* Rotate indices such that first_index is considered index 0 to 683 current_index = rotate_index(current_index);
683 simplify next calculation */
684 current_index -= playlist.first_index;
685 if (current_index < 0)
686 current_index += playlist.amount;
687 684
688 next_index = current_index+steps; 685 next_index = current_index+steps;
689 if ((next_index < 0) || (next_index >= playlist.amount)) 686 if ((next_index < 0) || (next_index >= playlist.amount))
@@ -993,6 +990,18 @@ static int flush_pending_control(void)
993} 990}
994 991
995/* 992/*
993 * Rotate indices such that first_index is index 0
994 */
995static int rotate_index(int index)
996{
997 index -= playlist.first_index;
998 if (index < 0)
999 index += playlist.amount;
1000
1001 return index;
1002}
1003
1004/*
996 * Initialize playlist entries at startup 1005 * Initialize playlist entries at startup
997 */ 1006 */
998void playlist_init(void) 1007void playlist_init(void)
@@ -1604,25 +1613,108 @@ int playlist_insert_playlist(char *filename, int position, bool queue)
1604 return result; 1613 return result;
1605} 1614}
1606 1615
1607/* delete track at specified index */ 1616/*
1617 * Delete track at specified index. If index is PLAYLIST_DELETE_CURRENT then
1618 * we want to delete the current playing track.
1619 */
1608int playlist_delete(int index) 1620int playlist_delete(int index)
1609{ 1621{
1610 int result; 1622 int result = 0;
1611 1623
1612 if (playlist.control_fd < 0) 1624 if (playlist.control_fd < 0)
1613 { 1625 {
1614 splash(HZ*2, 0, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); 1626 splash(HZ*2, 0, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR));
1615 return -1; 1627 return -1;
1616 } 1628 }
1617 1629
1618 result = remove_track_from_playlist(index, true); 1630 if (index == PLAYLIST_DELETE_CURRENT)
1631 index = playlist.index;
1619 1632
1633 result = remove_track_from_playlist(index, true);
1634
1620 if (result != -1) 1635 if (result != -1)
1621 mpeg_flush_and_reload_tracks(); 1636 mpeg_flush_and_reload_tracks();
1622 1637
1623 return result; 1638 return result;
1624} 1639}
1625 1640
1641/*
1642 * Move track at index to new_index. Tracks between the two are shifted
1643 * appropriately. Returns 0 on success and -1 on failure.
1644 */
1645int playlist_move(int index, int new_index)
1646{
1647 int result;
1648 int seek;
1649 bool control_file;
1650 bool queue;
1651 bool current = false;
1652 int r = rotate_index(new_index);
1653 char filename[MAX_PATH];
1654
1655 if (index == new_index)
1656 return -1;
1657
1658 if (index == playlist.index)
1659 /* Moving the current track */
1660 current = true;
1661
1662 control_file = playlist.indices[index] & PLAYLIST_INSERT_TYPE_MASK;
1663 queue = playlist.indices[index] & PLAYLIST_QUEUE_MASK;
1664 seek = playlist.indices[index] & PLAYLIST_SEEK_MASK;
1665
1666 if (get_filename(seek, control_file, filename, sizeof(filename)) < 0)
1667 return -1;
1668
1669 /* Delete track from original position */
1670 result = remove_track_from_playlist(index, true);
1671
1672 if (result != -1)
1673 {
1674 /* We want to insert the track at the position that was specified by
1675 new_index. This may be different then new_index because of the
1676 shifting that occurred after the delete */
1677 if (r == 0)
1678 /* First index */
1679 new_index = PLAYLIST_PREPEND;
1680 else if (r == playlist.amount)
1681 /* Append */
1682 new_index = PLAYLIST_INSERT_LAST;
1683 else
1684 /* Calculate index of desired position */
1685 new_index = (r+playlist.first_index)%playlist.amount;
1686
1687 result = add_track_to_playlist(filename, new_index, queue, -1);
1688
1689 if (result != -1)
1690 {
1691 if (current)
1692 {
1693 /* Moved the current track */
1694 switch (new_index)
1695 {
1696 case PLAYLIST_PREPEND:
1697 playlist.index = playlist.first_index;
1698 break;
1699 case PLAYLIST_INSERT_LAST:
1700 playlist.index = playlist.first_index - 1;
1701 if (playlist.index < 0)
1702 playlist.index += playlist.amount;
1703 break;
1704 default:
1705 playlist.index = new_index;
1706 break;
1707 }
1708 }
1709
1710 fsync(playlist.control_fd);
1711 mpeg_flush_and_reload_tracks();
1712 }
1713 }
1714
1715 return result;
1716}
1717
1626/* shuffle newly created playlist using random seed. */ 1718/* shuffle newly created playlist using random seed. */
1627int playlist_shuffle(int random_seed, int start_index) 1719int playlist_shuffle(int random_seed, int start_index)
1628{ 1720{
@@ -1763,21 +1855,13 @@ int playlist_next(int steps)
1763 index = get_next_index(steps); 1855 index = get_next_index(steps);
1764 playlist.index = index; 1856 playlist.index = index;
1765 1857
1766 if (playlist.last_insert_pos >= 0) 1858 if (playlist.last_insert_pos >= 0 && steps > 0)
1767 { 1859 {
1768 /* check to see if we've gone beyond the last inserted track */ 1860 /* check to see if we've gone beyond the last inserted track */
1769 int rot_index = index; 1861 int cur = rotate_index(index);
1770 int rot_last_pos = playlist.last_insert_pos; 1862 int last_pos = rotate_index(playlist.last_insert_pos);
1771 1863
1772 rot_index -= playlist.first_index; 1864 if (cur > last_pos)
1773 if (rot_index < 0)
1774 rot_index += playlist.amount;
1775
1776 rot_last_pos -= playlist.first_index;
1777 if (rot_last_pos < 0)
1778 rot_last_pos += playlist.amount;
1779
1780 if (rot_index > rot_last_pos)
1781 { 1865 {
1782 /* reset last inserted track */ 1866 /* reset last inserted track */
1783 playlist.last_insert_pos = -1; 1867 playlist.last_insert_pos = -1;
@@ -1826,16 +1910,18 @@ int playlist_get_resume_info(short *resume_index)
1826 index into the playlist */ 1910 index into the playlist */
1827int playlist_get_display_index(void) 1911int playlist_get_display_index(void)
1828{ 1912{
1829 int index = playlist.index;
1830
1831 /* first_index should always be index 0 for display purposes */ 1913 /* first_index should always be index 0 for display purposes */
1832 index -= playlist.first_index; 1914 int index = rotate_index(playlist.index);
1833 if (index < 0)
1834 index += playlist.amount;
1835 1915
1836 return (index+1); 1916 return (index+1);
1837} 1917}
1838 1918
1919/* returns index of first track in playlist */
1920int playlist_get_first_index(void)
1921{
1922 return playlist.first_index;
1923}
1924
1839/* returns number of tracks in playlist (includes queued/inserted tracks) */ 1925/* returns number of tracks in playlist (includes queued/inserted tracks) */
1840int playlist_amount(void) 1926int playlist_amount(void)
1841{ 1927{
@@ -1860,6 +1946,39 @@ char *playlist_name(char *buf, int buf_size)
1860 return buf; 1946 return buf;
1861} 1947}
1862 1948
1949/* Fills info structure with information about track at specified index.
1950 Returns 0 on success and -1 on failure */
1951int playlist_get_track_info(int index, struct playlist_track_info* info)
1952{
1953 int seek;
1954 bool control_file;
1955
1956 if (index < 0 || index >= playlist.amount)
1957 return -1;
1958
1959 control_file = playlist.indices[index] & PLAYLIST_INSERT_TYPE_MASK;
1960 seek = playlist.indices[index] & PLAYLIST_SEEK_MASK;
1961
1962 if (get_filename(seek, control_file, info->filename,
1963 sizeof(info->filename)) < 0)
1964 return -1;
1965
1966 info->attr = 0;
1967
1968 if (control_file)
1969 {
1970 if (playlist.indices[index] & PLAYLIST_QUEUE_MASK)
1971 info->attr |= PLAYLIST_ATTR_QUEUED;
1972 else
1973 info->attr |= PLAYLIST_ATTR_INSERTED;
1974 }
1975
1976 info->index = index;
1977 info->display_index = rotate_index(index) + 1;
1978
1979 return 0;
1980}
1981
1863/* save the current dynamic playlist to specified file */ 1982/* save the current dynamic playlist to specified file */
1864int playlist_save(char *filename) 1983int playlist_save(char *filename)
1865{ 1984{