summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playback.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 13d2bd6b02..1f1852b959 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -164,6 +164,7 @@ static bool audio_is_initialized = false;
164/* Variables are commented with the threads that use them: * 164/* Variables are commented with the threads that use them: *
165 * A=audio, C=codec, V=voice. A suffix of - indicates that * 165 * A=audio, C=codec, V=voice. A suffix of - indicates that *
166 * the variable is read but not updated on that thread. */ 166 * the variable is read but not updated on that thread. */
167/* TBD: Split out "audio" and "calling" threads */
167 168
168/* Main state control */ 169/* Main state control */
169static struct event_queue codec_callback_queue; /* Queue for codec callback responses */ 170static struct event_queue codec_callback_queue; /* Queue for codec callback responses */
@@ -205,6 +206,7 @@ static bool playlist_end = false; /* Have we reached end of the cu
205static bool dir_skip = false; /* Is a directory skip pending? (A) */ 206static bool dir_skip = false; /* Is a directory skip pending? (A) */
206static bool new_playlist = false; /* Are we starting a new playlist? (A) */ 207static bool new_playlist = false; /* Are we starting a new playlist? (A) */
207static int wps_offset = 0; /* Pending track change offset, to keep WPS responsive (A) */ 208static int wps_offset = 0; /* Pending track change offset, to keep WPS responsive (A) */
209static bool quick_restart = false; /* Are we doing a quick restart for buffer resizing? (A) */
208 210
209/* Callbacks.. */ 211/* Callbacks.. */
210void (*track_changed_callback)(struct mp3entry *id3); /* ...when current track has really changed */ 212void (*track_changed_callback)(struct mp3entry *id3); /* ...when current track has really changed */
@@ -612,6 +614,7 @@ void audio_set_crossfade(int enable)
612 enable = 0; 614 enable = 0;
613 size = NATIVE_FREQUENCY*2; 615 size = NATIVE_FREQUENCY*2;
614#endif 616#endif
617 logf("%ld->%ld", (long) pcmbuf_get_bufsize(), (long) size);
615 if (pcmbuf_get_bufsize() == size) 618 if (pcmbuf_get_bufsize() == size)
616 return ; 619 return ;
617 620
@@ -622,10 +625,8 @@ void audio_set_crossfade(int enable)
622 625
623 /* Playback has to be stopped before changing the buffer size. */ 626 /* Playback has to be stopped before changing the buffer size. */
624 gui_syncsplash(0, true, (char *)str(LANG_RESTARTING_PLAYBACK)); 627 gui_syncsplash(0, true, (char *)str(LANG_RESTARTING_PLAYBACK));
625 LOGFQUEUE("audio > audio Q_AUDIO_STOP"); 628 quick_restart = true;
626 queue_post(&audio_queue, Q_AUDIO_STOP, 0); 629 audio_stop();
627 while (audio_codec_loaded)
628 yield();
629 } 630 }
630 631
631 voice_stop(); 632 voice_stop();
@@ -642,13 +643,8 @@ void audio_set_crossfade(int enable)
642 /* Restart playback. */ 643 /* Restart playback. */
643 if (was_playing) 644 if (was_playing)
644 { 645 {
645 LOGFQUEUE("audio > audio Q_AUDIO_PLAY"); 646 audio_play(offset);
646 queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset); 647 quick_restart = false;
647
648 /* Wait for the playback to start again (and display the splash
649 screen during that period. */
650 while (!playing)
651 yield();
652 } 648 }
653} 649}
654 650
@@ -674,7 +670,9 @@ void audio_preinit(void)
674 track_ridx = 0; /* Just to prevent CUR_TI from being anything random. */ 670 track_ridx = 0; /* Just to prevent CUR_TI from being anything random. */
675 prev_ti = &tracks[MAX_TRACK-1]; /* And prevent prev_ti being random too */ 671 prev_ti = &tracks[MAX_TRACK-1]; /* And prevent prev_ti being random too */
676 672
673#ifdef PLAYBACK_VOICE
677 mutex_init(&mutex_codecthread); 674 mutex_init(&mutex_codecthread);
675#endif
678 676
679 queue_init(&audio_queue, true); 677 queue_init(&audio_queue, true);
680 queue_init(&codec_queue, true); 678 queue_init(&codec_queue, true);
@@ -954,9 +952,11 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
954 case Q_VOICE_STOP: 952 case Q_VOICE_STOP:
955 LOGFQUEUE("voice < Q_VOICE_STOP"); 953 LOGFQUEUE("voice < Q_VOICE_STOP");
956 if (ev.data == (void *)1 && !playing && pcm_is_playing()) 954 if (ev.data == (void *)1 && !playing && pcm_is_playing())
955 {
957 /* Aborting: Slight hack - flush PCM buffer if 956 /* Aborting: Slight hack - flush PCM buffer if
958 only being used for voice */ 957 only being used for voice */
959 pcmbuf_play_stop(); 958 pcmbuf_play_stop();
959 }
960 if (voice_is_playing) 960 if (voice_is_playing)
961 { 961 {
962 /* Clear the current buffer */ 962 /* Clear the current buffer */
@@ -1732,12 +1732,14 @@ static void codec_thread(void)
1732 LOGFQUEUE("codec > voice Q_AUDIO_PLAY"); 1732 LOGFQUEUE("codec > voice Q_AUDIO_PLAY");
1733 queue_post(&voice_queue, Q_AUDIO_PLAY, 0); 1733 queue_post(&voice_queue, Q_AUDIO_PLAY, 0);
1734 } 1734 }
1735#endif
1736 mutex_lock(&mutex_codecthread); 1735 mutex_lock(&mutex_codecthread);
1736#endif
1737 current_codec = CODEC_IDX_AUDIO; 1737 current_codec = CODEC_IDX_AUDIO;
1738 ci.stop_codec = false; 1738 ci.stop_codec = false;
1739 status = codec_load_file((const char *)ev.data, &ci); 1739 status = codec_load_file((const char *)ev.data, &ci);
1740#ifdef PLAYBACK_VOICE
1740 mutex_unlock(&mutex_codecthread); 1741 mutex_unlock(&mutex_codecthread);
1742#endif
1741 break ; 1743 break ;
1742 1744
1743 case Q_CODEC_LOAD: 1745 case Q_CODEC_LOAD:
@@ -1761,14 +1763,16 @@ static void codec_thread(void)
1761 LOGFQUEUE("codec > voice Q_AUDIO_PLAY"); 1763 LOGFQUEUE("codec > voice Q_AUDIO_PLAY");
1762 queue_post(&voice_queue, Q_AUDIO_PLAY, 0); 1764 queue_post(&voice_queue, Q_AUDIO_PLAY, 0);
1763 } 1765 }
1764#endif
1765 mutex_lock(&mutex_codecthread); 1766 mutex_lock(&mutex_codecthread);
1767#endif
1766 current_codec = CODEC_IDX_AUDIO; 1768 current_codec = CODEC_IDX_AUDIO;
1767 ci.stop_codec = false; 1769 ci.stop_codec = false;
1768 wrap = (size_t)&filebuf[filebuflen] - (size_t)CUR_TI->codecbuf; 1770 wrap = (size_t)&filebuf[filebuflen] - (size_t)CUR_TI->codecbuf;
1769 status = codec_load_ram(CUR_TI->codecbuf, CUR_TI->codecsize, 1771 status = codec_load_ram(CUR_TI->codecbuf, CUR_TI->codecsize,
1770 &filebuf[0], wrap, &ci); 1772 &filebuf[0], wrap, &ci);
1773#ifdef PLAYBACK_VOICE
1771 mutex_unlock(&mutex_codecthread); 1774 mutex_unlock(&mutex_codecthread);
1775#endif
1772 break ; 1776 break ;
1773 1777
1774#if defined(HAVE_RECORDING) && !defined(SIMULATOR) 1778#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
@@ -1810,6 +1814,7 @@ static void codec_thread(void)
1810 status = CODEC_OK; 1814 status = CODEC_OK;
1811 if (!playing) 1815 if (!playing)
1812 pcmbuf_play_stop(); 1816 pcmbuf_play_stop();
1817
1813 } 1818 }
1814 audio_codec_loaded = false; 1819 audio_codec_loaded = false;
1815 } 1820 }
@@ -1848,8 +1853,11 @@ static void codec_thread(void)
1848 CUR_TI->id3.elapsed = CUR_TI->id3.length - pcmbuf_get_latency(); 1853 CUR_TI->id3.elapsed = CUR_TI->id3.length - pcmbuf_get_latency();
1849 sleep(1); 1854 sleep(1);
1850 } 1855 }
1851 LOGFQUEUE("codec > audio Q_AUDIO_STOP"); 1856 if (!quick_restart)
1852 queue_post(&audio_queue, Q_AUDIO_STOP, 0); 1857 {
1858 LOGFQUEUE("codec > audio Q_AUDIO_STOP");
1859 queue_post(&audio_queue, Q_AUDIO_STOP, 0);
1860 }
1853 break; 1861 break;
1854 } 1862 }
1855 } 1863 }
@@ -2983,7 +2991,6 @@ static void audio_stop_playback(void)
2983 2991
2984 /* Mark all entries null. */ 2992 /* Mark all entries null. */
2985 audio_clear_track_entries(false); 2993 audio_clear_track_entries(false);
2986 memset(tracks, 0, sizeof(struct track_info) * MAX_TRACK);
2987} 2994}
2988 2995
2989static void audio_play_start(size_t offset) 2996static void audio_play_start(size_t offset)
@@ -3102,20 +3109,24 @@ static void audio_reset_buffer(void)
3102 /* Allow 2 codecs at end of file buffer */ 3109 /* Allow 2 codecs at end of file buffer */
3103 filebuflen -= 2 * (CODEC_IRAM_SIZE + CODEC_SIZE); 3110 filebuflen -= 2 * (CODEC_IRAM_SIZE + CODEC_SIZE);
3104 3111
3112#ifdef PLAYBACK_VOICE
3105 iram_buf[0] = &filebuf[filebuflen]; 3113 iram_buf[0] = &filebuf[filebuflen];
3106 iram_buf[1] = &filebuf[filebuflen+CODEC_IRAM_SIZE]; 3114 iram_buf[1] = &filebuf[filebuflen+CODEC_IRAM_SIZE];
3107 dram_buf[0] = (unsigned char *)&filebuf[filebuflen+CODEC_IRAM_SIZE*2]; 3115 dram_buf[0] = (unsigned char *)&filebuf[filebuflen+CODEC_IRAM_SIZE*2];
3108 dram_buf[1] = (unsigned char *)&filebuf[filebuflen+CODEC_IRAM_SIZE*2+CODEC_SIZE]; 3116 dram_buf[1] = (unsigned char *)&filebuf[filebuflen+CODEC_IRAM_SIZE*2+CODEC_SIZE];
3117#endif
3109 } 3118 }
3110 else 3119 else
3111 { 3120 {
3112 /* Allow for 1 codec at end of file buffer */ 3121 /* Allow for 1 codec at end of file buffer */
3113 filebuflen -= CODEC_IRAM_SIZE + CODEC_SIZE; 3122 filebuflen -= CODEC_IRAM_SIZE + CODEC_SIZE;
3114 3123
3124#ifdef PLAYBACK_VOICE
3115 iram_buf[0] = &filebuf[filebuflen]; 3125 iram_buf[0] = &filebuf[filebuflen];
3116 iram_buf[1] = NULL; 3126 iram_buf[1] = NULL;
3117 dram_buf[0] = (unsigned char *)&filebuf[filebuflen+CODEC_IRAM_SIZE]; 3127 dram_buf[0] = (unsigned char *)&filebuf[filebuflen+CODEC_IRAM_SIZE];
3118 dram_buf[1] = NULL; 3128 dram_buf[1] = NULL;
3129#endif
3119 } 3130 }
3120 3131
3121 /* Ensure that file buffer is aligned */ 3132 /* Ensure that file buffer is aligned */
@@ -3123,6 +3134,8 @@ static void audio_reset_buffer(void)
3123 filebuf += offset; 3134 filebuf += offset;
3124 filebuflen -= offset; 3135 filebuflen -= offset;
3125 filebuflen &= ~3; 3136 filebuflen &= ~3;
3137
3138 /* Clear any references to the file buffer */
3126} 3139}
3127 3140
3128 3141