diff options
author | Brandon Low <lostlogic@rockbox.org> | 2006-04-17 17:05:05 +0000 |
---|---|---|
committer | Brandon Low <lostlogic@rockbox.org> | 2006-04-17 17:05:05 +0000 |
commit | 98097d23ec15cb1978e0e75dc8d02753e73ad73d (patch) | |
tree | 7221ab39469482687e81d784045339b9dbe9d7c1 /apps | |
parent | 19bd1a4cebcbe406cf9cf53111004b5655609df7 (diff) | |
download | rockbox-98097d23ec15cb1978e0e75dc8d02753e73ad73d.tar.gz rockbox-98097d23ec15cb1978e0e75dc8d02753e73ad73d.zip |
Misc. minor fixes: Guarantee aligned buffer. Enable load-codec-from-disk if a new track requires a different codec than the playing track, but does not already have it on the buffer. Stop playback immediately on a manual track skip. Handle seeking a distance greater than the size of the audio buffer. Enforce the 'no malloc for voice codec'.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9704 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/playback.c | 233 |
1 files changed, 123 insertions, 110 deletions
diff --git a/apps/playback.c b/apps/playback.c index 1aa595b131..0a43d958b9 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -401,11 +401,17 @@ bool codec_pcmbuf_insert_callback(const char *buf, size_t length) | |||
401 | 401 | ||
402 | void* get_codec_memory_callback(size_t *size) | 402 | void* get_codec_memory_callback(size_t *size) |
403 | { | 403 | { |
404 | if (current_codec == CODEC_IDX_VOICE) | ||
405 | { | ||
406 | *size = 0; | ||
407 | return NULL; | ||
408 | } | ||
409 | |||
404 | *size = MALLOC_BUFSIZE; | 410 | *size = MALLOC_BUFSIZE; |
405 | if (voice_codec_loaded) | 411 | if (voice_codec_loaded) |
406 | return &audiobuf[talk_get_bufsize()]; | 412 | return &audiobuf[talk_get_bufsize()]; |
407 | 413 | else | |
408 | return &audiobuf[0]; | 414 | return audiobuf; |
409 | } | 415 | } |
410 | 416 | ||
411 | static void pcmbuf_position_callback(size_t size) ICODE_ATTR; | 417 | static void pcmbuf_position_callback(size_t size) ICODE_ATTR; |
@@ -662,24 +668,20 @@ size_t buffer_count_tracks(int from_track, int to_track) { | |||
662 | return amount; | 668 | return amount; |
663 | } | 669 | } |
664 | 670 | ||
665 | static bool buffer_wind_forward(bool require_codec, | 671 | static bool buffer_wind_forward(int new_track_ridx, int old_track_ridx) |
666 | int new_track_ridx, int old_track_ridx) | ||
667 | { | 672 | { |
668 | size_t amount; | 673 | size_t amount; |
669 | 674 | ||
670 | if (require_codec && !tracks[new_track_ridx].has_codec) | ||
671 | return false; | ||
672 | |||
673 | /* Start with the remainder of the previously playing track */ | 675 | /* Start with the remainder of the previously playing track */ |
674 | amount = tracks[old_track_ridx].filesize - ci.curpos; | 676 | amount = tracks[old_track_ridx].filesize - ci.curpos; |
675 | /* Then collect all data from tracks in between them */ | 677 | /* Then collect all data from tracks in between them */ |
676 | amount += buffer_count_tracks(old_track_ridx, new_track_ridx); | 678 | amount += buffer_count_tracks(old_track_ridx, new_track_ridx); |
677 | 679 | ||
678 | logf("bwf:%ldB",amount); | ||
679 | |||
680 | if (amount > filebufused) | 680 | if (amount > filebufused) |
681 | return false; | 681 | return false; |
682 | 682 | ||
683 | logf("bwf:%ldB",amount); | ||
684 | |||
683 | /* Wind the buffer to the beginning of the target track or its codec */ | 685 | /* Wind the buffer to the beginning of the target track or its codec */ |
684 | buf_ridx += amount; | 686 | buf_ridx += amount; |
685 | filebufused -= amount; | 687 | filebufused -= amount; |
@@ -690,8 +692,7 @@ static bool buffer_wind_forward(bool require_codec, | |||
690 | return true; | 692 | return true; |
691 | } | 693 | } |
692 | 694 | ||
693 | static bool buffer_wind_backward(bool require_codec, | 695 | static bool buffer_wind_backward(int new_track_ridx, int old_track_ridx) { |
694 | int new_track_ridx, int old_track_ridx) { | ||
695 | /* Available buffer data */ | 696 | /* Available buffer data */ |
696 | size_t buf_back = buf_ridx; | 697 | size_t buf_back = buf_ridx; |
697 | if (buf_ridx < buf_widx) | 698 | if (buf_ridx < buf_widx) |
@@ -712,15 +713,9 @@ static bool buffer_wind_backward(bool require_codec, | |||
712 | tracks[old_track_ridx].filesize - tracks[old_track_ridx].filerem; | 713 | tracks[old_track_ridx].filesize - tracks[old_track_ridx].filerem; |
713 | } | 714 | } |
714 | 715 | ||
715 | /* If the track needs to load its codec from the buffer */ | 716 | /* If the codec was ever buffered */ |
716 | if (require_codec || | 717 | if (tracks[new_track_ridx].codecsize) |
717 | get_codec_base_type(tracks[old_track_ridx].id3.codectype) != | ||
718 | get_codec_base_type(tracks[new_track_ridx].id3.codectype)) | ||
719 | { | 718 | { |
720 | /* If the codec was never buffered */ | ||
721 | if (!tracks[new_track_ridx].codecsize) | ||
722 | return false; | ||
723 | |||
724 | /* Add the codec to the needed size */ | 719 | /* Add the codec to the needed size */ |
725 | amount += tracks[new_track_ridx].codecsize; | 720 | amount += tracks[new_track_ridx].codecsize; |
726 | tracks[new_track_ridx].has_codec = true; | 721 | tracks[new_track_ridx].has_codec = true; |
@@ -782,7 +777,7 @@ static void audio_rebuffer(void) | |||
782 | audio_fill_file_buffer(false, true, 0); | 777 | audio_fill_file_buffer(false, true, 0); |
783 | } | 778 | } |
784 | 779 | ||
785 | static void audio_check_new_track(bool require_codec) | 780 | static void audio_check_new_track(void) |
786 | { | 781 | { |
787 | int track_count = audio_track_count(); | 782 | int track_count = audio_track_count(); |
788 | int old_track_ridx = track_ridx; | 783 | int old_track_ridx = track_ridx; |
@@ -836,7 +831,7 @@ static void audio_check_new_track(bool require_codec) | |||
836 | /* The track may be in memory, see if it really is */ | 831 | /* The track may be in memory, see if it really is */ |
837 | else if (forward) | 832 | else if (forward) |
838 | { | 833 | { |
839 | if (!buffer_wind_forward(require_codec, track_ridx, old_track_ridx)) | 834 | if (!buffer_wind_forward(track_ridx, old_track_ridx)) |
840 | audio_rebuffer(); | 835 | audio_rebuffer(); |
841 | } | 836 | } |
842 | else | 837 | else |
@@ -863,8 +858,7 @@ static void audio_check_new_track(bool require_codec) | |||
863 | } | 858 | } |
864 | if (taginfo_ready) | 859 | if (taginfo_ready) |
865 | { | 860 | { |
866 | if (!buffer_wind_backward( | 861 | if (!buffer_wind_backward(track_ridx, old_track_ridx)) |
867 | require_codec, track_ridx, old_track_ridx)) | ||
868 | audio_rebuffer(); | 862 | audio_rebuffer(); |
869 | } | 863 | } |
870 | else | 864 | else |
@@ -902,7 +896,10 @@ static void rebuffer_and_seek(size_t newpos) | |||
902 | 896 | ||
903 | /* Clear codec buffer. */ | 897 | /* Clear codec buffer. */ |
904 | filebufused = 0; | 898 | filebufused = 0; |
905 | buf_ridx = buf_widx = cur_ti->buf_idx + newpos; | 899 | buf_widx = cur_ti->buf_idx + newpos; |
900 | while (buf_widx >= filebuflen) | ||
901 | buf_widx -= filebuflen; | ||
902 | buf_ridx = buf_widx; | ||
906 | 903 | ||
907 | /* Write to the now current track */ | 904 | /* Write to the now current track */ |
908 | track_widx = track_ridx; | 905 | track_widx = track_ridx; |
@@ -962,7 +959,6 @@ void codec_advance_buffer_callback(size_t amount) | |||
962 | codec_set_offset_callback(ci.curpos); | 959 | codec_set_offset_callback(ci.curpos); |
963 | } | 960 | } |
964 | 961 | ||
965 | /* Unused as of today 2006, 04/14, will be removed for 3.0 */ | ||
966 | void codec_advance_buffer_loc_callback(void *ptr) | 962 | void codec_advance_buffer_loc_callback(void *ptr) |
967 | { | 963 | { |
968 | size_t amount; | 964 | size_t amount; |
@@ -971,6 +967,7 @@ void codec_advance_buffer_loc_callback(void *ptr) | |||
971 | amount = (size_t)ptr - (size_t)voicebuf; | 967 | amount = (size_t)ptr - (size_t)voicebuf; |
972 | else | 968 | else |
973 | amount = (size_t)ptr - (size_t)&filebuf[buf_ridx]; | 969 | amount = (size_t)ptr - (size_t)&filebuf[buf_ridx]; |
970 | |||
974 | codec_advance_buffer_callback(amount); | 971 | codec_advance_buffer_callback(amount); |
975 | } | 972 | } |
976 | 973 | ||
@@ -1178,7 +1175,7 @@ static void audio_read_file(void) | |||
1178 | 1175 | ||
1179 | /* If we're called and no file is open, this is an error */ | 1176 | /* If we're called and no file is open, this is an error */ |
1180 | if (current_fd < 0) { | 1177 | if (current_fd < 0) { |
1181 | logf("Zero fd in arf"); | 1178 | logf("Bad fd in arf"); |
1182 | /* Stop this buffer cycle immediately */ | 1179 | /* Stop this buffer cycle immediately */ |
1183 | fill_bytesleft = 0; | 1180 | fill_bytesleft = 0; |
1184 | /* Give some hope of miraculous recovery by forcing a track reload */ | 1181 | /* Give some hope of miraculous recovery by forcing a track reload */ |
@@ -1270,67 +1267,60 @@ static void codec_discard_codec_callback(void) | |||
1270 | } | 1267 | } |
1271 | } | 1268 | } |
1272 | 1269 | ||
1270 | static const char *get_codec_path(int codectype) { | ||
1271 | switch (codectype) { | ||
1272 | case AFMT_OGG_VORBIS: | ||
1273 | logf("Codec: Vorbis"); | ||
1274 | return CODEC_VORBIS; | ||
1275 | case AFMT_MPA_L1: | ||
1276 | case AFMT_MPA_L2: | ||
1277 | case AFMT_MPA_L3: | ||
1278 | logf("Codec: MPA L1/L2/L3"); | ||
1279 | return CODEC_MPA_L3; | ||
1280 | case AFMT_PCM_WAV: | ||
1281 | logf("Codec: PCM WAV"); | ||
1282 | return CODEC_WAV; | ||
1283 | case AFMT_FLAC: | ||
1284 | logf("Codec: FLAC"); | ||
1285 | return CODEC_FLAC; | ||
1286 | case AFMT_A52: | ||
1287 | logf("Codec: A52"); | ||
1288 | return CODEC_A52; | ||
1289 | case AFMT_MPC: | ||
1290 | logf("Codec: Musepack"); | ||
1291 | return CODEC_MPC; | ||
1292 | case AFMT_WAVPACK: | ||
1293 | logf("Codec: WAVPACK"); | ||
1294 | return CODEC_WAVPACK; | ||
1295 | case AFMT_ALAC: | ||
1296 | logf("Codec: ALAC"); | ||
1297 | return CODEC_ALAC; | ||
1298 | case AFMT_AAC: | ||
1299 | logf("Codec: AAC"); | ||
1300 | return CODEC_AAC; | ||
1301 | case AFMT_SHN: | ||
1302 | logf("Codec: SHN"); | ||
1303 | return CODEC_SHN; | ||
1304 | case AFMT_AIFF: | ||
1305 | logf("Codec: PCM AIFF"); | ||
1306 | return CODEC_AIFF; | ||
1307 | default: | ||
1308 | logf("Codec: Unsupported"); | ||
1309 | return NULL; | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1273 | static bool loadcodec(bool start_play) | 1313 | static bool loadcodec(bool start_play) |
1274 | { | 1314 | { |
1275 | size_t size; | 1315 | size_t size; |
1276 | int fd; | 1316 | int fd; |
1277 | int rc; | 1317 | int rc; |
1278 | const char *codec_path; | ||
1279 | size_t copy_n; | 1318 | size_t copy_n; |
1280 | int prev_track; | 1319 | int prev_track; |
1281 | 1320 | ||
1282 | switch (tracks[track_widx].id3.codectype) { | 1321 | const char *codec_path = get_codec_path(tracks[track_widx].id3.codectype); |
1283 | case AFMT_OGG_VORBIS: | 1322 | if (codec_path == NULL) |
1284 | logf("Codec: Vorbis"); | ||
1285 | codec_path = CODEC_VORBIS; | ||
1286 | break; | ||
1287 | case AFMT_MPA_L1: | ||
1288 | case AFMT_MPA_L2: | ||
1289 | case AFMT_MPA_L3: | ||
1290 | logf("Codec: MPA L1/L2/L3"); | ||
1291 | codec_path = CODEC_MPA_L3; | ||
1292 | break; | ||
1293 | case AFMT_PCM_WAV: | ||
1294 | logf("Codec: PCM WAV"); | ||
1295 | codec_path = CODEC_WAV; | ||
1296 | break; | ||
1297 | case AFMT_FLAC: | ||
1298 | logf("Codec: FLAC"); | ||
1299 | codec_path = CODEC_FLAC; | ||
1300 | break; | ||
1301 | case AFMT_A52: | ||
1302 | logf("Codec: A52"); | ||
1303 | codec_path = CODEC_A52; | ||
1304 | break; | ||
1305 | case AFMT_MPC: | ||
1306 | logf("Codec: Musepack"); | ||
1307 | codec_path = CODEC_MPC; | ||
1308 | break; | ||
1309 | case AFMT_WAVPACK: | ||
1310 | logf("Codec: WAVPACK"); | ||
1311 | codec_path = CODEC_WAVPACK; | ||
1312 | break; | ||
1313 | case AFMT_ALAC: | ||
1314 | logf("Codec: ALAC"); | ||
1315 | codec_path = CODEC_ALAC; | ||
1316 | break; | ||
1317 | case AFMT_AAC: | ||
1318 | logf("Codec: AAC"); | ||
1319 | codec_path = CODEC_AAC; | ||
1320 | break; | ||
1321 | case AFMT_SHN: | ||
1322 | logf("Codec: SHN"); | ||
1323 | codec_path = CODEC_SHN; | ||
1324 | break; | ||
1325 | case AFMT_AIFF: | ||
1326 | logf("Codec: PCM AIFF"); | ||
1327 | codec_path = CODEC_AIFF; | ||
1328 | break; | ||
1329 | default: | ||
1330 | logf("Codec: Unsupported"); | ||
1331 | codec_path = NULL; | ||
1332 | return false; | 1323 | return false; |
1333 | } | ||
1334 | 1324 | ||
1335 | tracks[track_widx].has_codec = false; | 1325 | tracks[track_widx].has_codec = false; |
1336 | tracks[track_widx].codecsize = 0; | 1326 | tracks[track_widx].codecsize = 0; |
@@ -1345,7 +1335,6 @@ static bool loadcodec(bool start_play) | |||
1345 | ci.taginfo_ready = &cur_ti->taginfo_ready; | 1335 | ci.taginfo_ready = &cur_ti->taginfo_ready; |
1346 | ci.curpos = 0; | 1336 | ci.curpos = 0; |
1347 | playing = true; | 1337 | playing = true; |
1348 | logf("Starting codec"); | ||
1349 | queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path); | 1338 | queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path); |
1350 | return true; | 1339 | return true; |
1351 | } | 1340 | } |
@@ -1376,7 +1365,7 @@ static bool loadcodec(bool start_play) | |||
1376 | 1365 | ||
1377 | size = filesize(fd); | 1366 | size = filesize(fd); |
1378 | /* Never load a partial codec */ | 1367 | /* Never load a partial codec */ |
1379 | if (filebuflen - filebufused < size) { | 1368 | if (fill_bytesleft < size) { |
1380 | logf("Not enough space"); | 1369 | logf("Not enough space"); |
1381 | fill_bytesleft = 0; | 1370 | fill_bytesleft = 0; |
1382 | close(fd); | 1371 | close(fd); |
@@ -1401,9 +1390,6 @@ static bool loadcodec(bool start_play) | |||
1401 | 1390 | ||
1402 | tracks[track_widx].codecsize += rc; | 1391 | tracks[track_widx].codecsize += rc; |
1403 | 1392 | ||
1404 | /* FIXME: This will spin around pretty quickly, but still requires | ||
1405 | * full read of the codec when an event is posted to the audio | ||
1406 | * queue during this loop */ | ||
1407 | yield_codecs(); | 1393 | yield_codecs(); |
1408 | } | 1394 | } |
1409 | 1395 | ||
@@ -1833,7 +1819,7 @@ static void track_skip_done(bool was_manual) | |||
1833 | } | 1819 | } |
1834 | } | 1820 | } |
1835 | 1821 | ||
1836 | static bool load_next_track(bool require_codec) { | 1822 | static bool load_next_track(void) { |
1837 | struct event ev; | 1823 | struct event ev; |
1838 | 1824 | ||
1839 | #ifdef AB_REPEAT_ENABLE | 1825 | #ifdef AB_REPEAT_ENABLE |
@@ -1848,10 +1834,13 @@ static bool load_next_track(bool require_codec) { | |||
1848 | manual_skip = false; | 1834 | manual_skip = false; |
1849 | } | 1835 | } |
1850 | else | 1836 | else |
1837 | { | ||
1851 | manual_skip = true; | 1838 | manual_skip = true; |
1839 | pcmbuf_play_stop(); | ||
1840 | } | ||
1852 | 1841 | ||
1853 | cpu_boost(true); | 1842 | cpu_boost(true); |
1854 | queue_post(&audio_queue, Q_AUDIO_CHECK_NEW_TRACK, (void *)require_codec); | 1843 | queue_post(&audio_queue, Q_AUDIO_CHECK_NEW_TRACK, 0); |
1855 | queue_wait(&codec_callback_queue, &ev); | 1844 | queue_wait(&codec_callback_queue, &ev); |
1856 | cpu_boost(false); | 1845 | cpu_boost(false); |
1857 | switch (ev.id) | 1846 | switch (ev.id) |
@@ -1871,6 +1860,8 @@ static bool load_next_track(bool require_codec) { | |||
1871 | 1860 | ||
1872 | static bool codec_request_next_track_callback(void) | 1861 | static bool codec_request_next_track_callback(void) |
1873 | { | 1862 | { |
1863 | int prev_codectype; | ||
1864 | |||
1874 | if (current_codec == CODEC_IDX_VOICE) { | 1865 | if (current_codec == CODEC_IDX_VOICE) { |
1875 | voice_remaining = 0; | 1866 | voice_remaining = 0; |
1876 | /* Terminate the codec if there are messages waiting on the queue or | 1867 | /* Terminate the codec if there are messages waiting on the queue or |
@@ -1881,12 +1872,13 @@ static bool codec_request_next_track_callback(void) | |||
1881 | if (ci.stop_codec || !playing) | 1872 | if (ci.stop_codec || !playing) |
1882 | return false; | 1873 | return false; |
1883 | 1874 | ||
1884 | if (!load_next_track(false)) | 1875 | prev_codectype = get_codec_base_type(cur_ti->id3.codectype); |
1876 | |||
1877 | if (!load_next_track()) | ||
1885 | return false; | 1878 | return false; |
1886 | 1879 | ||
1887 | /* Check if the next codec is the same file. */ | 1880 | /* Check if the next codec is the same file. */ |
1888 | if (get_codec_base_type(prev_ti->id3.codectype) == | 1881 | if (prev_codectype == get_codec_base_type(cur_ti->id3.codectype)) |
1889 | get_codec_base_type(cur_ti->id3.codectype)) | ||
1890 | { | 1882 | { |
1891 | logf("New track loaded"); | 1883 | logf("New track loaded"); |
1892 | codec_discard_codec_callback(); | 1884 | codec_discard_codec_callback(); |
@@ -1894,7 +1886,7 @@ static bool codec_request_next_track_callback(void) | |||
1894 | } | 1886 | } |
1895 | else | 1887 | else |
1896 | { | 1888 | { |
1897 | logf("New codec:%d/%d", cur_ti->id3.codectype, prev_ti->id3.codectype); | 1889 | logf("New codec:%d/%d", cur_ti->id3.codectype, prev_codectype); |
1898 | return false; | 1890 | return false; |
1899 | } | 1891 | } |
1900 | } | 1892 | } |
@@ -2006,7 +1998,7 @@ void audio_thread(void) | |||
2006 | 1998 | ||
2007 | case Q_AUDIO_CHECK_NEW_TRACK: | 1999 | case Q_AUDIO_CHECK_NEW_TRACK: |
2008 | logf("Check new track buffer"); | 2000 | logf("Check new track buffer"); |
2009 | audio_check_new_track((bool)ev.data); | 2001 | audio_check_new_track(); |
2010 | break; | 2002 | break; |
2011 | 2003 | ||
2012 | case Q_AUDIO_DIR_SKIP: | 2004 | case Q_AUDIO_DIR_SKIP: |
@@ -2055,11 +2047,12 @@ void codec_thread(void) | |||
2055 | 2047 | ||
2056 | switch (ev.id) { | 2048 | switch (ev.id) { |
2057 | case Q_CODEC_LOAD_DISK: | 2049 | case Q_CODEC_LOAD_DISK: |
2050 | logf("Codec load disk"); | ||
2058 | ci.stop_codec = false; | 2051 | ci.stop_codec = false; |
2059 | audio_codec_loaded = true; | 2052 | audio_codec_loaded = true; |
2060 | mutex_lock(&mutex_codecthread); | 2053 | mutex_lock(&mutex_codecthread); |
2061 | current_codec = CODEC_IDX_AUDIO; | 2054 | current_codec = CODEC_IDX_AUDIO; |
2062 | status = codec_load_file((char *)ev.data, &ci); | 2055 | status = codec_load_file((const char *)ev.data, &ci); |
2063 | mutex_unlock(&mutex_codecthread); | 2056 | mutex_unlock(&mutex_codecthread); |
2064 | break ; | 2057 | break ; |
2065 | 2058 | ||
@@ -2115,21 +2108,32 @@ void codec_thread(void) | |||
2115 | case Q_CODEC_LOAD_DISK: | 2108 | case Q_CODEC_LOAD_DISK: |
2116 | case Q_CODEC_LOAD: | 2109 | case Q_CODEC_LOAD: |
2117 | if (playing) { | 2110 | if (playing) { |
2118 | if (ci.new_track || status == CODEC_OK) { | 2111 | const char *codec_path; |
2119 | logf("Codec finished"); | 2112 | if (ci.new_track || status != CODEC_OK) { |
2120 | if (ci.stop_codec) | 2113 | if (!ci.new_track) { |
2121 | queue_post(&audio_queue, Q_AUDIO_STOP, 0); | 2114 | logf("Codec failure"); |
2122 | else | 2115 | gui_syncsplash(HZ*2, true, "Codec failure"); |
2123 | queue_post(&codec_queue, Q_CODEC_LOAD, 0); | 2116 | } |
2117 | if (!load_next_track()) | ||
2118 | { | ||
2119 | queue_post(&codec_queue, Q_AUDIO_STOP, 0); | ||
2120 | break; | ||
2121 | } | ||
2124 | } else { | 2122 | } else { |
2125 | logf("Codec failure"); | 2123 | logf("Codec finished"); |
2126 | gui_syncsplash(HZ*2, true, "Codec failure"); | ||
2127 | if (ci.stop_codec) | 2124 | if (ci.stop_codec) |
2125 | { | ||
2128 | queue_post(&audio_queue, Q_AUDIO_STOP, 0); | 2126 | queue_post(&audio_queue, Q_AUDIO_STOP, 0); |
2129 | else if (load_next_track(true)) | 2127 | break; |
2130 | queue_post(&codec_queue, Q_CODEC_LOAD, 0); | 2128 | } |
2131 | else | 2129 | } |
2132 | queue_post(&audio_queue, Q_AUDIO_STOP, 0); | 2130 | if (cur_ti->has_codec) |
2131 | queue_post(&codec_queue, Q_CODEC_LOAD, 0); | ||
2132 | else | ||
2133 | { | ||
2134 | codec_path = get_codec_path(cur_ti->id3.codectype); | ||
2135 | queue_post(&codec_queue, | ||
2136 | Q_CODEC_LOAD_DISK, (void *)codec_path); | ||
2133 | } | 2137 | } |
2134 | } | 2138 | } |
2135 | } | 2139 | } |
@@ -2138,17 +2142,24 @@ void codec_thread(void) | |||
2138 | 2142 | ||
2139 | static void reset_buffer(void) | 2143 | static void reset_buffer(void) |
2140 | { | 2144 | { |
2145 | size_t offset; | ||
2146 | |||
2141 | filebuf = (char *)&audiobuf[MALLOC_BUFSIZE]; | 2147 | filebuf = (char *)&audiobuf[MALLOC_BUFSIZE]; |
2142 | filebuflen = audiobufend - audiobuf - MALLOC_BUFSIZE - GUARD_BUFSIZE - | 2148 | filebuflen = audiobufend - audiobuf - MALLOC_BUFSIZE - GUARD_BUFSIZE - |
2143 | (pcmbuf_get_bufsize() + get_pcmbuf_descsize() + PCMBUF_FADE_CHUNK); | 2149 | (pcmbuf_get_bufsize() + get_pcmbuf_descsize() + PCMBUF_FADE_CHUNK); |
2144 | 2150 | ||
2145 | |||
2146 | if (talk_get_bufsize() && voice_codec_loaded) | 2151 | if (talk_get_bufsize() && voice_codec_loaded) |
2147 | { | 2152 | { |
2148 | filebuf = &filebuf[talk_get_bufsize()]; | 2153 | filebuf = &filebuf[talk_get_bufsize()]; |
2149 | filebuflen -= 2*CODEC_IRAM_SIZE + 2*CODEC_SIZE + talk_get_bufsize(); | 2154 | filebuflen -= 2*CODEC_IRAM_SIZE + 2*CODEC_SIZE + talk_get_bufsize(); |
2150 | } | 2155 | } |
2151 | 2156 | ||
2157 | /* Ensure that everything is aligned */ | ||
2158 | offset = (-(size_t)filebuf) & 3; | ||
2159 | filebuf += offset; | ||
2160 | filebuflen -= offset; | ||
2161 | filebuflen &= ~3; | ||
2162 | |||
2152 | #ifndef SIMULATOR | 2163 | #ifndef SIMULATOR |
2153 | iram_buf[0] = &filebuf[filebuflen]; | 2164 | iram_buf[0] = &filebuf[filebuflen]; |
2154 | iram_buf[1] = &filebuf[filebuflen+CODEC_IRAM_SIZE]; | 2165 | iram_buf[1] = &filebuf[filebuflen+CODEC_IRAM_SIZE]; |
@@ -2473,7 +2484,7 @@ int mp3_get_file_pos(void) | |||
2473 | remainder = (id3->elapsed*100)%id3->length; | 2484 | remainder = (id3->elapsed*100)%id3->length; |
2474 | remainder = (remainder*100)/id3->length; | 2485 | remainder = (remainder*100)/id3->length; |
2475 | plen = (nexttoc - curtoc)*(id3->filesize/256); | 2486 | plen = (nexttoc - curtoc)*(id3->filesize/256); |
2476 | pos += (plen/100)*remainder; | 2487 | pos += (plen/100)*remainder; |
2477 | } | 2488 | } |
2478 | else | 2489 | else |
2479 | { | 2490 | { |
@@ -2528,7 +2539,7 @@ void audio_set_crossfade(int enable) | |||
2528 | return; /* Audio buffers not yet set up */ | 2539 | return; /* Audio buffers not yet set up */ |
2529 | 2540 | ||
2530 | /* Store the track resume position */ | 2541 | /* Store the track resume position */ |
2531 | if (playing) | 2542 | if (was_playing) |
2532 | offset = cur_ti->id3.offset; | 2543 | offset = cur_ti->id3.offset; |
2533 | 2544 | ||
2534 | if (enable) | 2545 | if (enable) |
@@ -2542,12 +2553,14 @@ void audio_set_crossfade(int enable) | |||
2542 | if (pcmbuf_get_bufsize() == size) | 2553 | if (pcmbuf_get_bufsize() == size) |
2543 | return ; | 2554 | return ; |
2544 | 2555 | ||
2545 | /* Playback has to be stopped before changing the buffer size. */ | ||
2546 | audio_stop_playback(); | ||
2547 | |||
2548 | /* Re-initialize audio system. */ | ||
2549 | if (was_playing) | 2556 | if (was_playing) |
2557 | { | ||
2558 | /* Playback has to be stopped before changing the buffer size. */ | ||
2559 | audio_stop_playback(); | ||
2550 | gui_syncsplash(0, true, (char *)str(LANG_RESTARTING_PLAYBACK)); | 2560 | gui_syncsplash(0, true, (char *)str(LANG_RESTARTING_PLAYBACK)); |
2561 | } | ||
2562 | |||
2563 | /* Re-initialize audio system. */ | ||
2551 | pcmbuf_init(size); | 2564 | pcmbuf_init(size); |
2552 | pcmbuf_crossfade_enable(enable); | 2565 | pcmbuf_crossfade_enable(enable); |
2553 | reset_buffer(); | 2566 | reset_buffer(); |