mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 02:53:05 +00:00
Support 20 ms audio frames
This commit is contained in:
parent
11b3648fac
commit
c025432ad6
@ -14,10 +14,10 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
|
|
||||||
private AudioTrack track;
|
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) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
return new AudioTrack(AudioManager.STREAM_MUSIC,
|
return new AudioTrack(AudioManager.STREAM_MUSIC,
|
||||||
48000,
|
sampleRate,
|
||||||
channelConfig,
|
channelConfig,
|
||||||
AudioFormat.ENCODING_PCM_16BIT,
|
AudioFormat.ENCODING_PCM_16BIT,
|
||||||
bufferSize,
|
bufferSize,
|
||||||
@ -28,7 +28,7 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
.setUsage(AudioAttributes.USAGE_GAME);
|
.setUsage(AudioAttributes.USAGE_GAME);
|
||||||
AudioFormat format = new AudioFormat.Builder()
|
AudioFormat format = new AudioFormat.Builder()
|
||||||
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
|
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
|
||||||
.setSampleRate(48000)
|
.setSampleRate(sampleRate)
|
||||||
.setChannelMask(channelConfig)
|
.setChannelMask(channelConfig)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setup(int audioConfiguration) {
|
public int setup(int audioConfiguration, int sampleRate, int samplesPerFrame) {
|
||||||
int channelConfig;
|
int channelConfig;
|
||||||
int bytesPerFrame;
|
int bytesPerFrame;
|
||||||
|
|
||||||
@ -72,11 +72,11 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
{
|
{
|
||||||
case MoonBridge.AUDIO_CONFIGURATION_STEREO:
|
case MoonBridge.AUDIO_CONFIGURATION_STEREO:
|
||||||
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
|
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
|
||||||
bytesPerFrame = 2 * 240 * 2;
|
bytesPerFrame = 2 * samplesPerFrame * 2;
|
||||||
break;
|
break;
|
||||||
case MoonBridge.AUDIO_CONFIGURATION_51_SURROUND:
|
case MoonBridge.AUDIO_CONFIGURATION_51_SURROUND:
|
||||||
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
|
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
|
||||||
bytesPerFrame = 6 * 240 * 2;
|
bytesPerFrame = 6 * samplesPerFrame * 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LimeLog.severe("Decoder returned unhandled channel count");
|
LimeLog.severe("Decoder returned unhandled channel count");
|
||||||
@ -122,7 +122,7 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
// Try the larger buffer size
|
// Try the larger buffer size
|
||||||
bufferSize = Math.max(AudioTrack.getMinBufferSize(48000,
|
bufferSize = Math.max(AudioTrack.getMinBufferSize(sampleRate,
|
||||||
channelConfig,
|
channelConfig,
|
||||||
AudioFormat.ENCODING_PCM_16BIT),
|
AudioFormat.ENCODING_PCM_16BIT),
|
||||||
bytesPerFrame * 2);
|
bytesPerFrame * 2);
|
||||||
@ -135,13 +135,13 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip low latency options if hardware sample rate isn't 48000Hz
|
// Skip low latency options if hardware sample rate doesn't match the content
|
||||||
if (AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC) != 48000 && lowLatency) {
|
if (AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC) != sampleRate && lowLatency) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
track = createAudioTrack(channelConfig, bufferSize, lowLatency);
|
track = createAudioTrack(channelConfig, sampleRate, bufferSize, lowLatency);
|
||||||
track.play();
|
track.play();
|
||||||
|
|
||||||
// Successfully created working AudioTrack. We're done here.
|
// Successfully created working AudioTrack. We're done here.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.limelight.nvstream.av.audio;
|
package com.limelight.nvstream.av.audio;
|
||||||
|
|
||||||
public interface AudioRenderer {
|
public interface AudioRenderer {
|
||||||
int setup(int audioConfiguration);
|
int setup(int audioConfiguration, int sampleRate, int samplesPerFrame);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
@ -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) {
|
if (audioRenderer != null) {
|
||||||
return audioRenderer.setup(audioConfiguration);
|
return audioRenderer.setup(audioConfiguration, sampleRate, samplesPerFrame);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -80,7 +80,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_init(JNIEnv *env, jclass clazz) {
|
|||||||
BridgeDrStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrStop", "()V");
|
BridgeDrStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrStop", "()V");
|
||||||
BridgeDrCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrCleanup", "()V");
|
BridgeDrCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrCleanup", "()V");
|
||||||
BridgeDrSubmitDecodeUnitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrSubmitDecodeUnit", "([BIIIJ)I");
|
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");
|
BridgeArStartMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStart", "()V");
|
||||||
BridgeArStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStop", "()V");
|
BridgeArStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStop", "()V");
|
||||||
BridgeArCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArCleanup", "()V");
|
BridgeArCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArCleanup", "()V");
|
||||||
@ -206,7 +206,7 @@ int BridgeArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusCon
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeArInitMethod, audioConfiguration);
|
err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeArInitMethod, audioConfiguration, opusConfig->sampleRate, opusConfig->samplesPerFrame);
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
err = -1;
|
err = -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user