summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c210
1 files changed, 100 insertions, 110 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 11f76d4db8..3709b407fa 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -201,14 +201,15 @@ size_t filebuflen = 0; /* Size of buffer (A/C-) */
201/* Possible arrangements of the buffer */ 201/* Possible arrangements of the buffer */
202static int buffer_state = AUDIOBUF_STATE_TRASHED; /* Buffer state */ 202static int buffer_state = AUDIOBUF_STATE_TRASHED; /* Buffer state */
203 203
204/* Used to keep the WPS up-to-date during track transtition */ 204/* These are used to store the current and next (or prev if the current is the last)
205static struct mp3entry prevtrack_id3; 205 * mp3entry's in a round-robin system. This guarentees that the pointer returned
206 206 * by audio_current/next_track will be valid for the full duration of the
207/* Used to provide the codec with a pointer */ 207 * currently playing track */
208static struct mp3entry curtrack_id3; 208static struct mp3entry mp3entry_buf[2];
209 209static struct mp3entry *thistrack_id3, /* the currently playing track */
210/* Used to make next track info available while playing last track on buffer */ 210 *othertrack_id3; /* prev track during track-change-transition, or end of playlist,
211static struct mp3entry lasttrack_id3; 211 * next track otherwise */
212static struct mp3entry unbuffered_id3; /* the id3 for the first unbuffered track */
212 213
213/* Track info structure about songs in the file buffer (A/C-) */ 214/* Track info structure about songs in the file buffer (A/C-) */
214struct track_info { 215struct track_info {
@@ -232,10 +233,6 @@ static int track_widx = 0; /* Track being buffered (A) */
232static struct track_info *prev_ti = NULL; /* Pointer to the previously played 233static struct track_info *prev_ti = NULL; /* Pointer to the previously played
233 track */ 234 track */
234 235
235/* Set by the audio thread when the current track information has updated
236 * and the WPS may need to update its cached information */
237static bool track_changed = false;
238
239/* Information used only for filling the buffer */ 236/* Information used only for filling the buffer */
240/* Playlist steps from playing track to next track to be buffered (A) */ 237/* Playlist steps from playing track to next track to be buffered (A) */
241static int last_peek_offset = 0; 238static int last_peek_offset = 0;
@@ -567,24 +564,25 @@ struct mp3entry* audio_current_track(void)
567 564
568 cur_idx = (track_ridx + offset) & MAX_TRACK_MASK; 565 cur_idx = (track_ridx + offset) & MAX_TRACK_MASK;
569 566
570 if (cur_idx == track_ridx && *curtrack_id3.path) 567 if (cur_idx == track_ridx && *thistrack_id3->path)
571 { 568 {
572 /* The usual case */ 569 /* The usual case */
573 return &curtrack_id3; 570 return thistrack_id3;
574 } 571 }
575 else if (automatic_skip && offset == -1 && *prevtrack_id3.path) 572 else if (automatic_skip && offset == -1 && *othertrack_id3->path)
576 { 573 {
577 /* We're in a track transition. The codec has moved on to the nex track, 574 /* We're in a track transition. The codec has moved on to the next track,
578 but the audio being played is still the same (now previous) track. 575 but the audio being played is still the same (now previous) track.
579 prevtrack_id3.elapsed is being updated in an ISR by 576 othertrack_id3.elapsed is being updated in an ISR by
580 codec_pcmbuf_position_callback */ 577 codec_pcmbuf_position_callback */
581 return &prevtrack_id3; 578 return othertrack_id3;
582 } 579 }
583 else if (tracks[cur_idx].id3_hid >= 0) 580 else if (tracks[cur_idx].id3_hid >= 0)
584 { 581 {
585 /* Get the ID3 metadata from the main buffer */ 582 /* The current track's info has been buffered but not read yet, so get it */
586 struct mp3entry *ret = bufgetid3(tracks[cur_idx].id3_hid); 583 if (bufread(tracks[cur_idx].id3_hid, sizeof(struct mp3entry), &temp_id3)
587 if (ret) return ret; 584 == sizeof(struct mp3entry))
585 return &temp_id3;
588 } 586 }
589 587
590 /* We didn't find the ID3 metadata, so we fill temp_id3 with the little info 588 /* We didn't find the ID3 metadata, so we fill temp_id3 with the little info
@@ -620,42 +618,34 @@ struct mp3entry* audio_next_track(void)
620 if (!audio_have_tracks()) 618 if (!audio_have_tracks())
621 return NULL; 619 return NULL;
622 620
623 if (wps_offset == -1 && *prevtrack_id3.path) 621 if (wps_offset == -1 && *thistrack_id3->path)
624 { 622 {
625 /* We're in a track transition. The next track for the WPS is the one 623 /* We're in a track transition. The next track for the WPS is the one
626 currently being decoded. */ 624 currently being decoded. */
627 return &curtrack_id3; 625 return thistrack_id3;
628 } 626 }
629 627
630 next_idx = (track_ridx + offset + 1) & MAX_TRACK_MASK; 628 next_idx = (track_ridx + offset + 1) & MAX_TRACK_MASK;
631 629
632 if (tracks[next_idx].id3_hid >= 0) 630 if (tracks[next_idx].id3_hid >= 0)
633 return bufgetid3(tracks[next_idx].id3_hid); 631 {
632 if (bufread(tracks[next_idx].id3_hid, sizeof(struct mp3entry), othertrack_id3)
633 == sizeof(struct mp3entry))
634 return othertrack_id3;
635 else
636 return NULL;
637 }
634 638
635 if (next_idx == track_widx) 639 if (next_idx == track_widx)
636 { 640 {
637 /* The next track hasn't been buffered yet, so we return the static 641 /* The next track hasn't been buffered yet, so we return the static
638 version of its metadata. */ 642 version of its metadata. */
639 return &lasttrack_id3; 643 return &unbuffered_id3;
640 } 644 }
641 645
642 return NULL; 646 return NULL;
643} 647}
644 648
645bool audio_has_changed_track(void)
646{
647 if (track_changed)
648 {
649#ifdef IPOD_ACCESSORY_PROTOCOL
650 iap_track_changed();
651#endif
652 track_changed = false;
653 return true;
654 }
655
656 return false;
657}
658
659void audio_play(long offset) 649void audio_play(long offset)
660{ 650{
661 logf("audio_play"); 651 logf("audio_play");
@@ -705,7 +695,6 @@ void audio_skip(int direction)
705 queue_post(&audio_queue, Q_AUDIO_SKIP, direction); 695 queue_post(&audio_queue, Q_AUDIO_SKIP, direction);
706 /* Update wps while our message travels inside deep playback queues. */ 696 /* Update wps while our message travels inside deep playback queues. */
707 wps_offset += direction; 697 wps_offset += direction;
708 track_changed = true;
709 } 698 }
710 else 699 else
711 { 700 {
@@ -823,7 +812,7 @@ void audio_set_crossfade(int enable)
823 if (was_playing) 812 if (was_playing)
824 { 813 {
825 /* Store the track resume position */ 814 /* Store the track resume position */
826 offset = curtrack_id3.offset; 815 offset = thistrack_id3->offset;
827 } 816 }
828 817
829 /* Blast it - audio buffer will have to be setup again next time 818 /* Blast it - audio buffer will have to be setup again next time
@@ -963,15 +952,15 @@ static void codec_pcmbuf_position_callback(size_t size)
963{ 952{
964 /* This is called from an ISR, so be quick */ 953 /* This is called from an ISR, so be quick */
965 unsigned int time = size * 1000 / 4 / NATIVE_FREQUENCY + 954 unsigned int time = size * 1000 / 4 / NATIVE_FREQUENCY +
966 prevtrack_id3.elapsed; 955 othertrack_id3->elapsed;
967 956
968 if (time >= prevtrack_id3.length) 957 if (time >= othertrack_id3->length)
969 { 958 {
970 pcmbuf_set_position_callback(NULL); 959 pcmbuf_set_position_callback(NULL);
971 prevtrack_id3.elapsed = prevtrack_id3.length; 960 othertrack_id3->elapsed = othertrack_id3->length;
972 } 961 }
973 else 962 else
974 prevtrack_id3.elapsed = time; 963 othertrack_id3->elapsed = time;
975} 964}
976 965
977static void codec_set_elapsed_callback(unsigned int value) 966static void codec_set_elapsed_callback(unsigned int value)
@@ -986,11 +975,11 @@ static void codec_set_elapsed_callback(unsigned int value)
986 975
987 latency = pcmbuf_get_latency(); 976 latency = pcmbuf_get_latency();
988 if (value < latency) 977 if (value < latency)
989 curtrack_id3.elapsed = 0; 978 thistrack_id3->elapsed = 0;
990 else if (value - latency > curtrack_id3.elapsed || 979 else if (value - latency > thistrack_id3->elapsed ||
991 value - latency < curtrack_id3.elapsed - 2) 980 value - latency < thistrack_id3->elapsed - 2)
992 { 981 {
993 curtrack_id3.elapsed = value - latency; 982 thistrack_id3->elapsed = value - latency;
994 } 983 }
995} 984}
996 985
@@ -1001,11 +990,11 @@ static void codec_set_offset_callback(size_t value)
1001 if (ci.seek_time) 990 if (ci.seek_time)
1002 return; 991 return;
1003 992
1004 latency = pcmbuf_get_latency() * curtrack_id3.bitrate / 8; 993 latency = pcmbuf_get_latency() * thistrack_id3->bitrate / 8;
1005 if (value < latency) 994 if (value < latency)
1006 curtrack_id3.offset = 0; 995 thistrack_id3->offset = 0;
1007 else 996 else
1008 curtrack_id3.offset = value - latency; 997 thistrack_id3->offset = value - latency;
1009} 998}
1010 999
1011static void codec_advance_buffer_counters(size_t amount) 1000static void codec_advance_buffer_counters(size_t amount)
@@ -1197,7 +1186,7 @@ static bool codec_load_next_track(void)
1197{ 1186{
1198 intptr_t result = Q_CODEC_REQUEST_FAILED; 1187 intptr_t result = Q_CODEC_REQUEST_FAILED;
1199 1188
1200 prev_track_elapsed = curtrack_id3.elapsed; 1189 prev_track_elapsed = thistrack_id3->elapsed;
1201 1190
1202#ifdef AB_REPEAT_ENABLE 1191#ifdef AB_REPEAT_ENABLE
1203 ab_end_of_track_report(); 1192 ab_end_of_track_report();
@@ -1247,18 +1236,16 @@ static bool codec_request_next_track_callback(void)
1247 if (ci.stop_codec || !playing) 1236 if (ci.stop_codec || !playing)
1248 return false; 1237 return false;
1249 1238
1250 prev_codectype = get_codec_base_type(curtrack_id3.codectype); 1239 prev_codectype = get_codec_base_type(thistrack_id3->codectype);
1251
1252 if (!codec_load_next_track()) 1240 if (!codec_load_next_track())
1253 return false; 1241 return false;
1254 1242
1255 /* Seek to the beginning of the new track because if the struct 1243 /* Seek to the beginning of the new track because if the struct
1256 mp3entry was buffered, "elapsed" might not be zero (if the track has 1244 mp3entry was buffered, "elapsed" might not be zero (if the track has
1257 been played already but not unbuffered) */ 1245 been played already but not unbuffered) */
1258 codec_seek_buffer_callback(curtrack_id3.first_frame_offset); 1246 codec_seek_buffer_callback(thistrack_id3->first_frame_offset);
1259
1260 /* Check if the next codec is the same file. */ 1247 /* Check if the next codec is the same file. */
1261 if (prev_codectype == get_codec_base_type(curtrack_id3.codectype)) 1248 if (prev_codectype == get_codec_base_type(thistrack_id3->codectype))
1262 { 1249 {
1263 logf("New track loaded"); 1250 logf("New track loaded");
1264 codec_discard_codec_callback(); 1251 codec_discard_codec_callback();
@@ -1266,7 +1253,7 @@ static bool codec_request_next_track_callback(void)
1266 } 1253 }
1267 else 1254 else
1268 { 1255 {
1269 logf("New codec:%d/%d", curtrack_id3.codectype, prev_codectype); 1256 logf("New codec:%d/%d", thistrack_id3->codectype, prev_codectype);
1270 return false; 1257 return false;
1271 } 1258 }
1272} 1259}
@@ -1293,6 +1280,7 @@ static void codec_thread(void)
1293 audio_codec_loaded = true; 1280 audio_codec_loaded = true;
1294 ci.stop_codec = false; 1281 ci.stop_codec = false;
1295 status = codec_load_file((const char *)ev.data, &ci); 1282 status = codec_load_file((const char *)ev.data, &ci);
1283 LOGFQUEUE("codec_load_file %s %d\n", (const char *)ev.data, status);
1296 break; 1284 break;
1297 1285
1298 case Q_CODEC_LOAD: 1286 case Q_CODEC_LOAD:
@@ -1312,6 +1300,7 @@ static void codec_thread(void)
1312 audio_codec_loaded = true; 1300 audio_codec_loaded = true;
1313 ci.stop_codec = false; 1301 ci.stop_codec = false;
1314 status = codec_load_buf(CUR_TI->codec_hid, &ci); 1302 status = codec_load_buf(CUR_TI->codec_hid, &ci);
1303 LOGFQUEUE("codec_load_buf %d\n", status);
1315 break; 1304 break;
1316 1305
1317 case Q_CODEC_DO_CALLBACK: 1306 case Q_CODEC_DO_CALLBACK:
@@ -1362,7 +1351,7 @@ static void codec_thread(void)
1362 { 1351 {
1363 if (!ci.new_track) 1352 if (!ci.new_track)
1364 { 1353 {
1365 logf("Codec failure"); 1354 logf("Codec failure, %d %d", ci.new_track, status);
1366 splash(HZ*2, "Codec failure"); 1355 splash(HZ*2, "Codec failure");
1367 } 1356 }
1368 1357
@@ -1383,8 +1372,10 @@ static void codec_thread(void)
1383 * triggering the WPS exit */ 1372 * triggering the WPS exit */
1384 while(pcm_is_playing()) 1373 while(pcm_is_playing())
1385 { 1374 {
1386 curtrack_id3.elapsed = 1375 /* There has been one too many struct pointer swaps by now
1387 curtrack_id3.length - pcmbuf_get_latency(); 1376 * so even though it says othertrack_id3, its the correct one! */
1377 othertrack_id3->elapsed =
1378 othertrack_id3->length - pcmbuf_get_latency();
1388 sleep(1); 1379 sleep(1);
1389 } 1380 }
1390 1381
@@ -1405,7 +1396,7 @@ static void codec_thread(void)
1405 else 1396 else
1406 { 1397 {
1407 const char *codec_fn = 1398 const char *codec_fn =
1408 get_codec_filename(curtrack_id3.codectype); 1399 get_codec_filename(thistrack_id3->codectype);
1409 if (codec_fn) 1400 if (codec_fn)
1410 { 1401 {
1411 LOGFQUEUE("codec > codec Q_CODEC_LOAD_DISK"); 1402 LOGFQUEUE("codec > codec Q_CODEC_LOAD_DISK");
@@ -1481,10 +1472,14 @@ static void buffering_handle_finished_callback(int *data)
1481 1472
1482 if (*data == tracks[track_widx].id3_hid) 1473 if (*data == tracks[track_widx].id3_hid)
1483 { 1474 {
1475 int offset = ci.new_track + wps_offset;
1476 int next_idx = (track_ridx + offset + 1) & MAX_TRACK_MASK;
1484 /* The metadata handle for the last loaded track has been buffered. 1477 /* The metadata handle for the last loaded track has been buffered.
1485 We can ask the audio thread to load the rest of the track's data. */ 1478 We can ask the audio thread to load the rest of the track's data. */
1486 LOGFQUEUE("audio >| audio Q_AUDIO_FINISH_LOAD"); 1479 LOGFQUEUE("audio >| audio Q_AUDIO_FINISH_LOAD");
1487 queue_post(&audio_queue, Q_AUDIO_FINISH_LOAD, 0); 1480 queue_post(&audio_queue, Q_AUDIO_FINISH_LOAD, 0);
1481 if (tracks[next_idx].id3_hid == *data)
1482 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
1488 } 1483 }
1489 else 1484 else
1490 { 1485 {
@@ -1534,15 +1529,15 @@ static void audio_update_trackinfo(void)
1534{ 1529{
1535 /* Load the curent track's metadata into curtrack_id3 */ 1530 /* Load the curent track's metadata into curtrack_id3 */
1536 if (CUR_TI->id3_hid >= 0) 1531 if (CUR_TI->id3_hid >= 0)
1537 copy_mp3entry(&curtrack_id3, bufgetid3(CUR_TI->id3_hid)); 1532 copy_mp3entry(thistrack_id3, bufgetid3(CUR_TI->id3_hid));
1538 1533
1539 /* Reset current position */ 1534 /* Reset current position */
1540 curtrack_id3.elapsed = 0; 1535 thistrack_id3->elapsed = 0;
1541 curtrack_id3.offset = 0; 1536 thistrack_id3->offset = 0;
1542 1537
1543 /* Update the codec API */ 1538 /* Update the codec API */
1544 ci.filesize = CUR_TI->filesize; 1539 ci.filesize = CUR_TI->filesize;
1545 ci.id3 = &curtrack_id3; 1540 ci.id3 = thistrack_id3;
1546 ci.curpos = 0; 1541 ci.curpos = 0;
1547 ci.taginfo_ready = &CUR_TI->taginfo_ready; 1542 ci.taginfo_ready = &CUR_TI->taginfo_ready;
1548} 1543}
@@ -1608,7 +1603,7 @@ static bool audio_loadcodec(bool start_play)
1608 /* Load the codec directly from disk and save some memory. */ 1603 /* Load the codec directly from disk and save some memory. */
1609 track_ridx = track_widx; 1604 track_ridx = track_widx;
1610 ci.filesize = CUR_TI->filesize; 1605 ci.filesize = CUR_TI->filesize;
1611 ci.id3 = &curtrack_id3; 1606 ci.id3 = thistrack_id3;
1612 ci.taginfo_ready = &CUR_TI->taginfo_ready; 1607 ci.taginfo_ready = &CUR_TI->taginfo_ready;
1613 ci.curpos = 0; 1608 ci.curpos = 0;
1614 LOGFQUEUE("codec > codec Q_CODEC_LOAD_DISK"); 1609 LOGFQUEUE("codec > codec Q_CODEC_LOAD_DISK");
@@ -1698,10 +1693,10 @@ static bool audio_load_track(size_t offset, bool start_play)
1698 if (!trackname) 1693 if (!trackname)
1699 { 1694 {
1700 logf("End-of-playlist"); 1695 logf("End-of-playlist");
1701 memset(&lasttrack_id3, 0, sizeof(struct mp3entry)); 1696 memset(&unbuffered_id3, 0, sizeof(struct mp3entry));
1702 filling = STATE_END_OF_PLAYLIST; 1697 filling = STATE_END_OF_PLAYLIST;
1703 1698
1704 if (curtrack_id3.length == 0 && curtrack_id3.filesize == 0) 1699 if (thistrack_id3->length == 0 && thistrack_id3->filesize == 0)
1705 { 1700 {
1706 /* Stop playback if no valid track was found. */ 1701 /* Stop playback if no valid track was found. */
1707 audio_stop_playback(); 1702 audio_stop_playback();
@@ -1720,7 +1715,6 @@ static bool audio_load_track(size_t offset, bool start_play)
1720 { 1715 {
1721 buf_set_watermark(filebuflen/2); 1716 buf_set_watermark(filebuflen/2);
1722 dsp_configure(ci.dsp, DSP_RESET, 0); 1717 dsp_configure(ci.dsp, DSP_RESET, 0);
1723 track_changed = true;
1724 playlist_update_resume_info(audio_current_track()); 1718 playlist_update_resume_info(audio_current_track());
1725 } 1719 }
1726 1720
@@ -1732,7 +1726,7 @@ static bool audio_load_track(size_t offset, bool start_play)
1732 if (tracks[track_widx].id3_hid < 0) 1726 if (tracks[track_widx].id3_hid < 0)
1733 { 1727 {
1734 /* Buffer is full. */ 1728 /* Buffer is full. */
1735 get_metadata(&lasttrack_id3, fd, trackname); 1729 get_metadata(&unbuffered_id3, fd, trackname);
1736 last_peek_offset--; 1730 last_peek_offset--;
1737 close(fd); 1731 close(fd);
1738 logf("buffer is full for now"); 1732 logf("buffer is full for now");
@@ -1744,13 +1738,18 @@ static bool audio_load_track(size_t offset, bool start_play)
1744 { 1738 {
1745 /* TODO: Superfluos buffering call? */ 1739 /* TODO: Superfluos buffering call? */
1746 buf_request_buffer_handle(tracks[track_widx].id3_hid); 1740 buf_request_buffer_handle(tracks[track_widx].id3_hid);
1747 copy_mp3entry(&curtrack_id3, bufgetid3(tracks[track_widx].id3_hid)); 1741 struct mp3entry *id3 = bufgetid3(tracks[track_widx].id3_hid);
1748 curtrack_id3.offset = offset; 1742 if (id3)
1743 {
1744 copy_mp3entry(thistrack_id3, id3);
1745 thistrack_id3->offset = offset;
1746 }
1747 else
1748 memset(thistrack_id3, 0, sizeof(struct mp3entry));
1749 } 1749 }
1750 1750
1751 if (start_play) 1751 if (start_play)
1752 { 1752 {
1753 track_changed = true;
1754 playlist_update_resume_info(audio_current_track()); 1753 playlist_update_resume_info(audio_current_track());
1755 } 1754 }
1756 } 1755 }
@@ -1780,7 +1779,7 @@ static void audio_finish_load_track(void)
1780 struct mp3entry *track_id3; 1779 struct mp3entry *track_id3;
1781 1780
1782 if (track_widx == track_ridx) 1781 if (track_widx == track_ridx)
1783 track_id3 = &curtrack_id3; 1782 track_id3 = thistrack_id3;
1784 else 1783 else
1785 track_id3 = bufgetid3(tracks[track_widx].id3_hid); 1784 track_id3 = bufgetid3(tracks[track_widx].id3_hid);
1786 1785
@@ -1935,8 +1934,6 @@ static void audio_finish_load_track(void)
1935 1934
1936static void audio_fill_file_buffer(bool start_play, size_t offset) 1935static void audio_fill_file_buffer(bool start_play, size_t offset)
1937{ 1936{
1938 bool had_next_track = audio_next_track() != NULL;
1939
1940 filling = STATE_FILLING; 1937 filling = STATE_FILLING;
1941 trigger_cpu_boost(); 1938 trigger_cpu_boost();
1942 1939
@@ -1959,9 +1956,6 @@ static void audio_fill_file_buffer(bool start_play, size_t offset)
1959 playlist_update_resume_info(audio_current_track()); 1956 playlist_update_resume_info(audio_current_track());
1960 1957
1961 audio_load_track(offset, start_play); 1958 audio_load_track(offset, start_play);
1962
1963 if (!had_next_track && audio_next_track())
1964 track_changed = true;
1965} 1959}
1966 1960
1967static void audio_rebuffer(void) 1961static void audio_rebuffer(void)
@@ -1982,7 +1976,7 @@ static void audio_rebuffer(void)
1982 ci.curpos = 0; 1976 ci.curpos = 0;
1983 1977
1984 if (!CUR_TI->taginfo_ready) 1978 if (!CUR_TI->taginfo_ready)
1985 memset(&curtrack_id3, 0, sizeof(struct mp3entry)); 1979 memset(thistrack_id3, 0, sizeof(struct mp3entry));
1986 1980
1987 audio_fill_file_buffer(false, 0); 1981 audio_fill_file_buffer(false, 0);
1988} 1982}
@@ -1995,9 +1989,16 @@ static int audio_check_new_track(void)
1995 int old_track_ridx = track_ridx; 1989 int old_track_ridx = track_ridx;
1996 int i, idx; 1990 int i, idx;
1997 bool forward; 1991 bool forward;
1992 struct mp3entry *temp = thistrack_id3;
1998 1993
1999 /* Now it's good time to send track finish events. */ 1994 /* Now it's good time to send track finish events. */
2000 send_event(PLAYBACK_EVENT_TRACK_FINISH, &curtrack_id3); 1995 send_event(PLAYBACK_EVENT_TRACK_FINISH, thistrack_id3);
1996 /* swap the mp3entry pointers */
1997 thistrack_id3 = othertrack_id3;
1998 othertrack_id3 = temp;
1999 ci.id3 = thistrack_id3;
2000 memset(thistrack_id3, 0, sizeof(struct mp3entry));
2001
2001 if (dir_skip) 2002 if (dir_skip)
2002 { 2003 {
2003 dir_skip = false; 2004 dir_skip = false;
@@ -2035,22 +2036,23 @@ static int audio_check_new_track(void)
2035 LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED"); 2036 LOGFQUEUE("audio >|= codec Q_CODEC_REQUEST_FAILED");
2036 return Q_CODEC_REQUEST_FAILED; 2037 return Q_CODEC_REQUEST_FAILED;
2037 } 2038 }
2038 2039
2039 if (new_playlist) 2040 if (new_playlist)
2040 { 2041 {
2041 ci.new_track = 1; 2042 ci.new_track = 1;
2042 new_playlist = false; 2043 new_playlist = false;
2043 } 2044 }
2044 2045
2045 /* Save the track metadata to allow the WPS to display it 2046 /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
2046 while PCM finishes playing that track */ 2047 * 1) why are we doing this?
2047 copy_mp3entry(&prevtrack_id3, &curtrack_id3); 2048 * 2) thistrack_id3 has already been cleared anyway */
2048
2049 /* Update the main buffer copy of the track metadata with the one 2049 /* Update the main buffer copy of the track metadata with the one
2050 the codec has been using (for the unbuffer callbacks) */ 2050 the codec has been using (for the unbuffer callbacks) */
2051 if (CUR_TI->id3_hid >= 0) 2051 if (CUR_TI->id3_hid >= 0)
2052 copy_mp3entry(bufgetid3(CUR_TI->id3_hid), &curtrack_id3); 2052 copy_mp3entry(bufgetid3(CUR_TI->id3_hid), thistrack_id3);
2053 2053 /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
2054
2055
2054 /* Save a pointer to the old track to allow later clearing */ 2056 /* Save a pointer to the old track to allow later clearing */
2055 prev_ti = CUR_TI; 2057 prev_ti = CUR_TI;
2056 2058
@@ -2079,7 +2081,6 @@ static int audio_check_new_track(void)
2079 if (automatic_skip) 2081 if (automatic_skip)
2080 { 2082 {
2081 wps_offset = -ci.new_track; 2083 wps_offset = -ci.new_track;
2082 track_changed = true;
2083 } 2084 }
2084 2085
2085 /* If it is not safe to even skip this many track entries */ 2086 /* If it is not safe to even skip this many track entries */
@@ -2185,7 +2186,7 @@ static void audio_stop_playback(void)
2185 2186
2186 /* TODO: Create auto bookmark too? */ 2187 /* TODO: Create auto bookmark too? */
2187 2188
2188 prev_track_elapsed = curtrack_id3.elapsed; 2189 prev_track_elapsed = othertrack_id3->elapsed;
2189 2190
2190 remove_event(BUFFER_EVENT_BUFFER_LOW, buffering_low_buffer_callback); 2191 remove_event(BUFFER_EVENT_BUFFER_LOW, buffering_low_buffer_callback);
2191 } 2192 }
@@ -2202,8 +2203,6 @@ static void audio_stop_playback(void)
2202 2203
2203 /* Close all tracks */ 2204 /* Close all tracks */
2204 audio_release_tracks(); 2205 audio_release_tracks();
2205
2206 memset(&curtrack_id3, 0, sizeof(struct mp3entry));
2207} 2206}
2208 2207
2209static void audio_play_start(size_t offset) 2208static void audio_play_start(size_t offset)
@@ -2219,8 +2218,6 @@ static void audio_play_start(size_t offset)
2219 paused = false; 2218 paused = false;
2220 audio_stop_codec_flush(); 2219 audio_stop_codec_flush();
2221 2220
2222 track_changed = true;
2223
2224 playing = true; 2221 playing = true;
2225 track_load_started = false; 2222 track_load_started = false;
2226 2223
@@ -2325,25 +2322,15 @@ static void audio_finalise_track_change(void)
2325 automatic_skip = false; 2322 automatic_skip = false;
2326 2323
2327 /* Invalidate prevtrack_id3 */ 2324 /* Invalidate prevtrack_id3 */
2328 prevtrack_id3.path[0] = 0; 2325 memset(othertrack_id3, 0, sizeof(struct mp3entry));
2329 2326
2330 if (prev_ti && prev_ti->audio_hid < 0) 2327 if (prev_ti && prev_ti->audio_hid < 0)
2331 { 2328 {
2332 /* No audio left so we clear all the track info. */ 2329 /* No audio left so we clear all the track info. */
2333 clear_track_info(prev_ti); 2330 clear_track_info(prev_ti);
2334 } 2331 }
2335
2336 if (prev_ti && prev_ti->id3_hid >= 0)
2337 {
2338 /* Reset the elapsed time to force the progressbar to be empty if
2339 the user skips back to this track */
2340 bufgetid3(prev_ti->id3_hid)->elapsed = 0;
2341 }
2342 } 2332 }
2343 2333 send_event(PLAYBACK_EVENT_TRACK_CHANGE, thistrack_id3);
2344 send_event(PLAYBACK_EVENT_TRACK_CHANGE, &curtrack_id3);
2345
2346 track_changed = true;
2347 playlist_update_resume_info(audio_current_track()); 2334 playlist_update_resume_info(audio_current_track());
2348} 2335}
2349 2336
@@ -2588,6 +2575,9 @@ void audio_init(void)
2588 ci.dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP, 2575 ci.dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP,
2589 CODEC_IDX_AUDIO); 2576 CODEC_IDX_AUDIO);
2590 2577
2578 thistrack_id3 = &mp3entry_buf[0];
2579 othertrack_id3 = &mp3entry_buf[1];
2580
2591 /* initialize the buffer */ 2581 /* initialize the buffer */
2592 filebuf = audiobuf; 2582 filebuf = audiobuf;
2593 2583