Support 20 ms audio frames

This commit is contained in:
Cameron Gutman 2019-11-29 18:04:57 -06:00
parent 11b3648fac
commit c025432ad6
4 changed files with 15 additions and 15 deletions

View File

@ -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.

View File

@ -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();

View File

@ -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;

View File

@ -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;
} }