diff options
-rw-r--r-- | apps/debug_menu.c | 5 | ||||
-rw-r--r-- | apps/playback.c | 46 | ||||
-rw-r--r-- | firmware/export/audio.h | 1 |
3 files changed, 22 insertions, 30 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index fa650739f5..9b04cfafd8 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -270,7 +270,6 @@ bool dbg_audio_thread(void) | |||
270 | #else /* CONFIG_CODEC == SWCODEC */ | 270 | #else /* CONFIG_CODEC == SWCODEC */ |
271 | extern size_t filebuflen; | 271 | extern size_t filebuflen; |
272 | /* This is a size_t, but call it a long so it puts a - when it's bad. */ | 272 | /* This is a size_t, but call it a long so it puts a - when it's bad. */ |
273 | extern long filebufused; | ||
274 | 273 | ||
275 | static unsigned int ticks, boost_ticks; | 274 | static unsigned int ticks, boost_ticks; |
276 | 275 | ||
@@ -329,12 +328,12 @@ bool dbg_audio_thread(void) | |||
329 | scrollbar(0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL); | 328 | scrollbar(0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL); |
330 | line++; | 329 | line++; |
331 | 330 | ||
332 | snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", filebufused, (long) filebuflen); | 331 | snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen); |
333 | lcd_puts(0, line++, buf); | 332 | lcd_puts(0, line++, buf); |
334 | 333 | ||
335 | /* Playable space left */ | 334 | /* Playable space left */ |
336 | scrollbar(0, line*8, LCD_WIDTH, 6, filebuflen, 0, | 335 | scrollbar(0, line*8, LCD_WIDTH, 6, filebuflen, 0, |
337 | filebufused, HORIZONTAL); | 336 | audio_filebufused(), HORIZONTAL); |
338 | line++; | 337 | line++; |
339 | 338 | ||
340 | snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count()); | 339 | snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count()); |
diff --git a/apps/playback.c b/apps/playback.c index d1f098b2ed..5b811751db 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -192,13 +192,17 @@ static char *filebuf; | |||
192 | /* Total size of the ring buffer. */ | 192 | /* Total size of the ring buffer. */ |
193 | size_t filebuflen; | 193 | size_t filebuflen; |
194 | 194 | ||
195 | /* Bytes available in the buffer. */ | ||
196 | size_t filebufused; | ||
197 | |||
198 | /* Ring buffer read and write indexes. */ | 195 | /* Ring buffer read and write indexes. */ |
199 | static volatile size_t buf_ridx IDATA_ATTR; | 196 | static volatile size_t buf_ridx IDATA_ATTR; |
200 | static volatile size_t buf_widx IDATA_ATTR; | 197 | static volatile size_t buf_widx IDATA_ATTR; |
201 | 198 | ||
199 | /* Ring buffer arithmetic */ | ||
200 | #define RINGBUF_ADD(p,v) ((p+v)<=filebuflen ? p+v : p+v-filebuflen) | ||
201 | #define RINGBUF_SUB(p,v) ((p>=v) ? p-v : p+filebuflen-v) | ||
202 | |||
203 | /* Bytes available in the buffer. */ | ||
204 | #define FILEBUFUSED RINGBUF_SUB(buf_widx, buf_ridx) | ||
205 | |||
202 | /* Codec swapping pointers */ | 206 | /* Codec swapping pointers */ |
203 | static unsigned char *iram_buf[2]; | 207 | static unsigned char *iram_buf[2]; |
204 | static unsigned char *dram_buf[2]; | 208 | static unsigned char *dram_buf[2]; |
@@ -660,7 +664,6 @@ void audio_preinit(void) | |||
660 | { | 664 | { |
661 | logf("playback system pre-init"); | 665 | logf("playback system pre-init"); |
662 | 666 | ||
663 | filebufused = 0; | ||
664 | filling = false; | 667 | filling = false; |
665 | current_codec = CODEC_IDX_AUDIO; | 668 | current_codec = CODEC_IDX_AUDIO; |
666 | playing = false; | 669 | playing = false; |
@@ -1257,12 +1260,11 @@ static void codec_advance_buffer_counters(size_t amount) | |||
1257 | 1260 | ||
1258 | ci.curpos += amount; | 1261 | ci.curpos += amount; |
1259 | CUR_TI->available -= amount; | 1262 | CUR_TI->available -= amount; |
1260 | filebufused -= amount; | ||
1261 | 1263 | ||
1262 | /* Start buffer filling as necessary. */ | 1264 | /* Start buffer filling as necessary. */ |
1263 | if (!pcmbuf_is_lowdata() && !filling) | 1265 | if (!pcmbuf_is_lowdata() && !filling) |
1264 | { | 1266 | { |
1265 | if (conf_watermark && filebufused <= conf_watermark && playing) | 1267 | if (conf_watermark && FILEBUFUSED <= conf_watermark && playing) |
1266 | { | 1268 | { |
1267 | LOGFQUEUE("codec > audio Q_AUDIO_FILL_BUFFER"); | 1269 | LOGFQUEUE("codec > audio Q_AUDIO_FILL_BUFFER"); |
1268 | queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0); | 1270 | queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0); |
@@ -1562,7 +1564,6 @@ static bool codec_seek_buffer_callback(size_t newpos) | |||
1562 | 1564 | ||
1563 | /* Seeking inside buffer space. */ | 1565 | /* Seeking inside buffer space. */ |
1564 | logf("seek: -%d", difference); | 1566 | logf("seek: -%d", difference); |
1565 | filebufused += difference; | ||
1566 | CUR_TI->available += difference; | 1567 | CUR_TI->available += difference; |
1567 | if (buf_ridx < (unsigned)difference) | 1568 | if (buf_ridx < (unsigned)difference) |
1568 | buf_ridx += filebuflen; | 1569 | buf_ridx += filebuflen; |
@@ -1612,7 +1613,6 @@ static void codec_discard_codec_callback(void) | |||
1612 | if (CUR_TI->has_codec) | 1613 | if (CUR_TI->has_codec) |
1613 | { | 1614 | { |
1614 | CUR_TI->has_codec = false; | 1615 | CUR_TI->has_codec = false; |
1615 | filebufused -= CUR_TI->codecsize; | ||
1616 | buf_ridx += CUR_TI->codecsize; | 1616 | buf_ridx += CUR_TI->codecsize; |
1617 | if (buf_ridx >= filebuflen) | 1617 | if (buf_ridx >= filebuflen) |
1618 | buf_ridx -= filebuflen; | 1618 | buf_ridx -= filebuflen; |
@@ -1623,10 +1623,10 @@ static void codec_discard_codec_callback(void) | |||
1623 | if (buf_ridx != CUR_TI->buf_idx) | 1623 | if (buf_ridx != CUR_TI->buf_idx) |
1624 | { | 1624 | { |
1625 | int offset = CUR_TI->buf_idx - buf_ridx; | 1625 | int offset = CUR_TI->buf_idx - buf_ridx; |
1626 | size_t new_used = filebufused - offset; | 1626 | size_t new_used = FILEBUFUSED - offset; |
1627 | 1627 | ||
1628 | logf("Buf off :%d=%d-%d", offset, CUR_TI->buf_idx, buf_ridx); | 1628 | logf("Buf off :%d=%d-%d", offset, CUR_TI->buf_idx, buf_ridx); |
1629 | logf("Used off:%d",filebufused - new_used); | 1629 | logf("Used off:%d",FILEBUFUSED - new_used); |
1630 | 1630 | ||
1631 | /* This is a fatal internal error and it's not safe to | 1631 | /* This is a fatal internal error and it's not safe to |
1632 | * continue playback. */ | 1632 | * continue playback. */ |
@@ -1907,7 +1907,7 @@ static void codec_thread(void) | |||
1907 | 1907 | ||
1908 | static bool audio_filebuf_is_lowdata(void) | 1908 | static bool audio_filebuf_is_lowdata(void) |
1909 | { | 1909 | { |
1910 | return filebufused < AUDIO_FILEBUF_CRITICAL; | 1910 | return FILEBUFUSED < AUDIO_FILEBUF_CRITICAL; |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | static bool audio_have_tracks(void) | 1913 | static bool audio_have_tracks(void) |
@@ -1940,6 +1940,10 @@ int audio_track_count(void) | |||
1940 | return 0; | 1940 | return 0; |
1941 | } | 1941 | } |
1942 | 1942 | ||
1943 | long audio_filebufused(void) | ||
1944 | { | ||
1945 | return (long) FILEBUFUSED; | ||
1946 | } | ||
1943 | 1947 | ||
1944 | /* Count the data BETWEEN the selected tracks */ | 1948 | /* Count the data BETWEEN the selected tracks */ |
1945 | static size_t audio_buffer_count_tracks(int from_track, int to_track) | 1949 | static size_t audio_buffer_count_tracks(int from_track, int to_track) |
@@ -1972,14 +1976,13 @@ static bool audio_buffer_wind_forward(int new_track_ridx, int old_track_ridx) | |||
1972 | /* Then collect all data from tracks in between them */ | 1976 | /* Then collect all data from tracks in between them */ |
1973 | amount += audio_buffer_count_tracks(old_track_ridx, new_track_ridx); | 1977 | amount += audio_buffer_count_tracks(old_track_ridx, new_track_ridx); |
1974 | 1978 | ||
1975 | if (amount > filebufused) | 1979 | if (amount > FILEBUFUSED) |
1976 | return false; | 1980 | return false; |
1977 | 1981 | ||
1978 | logf("bwf:%ldB",amount); | 1982 | logf("bwf:%ldB",amount); |
1979 | 1983 | ||
1980 | /* Wind the buffer to the beginning of the target track or its codec */ | 1984 | /* Wind the buffer to the beginning of the target track or its codec */ |
1981 | buf_ridx += amount; | 1985 | buf_ridx += amount; |
1982 | filebufused -= amount; | ||
1983 | 1986 | ||
1984 | /* Check and handle buffer wrapping */ | 1987 | /* Check and handle buffer wrapping */ |
1985 | if (buf_ridx >= filebuflen) | 1988 | if (buf_ridx >= filebuflen) |
@@ -2035,7 +2038,6 @@ static bool audio_buffer_wind_backward(int new_track_ridx, int old_track_ridx) | |||
2035 | buf_ridx += filebuflen; | 2038 | buf_ridx += filebuflen; |
2036 | /* Rewind the buffer to the beginning of the target track or its codec */ | 2039 | /* Rewind the buffer to the beginning of the target track or its codec */ |
2037 | buf_ridx -= amount; | 2040 | buf_ridx -= amount; |
2038 | filebufused += amount; | ||
2039 | 2041 | ||
2040 | /* Reset to the beginning of the new track */ | 2042 | /* Reset to the beginning of the new track */ |
2041 | tracks[new_track_ridx].available = tracks[new_track_ridx].filesize; | 2043 | tracks[new_track_ridx].available = tracks[new_track_ridx].filesize; |
@@ -2143,7 +2145,7 @@ static void audio_strip_id3v1_tag(void) | |||
2143 | tag_idx += filebuflen; | 2145 | tag_idx += filebuflen; |
2144 | tag_idx -= 128; | 2146 | tag_idx -= 128; |
2145 | 2147 | ||
2146 | if (filebufused > 128 && tag_idx > buf_ridx) | 2148 | if (FILEBUFUSED > 128 && tag_idx > buf_ridx) |
2147 | { | 2149 | { |
2148 | cur_idx = tag_idx; | 2150 | cur_idx = tag_idx; |
2149 | for(i = 0;i < 3;i++) | 2151 | for(i = 0;i < 3;i++) |
@@ -2160,7 +2162,6 @@ static void audio_strip_id3v1_tag(void) | |||
2160 | buf_widx = tag_idx; | 2162 | buf_widx = tag_idx; |
2161 | tracks[track_widx].available -= 128; | 2163 | tracks[track_widx].available -= 128; |
2162 | tracks[track_widx].filesize -= 128; | 2164 | tracks[track_widx].filesize -= 128; |
2163 | filebufused -= 128; | ||
2164 | } | 2165 | } |
2165 | } | 2166 | } |
2166 | 2167 | ||
@@ -2218,7 +2219,6 @@ static void audio_read_file(bool quick) | |||
2218 | tracks[track_widx].available += rc; | 2219 | tracks[track_widx].available += rc; |
2219 | tracks[track_widx].filerem -= rc; | 2220 | tracks[track_widx].filerem -= rc; |
2220 | 2221 | ||
2221 | filebufused += rc; | ||
2222 | if (fill_bytesleft > (unsigned)rc) | 2222 | if (fill_bytesleft > (unsigned)rc) |
2223 | fill_bytesleft -= rc; | 2223 | fill_bytesleft -= rc; |
2224 | else | 2224 | else |
@@ -2325,7 +2325,6 @@ static bool audio_loadcodec(bool start_play) | |||
2325 | if (rc < 0) | 2325 | if (rc < 0) |
2326 | return false; | 2326 | return false; |
2327 | 2327 | ||
2328 | filebufused += rc; | ||
2329 | if (fill_bytesleft > (unsigned)rc) | 2328 | if (fill_bytesleft > (unsigned)rc) |
2330 | fill_bytesleft -= rc; | 2329 | fill_bytesleft -= rc; |
2331 | else | 2330 | else |
@@ -2501,7 +2500,6 @@ static bool audio_load_track(int offset, bool start_play, bool rebuffer) | |||
2501 | /* Must undo the buffer write of the partial codec */ | 2500 | /* Must undo the buffer write of the partial codec */ |
2502 | logf("Partial codec loaded"); | 2501 | logf("Partial codec loaded"); |
2503 | fill_bytesleft += tracks[track_widx].codecsize; | 2502 | fill_bytesleft += tracks[track_widx].codecsize; |
2504 | filebufused -= tracks[track_widx].codecsize; | ||
2505 | if (buf_widx < tracks[track_widx].codecsize) | 2503 | if (buf_widx < tracks[track_widx].codecsize) |
2506 | buf_widx += filebuflen; | 2504 | buf_widx += filebuflen; |
2507 | buf_widx -= tracks[track_widx].codecsize; | 2505 | buf_widx -= tracks[track_widx].codecsize; |
@@ -2667,12 +2665,12 @@ static bool audio_initialize_buffer_fill(bool clear_tracks) | |||
2667 | return true; | 2665 | return true; |
2668 | 2666 | ||
2669 | /* Don't start buffer fill if buffer is already full. */ | 2667 | /* Don't start buffer fill if buffer is already full. */ |
2670 | if (filebufused > conf_watermark && !filling) | 2668 | if (FILEBUFUSED > conf_watermark && !filling) |
2671 | return false; | 2669 | return false; |
2672 | 2670 | ||
2673 | logf("Starting buffer fill"); | 2671 | logf("Starting buffer fill"); |
2674 | 2672 | ||
2675 | fill_bytesleft = filebuflen - filebufused; | 2673 | fill_bytesleft = filebuflen - FILEBUFUSED; |
2676 | /* TODO: This doesn't look right, and might explain some problems with | 2674 | /* TODO: This doesn't look right, and might explain some problems with |
2677 | * seeking in large files (to offsets larger than filebuflen). | 2675 | * seeking in large files (to offsets larger than filebuflen). |
2678 | * And what about buffer wraps? | 2676 | * And what about buffer wraps? |
@@ -2763,7 +2761,6 @@ static void audio_rebuffer(void) | |||
2763 | tracks[track_ridx].buf_idx = buf_ridx = buf_widx = 0; | 2761 | tracks[track_ridx].buf_idx = buf_ridx = buf_widx = 0; |
2764 | track_widx = track_ridx; | 2762 | track_widx = track_ridx; |
2765 | audio_clear_track_entries(true, true, false); | 2763 | audio_clear_track_entries(true, true, false); |
2766 | filebufused = 0; | ||
2767 | CUR_TI->available = 0; | 2764 | CUR_TI->available = 0; |
2768 | 2765 | ||
2769 | /* Fill the buffer */ | 2766 | /* Fill the buffer */ |
@@ -2944,7 +2941,6 @@ static void audio_rebuffer_and_seek(size_t newpos) | |||
2944 | 2941 | ||
2945 | /* Clear codec buffer. */ | 2942 | /* Clear codec buffer. */ |
2946 | track_widx = track_ridx; | 2943 | track_widx = track_ridx; |
2947 | filebufused = 0; | ||
2948 | tracks[track_widx].buf_idx = buf_widx = buf_ridx = 0; | 2944 | tracks[track_widx].buf_idx = buf_widx = buf_ridx = 0; |
2949 | 2945 | ||
2950 | last_peek_offset = 0; | 2946 | last_peek_offset = 0; |
@@ -3012,7 +3008,6 @@ static void audio_stop_playback(void) | |||
3012 | (playlist_end && ci.stop_codec)?NULL:audio_current_track()); | 3008 | (playlist_end && ci.stop_codec)?NULL:audio_current_track()); |
3013 | } | 3009 | } |
3014 | 3010 | ||
3015 | filebufused = 0; | ||
3016 | playing = false; | 3011 | playing = false; |
3017 | filling = false; | 3012 | filling = false; |
3018 | paused = false; | 3013 | paused = false; |
@@ -3055,7 +3050,6 @@ static void audio_play_start(size_t offset) | |||
3055 | sound_set_volume(global_settings.volume); | 3050 | sound_set_volume(global_settings.volume); |
3056 | track_widx = track_ridx = 0; | 3051 | track_widx = track_ridx = 0; |
3057 | buf_ridx = buf_widx = 0; | 3052 | buf_ridx = buf_widx = 0; |
3058 | filebufused = 0; | ||
3059 | 3053 | ||
3060 | /* Mark all entries null. */ | 3054 | /* Mark all entries null. */ |
3061 | memset(tracks, 0, sizeof(struct track_info) * MAX_TRACK); | 3055 | memset(tracks, 0, sizeof(struct track_info) * MAX_TRACK); |
@@ -3081,7 +3075,6 @@ void audio_invalidate_tracks(void) | |||
3081 | track_widx = (track_widx + 1) & MAX_TRACK_MASK; | 3075 | track_widx = (track_widx + 1) & MAX_TRACK_MASK; |
3082 | 3076 | ||
3083 | /* Mark all other entries null (also buffered wrong metadata). */ | 3077 | /* Mark all other entries null (also buffered wrong metadata). */ |
3084 | filebufused = CUR_TI->available; | ||
3085 | buf_widx = buf_ridx + CUR_TI->available; | 3078 | buf_widx = buf_ridx + CUR_TI->available; |
3086 | if (buf_widx >= filebuflen) | 3079 | if (buf_widx >= filebuflen) |
3087 | buf_widx -= filebuflen; | 3080 | buf_widx -= filebuflen; |
@@ -3111,7 +3104,6 @@ static void audio_new_playlist(void) | |||
3111 | CUR_TI->taginfo_ready = false; | 3104 | CUR_TI->taginfo_ready = false; |
3112 | 3105 | ||
3113 | /* Invalidate the buffer other than the playing track */ | 3106 | /* Invalidate the buffer other than the playing track */ |
3114 | filebufused = CUR_TI->available; | ||
3115 | buf_widx = buf_ridx + CUR_TI->available; | 3107 | buf_widx = buf_ridx + CUR_TI->available; |
3116 | if (buf_widx >= filebuflen) | 3108 | if (buf_widx >= filebuflen) |
3117 | buf_widx -= filebuflen; | 3109 | buf_widx -= filebuflen; |
diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 2ee7f89dbd..58bc1e157d 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h | |||
@@ -74,6 +74,7 @@ void audio_prev(void); | |||
74 | int audio_status(void); | 74 | int audio_status(void); |
75 | bool audio_query_poweroff(void); | 75 | bool audio_query_poweroff(void); |
76 | int audio_track_count(void); /* SWCODEC only */ | 76 | int audio_track_count(void); /* SWCODEC only */ |
77 | long audio_filebufused(void); /* SWCODEC only */ | ||
77 | void audio_pre_ff_rewind(void); /* SWCODEC only */ | 78 | void audio_pre_ff_rewind(void); /* SWCODEC only */ |
78 | void audio_ff_rewind(long newtime); | 79 | void audio_ff_rewind(long newtime); |
79 | void audio_flush_and_reload_tracks(void); | 80 | void audio_flush_and_reload_tracks(void); |