From 09a38f9a289b626ec760103500c95989f7132693 Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Mon, 30 Dec 2024 09:42:37 +0100 Subject: [PATCH] AudioTrack: set buffer size and period size correctly Android buffer size is in bytes, but ALSA buffer size is in frames. Also the period size was not set previously. This fixes several audio issues on postmarketOS and probably other distributions that still use PulseAudio instead of PipeWire. --- src/api-impl-jni/audio/android_media_AudioTrack.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/api-impl-jni/audio/android_media_AudioTrack.c b/src/api-impl-jni/audio/android_media_AudioTrack.c index f3a3ec64..5e59028b 100644 --- a/src/api-impl-jni/audio/android_media_AudioTrack.c +++ b/src/api-impl-jni/audio/android_media_AudioTrack.c @@ -43,6 +43,7 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1constructor(JNIEnv unsigned int channels_out; unsigned int period_time; + unsigned int buffer_time; int ret; @@ -55,10 +56,15 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1constructor(JNIEnv helper_hw_params_init(pcm_handle, params, rate, channels, SND_PCM_FORMAT_S16_LE); /*--↓*/ - snd_pcm_uframes_t buffer_size_as_uframes_t = buffer_size; + snd_pcm_uframes_t buffer_size_as_uframes_t = buffer_size / channels / 2; // 2 means PCM16 snd_pcm_hw_params_set_buffer_size_near (pcm_handle, params, &buffer_size_as_uframes_t); /*--↑*/ + /* set the period time to 1/4 of the buffer time */ + ret = snd_pcm_hw_params_get_buffer_time(params, &buffer_time, NULL); + period_time = buffer_time / 4; + ret = snd_pcm_hw_params_set_period_time_near(pcm_handle, params, &period_time, NULL); + /* Write parameters */ ret = snd_pcm_hw_params(pcm_handle, params); if (ret < 0) @@ -78,7 +84,7 @@ JNIEXPORT void JNICALL Java_android_media_AudioTrack_native_1constructor(JNIEnv snd_pcm_sw_params_malloc (&sw_params); snd_pcm_sw_params_current (pcm_handle, sw_params); - snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, buffer_size - period_size); + snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, (buffer_size_as_uframes_t / period_size) * period_size); snd_pcm_sw_params_set_avail_min(pcm_handle, sw_params, period_size); snd_pcm_sw_params(pcm_handle, sw_params);