diff --git a/app/src/main/java/com/limelight/binding/audio/AndroidAudioRenderer.java b/app/src/main/java/com/limelight/binding/audio/AndroidAudioRenderer.java index 1901692c..c12021b4 100644 --- a/app/src/main/java/com/limelight/binding/audio/AndroidAudioRenderer.java +++ b/app/src/main/java/com/limelight/binding/audio/AndroidAudioRenderer.java @@ -14,10 +14,10 @@ public class AndroidAudioRenderer implements AudioRenderer { private AudioTrack track; - private AudioTrack createAudioTrack(int channelConfig, int bufferSize, boolean lowLatency) { + private AudioTrack createAudioTrack(int channelConfig, int sampleRate, int bufferSize, boolean lowLatency) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { return new AudioTrack(AudioManager.STREAM_MUSIC, - 48000, + sampleRate, channelConfig, AudioFormat.ENCODING_PCM_16BIT, bufferSize, @@ -28,7 +28,7 @@ public class AndroidAudioRenderer implements AudioRenderer { .setUsage(AudioAttributes.USAGE_GAME); AudioFormat format = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) - .setSampleRate(48000) + .setSampleRate(sampleRate) .setChannelMask(channelConfig) .build(); @@ -64,7 +64,7 @@ public class AndroidAudioRenderer implements AudioRenderer { } @Override - public int setup(int audioConfiguration) { + public int setup(int audioConfiguration, int sampleRate, int samplesPerFrame) { int channelConfig; int bytesPerFrame; @@ -72,11 +72,11 @@ public class AndroidAudioRenderer implements AudioRenderer { { case MoonBridge.AUDIO_CONFIGURATION_STEREO: channelConfig = AudioFormat.CHANNEL_OUT_STEREO; - bytesPerFrame = 2 * 240 * 2; + bytesPerFrame = 2 * samplesPerFrame * 2; break; case MoonBridge.AUDIO_CONFIGURATION_51_SURROUND: channelConfig = AudioFormat.CHANNEL_OUT_5POINT1; - bytesPerFrame = 6 * 240 * 2; + bytesPerFrame = 6 * samplesPerFrame * 2; break; default: LimeLog.severe("Decoder returned unhandled channel count"); @@ -122,7 +122,7 @@ public class AndroidAudioRenderer implements AudioRenderer { case 1: case 3: // Try the larger buffer size - bufferSize = Math.max(AudioTrack.getMinBufferSize(48000, + bufferSize = Math.max(AudioTrack.getMinBufferSize(sampleRate, channelConfig, AudioFormat.ENCODING_PCM_16BIT), bytesPerFrame * 2); @@ -135,13 +135,13 @@ public class AndroidAudioRenderer implements AudioRenderer { throw new IllegalStateException(); } - // Skip low latency options if hardware sample rate isn't 48000Hz - if (AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC) != 48000 && lowLatency) { + // Skip low latency options if hardware sample rate doesn't match the content + if (AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC) != sampleRate && lowLatency) { continue; } try { - track = createAudioTrack(channelConfig, bufferSize, lowLatency); + track = createAudioTrack(channelConfig, sampleRate, bufferSize, lowLatency); track.play(); // Successfully created working AudioTrack. We're done here. diff --git a/app/src/main/java/com/limelight/nvstream/av/audio/AudioRenderer.java b/app/src/main/java/com/limelight/nvstream/av/audio/AudioRenderer.java index f41ff52e..46182c62 100644 --- a/app/src/main/java/com/limelight/nvstream/av/audio/AudioRenderer.java +++ b/app/src/main/java/com/limelight/nvstream/av/audio/AudioRenderer.java @@ -1,7 +1,7 @@ package com.limelight.nvstream.av.audio; public interface AudioRenderer { - int setup(int audioConfiguration); + int setup(int audioConfiguration, int sampleRate, int samplesPerFrame); void start(); diff --git a/app/src/main/java/com/limelight/nvstream/jni/MoonBridge.java b/app/src/main/java/com/limelight/nvstream/jni/MoonBridge.java index 2eed45ec..e8fe6d38 100644 --- a/app/src/main/java/com/limelight/nvstream/jni/MoonBridge.java +++ b/app/src/main/java/com/limelight/nvstream/jni/MoonBridge.java @@ -84,9 +84,9 @@ public class MoonBridge { } } - public static int bridgeArInit(int audioConfiguration) { + public static int bridgeArInit(int audioConfiguration, int sampleRate, int samplesPerFrame) { if (audioRenderer != null) { - return audioRenderer.setup(audioConfiguration); + return audioRenderer.setup(audioConfiguration, sampleRate, samplesPerFrame); } else { return -1; diff --git a/app/src/main/jni/moonlight-core/callbacks.c b/app/src/main/jni/moonlight-core/callbacks.c index c92b15e5..27050372 100644 --- a/app/src/main/jni/moonlight-core/callbacks.c +++ b/app/src/main/jni/moonlight-core/callbacks.c @@ -80,7 +80,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_init(JNIEnv *env, jclass clazz) { BridgeDrStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrStop", "()V"); BridgeDrCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrCleanup", "()V"); BridgeDrSubmitDecodeUnitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrSubmitDecodeUnit", "([BIIIJ)I"); - BridgeArInitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArInit", "(I)I"); + BridgeArInitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArInit", "(III)I"); BridgeArStartMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStart", "()V"); BridgeArStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStop", "()V"); BridgeArCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArCleanup", "()V"); @@ -206,7 +206,7 @@ int BridgeArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusCon return -1; } - err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeArInitMethod, audioConfiguration); + err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeArInitMethod, audioConfiguration, opusConfig->sampleRate, opusConfig->samplesPerFrame); if ((*env)->ExceptionCheck(env)) { err = -1; }