summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playback.c62
1 files changed, 25 insertions, 37 deletions
diff --git a/apps/playback.c b/apps/playback.c
index dbe28dd1c4..bc56d72500 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -744,7 +744,7 @@ size_t audio_buffer_available(void)
744 744
745/* Set up the audio buffer for playback 745/* Set up the audio buffer for playback
746 * filebuflen must be pre-initialized with the maximum size */ 746 * filebuflen must be pre-initialized with the maximum size */
747static void audio_reset_buffer_noalloc(void* filebuf) 747static void audio_reset_buffer_noalloc(void)
748{ 748{
749 /* 749 /*
750 * Layout audio buffer as follows: 750 * Layout audio buffer as follows:
@@ -761,6 +761,7 @@ static void audio_reset_buffer_noalloc(void* filebuf)
761 /* Initially set up file buffer as all space available */ 761 /* Initially set up file buffer as all space available */
762 size_t allocsize; 762 size_t allocsize;
763 763
764 void* filebuf = core_get_data(audiobuf_handle);
764 /* Subtract whatever voice needs */ 765 /* Subtract whatever voice needs */
765 allocsize = talkbuf_init(filebuf); 766 allocsize = talkbuf_init(filebuf);
766 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t)); 767 allocsize = ALIGN_UP(allocsize, sizeof (intptr_t));
@@ -828,44 +829,30 @@ bufpanic:
828/* Buffer must not move. */ 829/* Buffer must not move. */
829static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size) 830static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
830{ 831{
831 long offset = audio_current_track()->offset;
832 int status = audio_status();
833 /* TODO: Do it without stopping playback, if possible */
834 /* don't call audio_hard_stop() as it frees this handle */
835 if (thread_self() == audio_thread_id)
836 { /* inline case Q_AUDIO_STOP (audio_hard_stop() response
837 * if we're in the audio thread */
838 audio_stop_playback();
839 queue_clear(&audio_queue);
840 }
841 else
842 audio_queue_send(Q_AUDIO_STOP, 1);
843#ifdef PLAYBACK_VOICE
844 voice_stop();
845#endif
846 /* we should be free to change the buffer now */ 832 /* we should be free to change the buffer now */
847 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK); 833 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
848 ssize_t size = (ssize_t)old_size - wanted_size; 834 ssize_t size = (ssize_t)old_size - wanted_size;
849 /* set final buffer size before calling audio_reset_buffer_noalloc() */
850 filebuflen = size;
851 switch (hints & BUFLIB_SHRINK_POS_MASK) 835 switch (hints & BUFLIB_SHRINK_POS_MASK)
852 { 836 {
853 case BUFLIB_SHRINK_POS_BACK: 837 case BUFLIB_SHRINK_POS_BACK:
854 core_shrink(handle, start, size); 838 core_shrink(handle, start, size);
855 audio_reset_buffer_noalloc(start);
856 break; 839 break;
857 case BUFLIB_SHRINK_POS_FRONT: 840 case BUFLIB_SHRINK_POS_FRONT:
858 core_shrink(handle, start + wanted_size, size); 841 core_shrink(handle, start + wanted_size, size);
859 audio_reset_buffer_noalloc(start + wanted_size);
860 break; 842 break;
861 } 843 }
862 if ((status & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY) 844 /* set final buffer size before calling audio_start_playback()
863 { 845 * (which calls audio_reset_buffer_noalloc() which needs the new size) */
864 if (thread_self() == audio_thread_id) 846 filebuflen = size;
865 audio_start_playback(offset, 0); /* inline Q_AUDIO_PLAY */ 847 /* TODO: Do it without stopping playback, if possible */
866 else 848 /* don't call audio_hard_stop() as it frees this handle */
867 audio_play(offset); 849 if (thread_self() == audio_thread_id)
850 { /* inline case Q_AUDIO_REMAKE_AUDIO_BUFFER to avoid deadlock if
851 * we're in the audio thread */
852 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
868 } 853 }
854 else
855 audio_queue_send(Q_AUDIO_REMAKE_AUDIO_BUFFER, 0);
869 856
870 return BUFLIB_CB_OK; 857 return BUFLIB_CB_OK;
871} 858}
@@ -883,9 +870,8 @@ static void audio_reset_buffer(void)
883 audiobuf_handle = 0; 870 audiobuf_handle = 0;
884 } 871 }
885 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops); 872 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
886 unsigned char *filebuf = core_get_data(audiobuf_handle);
887 873
888 audio_reset_buffer_noalloc(filebuf); 874 audio_reset_buffer_noalloc();
889} 875}
890 876
891/* Set the buffer margin to begin rebuffering when 'seconds' from empty */ 877/* Set the buffer margin to begin rebuffering when 'seconds' from empty */
@@ -1949,14 +1935,6 @@ static int audio_fill_file_buffer(void)
1949 if (play_status == PLAY_STOPPED) 1935 if (play_status == PLAY_STOPPED)
1950 return LOAD_TRACK_ERR_FAILED; 1936 return LOAD_TRACK_ERR_FAILED;
1951 1937
1952 trigger_cpu_boost();
1953
1954 /* Must reset the buffer before use if trashed or voice only - voice
1955 file size shouldn't have changed so we can go straight from
1956 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
1957 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
1958 audio_reset_buffer();
1959
1960 logf("Starting buffer fill"); 1938 logf("Starting buffer fill");
1961 1939
1962 int trackstat = audio_load_track(); 1940 int trackstat = audio_load_track();
@@ -2467,7 +2445,17 @@ static void audio_start_playback(size_t offset, unsigned int flags)
2467 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL); 2445 send_event(PLAYBACK_EVENT_START_PLAYBACK, NULL);
2468 } 2446 }
2469 2447
2470 /* Fill the buffer */ 2448 /* Must reset the buffer before use if trashed or voice only - voice
2449 file size shouldn't have changed so we can go straight from
2450 AUDIOBUF_STATE_VOICED_ONLY to AUDIOBUF_STATE_INITIALIZED */
2451 if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
2452 {
2453 /* If not alloced, that must be done as well */
2454 audiobuf_handle <= 0 ?
2455 audio_reset_buffer() : audio_reset_buffer_noalloc();
2456 }
2457
2458 /* Fill the buffer, assumed to be setup already here, thus realloc=false */
2471 int trackstat = audio_fill_file_buffer(); 2459 int trackstat = audio_fill_file_buffer();
2472 2460
2473 if (trackstat >= LOAD_TRACK_OK) 2461 if (trackstat >= LOAD_TRACK_OK)