diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/playback.c | 62 |
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 */ |
747 | static void audio_reset_buffer_noalloc(void* filebuf) | 747 | static 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. */ |
829 | static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size) | 830 | static 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) |