mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-18 10:32:43 +00:00
Refactor audio configuration in preparation for 7.1 surround sound
This commit is contained in:
parent
c957b8b06b
commit
49a1524f4f
@ -454,9 +454,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
.setEnableHdr(willStreamHdr)
|
.setEnableHdr(willStreamHdr)
|
||||||
.setAttachedGamepadMask(gamepadMask)
|
.setAttachedGamepadMask(gamepadMask)
|
||||||
.setClientRefreshRateX100((int)(displayRefreshRate * 100))
|
.setClientRefreshRateX100((int)(displayRefreshRate * 100))
|
||||||
.setAudioConfiguration(prefConfig.enable51Surround ?
|
.setAudioConfiguration(prefConfig.audioConfiguration)
|
||||||
MoonBridge.AUDIO_CONFIGURATION_51_SURROUND :
|
|
||||||
MoonBridge.AUDIO_CONFIGURATION_STEREO)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Initialize the connection
|
// Initialize the connection
|
||||||
|
@ -64,25 +64,36 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setup(int audioConfiguration, int sampleRate, int samplesPerFrame) {
|
public int setup(MoonBridge.AudioConfiguration audioConfiguration, int sampleRate, int samplesPerFrame) {
|
||||||
int channelConfig;
|
int channelConfig;
|
||||||
int bytesPerFrame;
|
int bytesPerFrame;
|
||||||
|
|
||||||
switch (audioConfiguration)
|
switch (audioConfiguration.channelCount)
|
||||||
{
|
{
|
||||||
case MoonBridge.AUDIO_CONFIGURATION_STEREO:
|
case 2:
|
||||||
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
|
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
|
||||||
bytesPerFrame = 2 * samplesPerFrame * 2;
|
|
||||||
break;
|
break;
|
||||||
case MoonBridge.AUDIO_CONFIGURATION_51_SURROUND:
|
case 4:
|
||||||
|
channelConfig = AudioFormat.CHANNEL_OUT_QUAD;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
|
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
|
||||||
bytesPerFrame = 6 * samplesPerFrame * 2;
|
break;
|
||||||
|
case 8:
|
||||||
|
// AudioFormat.CHANNEL_OUT_7POINT1_SURROUND isn't available until Android 6.0,
|
||||||
|
// yet the CHANNEL_OUT_SIDE_LEFT and CHANNEL_OUT_SIDE_RIGHT constants were added
|
||||||
|
// in 5.0, so just hardcode the constant so we can work on Lollipop.
|
||||||
|
channelConfig = 0x000018fc; // AudioFormat.CHANNEL_OUT_7POINT1_SURROUND
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LimeLog.severe("Decoder returned unhandled channel count");
|
LimeLog.severe("Decoder returned unhandled channel count");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LimeLog.info("Audio channel config: "+String.format("0x%X", channelConfig));
|
||||||
|
|
||||||
|
bytesPerFrame = audioConfiguration.channelCount * samplesPerFrame * 2;
|
||||||
|
|
||||||
// We're not supposed to request less than the minimum
|
// We're not supposed to request less than the minimum
|
||||||
// buffer size for our buffer, but it appears that we can
|
// buffer size for our buffer, but it appears that we can
|
||||||
// do this on many devices and it lowers audio latency.
|
// do this on many devices and it lowers audio latency.
|
||||||
|
@ -263,7 +263,7 @@ public class NvConnection {
|
|||||||
context.negotiatedWidth, context.negotiatedHeight,
|
context.negotiatedWidth, context.negotiatedHeight,
|
||||||
context.streamConfig.getRefreshRate(), context.streamConfig.getBitrate(),
|
context.streamConfig.getRefreshRate(), context.streamConfig.getBitrate(),
|
||||||
context.streamConfig.getMaxPacketSize(),
|
context.streamConfig.getMaxPacketSize(),
|
||||||
context.streamConfig.getRemote(), context.streamConfig.getAudioConfiguration(),
|
context.streamConfig.getRemote(), context.streamConfig.getAudioConfiguration().toInt(),
|
||||||
context.streamConfig.getHevcSupported(),
|
context.streamConfig.getHevcSupported(),
|
||||||
context.negotiatedHdr,
|
context.negotiatedHdr,
|
||||||
context.streamConfig.getHevcBitratePercentageMultiplier(),
|
context.streamConfig.getHevcBitratePercentageMultiplier(),
|
||||||
|
@ -9,12 +9,6 @@ public class StreamConfiguration {
|
|||||||
public static final int STREAM_CFG_LOCAL = 0;
|
public static final int STREAM_CFG_LOCAL = 0;
|
||||||
public static final int STREAM_CFG_REMOTE = 1;
|
public static final int STREAM_CFG_REMOTE = 1;
|
||||||
public static final int STREAM_CFG_AUTO = 2;
|
public static final int STREAM_CFG_AUTO = 2;
|
||||||
|
|
||||||
private static final int CHANNEL_COUNT_STEREO = 2;
|
|
||||||
private static final int CHANNEL_COUNT_5_1 = 6;
|
|
||||||
|
|
||||||
private static final int CHANNEL_MASK_STEREO = 0x3;
|
|
||||||
private static final int CHANNEL_MASK_5_1 = 0xFC;
|
|
||||||
|
|
||||||
private NvApp app;
|
private NvApp app;
|
||||||
private int width, height;
|
private int width, height;
|
||||||
@ -27,9 +21,7 @@ public class StreamConfiguration {
|
|||||||
private boolean playLocalAudio;
|
private boolean playLocalAudio;
|
||||||
private int maxPacketSize;
|
private int maxPacketSize;
|
||||||
private int remote;
|
private int remote;
|
||||||
private int audioChannelMask;
|
private MoonBridge.AudioConfiguration audioConfiguration;
|
||||||
private int audioChannelCount;
|
|
||||||
private int audioConfiguration;
|
|
||||||
private boolean supportsHevc;
|
private boolean supportsHevc;
|
||||||
private int hevcBitratePercentageMultiplier;
|
private int hevcBitratePercentageMultiplier;
|
||||||
private boolean enableHdr;
|
private boolean enableHdr;
|
||||||
@ -119,21 +111,8 @@ public class StreamConfiguration {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamConfiguration.Builder setAudioConfiguration(int audioConfig) {
|
public StreamConfiguration.Builder setAudioConfiguration(MoonBridge.AudioConfiguration audioConfig) {
|
||||||
if (audioConfig == MoonBridge.AUDIO_CONFIGURATION_STEREO) {
|
|
||||||
config.audioChannelCount = CHANNEL_COUNT_STEREO;
|
|
||||||
config.audioChannelMask = CHANNEL_MASK_STEREO;
|
|
||||||
}
|
|
||||||
else if (audioConfig == MoonBridge.AUDIO_CONFIGURATION_51_SURROUND) {
|
|
||||||
config.audioChannelCount = CHANNEL_COUNT_5_1;
|
|
||||||
config.audioChannelMask = CHANNEL_MASK_5_1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IllegalArgumentException("Invalid audio configuration");
|
|
||||||
}
|
|
||||||
|
|
||||||
config.audioConfiguration = audioConfig;
|
config.audioConfiguration = audioConfig;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,8 +138,7 @@ public class StreamConfiguration {
|
|||||||
this.remote = STREAM_CFG_AUTO;
|
this.remote = STREAM_CFG_AUTO;
|
||||||
this.sops = true;
|
this.sops = true;
|
||||||
this.enableAdaptiveResolution = false;
|
this.enableAdaptiveResolution = false;
|
||||||
this.audioChannelCount = CHANNEL_COUNT_STEREO;
|
this.audioConfiguration = MoonBridge.AUDIO_CONFIGURATION_STEREO;
|
||||||
this.audioChannelMask = CHANNEL_MASK_STEREO;
|
|
||||||
this.supportsHevc = false;
|
this.supportsHevc = false;
|
||||||
this.enableHdr = false;
|
this.enableHdr = false;
|
||||||
this.attachedGamepadMask = 0;
|
this.attachedGamepadMask = 0;
|
||||||
@ -209,16 +187,8 @@ public class StreamConfiguration {
|
|||||||
public int getRemote() {
|
public int getRemote() {
|
||||||
return remote;
|
return remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAudioChannelCount() {
|
|
||||||
return audioChannelCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAudioChannelMask() {
|
|
||||||
return audioChannelMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAudioConfiguration() {
|
public MoonBridge.AudioConfiguration getAudioConfiguration() {
|
||||||
return audioConfiguration;
|
return audioConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.limelight.nvstream.av.audio;
|
package com.limelight.nvstream.av.audio;
|
||||||
|
|
||||||
|
import com.limelight.nvstream.jni.MoonBridge;
|
||||||
|
|
||||||
public interface AudioRenderer {
|
public interface AudioRenderer {
|
||||||
int setup(int audioConfiguration, int sampleRate, int samplesPerFrame);
|
int setup(MoonBridge.AudioConfiguration audioConfiguration, int sampleRate, int samplesPerFrame);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
@ -648,7 +648,7 @@ public class NvHTTP {
|
|||||||
"&rikeyid="+context.riKeyId +
|
"&rikeyid="+context.riKeyId +
|
||||||
(!enableHdr ? "" : "&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0") +
|
(!enableHdr ? "" : "&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0") +
|
||||||
"&localAudioPlayMode=" + (context.streamConfig.getPlayLocalAudio() ? 1 : 0) +
|
"&localAudioPlayMode=" + (context.streamConfig.getPlayLocalAudio() ? 1 : 0) +
|
||||||
"&surroundAudioInfo=" + ((context.streamConfig.getAudioChannelMask() << 16) + context.streamConfig.getAudioChannelCount()) +
|
"&surroundAudioInfo=" + context.streamConfig.getAudioConfiguration().getSurroundAudioInfo() +
|
||||||
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&remoteControllersBitmap=" + context.streamConfig.getAttachedGamepadMask() : "") +
|
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&remoteControllersBitmap=" + context.streamConfig.getAttachedGamepadMask() : "") +
|
||||||
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&gcmap=" + context.streamConfig.getAttachedGamepadMask() : ""),
|
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&gcmap=" + context.streamConfig.getAttachedGamepadMask() : ""),
|
||||||
false);
|
false);
|
||||||
@ -660,7 +660,7 @@ public class NvHTTP {
|
|||||||
String xmlStr = openHttpConnectionToString(baseUrlHttps + "/resume?" + buildUniqueIdUuidString() +
|
String xmlStr = openHttpConnectionToString(baseUrlHttps + "/resume?" + buildUniqueIdUuidString() +
|
||||||
"&rikey="+bytesToHex(context.riKey.getEncoded()) +
|
"&rikey="+bytesToHex(context.riKey.getEncoded()) +
|
||||||
"&rikeyid="+context.riKeyId +
|
"&rikeyid="+context.riKeyId +
|
||||||
"&surroundAudioInfo=" + ((context.streamConfig.getAudioChannelMask() << 16) + context.streamConfig.getAudioChannelCount()),
|
"&surroundAudioInfo=" + context.streamConfig.getAudioConfiguration().getSurroundAudioInfo(),
|
||||||
false);
|
false);
|
||||||
String resume = getXmlString(xmlStr, "resume");
|
String resume = getXmlString(xmlStr, "resume");
|
||||||
return Integer.parseInt(resume) != 0;
|
return Integer.parseInt(resume) != 0;
|
||||||
|
@ -7,8 +7,9 @@ import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
|||||||
public class MoonBridge {
|
public class MoonBridge {
|
||||||
/* See documentation in Limelight.h for information about these functions and constants */
|
/* See documentation in Limelight.h for information about these functions and constants */
|
||||||
|
|
||||||
public static final int AUDIO_CONFIGURATION_STEREO = 0;
|
public static final AudioConfiguration AUDIO_CONFIGURATION_STEREO = new AudioConfiguration(2, 0x3);
|
||||||
public static final int AUDIO_CONFIGURATION_51_SURROUND = 1;
|
public static final AudioConfiguration AUDIO_CONFIGURATION_51_SURROUND = new AudioConfiguration(6, 0x3F);
|
||||||
|
public static final AudioConfiguration AUDIO_CONFIGURATION_71_SURROUND = new AudioConfiguration(8, 0x63F);
|
||||||
|
|
||||||
public static final int VIDEO_FORMAT_H264 = 0x0001;
|
public static final int VIDEO_FORMAT_H264 = 0x0001;
|
||||||
public static final int VIDEO_FORMAT_H265 = 0x0100;
|
public static final int VIDEO_FORMAT_H265 = 0x0100;
|
||||||
@ -45,6 +46,57 @@ public class MoonBridge {
|
|||||||
return slices << 24;
|
return slices << 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class AudioConfiguration {
|
||||||
|
public final int channelCount;
|
||||||
|
public final int channelMask;
|
||||||
|
|
||||||
|
public AudioConfiguration(int channelCount, int channelMask) {
|
||||||
|
this.channelCount = channelCount;
|
||||||
|
this.channelMask = channelMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an AudioConfiguration from the integer value returned by moonlight-common-c
|
||||||
|
// See CHANNEL_COUNT_FROM_AUDIO_CONFIGURATION() and CHANNEL_MASK_FROM_AUDIO_CONFIGURATION()
|
||||||
|
// in Limelight.h
|
||||||
|
private AudioConfiguration(int audioConfiguration) {
|
||||||
|
// Check the magic byte before decoding to make sure we got something that's actually
|
||||||
|
// a MAKE_AUDIO_CONFIGURATION()-based value and not something else like an older version
|
||||||
|
// hardcoded AUDIO_CONFIGURATION value from an earlier version of moonlight-common-c.
|
||||||
|
if ((audioConfiguration & 0xFF) != 0xCA) {
|
||||||
|
throw new IllegalArgumentException("Audio configuration has invalid magic byte!");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.channelCount = (audioConfiguration >> 8) & 0xFF;
|
||||||
|
this.channelMask = (audioConfiguration >> 16) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See SURROUNDAUDIOINFO_FROM_AUDIO_CONFIGURATION() in Limelight.h
|
||||||
|
public int getSurroundAudioInfo() {
|
||||||
|
return channelMask << 16 | channelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof AudioConfiguration) {
|
||||||
|
AudioConfiguration that = (AudioConfiguration)obj;
|
||||||
|
return this.toInt() == that.toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the integer value expected by moonlight-common-c
|
||||||
|
// See MAKE_AUDIO_CONFIGURATION() in Limelight.h
|
||||||
|
public int toInt() {
|
||||||
|
return ((channelMask) << 16) | (channelCount << 8) | 0xCA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int bridgeDrSetup(int videoFormat, int width, int height, int redrawRate) {
|
public static int bridgeDrSetup(int videoFormat, int width, int height, int redrawRate) {
|
||||||
if (videoRenderer != null) {
|
if (videoRenderer != null) {
|
||||||
return videoRenderer.setup(videoFormat, width, height, redrawRate);
|
return videoRenderer.setup(videoFormat, width, height, redrawRate);
|
||||||
@ -86,7 +138,7 @@ public class MoonBridge {
|
|||||||
|
|
||||||
public static int bridgeArInit(int audioConfiguration, int sampleRate, int samplesPerFrame) {
|
public static int bridgeArInit(int audioConfiguration, int sampleRate, int samplesPerFrame) {
|
||||||
if (audioRenderer != null) {
|
if (audioRenderer != null) {
|
||||||
return audioRenderer.setup(audioConfiguration, sampleRate, samplesPerFrame);
|
return audioRenderer.setup(new AudioConfiguration(audioConfiguration), sampleRate, samplesPerFrame);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -6,6 +6,8 @@ import android.content.pm.PackageManager;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import com.limelight.nvstream.jni.MoonBridge;
|
||||||
|
|
||||||
public class PreferenceConfiguration {
|
public class PreferenceConfiguration {
|
||||||
private static final String LEGACY_RES_FPS_PREF_STRING = "list_resolution_fps";
|
private static final String LEGACY_RES_FPS_PREF_STRING = "list_resolution_fps";
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ public class PreferenceConfiguration {
|
|||||||
public int oscOpacity;
|
public int oscOpacity;
|
||||||
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
|
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
|
||||||
public String language;
|
public String language;
|
||||||
public boolean listMode, smallIconMode, multiController, enable51Surround, usbDriver;
|
public boolean listMode, smallIconMode, multiController, usbDriver;
|
||||||
public boolean onscreenController;
|
public boolean onscreenController;
|
||||||
public boolean onlyL3R3;
|
public boolean onlyL3R3;
|
||||||
public boolean disableFrameDrop;
|
public boolean disableFrameDrop;
|
||||||
@ -91,6 +93,7 @@ public class PreferenceConfiguration {
|
|||||||
public boolean unlockFps;
|
public boolean unlockFps;
|
||||||
public boolean vibrateOsc;
|
public boolean vibrateOsc;
|
||||||
public boolean vibrateFallbackToDevice;
|
public boolean vibrateFallbackToDevice;
|
||||||
|
public MoonBridge.AudioConfiguration audioConfiguration;
|
||||||
|
|
||||||
private static int getHeightFromResolutionString(String resString) {
|
private static int getHeightFromResolutionString(String resString) {
|
||||||
if (resString.equalsIgnoreCase("360p")) {
|
if (resString.equalsIgnoreCase("360p")) {
|
||||||
@ -332,7 +335,8 @@ public class PreferenceConfiguration {
|
|||||||
config.listMode = prefs.getBoolean(LIST_MODE_PREF_STRING, DEFAULT_LIST_MODE);
|
config.listMode = prefs.getBoolean(LIST_MODE_PREF_STRING, DEFAULT_LIST_MODE);
|
||||||
config.smallIconMode = prefs.getBoolean(SMALL_ICONS_PREF_STRING, getDefaultSmallMode(context));
|
config.smallIconMode = prefs.getBoolean(SMALL_ICONS_PREF_STRING, getDefaultSmallMode(context));
|
||||||
config.multiController = prefs.getBoolean(MULTI_CONTROLLER_PREF_STRING, DEFAULT_MULTI_CONTROLLER);
|
config.multiController = prefs.getBoolean(MULTI_CONTROLLER_PREF_STRING, DEFAULT_MULTI_CONTROLLER);
|
||||||
config.enable51Surround = prefs.getBoolean(ENABLE_51_SURROUND_PREF_STRING, DEFAULT_ENABLE_51_SURROUND);
|
config.audioConfiguration = prefs.getBoolean(ENABLE_51_SURROUND_PREF_STRING, DEFAULT_ENABLE_51_SURROUND) ?
|
||||||
|
MoonBridge.AUDIO_CONFIGURATION_51_SURROUND : MoonBridge.AUDIO_CONFIGURATION_STEREO;
|
||||||
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
||||||
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
|
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
|
||||||
config.onlyL3R3 = prefs.getBoolean(ONLY_L3_R3_PREF_STRING, ONLY_L3_R3_DEFAULT);
|
config.onlyL3R3 = prefs.getBoolean(ONLY_L3_R3_PREF_STRING, ONLY_L3_R3_DEFAULT);
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit f489c9d725d22517d3b3a017f6bbb0a22ed43707
|
Subproject commit 85de16b41bca7ece0a6e0c69acdb76a5da0e79e0
|
Loading…
x
Reference in New Issue
Block a user