Add option to mute audio on minimize and background gamepad input

Fixes #461
This commit is contained in:
Cameron Gutman 2020-12-25 15:32:11 -06:00
parent f7ffb30bc6
commit a11f623b17
8 changed files with 74 additions and 6 deletions

View file

@ -303,6 +303,8 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
parser.addToggleOption("game-optimization", "game optimizations");
parser.addToggleOption("audio-on-host", "audio on host PC");
parser.addToggleOption("frame-pacing", "frame pacing");
parser.addToggleOption("mute-on-minimize", "mute audio whe minimized");
parser.addToggleOption("background-gamepad", "background gamepad input");
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
@ -405,6 +407,12 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
// Resolve --frame-pacing and --no-frame-pacing options
preferences->framePacing = parser.getToggleOptionValue("frame-pacing", preferences->framePacing);
// Resolve --mute-on-minimize and --no-mute-on-minimize options
preferences->muteOnMinimize = parser.getToggleOptionValue("mute-on-minimize", preferences->muteOnMinimize);
// Resolve --background-gamepad and --no-background-gamepad options
preferences->backgroundGamepad = parser.getToggleOptionValue("background-gamepad", preferences->backgroundGamepad);
// Resolve --video-codec option
if (parser.isSet("video-codec")) {
preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec"));

View file

@ -683,6 +683,17 @@ Flickable {
ToolTip.visible: hovered
ToolTip.text: qsTr("You must restart any game currently in progress for this setting to take effect")
}
CheckBox {
id: muteOnMinimizeCheck
width: parent.width
text: qsTr("Mute audio stream when Moonlight is minimized")
font.pointSize: 12
checked: StreamingPreferences.muteOnMinimize
onCheckedChanged: {
StreamingPreferences.muteOnMinimize = checked
}
}
}
}
@ -823,7 +834,7 @@ Flickable {
CheckBox {
id: singleControllerCheck
width: parent.width
text: qsTr("Force gamepad #1 always present")
text: qsTr("Force gamepad #1 always connected")
font.pointSize: 12
checked: !StreamingPreferences.multiController
onCheckedChanged: {
@ -853,6 +864,22 @@ Flickable {
ToolTip.visible: hovered
ToolTip.text: qsTr("When enabled, holding the Start button will toggle mouse mode")
}
CheckBox {
id: backgroundGamepadCheck
width: parent.width
text: qsTr("Process gamepad input when Moonlight is in the background")
font.pointSize: 12
checked: StreamingPreferences.backgroundGamepad
onCheckedChanged: {
StreamingPreferences.backgroundGamepad = checked
}
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: qsTr("Allows Moonlight to capture gamepad inputs even if it's not the current window in focus")
}
}
}

View file

@ -30,6 +30,8 @@
#define SER_PACKETSIZE "packetsize"
#define SER_DETECTNETBLOCKING "detectnetblocking"
#define SER_SWAPMOUSEBUTTONS "swapmousebuttons"
#define SER_MUTEONMINIMIZE "muteonminimize"
#define SER_BACKGROUNDGAMEPAD "backgroundgamepad"
#define CURRENT_DEFAULT_VER 1
@ -72,6 +74,8 @@ void StreamingPreferences::reload()
detectNetworkBlocking = settings.value(SER_DETECTNETBLOCKING, true).toBool();
packetSize = settings.value(SER_PACKETSIZE, 0).toInt();
swapMouseButtons = settings.value(SER_SWAPMOUSEBUTTONS, false).toBool();
muteOnMinimize = settings.value(SER_MUTEONMINIMIZE, false).toBool();
backgroundGamepad = settings.value(SER_BACKGROUNDGAMEPAD, false).toBool();
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
@ -124,6 +128,8 @@ void StreamingPreferences::save()
settings.setValue(SER_WINDOWMODE, static_cast<int>(windowMode));
settings.setValue(SER_DEFAULTVER, CURRENT_DEFAULT_VER);
settings.setValue(SER_SWAPMOUSEBUTTONS, swapMouseButtons);
settings.setValue(SER_MUTEONMINIMIZE, muteOnMinimize);
settings.setValue(SER_BACKGROUNDGAMEPAD, backgroundGamepad);
}
int StreamingPreferences::getDefaultBitrate(int width, int height, int fps)

View file

@ -75,6 +75,8 @@ public:
Q_PROPERTY(WindowMode windowMode MEMBER windowMode NOTIFY windowModeChanged)
Q_PROPERTY(WindowMode recommendedFullScreenMode MEMBER recommendedFullScreenMode CONSTANT)
Q_PROPERTY(bool swapMouseButtons MEMBER swapMouseButtons NOTIFY mouseButtonsChanged)
Q_PROPERTY(bool muteOnMinimize MEMBER muteOnMinimize NOTIFY muteOnMinimizeChanged)
Q_PROPERTY(bool backgroundGamepad MEMBER backgroundGamepad NOTIFY backgroundGamepadChanged)
// Directly accessible members for preferences
int width;
@ -97,6 +99,8 @@ public:
bool gamepadMouse;
bool detectNetworkBlocking;
bool swapMouseButtons;
bool muteOnMinimize;
bool backgroundGamepad;
int packetSize;
AudioConfig audioConfig;
VideoCodecConfig videoCodecConfig;
@ -127,5 +131,7 @@ signals:
void gamepadMouseChanged();
void detectNetworkBlockingChanged();
void mouseButtonsChanged();
void muteOnMinimizeChanged();
void backgroundGamepadChanged();
};

View file

@ -197,6 +197,11 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength)
s_ActiveSession->m_AudioSampleCount++;
// If audio is muted, don't decode or play the audio
if (s_ActiveSession->m_AudioMuted) {
return;
}
if (s_ActiveSession->m_AudioRenderer != nullptr) {
int desiredSize = sizeof(short) * s_ActiveSession->m_AudioConfig.samplesPerFrame * s_ActiveSession->m_AudioConfig.channelCount;
void* buffer = s_ActiveSession->m_AudioRenderer->getAudioBuffer(&desiredSize);

View file

@ -30,8 +30,8 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
m_DragButton(0),
m_NumFingersDown(0)
{
// Allow gamepad input when the app doesn't have focus
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
// Allow gamepad input when the app doesn't have focus if requested
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, prefs.backgroundGamepad ? "1" : "0");
// If absolute mouse mode is enabled, use relative mode warp (which
// is via normal motion events that are influenced by mouse acceleration).

View file

@ -370,6 +370,7 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere
m_DecoderLock(0),
m_NeedsIdr(false),
m_AudioDisabled(false),
m_AudioMuted(false),
m_DisplayOriginX(0),
m_DisplayOriginY(0),
m_PendingWindowedTransition(false),
@ -1318,11 +1319,25 @@ void Session::exec(int displayOriginX, int displayOriginY)
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
// Early handling of some events
switch (event.window.event) {
case SDL_WINDOWEVENT_FOCUS_LOST:
m_InputHandler->notifyFocusLost();
}
else if (event.window.event == SDL_WINDOWEVENT_LEAVE) {
break;
case SDL_WINDOWEVENT_LEAVE:
m_InputHandler->notifyMouseLeave();
break;
case SDL_WINDOWEVENT_MINIMIZED:
if (m_Preferences->muteOnMinimize) {
m_AudioMuted = true;
}
break;
case SDL_WINDOWEVENT_MAXIMIZED:
case SDL_WINDOWEVENT_RESTORED:
if (m_Preferences->muteOnMinimize) {
m_AudioMuted = false;
}
break;
}
// Capture the mouse on SDL_WINDOWEVENT_ENTER if needed

View file

@ -141,6 +141,7 @@ private:
SDL_SpinLock m_DecoderLock;
bool m_NeedsIdr;
bool m_AudioDisabled;
bool m_AudioMuted;
Uint32 m_FullScreenFlag;
int m_DisplayOriginX;
int m_DisplayOriginY;