summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-11-17 19:31:29 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-11-17 19:31:29 +0000
commit735f4537309d4a66e16dd020fa99149a9d5f8d29 (patch)
tree7326f1f8f45f43c40bc78b86e4809087dffa9aa7 /apps/playback.c
parentbc8a4e4b8cb613b7a0e4f348fe81086f92d9a994 (diff)
downloadrockbox-735f4537309d4a66e16dd020fa99149a9d5f8d29.tar.gz
rockbox-735f4537309d4a66e16dd020fa99149a9d5f8d29.zip
Added dircache support to playlist. Now playlist filename pointers are
automatically accuired from dircache. WPS UI response with dircache enabled should be instant. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7931 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c137
1 files changed, 83 insertions, 54 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 7f28331b75..b68cb641fe 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -165,9 +165,6 @@ static volatile int buf_widx;
165/* Step count to the next unbuffered track. */ 165/* Step count to the next unbuffered track. */
166static int last_peek_offset; 166static int last_peek_offset;
167 167
168/* Index of the last buffered track. */
169static int last_index;
170
171/* Track information (count in file buffer, read/write indexes for 168/* Track information (count in file buffer, read/write indexes for
172 track ring structure. */ 169 track ring structure. */
173int track_count; 170int track_count;
@@ -589,7 +586,7 @@ static bool rebuffer_and_seek(int newpos)
589 586
590 while (cur_ti->available == 0 && cur_ti->filerem > 0) { 587 while (cur_ti->available == 0 && cur_ti->filerem > 0) {
591 yield(); 588 yield();
592 if (ci.stop_codec || ci.reload_codec) 589 if (ci.stop_codec || ci.reload_codec || !queue_empty(&audio_queue))
593 return false; 590 return false;
594 } 591 }
595 592
@@ -1048,8 +1045,6 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
1048 if (tracks[track_widx].filesize != 0) 1045 if (tracks[track_widx].filesize != 0)
1049 return false; 1046 return false;
1050 1047
1051 last_index = playlist_get_display_index();
1052
1053 peek_again: 1048 peek_again:
1054 /* Get track name from current playlist read position. */ 1049 /* Get track name from current playlist read position. */
1055 logf("Buffering track:%d/%d", track_widx, track_ridx); 1050 logf("Buffering track:%d/%d", track_widx, track_ridx);
@@ -1456,7 +1451,6 @@ void audio_update_trackinfo(void)
1456 } else { 1451 } else {
1457 pcmbuf_add_event(codec_track_changed); 1452 pcmbuf_add_event(codec_track_changed);
1458 } 1453 }
1459 last_index = playlist_get_display_index();
1460} 1454}
1461 1455
1462static void audio_stop_playback(void) 1456static void audio_stop_playback(void)
@@ -1519,8 +1513,8 @@ bool codec_request_next_track_callback(void)
1519{ 1513{
1520 if (current_codec == CODEC_IDX_VOICE) { 1514 if (current_codec == CODEC_IDX_VOICE) {
1521 voice_remaining = 0; 1515 voice_remaining = 0;
1522 /* Terminate the codec if they are messages waiting on the queue or 1516 /* Terminate the codec if there are messages waiting on the queue or
1523 core has been requested the codec to be terminated. */ 1517 the core has been requested the codec to be terminated. */
1524 return !ci_voice.stop_codec && queue_empty(&voice_codec_queue); 1518 return !ci_voice.stop_codec && queue_empty(&voice_codec_queue);
1525 } 1519 }
1526 1520
@@ -1531,12 +1525,7 @@ bool codec_request_next_track_callback(void)
1531 1525
1532 /* Advance to next track. */ 1526 /* Advance to next track. */
1533 if (ci.reload_codec && new_track > 0) { 1527 if (ci.reload_codec && new_track > 0) {
1534 if (!playlist_check(new_track)) {
1535 ci.reload_codec = false;
1536 return false;
1537 }
1538 last_peek_offset--; 1528 last_peek_offset--;
1539 playlist_next(new_track);
1540 if (++track_ridx == MAX_TRACK) 1529 if (++track_ridx == MAX_TRACK)
1541 track_ridx = 0; 1530 track_ridx = 0;
1542 1531
@@ -1549,7 +1538,6 @@ bool codec_request_next_track_callback(void)
1549 if (tracks[track_ridx].filesize == 0) { 1538 if (tracks[track_ridx].filesize == 0) {
1550 logf("Loading from disk..."); 1539 logf("Loading from disk...");
1551 new_track = 0; 1540 new_track = 0;
1552 last_index = -1;
1553 queue_post(&audio_queue, AUDIO_PLAY, 0); 1541 queue_post(&audio_queue, AUDIO_PLAY, 0);
1554 return false; 1542 return false;
1555 } 1543 }
@@ -1557,12 +1545,7 @@ bool codec_request_next_track_callback(void)
1557 1545
1558 /* Advance to previous track. */ 1546 /* Advance to previous track. */
1559 else if (ci.reload_codec && new_track < 0) { 1547 else if (ci.reload_codec && new_track < 0) {
1560 if (!playlist_check(new_track)) {
1561 ci.reload_codec = false;
1562 return false;
1563 }
1564 last_peek_offset++; 1548 last_peek_offset++;
1565 playlist_next(new_track);
1566 if (--track_ridx < 0) 1549 if (--track_ridx < 0)
1567 track_ridx = MAX_TRACK-1; 1550 track_ridx = MAX_TRACK-1;
1568 if (tracks[track_ridx].filesize == 0 || 1551 if (tracks[track_ridx].filesize == 0 ||
@@ -1570,7 +1553,6 @@ bool codec_request_next_track_callback(void)
1570 /*+ (off_t)tracks[track_ridx].codecsize*/ > filebuflen) { 1553 /*+ (off_t)tracks[track_ridx].codecsize*/ > filebuflen) {
1571 logf("Loading from disk..."); 1554 logf("Loading from disk...");
1572 new_track = 0; 1555 new_track = 0;
1573 last_index = -1;
1574 queue_post(&audio_queue, AUDIO_PLAY, 0); 1556 queue_post(&audio_queue, AUDIO_PLAY, 0);
1575 return false; 1557 return false;
1576 } 1558 }
@@ -1597,7 +1579,6 @@ bool codec_request_next_track_callback(void)
1597 logf("No more tracks [2]"); 1579 logf("No more tracks [2]");
1598 ci.stop_codec = true; 1580 ci.stop_codec = true;
1599 new_track = 0; 1581 new_track = 0;
1600 last_index = -1;
1601 queue_post(&audio_queue, AUDIO_PLAY, 0); 1582 queue_post(&audio_queue, AUDIO_PLAY, 0);
1602 return false; 1583 return false;
1603 } 1584 }
@@ -1652,7 +1633,6 @@ static void initiate_track_change(int peek_index)
1652 1633
1653 /* Detect if disk is spinning.. */ 1634 /* Detect if disk is spinning.. */
1654 if (filling) { 1635 if (filling) {
1655 playlist_next(peek_index);
1656 queue_post(&audio_queue, AUDIO_PLAY, 0); 1636 queue_post(&audio_queue, AUDIO_PLAY, 0);
1657 } else { 1637 } else {
1658 new_track = peek_index; 1638 new_track = peek_index;
@@ -1677,35 +1657,49 @@ static void initiate_dir_change(int direction)
1677void audio_thread(void) 1657void audio_thread(void)
1678{ 1658{
1679 struct event ev; 1659 struct event ev;
1660 int last_tick = 0;
1661 bool play_pending = false;
1680 1662
1681 while (1) { 1663 while (1) {
1682 yield_codecs(); 1664 if (!play_pending)
1683 1665 {
1684 audio_check_buffer(); 1666 yield_codecs();
1667 audio_check_buffer();
1668 }
1669 else
1670 {
1671 // ata_spin();
1672 sleep(1);
1673 }
1685 1674
1686 queue_wait_w_tmo(&audio_queue, &ev, 0); 1675 queue_wait_w_tmo(&audio_queue, &ev, 0);
1676 if (ev.id == SYS_TIMEOUT && play_pending)
1677 {
1678 ev.id = AUDIO_PLAY;
1679 ev.data = 0;
1680 }
1681
1687 switch (ev.id) { 1682 switch (ev.id) {
1688 case AUDIO_PLAY: 1683 case AUDIO_PLAY:
1689 /* Refuse to start playback if we are already playing 1684 /* Don't start playing immediately if user is skipping tracks
1690 the requested track. This is needed because when skipping 1685 * fast to prevent UI lag. */
1691 tracks fast, AUDIO_PLAY commands will get queued with the 1686 track_count = 0;
1692 the same track and playback will stutter. */ 1687 last_peek_offset = 0;
1693 if (last_index == playlist_get_display_index() && playing 1688 if (current_tick - last_tick < HZ/2)
1694 && pcm_is_playing()) { 1689 {
1695 logf("already playing req. track"); 1690 play_pending = true;
1696 break ; 1691 break ;
1697 } 1692 }
1698 1693 play_pending = false;
1694
1699 /* Do not start crossfading if audio is paused. */ 1695 /* Do not start crossfading if audio is paused. */
1700 if (paused) { 1696 if (paused)
1701 audio_stop_playback(); 1697 pcmbuf_play_stop();
1702 paused = false;
1703 }
1704 1698
1705#ifdef CONFIG_TUNER 1699#ifdef CONFIG_TUNER
1706 /* check if radio is playing */ 1700 /* check if radio is playing */
1707 if(radio_get_status() != FMRADIO_OFF){ 1701 if (radio_get_status() != FMRADIO_OFF) {
1708 radio_stop(); 1702 radio_stop();
1709 } 1703 }
1710#endif 1704#endif
1711 1705
@@ -1751,15 +1745,13 @@ void audio_thread(void)
1751 1745
1752 case AUDIO_NEXT: 1746 case AUDIO_NEXT:
1753 logf("audio_next"); 1747 logf("audio_next");
1754 if (global_settings.beep) 1748 last_tick = current_tick;
1755 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
1756 initiate_track_change(1); 1749 initiate_track_change(1);
1757 break ; 1750 break ;
1758 1751
1759 case AUDIO_PREV: 1752 case AUDIO_PREV:
1760 logf("audio_prev"); 1753 logf("audio_prev");
1761 if (global_settings.beep) 1754 last_tick = current_tick;
1762 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
1763 initiate_track_change(-1); 1755 initiate_track_change(-1);
1764 break; 1756 break;
1765 1757
@@ -1793,7 +1785,7 @@ void audio_thread(void)
1793 // audio_change_track(); 1785 // audio_change_track();
1794 break ; 1786 break ;
1795 1787
1796#ifndef SIMULATOR 1788#ifndef SIMULATOR
1797 case SYS_USB_CONNECTED: 1789 case SYS_USB_CONNECTED:
1798 logf("USB: Audio core"); 1790 logf("USB: Audio core");
1799 audio_stop_playback(); 1791 audio_stop_playback();
@@ -1973,12 +1965,28 @@ void voice_init(void)
1973 1965
1974struct mp3entry* audio_current_track(void) 1966struct mp3entry* audio_current_track(void)
1975{ 1967{
1976 // logf("audio_current_track"); 1968 const char *filename;
1969 const char *p;
1970 static struct mp3entry temp_id3;
1977 1971
1978 if (track_count > 0 && cur_ti->taginfo_ready) 1972 if (track_count > 0 && cur_ti->taginfo_ready)
1979 return (struct mp3entry *)&cur_ti->id3; 1973 return (struct mp3entry *)&cur_ti->id3;
1980 else 1974 else {
1981 return NULL; 1975 filename = playlist_peek(0);
1976 if (!filename)
1977 filename = "No file!";
1978 p = strrchr(filename, '/');
1979 if (!p)
1980 p = filename;
1981 else
1982 p++;
1983
1984 memset(&temp_id3, 0, sizeof(struct mp3entry));
1985 strncpy(temp_id3.path, p, sizeof(temp_id3.path)-1);
1986 temp_id3.title = &temp_id3.path[0];
1987
1988 return &temp_id3;
1989 }
1982} 1990}
1983 1991
1984struct mp3entry* audio_next_track(void) 1992struct mp3entry* audio_next_track(void)
@@ -1994,16 +2002,12 @@ struct mp3entry* audio_next_track(void)
1994 if (!tracks[next_idx].taginfo_ready) 2002 if (!tracks[next_idx].taginfo_ready)
1995 return NULL; 2003 return NULL;
1996 2004
1997 //logf("audio_next_track");
1998
1999 return &tracks[next_idx].id3; 2005 return &tracks[next_idx].id3;
2000} 2006}
2001 2007
2002bool audio_has_changed_track(void) 2008bool audio_has_changed_track(void)
2003{ 2009{
2004 if (track_changed && track_count > 0 && playing) { 2010 if (track_changed) {
2005 if (!cur_ti->taginfo_ready)
2006 return false;
2007 track_changed = false; 2011 track_changed = false;
2008 return true; 2012 return true;
2009 } 2013 }
@@ -2014,7 +2018,6 @@ bool audio_has_changed_track(void)
2014void audio_play(int offset) 2018void audio_play(int offset)
2015{ 2019{
2016 logf("audio_play"); 2020 logf("audio_play");
2017 last_index = -1;
2018 queue_post(&audio_queue, AUDIO_PLAY, (void *)offset); 2021 queue_post(&audio_queue, AUDIO_PLAY, (void *)offset);
2019} 2022}
2020 2023
@@ -2043,11 +2046,37 @@ void audio_resume(void)
2043 2046
2044void audio_next(void) 2047void audio_next(void)
2045{ 2048{
2049 /* Prevent UI lag and update the WPS immediately. */
2050 if (global_settings.beep)
2051 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
2052
2053 if (!playlist_check(1))
2054 return ;
2055 playlist_next(1);
2056 track_changed = true;
2057
2058 /* Force WPS to update even if audio thread is blocked spinning. */
2059 if (mutex_bufferfill.locked)
2060 cur_ti->taginfo_ready = false;
2061
2046 queue_post(&audio_queue, AUDIO_NEXT, 0); 2062 queue_post(&audio_queue, AUDIO_NEXT, 0);
2047} 2063}
2048 2064
2049void audio_prev(void) 2065void audio_prev(void)
2050{ 2066{
2067 /* Prevent UI lag and update the WPS immediately. */
2068 if (global_settings.beep)
2069 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
2070
2071 if (!playlist_check(-1))
2072 return ;
2073 playlist_next(-1);
2074 track_changed = true;
2075
2076 /* Force WPS to update even if audio thread is blocked spinning. */
2077 if (mutex_bufferfill.locked)
2078 cur_ti->taginfo_ready = false;
2079
2051 queue_post(&audio_queue, AUDIO_PREV, 0); 2080 queue_post(&audio_queue, AUDIO_PREV, 0);
2052} 2081}
2053 2082