summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c76
1 files changed, 67 insertions, 9 deletions
diff --git a/apps/playback.c b/apps/playback.c
index e35d652ffb..af077e639a 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -732,8 +732,6 @@ static void scratch_mem_init(void *mem)
732 } 732 }
733} 733}
734 734
735/* Buffer must not move. And not shrink for now */
736static struct buflib_callbacks ops = { NULL, NULL };
737static int audiobuf_handle; 735static int audiobuf_handle;
738static size_t filebuflen; 736static size_t filebuflen;
739 737
@@ -744,8 +742,9 @@ size_t audio_buffer_available(void)
744 return core_available(); 742 return core_available();
745} 743}
746 744
747/* Set up the audio buffer for playback */ 745/* Set up the audio buffer for playback
748static void audio_reset_buffer(void) 746 * filebuflen must be pre-initialized with the maximum size */
747static void audio_reset_buffer_noalloc(void* filebuf)
749{ 748{
750 /* 749 /*
751 * Layout audio buffer as follows: 750 * Layout audio buffer as follows:
@@ -761,11 +760,6 @@ static void audio_reset_buffer(void)
761 760
762 /* Initially set up file buffer as all space available */ 761 /* Initially set up file buffer as all space available */
763 size_t allocsize; 762 size_t allocsize;
764 if (audiobuf_handle > 0)
765 audiobuf_handle = core_free(audiobuf_handle);
766
767 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
768 unsigned char *filebuf = core_get_data(audiobuf_handle);
769 763
770 /* Subtract whatever voice needs */ 764 /* Subtract whatever voice needs */
771 allocsize = talkbuf_init(filebuf); 765 allocsize = talkbuf_init(filebuf);
@@ -830,6 +824,70 @@ bufpanic:
830 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen); 824 panicf("%s(): EOM (%zu > %zu)", __func__, allocsize, filebuflen);
831} 825}
832 826
827
828/* Buffer must not move. */
829static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
830{
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 */
847 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
848 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)
852 {
853 case BUFLIB_SHRINK_POS_BACK:
854 core_shrink(handle, start, size);
855 audio_reset_buffer_noalloc(start);
856 break;
857 case BUFLIB_SHRINK_POS_FRONT:
858 core_shrink(handle, start + wanted_size, size);
859 audio_reset_buffer_noalloc(start + wanted_size);
860 break;
861 }
862 if ((status & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY)
863 {
864 if (thread_self() == audio_thread_id)
865 audio_start_playback(offset, 0); /* inline Q_AUDIO_PLAY */
866 else
867 audio_play(offset);
868 }
869
870 return BUFLIB_CB_OK;
871}
872
873static struct buflib_callbacks ops = {
874 .move_callback = NULL,
875 .shrink_callback = shrink_callback,
876};
877
878static void audio_reset_buffer(void)
879{
880 if (audiobuf_handle > 0)
881 {
882 core_free(audiobuf_handle);
883 audiobuf_handle = 0;
884 }
885 audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
886 unsigned char *filebuf = core_get_data(audiobuf_handle);
887
888 audio_reset_buffer_noalloc(filebuf);
889}
890
833/* Set the buffer margin to begin rebuffering when 'seconds' from empty */ 891/* Set the buffer margin to begin rebuffering when 'seconds' from empty */
834static void audio_update_filebuf_watermark(int seconds) 892static void audio_update_filebuf_watermark(int seconds)
835{ 893{