diff options
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 208 |
1 files changed, 119 insertions, 89 deletions
diff --git a/apps/playback.c b/apps/playback.c index 779fd97bde..c535e30c8a 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -87,23 +87,26 @@ static volatile bool paused; | |||
87 | #define AUDIO_DEFAULT_WATERMARK (1024*512) | 87 | #define AUDIO_DEFAULT_WATERMARK (1024*512) |
88 | #define AUDIO_DEFAULT_FILECHUNK (1024*32) | 88 | #define AUDIO_DEFAULT_FILECHUNK (1024*32) |
89 | 89 | ||
90 | #define AUDIO_PLAY 1 | 90 | enum { |
91 | #define AUDIO_STOP 2 | 91 | Q_AUDIO_PLAY = 1, |
92 | #define AUDIO_PAUSE 3 | 92 | Q_AUDIO_STOP, |
93 | #define AUDIO_RESUME 4 | 93 | Q_AUDIO_PAUSE, |
94 | #define AUDIO_NEXT 5 | 94 | Q_AUDIO_RESUME, |
95 | #define AUDIO_PREV 6 | 95 | Q_AUDIO_NEXT, |
96 | #define AUDIO_FF_REWIND 7 | 96 | Q_AUDIO_PREV, |
97 | #define AUDIO_FLUSH_RELOAD 8 | 97 | Q_AUDIO_FF_REWIND, |
98 | #define AUDIO_CODEC_DONE 9 | 98 | Q_AUDIO_FLUSH_RELOAD, |
99 | #define AUDIO_FLUSH 10 | 99 | Q_AUDIO_CODEC_DONE, |
100 | #define AUDIO_TRACK_CHANGED 11 | 100 | Q_AUDIO_FLUSH, |
101 | #define AUDIO_DIR_NEXT 12 | 101 | Q_AUDIO_TRACK_CHANGED, |
102 | #define AUDIO_DIR_PREV 13 | 102 | Q_AUDIO_DIR_NEXT, |
103 | #define AUDIO_SEAMLESS_SEEK 14 | 103 | Q_AUDIO_DIR_PREV, |
104 | 104 | Q_AUDIO_SEAMLESS_SEEK, | |
105 | #define CODEC_LOAD 1 | 105 | Q_AUDIO_POSTINIT, |
106 | #define CODEC_LOAD_DISK 2 | 106 | |
107 | Q_CODEC_LOAD, | ||
108 | Q_CODEC_LOAD_DISK, | ||
109 | }; | ||
107 | 110 | ||
108 | /* As defined in plugins/lib/xxx2wav.h */ | 111 | /* As defined in plugins/lib/xxx2wav.h */ |
109 | #define MALLOC_BUFSIZE (512*1024) | 112 | #define MALLOC_BUFSIZE (512*1024) |
@@ -199,6 +202,8 @@ void (*track_changed_callback)(struct mp3entry *id3); | |||
199 | void (*track_buffer_callback)(struct mp3entry *id3, bool last_track); | 202 | void (*track_buffer_callback)(struct mp3entry *id3, bool last_track); |
200 | void (*track_unbuffer_callback)(struct mp3entry *id3, bool last_track); | 203 | void (*track_unbuffer_callback)(struct mp3entry *id3, bool last_track); |
201 | 204 | ||
205 | static void playback_init(void); | ||
206 | |||
202 | /* Configuration */ | 207 | /* Configuration */ |
203 | static int conf_bufferlimit; | 208 | static int conf_bufferlimit; |
204 | static int conf_watermark; | 209 | static int conf_watermark; |
@@ -776,7 +781,7 @@ void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3)) | |||
776 | static void codec_track_changed(void) | 781 | static void codec_track_changed(void) |
777 | { | 782 | { |
778 | track_changed = true; | 783 | track_changed = true; |
779 | queue_post(&audio_queue, AUDIO_TRACK_CHANGED, 0); | 784 | queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0); |
780 | } | 785 | } |
781 | 786 | ||
782 | /* Give codecs or file buffering the right amount of processing time | 787 | /* Give codecs or file buffering the right amount of processing time |
@@ -973,7 +978,7 @@ static bool loadcodec(bool start_play) | |||
973 | ci.curpos = 0; | 978 | ci.curpos = 0; |
974 | playing = true; | 979 | playing = true; |
975 | logf("Starting codec"); | 980 | logf("Starting codec"); |
976 | queue_post(&codec_queue, CODEC_LOAD_DISK, (void *)codec_path); | 981 | queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path); |
977 | return true; | 982 | return true; |
978 | } | 983 | } |
979 | 984 | ||
@@ -1571,7 +1576,7 @@ static int skip_next_track(bool inside_codec_thread) | |||
1571 | else if (pcmbuf_is_crossfade_enabled()) | 1576 | else if (pcmbuf_is_crossfade_enabled()) |
1572 | pcmbuf_crossfade_init(); | 1577 | pcmbuf_crossfade_init(); |
1573 | 1578 | ||
1574 | queue_post(&audio_queue, AUDIO_PLAY, 0); | 1579 | queue_post(&audio_queue, Q_AUDIO_PLAY, 0); |
1575 | return SKIP_OK_DISK; | 1580 | return SKIP_OK_DISK; |
1576 | } | 1581 | } |
1577 | 1582 | ||
@@ -1612,7 +1617,7 @@ static int skip_previous_track(bool inside_codec_thread) | |||
1612 | else | 1617 | else |
1613 | stop_codec_flush(); | 1618 | stop_codec_flush(); |
1614 | 1619 | ||
1615 | queue_post(&audio_queue, AUDIO_PLAY, 0); | 1620 | queue_post(&audio_queue, Q_AUDIO_PLAY, 0); |
1616 | return SKIP_OK_DISK; | 1621 | return SKIP_OK_DISK; |
1617 | } | 1622 | } |
1618 | 1623 | ||
@@ -1652,7 +1657,7 @@ static void audio_change_track(void) | |||
1652 | ci.reload_codec = false; | 1657 | ci.reload_codec = false; |
1653 | /* Needed for fast skipping. */ | 1658 | /* Needed for fast skipping. */ |
1654 | if (cur_ti->codecsize > 0) | 1659 | if (cur_ti->codecsize > 0) |
1655 | queue_post(&codec_queue, CODEC_LOAD, 0); | 1660 | queue_post(&codec_queue, Q_CODEC_LOAD, 0); |
1656 | } | 1661 | } |
1657 | 1662 | ||
1658 | bool codec_request_next_track_callback(void) | 1663 | bool codec_request_next_track_callback(void) |
@@ -1703,7 +1708,7 @@ bool codec_request_next_track_callback(void) | |||
1703 | if (cur_ti->codecsize == 0) | 1708 | if (cur_ti->codecsize == 0) |
1704 | { | 1709 | { |
1705 | logf("Loading from disk [2]..."); | 1710 | logf("Loading from disk [2]..."); |
1706 | queue_post(&audio_queue, AUDIO_PLAY, 0); | 1711 | queue_post(&audio_queue, Q_AUDIO_PLAY, 0); |
1707 | } | 1712 | } |
1708 | else | 1713 | else |
1709 | ci.reload_codec = true; | 1714 | ci.reload_codec = true; |
@@ -1720,7 +1725,7 @@ void audio_invalidate_tracks(void) | |||
1720 | if (track_count == 0) { | 1725 | if (track_count == 0) { |
1721 | /* This call doesn't seem necessary anymore. Uncomment it | 1726 | /* This call doesn't seem necessary anymore. Uncomment it |
1722 | if things break */ | 1727 | if things break */ |
1723 | /* queue_post(&audio_queue, AUDIO_PLAY, 0); */ | 1728 | /* queue_post(&audio_queue, Q_AUDIO_PLAY, 0); */ |
1724 | return ; | 1729 | return ; |
1725 | } | 1730 | } |
1726 | 1731 | ||
@@ -1746,7 +1751,7 @@ static void initiate_track_change(int peek_index) | |||
1746 | else | 1751 | else |
1747 | pcmbuf_play_stop(); | 1752 | pcmbuf_play_stop(); |
1748 | ci.stop_codec = true; | 1753 | ci.stop_codec = true; |
1749 | queue_post(&audio_queue, AUDIO_PLAY, 0); | 1754 | queue_post(&audio_queue, Q_AUDIO_PLAY, 0); |
1750 | } else { | 1755 | } else { |
1751 | new_track = peek_index; | 1756 | new_track = peek_index; |
1752 | ci.reload_codec = true; | 1757 | ci.reload_codec = true; |
@@ -1760,7 +1765,7 @@ static void initiate_dir_change(int direction) | |||
1760 | if(!playlist_next_dir(direction)) | 1765 | if(!playlist_next_dir(direction)) |
1761 | return; | 1766 | return; |
1762 | 1767 | ||
1763 | queue_post(&audio_queue, AUDIO_PLAY, (bool *)true); | 1768 | queue_post(&audio_queue, Q_AUDIO_PLAY, (bool *)true); |
1764 | 1769 | ||
1765 | codec_track_changed(); | 1770 | codec_track_changed(); |
1766 | } | 1771 | } |
@@ -1770,6 +1775,9 @@ void audio_thread(void) | |||
1770 | struct event ev; | 1775 | struct event ev; |
1771 | int last_tick = 0; | 1776 | int last_tick = 0; |
1772 | bool play_pending = false; | 1777 | bool play_pending = false; |
1778 | |||
1779 | /* At first initialize audio system in background. */ | ||
1780 | playback_init(); | ||
1773 | 1781 | ||
1774 | while (1) { | 1782 | while (1) { |
1775 | if (!play_pending && queue_empty(&audio_queue)) | 1783 | if (!play_pending && queue_empty(&audio_queue)) |
@@ -1786,12 +1794,12 @@ void audio_thread(void) | |||
1786 | queue_wait_w_tmo(&audio_queue, &ev, 0); | 1794 | queue_wait_w_tmo(&audio_queue, &ev, 0); |
1787 | if (ev.id == SYS_TIMEOUT && play_pending) | 1795 | if (ev.id == SYS_TIMEOUT && play_pending) |
1788 | { | 1796 | { |
1789 | ev.id = AUDIO_PLAY; | 1797 | ev.id = Q_AUDIO_PLAY; |
1790 | ev.data = (bool *)1; | 1798 | ev.data = (bool *)1; |
1791 | } | 1799 | } |
1792 | 1800 | ||
1793 | switch (ev.id) { | 1801 | switch (ev.id) { |
1794 | case AUDIO_PLAY: | 1802 | case Q_AUDIO_PLAY: |
1795 | /* Don't start playing immediately if user is skipping tracks | 1803 | /* Don't start playing immediately if user is skipping tracks |
1796 | * fast to prevent UI lag. */ | 1804 | * fast to prevent UI lag. */ |
1797 | track_count = 0; | 1805 | track_count = 0; |
@@ -1837,52 +1845,52 @@ void audio_thread(void) | |||
1837 | } | 1845 | } |
1838 | break ; | 1846 | break ; |
1839 | 1847 | ||
1840 | case AUDIO_STOP: | 1848 | case Q_AUDIO_STOP: |
1841 | audio_stop_playback(true); | 1849 | audio_stop_playback(true); |
1842 | break ; | 1850 | break ; |
1843 | 1851 | ||
1844 | case AUDIO_PAUSE: | 1852 | case Q_AUDIO_PAUSE: |
1845 | logf("audio_pause"); | 1853 | logf("audio_pause"); |
1846 | pcm_mute(true); | 1854 | pcm_mute(true); |
1847 | pcm_play_pause(false); | 1855 | pcm_play_pause(false); |
1848 | paused = true; | 1856 | paused = true; |
1849 | break ; | 1857 | break ; |
1850 | 1858 | ||
1851 | case AUDIO_RESUME: | 1859 | case Q_AUDIO_RESUME: |
1852 | logf("audio_resume"); | 1860 | logf("audio_resume"); |
1853 | pcm_play_pause(true); | 1861 | pcm_play_pause(true); |
1854 | pcm_mute(false); | 1862 | pcm_mute(false); |
1855 | paused = false; | 1863 | paused = false; |
1856 | break ; | 1864 | break ; |
1857 | 1865 | ||
1858 | case AUDIO_NEXT: | 1866 | case Q_AUDIO_NEXT: |
1859 | logf("audio_next"); | 1867 | logf("audio_next"); |
1860 | last_tick = current_tick; | 1868 | last_tick = current_tick; |
1861 | playlist_end = false; | 1869 | playlist_end = false; |
1862 | initiate_track_change(1); | 1870 | initiate_track_change(1); |
1863 | break ; | 1871 | break ; |
1864 | 1872 | ||
1865 | case AUDIO_PREV: | 1873 | case Q_AUDIO_PREV: |
1866 | logf("audio_prev"); | 1874 | logf("audio_prev"); |
1867 | last_tick = current_tick; | 1875 | last_tick = current_tick; |
1868 | playlist_end = false; | 1876 | playlist_end = false; |
1869 | initiate_track_change(-1); | 1877 | initiate_track_change(-1); |
1870 | break; | 1878 | break; |
1871 | 1879 | ||
1872 | case AUDIO_FF_REWIND: | 1880 | case Q_AUDIO_FF_REWIND: |
1873 | if (!playing) | 1881 | if (!playing) |
1874 | break ; | 1882 | break ; |
1875 | pcmbuf_play_stop(); | 1883 | pcmbuf_play_stop(); |
1876 | ci.seek_time = (int)ev.data+1; | 1884 | ci.seek_time = (int)ev.data+1; |
1877 | break ; | 1885 | break ; |
1878 | 1886 | ||
1879 | case AUDIO_SEAMLESS_SEEK: | 1887 | case Q_AUDIO_SEAMLESS_SEEK: |
1880 | if (!playing) | 1888 | if (!playing) |
1881 | break ; | 1889 | break ; |
1882 | ci.seek_time = (int)ev.data+1; | 1890 | ci.seek_time = (int)ev.data+1; |
1883 | break ; | 1891 | break ; |
1884 | 1892 | ||
1885 | case AUDIO_DIR_NEXT: | 1893 | case Q_AUDIO_DIR_NEXT: |
1886 | logf("audio_dir_next"); | 1894 | logf("audio_dir_next"); |
1887 | playlist_end = false; | 1895 | playlist_end = false; |
1888 | if (global_settings.beep) | 1896 | if (global_settings.beep) |
@@ -1890,7 +1898,7 @@ void audio_thread(void) | |||
1890 | initiate_dir_change(1); | 1898 | initiate_dir_change(1); |
1891 | break; | 1899 | break; |
1892 | 1900 | ||
1893 | case AUDIO_DIR_PREV: | 1901 | case Q_AUDIO_DIR_PREV: |
1894 | logf("audio_dir_prev"); | 1902 | logf("audio_dir_prev"); |
1895 | playlist_end = false; | 1903 | playlist_end = false; |
1896 | if (global_settings.beep) | 1904 | if (global_settings.beep) |
@@ -1898,18 +1906,18 @@ void audio_thread(void) | |||
1898 | initiate_dir_change(-1); | 1906 | initiate_dir_change(-1); |
1899 | break; | 1907 | break; |
1900 | 1908 | ||
1901 | case AUDIO_FLUSH: | 1909 | case Q_AUDIO_FLUSH: |
1902 | audio_invalidate_tracks(); | 1910 | audio_invalidate_tracks(); |
1903 | break ; | 1911 | break ; |
1904 | 1912 | ||
1905 | case AUDIO_TRACK_CHANGED: | 1913 | case Q_AUDIO_TRACK_CHANGED: |
1906 | if (track_changed_callback) | 1914 | if (track_changed_callback) |
1907 | track_changed_callback(&cur_ti->id3); | 1915 | track_changed_callback(&cur_ti->id3); |
1908 | playlist_update_resume_info(audio_current_track()); | 1916 | playlist_update_resume_info(audio_current_track()); |
1909 | pcmbuf_set_position_callback(NULL); | 1917 | pcmbuf_set_position_callback(NULL); |
1910 | break ; | 1918 | break ; |
1911 | 1919 | ||
1912 | case AUDIO_CODEC_DONE: | 1920 | case Q_AUDIO_CODEC_DONE: |
1913 | break ; | 1921 | break ; |
1914 | 1922 | ||
1915 | #ifndef SIMULATOR | 1923 | #ifndef SIMULATOR |
@@ -1939,7 +1947,7 @@ void codec_thread(void) | |||
1939 | new_track = 0; | 1947 | new_track = 0; |
1940 | 1948 | ||
1941 | switch (ev.id) { | 1949 | switch (ev.id) { |
1942 | case CODEC_LOAD_DISK: | 1950 | case Q_CODEC_LOAD_DISK: |
1943 | ci.stop_codec = false; | 1951 | ci.stop_codec = false; |
1944 | audio_codec_loaded = true; | 1952 | audio_codec_loaded = true; |
1945 | mutex_lock(&mutex_codecthread); | 1953 | mutex_lock(&mutex_codecthread); |
@@ -1948,7 +1956,7 @@ void codec_thread(void) | |||
1948 | mutex_unlock(&mutex_codecthread); | 1956 | mutex_unlock(&mutex_codecthread); |
1949 | break ; | 1957 | break ; |
1950 | 1958 | ||
1951 | case CODEC_LOAD: | 1959 | case Q_CODEC_LOAD: |
1952 | logf("Codec start"); | 1960 | logf("Codec start"); |
1953 | codecsize = cur_ti->codecsize; | 1961 | codecsize = cur_ti->codecsize; |
1954 | if (codecsize == 0) { | 1962 | if (codecsize == 0) { |
@@ -1987,8 +1995,8 @@ void codec_thread(void) | |||
1987 | audio_codec_loaded = false; | 1995 | audio_codec_loaded = false; |
1988 | 1996 | ||
1989 | switch (ev.id) { | 1997 | switch (ev.id) { |
1990 | case CODEC_LOAD_DISK: | 1998 | case Q_CODEC_LOAD_DISK: |
1991 | case CODEC_LOAD: | 1999 | case Q_CODEC_LOAD: |
1992 | if (status != CODEC_OK) { | 2000 | if (status != CODEC_OK) { |
1993 | logf("Codec failure"); | 2001 | logf("Codec failure"); |
1994 | // audio_stop_playback(); | 2002 | // audio_stop_playback(); |
@@ -2001,7 +2009,7 @@ void codec_thread(void) | |||
2001 | if (playing && !ci.stop_codec) | 2009 | if (playing && !ci.stop_codec) |
2002 | audio_change_track(); | 2010 | audio_change_track(); |
2003 | 2011 | ||
2004 | // queue_post(&audio_queue, AUDIO_CODEC_DONE, (void *)status); | 2012 | // queue_post(&audio_queue, Q_AUDIO_CODEC_DONE, (void *)status); |
2005 | } | 2013 | } |
2006 | } | 2014 | } |
2007 | } | 2015 | } |
@@ -2031,7 +2039,7 @@ void voice_codec_thread(void) | |||
2031 | voice_is_playing = false; | 2039 | voice_is_playing = false; |
2032 | queue_wait(&voice_codec_queue, &ev); | 2040 | queue_wait(&voice_codec_queue, &ev); |
2033 | switch (ev.id) { | 2041 | switch (ev.id) { |
2034 | case CODEC_LOAD_DISK: | 2042 | case Q_CODEC_LOAD_DISK: |
2035 | logf("Loading voice codec"); | 2043 | logf("Loading voice codec"); |
2036 | audio_stop_playback(true); | 2044 | audio_stop_playback(true); |
2037 | mutex_lock(&mutex_codecthread); | 2045 | mutex_lock(&mutex_codecthread); |
@@ -2083,7 +2091,7 @@ void voice_init(void) | |||
2083 | return ; | 2091 | return ; |
2084 | 2092 | ||
2085 | logf("Starting voice codec"); | 2093 | logf("Starting voice codec"); |
2086 | queue_post(&voice_codec_queue, CODEC_LOAD_DISK, (void *)CODEC_MPA_L3); | 2094 | queue_post(&voice_codec_queue, Q_CODEC_LOAD_DISK, (void *)CODEC_MPA_L3); |
2087 | while (!voice_codec_loaded) | 2095 | while (!voice_codec_loaded) |
2088 | sleep(1); | 2096 | sleep(1); |
2089 | } | 2097 | } |
@@ -2158,13 +2166,13 @@ void audio_play(int offset) | |||
2158 | pcmbuf_play_stop(); | 2166 | pcmbuf_play_stop(); |
2159 | } | 2167 | } |
2160 | 2168 | ||
2161 | queue_post(&audio_queue, AUDIO_PLAY, (void *)offset); | 2169 | queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset); |
2162 | } | 2170 | } |
2163 | 2171 | ||
2164 | void audio_stop(void) | 2172 | void audio_stop(void) |
2165 | { | 2173 | { |
2166 | logf("audio_stop"); | 2174 | logf("audio_stop"); |
2167 | queue_post(&audio_queue, AUDIO_STOP, 0); | 2175 | queue_post(&audio_queue, Q_AUDIO_STOP, 0); |
2168 | while (playing || audio_codec_loaded) | 2176 | while (playing || audio_codec_loaded) |
2169 | yield(); | 2177 | yield(); |
2170 | } | 2178 | } |
@@ -2176,12 +2184,12 @@ bool mp3_pause_done(void) | |||
2176 | 2184 | ||
2177 | void audio_pause(void) | 2185 | void audio_pause(void) |
2178 | { | 2186 | { |
2179 | queue_post(&audio_queue, AUDIO_PAUSE, 0); | 2187 | queue_post(&audio_queue, Q_AUDIO_PAUSE, 0); |
2180 | } | 2188 | } |
2181 | 2189 | ||
2182 | void audio_resume(void) | 2190 | void audio_resume(void) |
2183 | { | 2191 | { |
2184 | queue_post(&audio_queue, AUDIO_RESUME, 0); | 2192 | queue_post(&audio_queue, Q_AUDIO_RESUME, 0); |
2185 | } | 2193 | } |
2186 | 2194 | ||
2187 | void audio_next(void) | 2195 | void audio_next(void) |
@@ -2199,7 +2207,7 @@ void audio_next(void) | |||
2199 | if (mutex_bufferfill.locked) | 2207 | if (mutex_bufferfill.locked) |
2200 | cur_ti->taginfo_ready = false; | 2208 | cur_ti->taginfo_ready = false; |
2201 | 2209 | ||
2202 | queue_post(&audio_queue, AUDIO_NEXT, 0); | 2210 | queue_post(&audio_queue, Q_AUDIO_NEXT, 0); |
2203 | } | 2211 | } |
2204 | 2212 | ||
2205 | void audio_prev(void) | 2213 | void audio_prev(void) |
@@ -2217,35 +2225,35 @@ void audio_prev(void) | |||
2217 | if (mutex_bufferfill.locked) | 2225 | if (mutex_bufferfill.locked) |
2218 | cur_ti->taginfo_ready = false; | 2226 | cur_ti->taginfo_ready = false; |
2219 | 2227 | ||
2220 | queue_post(&audio_queue, AUDIO_PREV, 0); | 2228 | queue_post(&audio_queue, Q_AUDIO_PREV, 0); |
2221 | } | 2229 | } |
2222 | 2230 | ||
2223 | void audio_next_dir(void) | 2231 | void audio_next_dir(void) |
2224 | { | 2232 | { |
2225 | queue_post(&audio_queue, AUDIO_DIR_NEXT, 0); | 2233 | queue_post(&audio_queue, Q_AUDIO_DIR_NEXT, 0); |
2226 | } | 2234 | } |
2227 | 2235 | ||
2228 | void audio_prev_dir(void) | 2236 | void audio_prev_dir(void) |
2229 | { | 2237 | { |
2230 | queue_post(&audio_queue, AUDIO_DIR_PREV, 0); | 2238 | queue_post(&audio_queue, Q_AUDIO_DIR_PREV, 0); |
2231 | } | 2239 | } |
2232 | 2240 | ||
2233 | void audio_ff_rewind(int newpos) | 2241 | void audio_ff_rewind(int newpos) |
2234 | { | 2242 | { |
2235 | logf("rewind: %d", newpos); | 2243 | logf("rewind: %d", newpos); |
2236 | queue_post(&audio_queue, AUDIO_FF_REWIND, (int *)newpos); | 2244 | queue_post(&audio_queue, Q_AUDIO_FF_REWIND, (int *)newpos); |
2237 | } | 2245 | } |
2238 | 2246 | ||
2239 | void audio_seamless_seek(int newpos) | 2247 | void audio_seamless_seek(int newpos) |
2240 | { | 2248 | { |
2241 | logf("seamless_seek: %d", newpos); | 2249 | logf("seamless_seek: %d", newpos); |
2242 | queue_post(&audio_queue, AUDIO_SEAMLESS_SEEK, (int *)newpos); | 2250 | queue_post(&audio_queue, Q_AUDIO_SEAMLESS_SEEK, (int *)newpos); |
2243 | } | 2251 | } |
2244 | 2252 | ||
2245 | void audio_flush_and_reload_tracks(void) | 2253 | void audio_flush_and_reload_tracks(void) |
2246 | { | 2254 | { |
2247 | logf("flush & reload"); | 2255 | logf("flush & reload"); |
2248 | queue_post(&audio_queue, AUDIO_FLUSH, 0); | 2256 | queue_post(&audio_queue, Q_AUDIO_FLUSH, 0); |
2249 | } | 2257 | } |
2250 | 2258 | ||
2251 | void audio_error_clear(void) | 2259 | void audio_error_clear(void) |
@@ -2481,38 +2489,23 @@ void test_unbuffer_event(struct mp3entry *id3, bool last_track) | |||
2481 | logf("ube:%d%s", last_track, id3->path); | 2489 | logf("ube:%d%s", last_track, id3->path); |
2482 | } | 2490 | } |
2483 | 2491 | ||
2484 | void audio_init(void) | 2492 | static void playback_init(void) |
2485 | { | 2493 | { |
2486 | static bool voicetagtrue = true; | 2494 | static bool voicetagtrue = true; |
2495 | struct event ev; | ||
2487 | 2496 | ||
2488 | logf("audio api init"); | 2497 | logf("playback api init"); |
2489 | pcm_init(); | 2498 | pcm_init(); |
2490 | 2499 | ||
2491 | #if defined(HAVE_RECORDING) && !defined(SIMULATOR) | 2500 | #if defined(HAVE_RECORDING) && !defined(SIMULATOR) |
2492 | /* Set the input multiplexer to Line In */ | 2501 | /* Set the input multiplexer to Line In */ |
2493 | pcm_rec_mux(0); | 2502 | pcm_rec_mux(0); |
2494 | #endif | 2503 | #endif |
2495 | 2504 | ||
2496 | filebufused = 0; | ||
2497 | filling = false; | ||
2498 | current_codec = CODEC_IDX_AUDIO; | ||
2499 | filebuf = (char *)&audiobuf[MALLOC_BUFSIZE]; | ||
2500 | playing = false; | ||
2501 | audio_codec_loaded = false; | ||
2502 | voice_is_playing = false; | ||
2503 | paused = false; | ||
2504 | track_changed = false; | ||
2505 | current_fd = -1; | ||
2506 | track_buffer_callback = NULL; | ||
2507 | track_unbuffer_callback = NULL; | ||
2508 | track_changed_callback = NULL; | ||
2509 | /* Just to prevent cur_ti never be anything random. */ | ||
2510 | cur_ti = &tracks[0]; | ||
2511 | |||
2512 | audio_set_track_buffer_event(test_buffer_event); | 2505 | audio_set_track_buffer_event(test_buffer_event); |
2513 | audio_set_track_unbuffer_event(test_unbuffer_event); | 2506 | audio_set_track_unbuffer_event(test_unbuffer_event); |
2514 | 2507 | ||
2515 | /* Initialize codec api. */ | 2508 | /* Initialize codec api. */ |
2516 | ci.read_filebuf = codec_filebuf_callback; | 2509 | ci.read_filebuf = codec_filebuf_callback; |
2517 | ci.pcmbuf_insert = pcmbuf_insert_buffer; | 2510 | ci.pcmbuf_insert = pcmbuf_insert_buffer; |
2518 | ci.pcmbuf_insert_split = codec_pcmbuf_insert_split_callback; | 2511 | ci.pcmbuf_insert_split = codec_pcmbuf_insert_split_callback; |
@@ -2535,24 +2528,61 @@ void audio_init(void) | |||
2535 | ci_voice.pcmbuf_insert = codec_pcmbuf_insert_callback; | 2528 | ci_voice.pcmbuf_insert = codec_pcmbuf_insert_callback; |
2536 | id3_voice.frequency = 11200; | 2529 | id3_voice.frequency = 11200; |
2537 | id3_voice.length = 1000000L; | 2530 | id3_voice.length = 1000000L; |
2538 | 2531 | ||
2539 | mutex_init(&mutex_bufferfill); | ||
2540 | mutex_init(&mutex_codecthread); | ||
2541 | |||
2542 | queue_init(&audio_queue); | ||
2543 | queue_init(&codec_queue); | ||
2544 | queue_init(&voice_codec_queue); | ||
2545 | |||
2546 | create_thread(codec_thread, codec_stack, sizeof(codec_stack), | 2532 | create_thread(codec_thread, codec_stack, sizeof(codec_stack), |
2547 | codec_thread_name); | 2533 | codec_thread_name); |
2548 | create_thread(voice_codec_thread, voice_codec_stack, | 2534 | create_thread(voice_codec_thread, voice_codec_stack, |
2549 | sizeof(voice_codec_stack), voice_codec_thread_name); | 2535 | sizeof(voice_codec_stack), voice_codec_thread_name); |
2550 | create_thread(audio_thread, audio_stack, sizeof(audio_stack), | ||
2551 | audio_thread_name); | ||
2552 | 2536 | ||
2537 | while (1) | ||
2538 | { | ||
2539 | queue_wait(&audio_queue, &ev); | ||
2540 | if (ev.id == Q_AUDIO_POSTINIT) | ||
2541 | break ; | ||
2542 | } | ||
2543 | |||
2553 | /* Apply relevant settings */ | 2544 | /* Apply relevant settings */ |
2554 | audio_set_buffer_margin(global_settings.buffer_margin); | 2545 | audio_set_buffer_margin(global_settings.buffer_margin); |
2555 | audio_set_crossfade(global_settings.crossfade); | 2546 | audio_set_crossfade(global_settings.crossfade); |
2547 | |||
2548 | sound_settings_apply(); | ||
2556 | } | 2549 | } |
2557 | 2550 | ||
2551 | void audio_preinit(void) | ||
2552 | { | ||
2553 | logf("playback system pre-init"); | ||
2554 | |||
2555 | filebufused = 0; | ||
2556 | filling = false; | ||
2557 | current_codec = CODEC_IDX_AUDIO; | ||
2558 | filebuf = (char *)&audiobuf[MALLOC_BUFSIZE]; | ||
2559 | playing = false; | ||
2560 | audio_codec_loaded = false; | ||
2561 | voice_is_playing = false; | ||
2562 | paused = false; | ||
2563 | track_changed = false; | ||
2564 | current_fd = -1; | ||
2565 | track_buffer_callback = NULL; | ||
2566 | track_unbuffer_callback = NULL; | ||
2567 | track_changed_callback = NULL; | ||
2568 | /* Just to prevent cur_ti never be anything random. */ | ||
2569 | cur_ti = &tracks[0]; | ||
2570 | |||
2571 | mutex_init(&mutex_bufferfill); | ||
2572 | mutex_init(&mutex_codecthread); | ||
2573 | |||
2574 | queue_init(&audio_queue); | ||
2575 | queue_init(&codec_queue); | ||
2576 | queue_init(&voice_codec_queue); | ||
2577 | |||
2578 | create_thread(audio_thread, audio_stack, sizeof(audio_stack), | ||
2579 | audio_thread_name); | ||
2580 | } | ||
2581 | |||
2582 | void audio_init(void) | ||
2583 | { | ||
2584 | logf("playback system post-init"); | ||
2585 | |||
2586 | queue_post(&audio_queue, Q_AUDIO_POSTINIT, 0); | ||
2587 | } | ||
2558 | 2588 | ||