diff options
author | Brandon Low <lostlogic@rockbox.org> | 2006-04-06 04:07:06 +0000 |
---|---|---|
committer | Brandon Low <lostlogic@rockbox.org> | 2006-04-06 04:07:06 +0000 |
commit | 857db456affc0b65e4fa3db1020117f547bcade5 (patch) | |
tree | f649f24e7b141cc3ed395def3a156a029799483d /apps | |
parent | 295fdf294c5f7db3bfd1583b8f271ccfcb3063f6 (diff) | |
download | rockbox-857db456affc0b65e4fa3db1020117f547bcade5.tar.gz rockbox-857db456affc0b65e4fa3db1020117f547bcade5.zip |
Fix seeking on swcodec, but probably break some cases of skipping. Another important rework here, buffer management is serialized along with most other operations on the audio thread. This has some minor performance issues on ipod that can lead to audio skips during buffer fill as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9529 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/gui/gwps-common.c | 6 | ||||
-rw-r--r-- | apps/playback.c | 194 |
2 files changed, 97 insertions, 103 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index 231aa28162..41e20ecadd 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c | |||
@@ -2347,7 +2347,11 @@ bool ffwd_rew(int button) | |||
2347 | wps_state.id3 && wps_state.id3->length ) | 2347 | wps_state.id3 && wps_state.id3->length ) |
2348 | { | 2348 | { |
2349 | if (!wps_state.paused) | 2349 | if (!wps_state.paused) |
2350 | #if (CONFIG_CODEC == SWCODEC) | ||
2351 | audio_pre_ff_rewind(); | ||
2352 | #else | ||
2350 | audio_pause(); | 2353 | audio_pause(); |
2354 | #endif | ||
2351 | #if CONFIG_KEYPAD == PLAYER_PAD | 2355 | #if CONFIG_KEYPAD == PLAYER_PAD |
2352 | FOR_NB_SCREENS(i) | 2356 | FOR_NB_SCREENS(i) |
2353 | gui_wps[i].display->stop_scroll(); | 2357 | gui_wps[i].display->stop_scroll(); |
@@ -2399,8 +2403,10 @@ bool ffwd_rew(int button) | |||
2399 | ff_rewind_count = 0; | 2403 | ff_rewind_count = 0; |
2400 | wps_state.ff_rewind = false; | 2404 | wps_state.ff_rewind = false; |
2401 | status_set_ffmode(0); | 2405 | status_set_ffmode(0); |
2406 | #if (CONFIG_CODEC != SWCODEC) | ||
2402 | if (!wps_state.paused) | 2407 | if (!wps_state.paused) |
2403 | audio_resume(); | 2408 | audio_resume(); |
2409 | #endif | ||
2404 | #ifdef HAVE_LCD_CHARCELLS | 2410 | #ifdef HAVE_LCD_CHARCELLS |
2405 | gui_wps_display(); | 2411 | gui_wps_display(); |
2406 | #endif | 2412 | #endif |
diff --git a/apps/playback.c b/apps/playback.c index aa48dd9bae..6baf683342 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -70,7 +70,7 @@ | |||
70 | static volatile bool audio_codec_loaded; | 70 | static volatile bool audio_codec_loaded; |
71 | static volatile bool voice_codec_loaded; | 71 | static volatile bool voice_codec_loaded; |
72 | static volatile bool playing; | 72 | static volatile bool playing; |
73 | static volatile bool seeking; | 73 | static volatile bool paused; |
74 | 74 | ||
75 | #define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec" | 75 | #define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec" |
76 | #define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec" | 76 | #define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec" |
@@ -104,6 +104,7 @@ enum { | |||
104 | Q_AUDIO_DIR_NEXT, | 104 | Q_AUDIO_DIR_NEXT, |
105 | Q_AUDIO_DIR_PREV, | 105 | Q_AUDIO_DIR_PREV, |
106 | Q_AUDIO_POSTINIT, | 106 | Q_AUDIO_POSTINIT, |
107 | Q_AUDIO_CHECK_BUFFER, | ||
107 | 108 | ||
108 | Q_CODEC_LOAD, | 109 | Q_CODEC_LOAD, |
109 | Q_CODEC_LOAD_DISK, | 110 | Q_CODEC_LOAD_DISK, |
@@ -454,6 +455,9 @@ static void advance_buffer_counters(size_t amount) { | |||
454 | ci.curpos += amount; | 455 | ci.curpos += amount; |
455 | cur_ti->available -= amount; | 456 | cur_ti->available -= amount; |
456 | filebufused -= amount; | 457 | filebufused -= amount; |
458 | |||
459 | if (!pcmbuf_is_lowdata() && !mutex_bufferfill.locked) | ||
460 | queue_post(&audio_queue, Q_AUDIO_CHECK_BUFFER, 0); | ||
457 | } | 461 | } |
458 | 462 | ||
459 | /* copy up-to size bytes into ptr and return the actual size copied */ | 463 | /* copy up-to size bytes into ptr and return the actual size copied */ |
@@ -476,6 +480,7 @@ size_t codec_filebuf_callback(void *ptr, size_t size) | |||
476 | 480 | ||
477 | /* Let the disk buffer catch fill until enough data is available */ | 481 | /* Let the disk buffer catch fill until enough data is available */ |
478 | while (copy_n > cur_ti->available) { | 482 | while (copy_n > cur_ti->available) { |
483 | queue_post(&audio_queue, Q_AUDIO_CHECK_BUFFER, 0); | ||
479 | yield(); | 484 | yield(); |
480 | if (ci.stop_codec || ci.reload_codec) | 485 | if (ci.stop_codec || ci.reload_codec) |
481 | return 0; | 486 | return 0; |
@@ -550,7 +555,7 @@ void* codec_request_buffer_callback(size_t *realsize, size_t reqsize) | |||
550 | return voice_request_data(realsize, reqsize); | 555 | return voice_request_data(realsize, reqsize); |
551 | } | 556 | } |
552 | 557 | ||
553 | if (ci.stop_codec || !playing) { | 558 | if (!playing) { |
554 | *realsize = 0; | 559 | *realsize = 0; |
555 | return NULL; | 560 | return NULL; |
556 | } | 561 | } |
@@ -562,6 +567,7 @@ void* codec_request_buffer_callback(size_t *realsize, size_t reqsize) | |||
562 | } | 567 | } |
563 | 568 | ||
564 | while (copy_n > cur_ti->available) { | 569 | while (copy_n > cur_ti->available) { |
570 | queue_post(&audio_queue, Q_AUDIO_CHECK_BUFFER, 0); | ||
565 | yield(); | 571 | yield(); |
566 | if (ci.stop_codec || ci.reload_codec) { | 572 | if (ci.stop_codec || ci.reload_codec) { |
567 | *realsize = 0; | 573 | *realsize = 0; |
@@ -618,11 +624,7 @@ static bool rebuffer_and_seek(size_t newpos) | |||
618 | 624 | ||
619 | mutex_unlock(&mutex_bufferfill); | 625 | mutex_unlock(&mutex_bufferfill); |
620 | 626 | ||
621 | while (cur_ti->available == 0 && cur_ti->filerem > 0) { | 627 | queue_post(&audio_queue, Q_AUDIO_CHECK_BUFFER, 0); |
622 | sleep(1); | ||
623 | if (ci.stop_codec || ci.reload_codec || !queue_empty(&audio_queue)) | ||
624 | return false; | ||
625 | } | ||
626 | 628 | ||
627 | return true; | 629 | return true; |
628 | } | 630 | } |
@@ -644,6 +646,7 @@ void codec_advance_buffer_callback(size_t amount) | |||
644 | while (amount > cur_ti->available && filling) | 646 | while (amount > cur_ti->available && filling) |
645 | sleep(1); | 647 | sleep(1); |
646 | 648 | ||
649 | /* This should not happen */ | ||
647 | if (amount > cur_ti->available) { | 650 | if (amount > cur_ti->available) { |
648 | if (!rebuffer_and_seek(ci.curpos + amount)) | 651 | if (!rebuffer_and_seek(ci.curpos + amount)) |
649 | ci.stop_codec = true; | 652 | ci.stop_codec = true; |
@@ -682,9 +685,11 @@ void codec_seek_complete_callback(void) | |||
682 | if (pcm_is_paused()) { | 685 | if (pcm_is_paused()) { |
683 | /* If this is not a seamless seek, clear the buffer */ | 686 | /* If this is not a seamless seek, clear the buffer */ |
684 | pcmbuf_play_stop(); | 687 | pcmbuf_play_stop(); |
688 | /* If playback was not 'deliberately' paused, unpause now */ | ||
689 | if (!paused) | ||
690 | pcmbuf_pause(false); | ||
685 | } | 691 | } |
686 | ci.seek_time = 0; | 692 | ci.seek_time = 0; |
687 | seeking = false; | ||
688 | } | 693 | } |
689 | 694 | ||
690 | bool codec_seek_buffer_callback(size_t newpos) | 695 | bool codec_seek_buffer_callback(size_t newpos) |
@@ -852,7 +857,6 @@ void strip_id3v1_tag(void) | |||
852 | 857 | ||
853 | static void audio_fill_file_buffer(void) | 858 | static void audio_fill_file_buffer(void) |
854 | { | 859 | { |
855 | unsigned long i; | ||
856 | size_t size; | 860 | size_t size; |
857 | size_t copy_n; | 861 | size_t copy_n; |
858 | int rc; | 862 | int rc; |
@@ -865,9 +869,8 @@ static void audio_fill_file_buffer(void) | |||
865 | tracks[track_widx].codecsize = 0; | 869 | tracks[track_widx].codecsize = 0; |
866 | 870 | ||
867 | mutex_lock(&mutex_bufferfill); | 871 | mutex_lock(&mutex_bufferfill); |
868 | i = 0; | ||
869 | size = MIN(tracks[track_widx].filerem, AUDIO_FILL_CYCLE); | 872 | size = MIN(tracks[track_widx].filerem, AUDIO_FILL_CYCLE); |
870 | while (i < size) { | 873 | while (size > 0) { |
871 | /* Give codecs some processing time. */ | 874 | /* Give codecs some processing time. */ |
872 | yield_codecs(); | 875 | yield_codecs(); |
873 | 876 | ||
@@ -884,12 +887,16 @@ static void audio_fill_file_buffer(void) | |||
884 | buf_widx += rc; | 887 | buf_widx += rc; |
885 | if (buf_widx >= filebuflen) | 888 | if (buf_widx >= filebuflen) |
886 | buf_widx -= filebuflen; | 889 | buf_widx -= filebuflen; |
887 | i += rc; | ||
888 | tracks[track_widx].available += rc; | 890 | tracks[track_widx].available += rc; |
889 | tracks[track_widx].filerem -= rc; | 891 | tracks[track_widx].filerem -= rc; |
890 | tracks[track_widx].filepos += rc; | 892 | tracks[track_widx].filepos += rc; |
891 | filebufused += rc; | 893 | filebufused += rc; |
892 | fill_bytesleft -= rc; | 894 | fill_bytesleft -= rc; |
895 | if ((unsigned)rc > size) { | ||
896 | rc = size; | ||
897 | logf("audio_fill_file_buffer read past end of file\n"); | ||
898 | } | ||
899 | size -= rc; | ||
893 | } | 900 | } |
894 | 901 | ||
895 | if (tracks[track_widx].filerem == 0) { | 902 | if (tracks[track_widx].filerem == 0) { |
@@ -1092,15 +1099,12 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
1092 | char *trackname; | 1099 | char *trackname; |
1093 | int fd = -1; | 1100 | int fd = -1; |
1094 | off_t size; | 1101 | off_t size; |
1095 | int rc, i; | ||
1096 | int copy_n; | ||
1097 | char msgbuf[80]; | 1102 | char msgbuf[80]; |
1098 | 1103 | ||
1099 | /* Stop buffer filling if there is no free track entries. | 1104 | /* Stop buffer filling if there is no free track entries. |
1100 | Don't fill up the last track entry (we wan't to store next track | 1105 | Don't fill up the last track entry (we wan't to store next track |
1101 | metadata there). */ | 1106 | metadata there). */ |
1102 | if (track_count >= MAX_TRACK - 1) { | 1107 | if (track_count >= MAX_TRACK - 1) { |
1103 | fill_bytesleft = 0; | ||
1104 | return false; | 1108 | return false; |
1105 | } | 1109 | } |
1106 | 1110 | ||
@@ -1196,7 +1200,6 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
1196 | set_filebuf_watermark(buffer_margin); | 1200 | set_filebuf_watermark(buffer_margin); |
1197 | tracks[track_widx].id3.elapsed = 0; | 1201 | tracks[track_widx].id3.elapsed = 0; |
1198 | 1202 | ||
1199 | /* Starting playback from an offset is only support in MPA at the moment */ | ||
1200 | if (offset > 0) { | 1203 | if (offset > 0) { |
1201 | switch (tracks[track_widx].id3.codectype) { | 1204 | switch (tracks[track_widx].id3.codectype) { |
1202 | case AFMT_MPA_L2: | 1205 | case AFMT_MPA_L2: |
@@ -1231,64 +1234,27 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
1231 | codec_track_changed(); | 1234 | codec_track_changed(); |
1232 | } | 1235 | } |
1233 | 1236 | ||
1234 | /* Do some initial file buffering. */ | 1237 | if (current_fd >= 0) { |
1235 | mutex_lock(&mutex_bufferfill); | 1238 | close(current_fd); |
1236 | i = tracks[track_widx].start_pos; | ||
1237 | size = MIN(size, AUDIO_FILL_CYCLE); | ||
1238 | while (i < size) { | ||
1239 | /* Give codecs some processing time to prevent glitches. */ | ||
1240 | yield_codecs(); | ||
1241 | |||
1242 | if (fill_bytesleft == 0) | ||
1243 | break ; | ||
1244 | |||
1245 | copy_n = MIN(conf_filechunk, filebuflen - buf_widx); | ||
1246 | copy_n = MIN(size - i, copy_n); | ||
1247 | copy_n = MIN((int)fill_bytesleft, copy_n); | ||
1248 | rc = read(fd, &filebuf[buf_widx], copy_n); | ||
1249 | if (rc < copy_n) { | ||
1250 | logf("File error!"); | ||
1251 | tracks[track_widx].filesize = 0; | ||
1252 | tracks[track_widx].filerem = 0; | ||
1253 | close(fd); | ||
1254 | mutex_unlock(&mutex_bufferfill); | ||
1255 | return false; | ||
1256 | } | ||
1257 | buf_widx += rc; | ||
1258 | if (buf_widx >= filebuflen) | ||
1259 | buf_widx -= filebuflen; | ||
1260 | i += rc; | ||
1261 | tracks[track_widx].available += rc; | ||
1262 | tracks[track_widx].filerem -= rc; | ||
1263 | filebufused += rc; | ||
1264 | fill_bytesleft -= rc; | ||
1265 | } | 1239 | } |
1266 | mutex_unlock(&mutex_bufferfill); | 1240 | current_fd = fd; |
1241 | |||
1242 | audio_fill_file_buffer(); | ||
1267 | 1243 | ||
1268 | if (!start_play) | 1244 | if (!start_play) |
1269 | track_count++; | 1245 | track_count++; |
1270 | 1246 | ||
1271 | tracks[track_widx].filepos = i; | ||
1272 | |||
1273 | if (current_fd >= 0) { | ||
1274 | close(current_fd); | ||
1275 | current_fd = -1; | ||
1276 | } | ||
1277 | |||
1278 | /* Leave the file handle open for faster buffer refill. */ | 1247 | /* Leave the file handle open for faster buffer refill. */ |
1279 | if (tracks[track_widx].filerem != 0) { | 1248 | if (tracks[track_widx].filerem != 0) { |
1280 | current_fd = fd; | ||
1281 | logf("Partially buf:%d", tracks[track_widx].available); | 1249 | logf("Partially buf:%d", tracks[track_widx].available); |
1282 | } else { | 1250 | } else { |
1283 | logf("Completely buf."); | 1251 | logf("Completely buf."); |
1284 | close(fd); | 1252 | close(fd); |
1285 | 1253 | ||
1286 | strip_id3v1_tag(); | ||
1287 | |||
1288 | if (++track_widx >= MAX_TRACK) { | 1254 | if (++track_widx >= MAX_TRACK) { |
1289 | track_widx = 0; | 1255 | track_widx = 0; |
1290 | } | 1256 | } |
1291 | tracks[track_widx].filerem = 0; | 1257 | tracks[track_widx].filesize = 0; |
1292 | } | 1258 | } |
1293 | 1259 | ||
1294 | return true; | 1260 | return true; |
@@ -1337,7 +1303,7 @@ static void stop_codec_flush(void) | |||
1337 | pcmbuf_pause(true); | 1303 | pcmbuf_pause(true); |
1338 | while (audio_codec_loaded) | 1304 | while (audio_codec_loaded) |
1339 | yield(); | 1305 | yield(); |
1340 | pcmbuf_pause(false); | 1306 | pcmbuf_pause(paused); |
1341 | } | 1307 | } |
1342 | 1308 | ||
1343 | static void audio_stop_playback(bool resume) | 1309 | static void audio_stop_playback(bool resume) |
@@ -1348,6 +1314,7 @@ static void audio_stop_playback(bool resume) | |||
1348 | playing = false; | 1314 | playing = false; |
1349 | filling = false; | 1315 | filling = false; |
1350 | stop_codec_flush(); | 1316 | stop_codec_flush(); |
1317 | paused = false; | ||
1351 | if (current_fd >= 0) { | 1318 | if (current_fd >= 0) { |
1352 | close(current_fd); | 1319 | close(current_fd); |
1353 | current_fd = -1; | 1320 | current_fd = -1; |
@@ -1467,10 +1434,10 @@ static void initialize_buffer_fill(void) | |||
1467 | static void audio_check_buffer(void) | 1434 | static void audio_check_buffer(void) |
1468 | { | 1435 | { |
1469 | /* Start buffer filling as necessary. */ | 1436 | /* Start buffer filling as necessary. */ |
1470 | if ((!conf_watermark || filebufused > conf_watermark | 1437 | if ((!conf_watermark || filebufused > conf_watermark || !playing |
1471 | || !queue_empty(&audio_queue) || !playing || ci.stop_codec | 1438 | || ci.stop_codec || ci.reload_codec || playlist_end) |
1472 | || ci.reload_codec || playlist_end) && !filling) | 1439 | && !filling) |
1473 | return ; | 1440 | return; |
1474 | 1441 | ||
1475 | mutex_lock(&mutex_bufferfill); | 1442 | mutex_lock(&mutex_bufferfill); |
1476 | initialize_buffer_fill(); | 1443 | initialize_buffer_fill(); |
@@ -1485,23 +1452,33 @@ static void audio_check_buffer(void) | |||
1485 | fill_bytesleft = 0; | 1452 | fill_bytesleft = 0; |
1486 | } | 1453 | } |
1487 | 1454 | ||
1488 | /* Try to load remainings of the file. */ | 1455 | /* If the current track has been started */ |
1489 | if (tracks[track_widx].filerem > 0) | 1456 | if (tracks[track_widx].filesize > 0) |
1490 | audio_fill_file_buffer(); | 1457 | { |
1491 | 1458 | /* Try to load remainings of the file. */ | |
1492 | /* Increase track write index as necessary. */ | 1459 | if (tracks[track_widx].filerem > 0) |
1493 | if (tracks[track_widx].filerem == 0 && tracks[track_widx].filesize != 0) { | 1460 | { |
1494 | if (++track_widx == MAX_TRACK) | 1461 | audio_fill_file_buffer(); |
1495 | track_widx = 0; | 1462 | } |
1463 | if (tracks[track_widx].filerem == 0) { | ||
1464 | if (++track_widx == MAX_TRACK) | ||
1465 | track_widx = 0; | ||
1466 | tracks[track_widx].filesize = 0; | ||
1467 | } | ||
1468 | else | ||
1469 | { | ||
1470 | /* Done filling, couldn't read that whole file */ | ||
1471 | fill_bytesleft = 0; | ||
1472 | } | ||
1496 | } | 1473 | } |
1497 | 1474 | /* Otherwise, load a new track */ | |
1498 | /* Load new files to fill the entire buffer. */ | 1475 | else if (audio_load_track(0, false, last_peek_offset + 1)) |
1499 | if (audio_load_track(0, false, last_peek_offset + 1)) { | 1476 | { |
1500 | if (conf_bufferlimit) | 1477 | if (conf_bufferlimit) |
1501 | fill_bytesleft = 0; | 1478 | fill_bytesleft = 0; |
1502 | } | 1479 | } else { |
1503 | else if (tracks[track_widx].filerem == 0) | ||
1504 | fill_bytesleft = 0; | 1480 | fill_bytesleft = 0; |
1481 | } | ||
1505 | 1482 | ||
1506 | if (fill_bytesleft <= 0) | 1483 | if (fill_bytesleft <= 0) |
1507 | { | 1484 | { |
@@ -1581,9 +1558,12 @@ static int skip_next_track(bool inside_codec_thread) | |||
1581 | track_ridx = 0; | 1558 | track_ridx = 0; |
1582 | 1559 | ||
1583 | /* Wait for new track data. */ | 1560 | /* Wait for new track data. */ |
1584 | while (tracks[track_ridx].filesize == 0 && filling | 1561 | while (tracks[track_ridx].filesize == 0 && filling) |
1585 | && !ci.stop_codec) | 1562 | { |
1586 | yield(); | 1563 | yield(); |
1564 | if (ci.stop_codec) | ||
1565 | return SKIP_FAIL; | ||
1566 | } | ||
1587 | 1567 | ||
1588 | if (tracks[track_ridx].filesize <= 0) | 1568 | if (tracks[track_ridx].filesize <= 0) |
1589 | { | 1569 | { |
@@ -1604,18 +1584,21 @@ static int skip_next_track(bool inside_codec_thread) | |||
1604 | return SKIP_OK_DISK; | 1584 | return SKIP_OK_DISK; |
1605 | } | 1585 | } |
1606 | 1586 | ||
1587 | /* Wind the buffer forward to the end of the current track */ | ||
1607 | buf_ridx += cur_ti->available; | 1588 | buf_ridx += cur_ti->available; |
1608 | filebufused -= cur_ti->available; | 1589 | filebufused -= cur_ti->available; |
1609 | 1590 | ||
1591 | /* Move to the new track */ | ||
1610 | cur_ti = &tracks[track_ridx]; | 1592 | cur_ti = &tracks[track_ridx]; |
1593 | /* Wind past the new track's codec */ | ||
1611 | buf_ridx += cur_ti->codecsize; | 1594 | buf_ridx += cur_ti->codecsize; |
1612 | filebufused -= cur_ti->codecsize; | 1595 | filebufused -= cur_ti->codecsize; |
1596 | |||
1597 | /* Check and handle buffer wrapping */ | ||
1613 | if (buf_ridx >= filebuflen) | 1598 | if (buf_ridx >= filebuflen) |
1614 | buf_ridx -= filebuflen; | 1599 | buf_ridx -= filebuflen; |
1615 | audio_update_trackinfo(); | ||
1616 | 1600 | ||
1617 | if (!filling) | 1601 | audio_update_trackinfo(); |
1618 | pcmbuf_set_boost_mode(false); | ||
1619 | 1602 | ||
1620 | return SKIP_OK_RAM; | 1603 | return SKIP_OK_RAM; |
1621 | } | 1604 | } |
@@ -1628,8 +1611,8 @@ static int skip_previous_track(bool inside_codec_thread) | |||
1628 | track_ridx += MAX_TRACK; | 1611 | track_ridx += MAX_TRACK; |
1629 | 1612 | ||
1630 | if (tracks[track_ridx].filesize == 0 || | 1613 | if (tracks[track_ridx].filesize == 0 || |
1631 | filebufused+ci.curpos+tracks[track_ridx].filesize | 1614 | filebufused+ci.curpos + tracks[track_ridx].filesize > filebuflen) |
1632 | /*+ (off_t)tracks[track_ridx].codecsize*/ > filebuflen) { | 1615 | { |
1633 | logf("Loading from disk..."); | 1616 | logf("Loading from disk..."); |
1634 | ci.reload_codec = true; | 1617 | ci.reload_codec = true; |
1635 | /* Stop playback. */ | 1618 | /* Stop playback. */ |
@@ -1645,16 +1628,23 @@ static int skip_previous_track(bool inside_codec_thread) | |||
1645 | return SKIP_OK_DISK; | 1628 | return SKIP_OK_DISK; |
1646 | } | 1629 | } |
1647 | 1630 | ||
1631 | /* Rewind the buffer to the beginning of the playing track */ | ||
1648 | buf_ridx -= ci.curpos + cur_ti->codecsize; | 1632 | buf_ridx -= ci.curpos + cur_ti->codecsize; |
1649 | filebufused += ci.curpos + cur_ti->codecsize; | 1633 | filebufused += ci.curpos + cur_ti->codecsize; |
1634 | /* Rewind the track to its beginning */ | ||
1650 | cur_ti->available = cur_ti->filesize - cur_ti->filerem; | 1635 | cur_ti->available = cur_ti->filesize - cur_ti->filerem; |
1651 | 1636 | ||
1637 | /* Move to the new track */ | ||
1652 | cur_ti = &tracks[track_ridx]; | 1638 | cur_ti = &tracks[track_ridx]; |
1639 | /* Rewind the buffer to the beginning of the new track */ | ||
1640 | buf_ridx -= cur_ti->filesize; | ||
1653 | filebufused += cur_ti->filesize; | 1641 | filebufused += cur_ti->filesize; |
1642 | /* Reset to the beginning of the new track */ | ||
1654 | cur_ti->available = cur_ti->filesize; | 1643 | cur_ti->available = cur_ti->filesize; |
1655 | if (buf_ridx < cur_ti->filesize) | 1644 | |
1645 | /* Check and handle buffer wrapping */ | ||
1646 | if (buf_ridx <= 0) | ||
1656 | buf_ridx += filebuflen; | 1647 | buf_ridx += filebuflen; |
1657 | buf_ridx -= cur_ti->filesize; | ||
1658 | 1648 | ||
1659 | audio_update_trackinfo(); | 1649 | audio_update_trackinfo(); |
1660 | 1650 | ||
@@ -1806,18 +1796,11 @@ void audio_thread(void) | |||
1806 | playback_init(); | 1796 | playback_init(); |
1807 | 1797 | ||
1808 | while (1) { | 1798 | while (1) { |
1809 | if (!play_pending && queue_empty(&audio_queue)) | 1799 | if (play_pending) |
1810 | { | 1800 | queue_wait_w_tmo(&audio_queue, &ev, 0); |
1811 | yield_codecs(); | ||
1812 | audio_check_buffer(); | ||
1813 | } | ||
1814 | else | 1801 | else |
1815 | { | 1802 | queue_wait(&audio_queue, &ev); |
1816 | // ata_spin(); | ||
1817 | sleep(1); | ||
1818 | } | ||
1819 | 1803 | ||
1820 | queue_wait_w_tmo(&audio_queue, &ev, 0); | ||
1821 | if (ev.id == SYS_TIMEOUT && play_pending) | 1804 | if (ev.id == SYS_TIMEOUT && play_pending) |
1822 | { | 1805 | { |
1823 | ev.id = Q_AUDIO_PLAY; | 1806 | ev.id = Q_AUDIO_PLAY; |
@@ -1825,6 +1808,9 @@ void audio_thread(void) | |||
1825 | } | 1808 | } |
1826 | 1809 | ||
1827 | switch (ev.id) { | 1810 | switch (ev.id) { |
1811 | case Q_AUDIO_CHECK_BUFFER: | ||
1812 | audio_check_buffer(); | ||
1813 | break; | ||
1828 | case Q_AUDIO_PLAY: | 1814 | case Q_AUDIO_PLAY: |
1829 | /* Don't start playing immediately if user is skipping tracks | 1815 | /* Don't start playing immediately if user is skipping tracks |
1830 | * fast to prevent UI lag. */ | 1816 | * fast to prevent UI lag. */ |
@@ -1875,11 +1861,13 @@ void audio_thread(void) | |||
1875 | case Q_AUDIO_PAUSE: | 1861 | case Q_AUDIO_PAUSE: |
1876 | logf("audio_pause"); | 1862 | logf("audio_pause"); |
1877 | pcmbuf_pause(true); | 1863 | pcmbuf_pause(true); |
1864 | paused = true; | ||
1878 | break ; | 1865 | break ; |
1879 | 1866 | ||
1880 | case Q_AUDIO_RESUME: | 1867 | case Q_AUDIO_RESUME: |
1881 | logf("audio_resume"); | 1868 | logf("audio_resume"); |
1882 | pcmbuf_pause(false); | 1869 | pcmbuf_pause(false); |
1870 | paused = false; | ||
1883 | break ; | 1871 | break ; |
1884 | 1872 | ||
1885 | case Q_AUDIO_NEXT: | 1873 | case Q_AUDIO_NEXT: |
@@ -2264,16 +2252,15 @@ void audio_prev_dir(void) | |||
2264 | queue_post(&audio_queue, Q_AUDIO_DIR_PREV, 0); | 2252 | queue_post(&audio_queue, Q_AUDIO_DIR_PREV, 0); |
2265 | } | 2253 | } |
2266 | 2254 | ||
2255 | void audio_pre_ff_rewind(void) { | ||
2256 | logf("pre ff/rewind"); | ||
2257 | pcmbuf_pause(true); | ||
2258 | } | ||
2259 | |||
2267 | void audio_ff_rewind(long newpos) | 2260 | void audio_ff_rewind(long newpos) |
2268 | { | 2261 | { |
2269 | logf("ff/rewind: %d", newpos); | 2262 | logf("ff/rewind: %d", newpos); |
2270 | seeking = true; | ||
2271 | queue_post(&audio_queue, Q_AUDIO_FF_REWIND, (int *)newpos); | 2263 | queue_post(&audio_queue, Q_AUDIO_FF_REWIND, (int *)newpos); |
2272 | /* This is a hack, the correct solution is to report back to | ||
2273 | * the caller when the seek is complete. */ | ||
2274 | while (seeking) { | ||
2275 | yield(); | ||
2276 | } | ||
2277 | } | 2264 | } |
2278 | 2265 | ||
2279 | void audio_flush_and_reload_tracks(void) | 2266 | void audio_flush_and_reload_tracks(void) |
@@ -2293,7 +2280,7 @@ int audio_status(void) | |||
2293 | if (playing) | 2280 | if (playing) |
2294 | ret |= AUDIO_STATUS_PLAY; | 2281 | ret |= AUDIO_STATUS_PLAY; |
2295 | 2282 | ||
2296 | if (pcm_is_paused()) | 2283 | if (paused) |
2297 | ret |= AUDIO_STATUS_PAUSE; | 2284 | ret |= AUDIO_STATUS_PAUSE; |
2298 | 2285 | ||
2299 | return ret; | 2286 | return ret; |
@@ -2596,6 +2583,7 @@ void audio_preinit(void) | |||
2596 | filling = false; | 2583 | filling = false; |
2597 | current_codec = CODEC_IDX_AUDIO; | 2584 | current_codec = CODEC_IDX_AUDIO; |
2598 | playing = false; | 2585 | playing = false; |
2586 | paused = false; | ||
2599 | audio_codec_loaded = false; | 2587 | audio_codec_loaded = false; |
2600 | voice_is_playing = false; | 2588 | voice_is_playing = false; |
2601 | track_changed = false; | 2589 | track_changed = false; |