diff --git a/app/src/main/assets/pulseaudio-gamenative.tzst b/app/src/main/assets/pulseaudio-gamenative.tzst index 23a183b109..219be9b4a4 100644 Binary files a/app/src/main/assets/pulseaudio-gamenative.tzst and b/app/src/main/assets/pulseaudio-gamenative.tzst differ diff --git a/app/src/main/java/com/winlator/xenvironment/components/PulseAudioComponent.java b/app/src/main/java/com/winlator/xenvironment/components/PulseAudioComponent.java index 5982e839f1..8a4befc879 100644 --- a/app/src/main/java/com/winlator/xenvironment/components/PulseAudioComponent.java +++ b/app/src/main/java/com/winlator/xenvironment/components/PulseAudioComponent.java @@ -1,6 +1,7 @@ package com.winlator.xenvironment.components; import android.content.Context; +import android.media.AudioManager; import android.os.Handler; import android.os.Looper; import android.os.Process; @@ -27,13 +28,33 @@ public class PulseAudioComponent extends EnvironmentComponent { private final Object lock = new Object(); private float volume = 1.0f; private byte performanceMode = 1; - private int sampleRate = 48000; private boolean isPaused = false; public PulseAudioComponent(UnixSocketConfig socketConfig) { this.socketConfig = socketConfig; } + // Add this method to detect optimal sample rate + private int getOptimalSampleRate() { + final int fallbackSampleRate = 44100; + AudioManager audioManager = (AudioManager) environment.getContext().getSystemService(Context.AUDIO_SERVICE); + if (audioManager == null) { + return fallbackSampleRate; + } + + String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); + if (rate == null) { + return fallbackSampleRate; + } + + try { + int parsed = Integer.parseInt(rate.trim()); + return parsed > 0 ? parsed : fallbackSampleRate; + } catch (NumberFormatException ignored) { + return fallbackSampleRate; + } + } + @Override public void start() { Log.d("PulseAudioComponent", "Starting..."); @@ -137,11 +158,9 @@ public void setPerformanceMode(int performanceMode) { this.performanceMode = (byte) performanceMode; } - public void setSampleRate(int sampleRate) { - this.sampleRate = sampleRate; - } - private java.lang.Process execPulseAudio() { + final int bitRate = getOptimalSampleRate(); + Context context = environment.getContext(); String nativeLibraryDir = context.getApplicationInfo().nativeLibraryDir; // nativeLibraryDir = nativeLibraryDir.replace("arm64", "arm64-v8a"); @@ -154,7 +173,7 @@ private java.lang.Process execPulseAudio() { File configFile = new File(workingDir, "default.pa"); FileUtils.writeString(configFile, String.join("\n", "load-module module-native-protocol-unix auth-anonymous=1 auth-cookie-enabled=0 socket=\""+socketConfig.path+"\"", - "load-module module-aaudio-sink volume=" + this.volume + " performance_mode=" + ((int) this.performanceMode) + " rate=" + this.sampleRate, + "load-module module-aaudio-sink volume=" + this.volume + " performance_mode=" + ((int) this.performanceMode) + " rate=" + bitRate, "set-default-sink AAudioSink" )); @@ -176,6 +195,9 @@ private java.lang.Process execPulseAudio() { command += " --use-pid-file=false"; command += " --exit-idle-time=-1"; + // Uncomment to enable verbose log in pulseaudio + //command += " -vvv"; + return ProcessHelper.startProcess(command, envVars.toStringArray(), workingDir); }