From 665b21f2f788a0ec649bf214196b2891c5cc461e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 23 Mar 2017 17:08:32 -0700 Subject: [PATCH 01/11] Checkpoint --- .../src/scripting/HMDScriptingInterface.h | 1 + scripts/system/selectAudioDevice.js | 160 ++++++++++-------- 2 files changed, 90 insertions(+), 71 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 276e23d2d5..846aa13017 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -80,6 +80,7 @@ public: signals: bool shouldShowHandControllersChanged(); + void mountedChanged(); public: HMDScriptingInterface(); diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index f5929ce151..04215c966d 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -45,26 +45,43 @@ if (typeof String.prototype.trimEndsWith != 'function') { }; } +/**************************************** + VAR DEFINITIONS +****************************************/ const INPUT_DEVICE_SETTING = "audio_input_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device"; - var selectedInputMenu = ""; var selectedOutputMenu = ""; +var audioDevicesList = []; +// Some HMDs (like Oculus CV1) have a built in audio device. If they +// do, then this function will handle switching to that device automatically +// when you goActive with the HMD active. +var wasHmdActive = false; // assume it's not active to start +var switchedAudioInputToHMD = false; +var switchedAudioOutputToHMD = false; +var previousSelectedInputAudioDevice = ""; +var previousSelectedOutputAudioDevice = ""; - var audioDevicesList = []; +/**************************************** + BEGIN FUNCTION DEFINITIONS +****************************************/ function setupAudioMenus() { removeAudioMenus(); - Menu.addSeparator("Audio", "Input Audio Device"); + /* Setup audio input devices */ + Menu.addSeparator("Audio", "Input Audio Device"); var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var inputDevices = AudioDevice.getInputDevices(); var selectedInputDevice = AudioDevice.getInputDevice(); if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { + print ("Audio input device SETTING does not match Input AudioDevice. Attempting to change Input AudioDevice...") if (AudioDevice.setInputDevice(inputDeviceSetting)) { selectedInputDevice = inputDeviceSetting; + } else { + print("Error setting audio input device!") } } - print("audio input devices: " + inputDevices); + print("Audio input devices: " + inputDevices); for(var i = 0; i < inputDevices.length; i++) { var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; @@ -80,17 +97,20 @@ function setupAudioMenus() { } } + /* Setup audio output devices */ Menu.addSeparator("Audio", "Output Audio Device"); - var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var outputDevices = AudioDevice.getOutputDevices(); var selectedOutputDevice = AudioDevice.getOutputDevice(); if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { + print("Audio output device SETTING does not match Output AudioDevice. Attempting to change Output AudioDevice...") if (AudioDevice.setOutputDevice(outputDeviceSetting)) { selectedOutputDevice = outputDeviceSetting; + } else { + print("Error setting audio output device!") } } - print("audio output devices: " + outputDevices); + print("Audio output devices: " + outputDevices); for (var i = 0; i < outputDevices.length; i++) { var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; @@ -115,127 +135,125 @@ function removeAudioMenus() { Menu.removeMenuItem("Audio", audioDevicesList[index]); } + Menu.removeMenu("Audio > Devices"); + audioDevicesList = []; } function onDevicechanged() { - print("audio devices changed, removing Audio > Devices menu..."); - Menu.removeMenu("Audio > Devices"); - print("now setting up Audio > Devices menu"); + print("System audio device changed. Removing and replacing Audio Menus..."); setupAudioMenus(); } -// Have a small delay before the menu's get setup and the audio devices can switch to the last selected ones -Script.setTimeout(function () { - print("connecting deviceChanged"); - AudioDevice.deviceChanged.connect(onDevicechanged); - print("setting up Audio > Devices menu for first time"); - setupAudioMenus(); -}, 5000); - -function scriptEnding() { - Menu.removeMenu("Audio > Devices"); -} -Script.scriptEnding.connect(scriptEnding); - - function menuItemEvent(menuItem) { if (menuItem.startsWith("Use ")) { - if (menuItem.endsWith(" for Output")) { - var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); - print("output audio selection..." + selectedDevice); - Menu.menuItemEvent.disconnect(menuItemEvent); - Menu.setIsOptionChecked(selectedOutputMenu, false); - selectedOutputMenu = menuItem; - Menu.setIsOptionChecked(selectedOutputMenu, true); - if (AudioDevice.setOutputDevice(selectedDevice)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); - } - Menu.menuItemEvent.connect(menuItemEvent); - } else if (menuItem.endsWith(" for Input")) { + if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); - print("input audio selection..." + selectedDevice); + print("User selected a new Audio Input Device: " + selectedDevice); Menu.menuItemEvent.disconnect(menuItemEvent); Menu.setIsOptionChecked(selectedInputMenu, false); selectedInputMenu = menuItem; Menu.setIsOptionChecked(selectedInputMenu, true); if (AudioDevice.setInputDevice(selectedDevice)) { Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); + } else { + print("Error setting audio input device!") + } + Menu.menuItemEvent.connect(menuItemEvent); + } else if (menuItem.endsWith(" for Output")) { + var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); + print("User selected a new Audio Output Device: " + selectedDevice); + Menu.menuItemEvent.disconnect(menuItemEvent); + Menu.setIsOptionChecked(selectedOutputMenu, false); + selectedOutputMenu = menuItem; + Menu.setIsOptionChecked(selectedOutputMenu, true); + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + } else { + print("Error setting audio output device!") } Menu.menuItemEvent.connect(menuItemEvent); } } } -Menu.menuItemEvent.connect(menuItemEvent); - -// Some HMDs (like Oculus CV1) have a built in audio device. If they -// do, then this function will handle switching to that device automatically -// when you goActive with the HMD active. -var wasHmdMounted = false; // assume it's un-mounted to start -var switchedAudioInputToHMD = false; -var switchedAudioOutputToHMD = false; -var previousSelectedInputAudioDevice = ""; -var previousSelectedOutputAudioDevice = ""; - function restoreAudio() { if (switchedAudioInputToHMD) { - print("switching back from HMD preferred audio input to:" + previousSelectedInputAudioDevice); + print("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); menuItemEvent("Use " + previousSelectedInputAudioDevice + " for Input"); + switchedAudioInputToHMD = false; } if (switchedAudioOutputToHMD) { - print("switching back from HMD preferred audio output to:" + previousSelectedOutputAudioDevice); + print("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); menuItemEvent("Use " + previousSelectedOutputAudioDevice + " for Output"); + switchedAudioOutputToHMD = false; } } function checkHMDAudio() { - // Mounted state is changing... handle switching - if (HMD.mounted != wasHmdMounted) { - print("HMD mounted changed..."); + // HMD Active state is changing; handle switching + if (HMD.active != wasHmdActive) { + print("HMD Active state changed!"); - // We're putting the HMD on... switch to those devices - if (HMD.mounted) { - print("NOW mounted..."); + // We're putting the HMD on; switch to those devices + if (HMD.active) { + print("HMD is now Active."); var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); - print("hmdPreferredAudioInput:" + hmdPreferredAudioInput); - print("hmdPreferredAudioOutput:" + hmdPreferredAudioOutput); + print("hmdPreferredAudioInput: " + hmdPreferredAudioInput); + print("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); - var hmdHasPreferredAudio = (hmdPreferredAudioInput !== "") || (hmdPreferredAudioOutput !== ""); - if (hmdHasPreferredAudio) { - print("HMD has preferred audio!"); + if (hmdPreferredAudioInput !== "") { + print("HMD has preferred audio input device."); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); - previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); - print("previousSelectedInputAudioDevice:" + previousSelectedInputAudioDevice); - print("previousSelectedOutputAudioDevice:" + previousSelectedOutputAudioDevice); - if (hmdPreferredAudioInput != previousSelectedInputAudioDevice && hmdPreferredAudioInput !== "") { - print("switching to HMD preferred audio input to:" + hmdPreferredAudioInput); + print("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); + if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { + print("Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); switchedAudioInputToHMD = true; menuItemEvent("Use " + hmdPreferredAudioInput + " for Input"); } - if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice && hmdPreferredAudioOutput !== "") { - print("switching to HMD preferred audio output to:" + hmdPreferredAudioOutput); + } + if (hmdPreferredAudioOutput !== "") { + print("HMD has preferred audio output device."); + previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); + print("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); + if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { + print("Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); switchedAudioOutputToHMD = true; menuItemEvent("Use " + hmdPreferredAudioOutput + " for Output"); } } } else { - print("HMD NOW un-mounted..."); + print("HMD no longer active. Restoring audio I/O devices..."); restoreAudio(); } } - wasHmdMounted = HMD.mounted; + wasHmdActive = HMD.active; } +/**************************************** + END FUNCTION DEFINITIONS +****************************************/ -Script.update.connect(checkHMDAudio); +/**************************************** + BEGIN SCRIPT BODY +****************************************/ +// Have a small delay before the menus get setup so the audio devices can switch to the last selected ones +Script.setTimeout(function () { + print("Connecting deviceChanged() and displayModeChanged()"); + AudioDevice.deviceChanged.connect(onDevicechanged); + HMD.displayModeChanged.connect(checkHMDAudio); + print("Setting up Audio > Devices menu for the first time"); + setupAudioMenus(); +}, 2000); +print("Connecting menuItemEvent() and scriptEnding()"); +Menu.menuItemEvent.connect(menuItemEvent); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); Menu.menuItemEvent.disconnect(menuItemEvent); - Script.update.disconnect(checkHMDAudio); + HMD.displayModeChanged.disconnect(checkHMDAudio); }); }()); // END LOCAL_SCOPE From 4473e6ba38b7830343d717a20a908888fdda9452 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 09:50:35 -0700 Subject: [PATCH 02/11] Remove dead code --- interface/src/scripting/HMDScriptingInterface.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 846aa13017..276e23d2d5 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -80,7 +80,6 @@ public: signals: bool shouldShowHandControllersChanged(); - void mountedChanged(); public: HMDScriptingInterface(); From e5741869e545e3f0a55b0c355136bf57e64580df Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 12:22:11 -0700 Subject: [PATCH 03/11] Checkpoint --- scripts/system/selectAudioDevice.js | 152 ++++++++++++++++------------ 1 file changed, 90 insertions(+), 62 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 04215c966d..5d1f44c1f6 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -61,28 +61,29 @@ var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; +var menuConnected = false; /**************************************** BEGIN FUNCTION DEFINITIONS ****************************************/ function setupAudioMenus() { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } removeAudioMenus(); /* Setup audio input devices */ Menu.addSeparator("Audio", "Input Audio Device"); - var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var inputDevices = AudioDevice.getInputDevices(); + print("selectAudioDevice: Audio input devices: " + inputDevices); var selectedInputDevice = AudioDevice.getInputDevice(); + var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { - print ("Audio input device SETTING does not match Input AudioDevice. Attempting to change Input AudioDevice...") - if (AudioDevice.setInputDevice(inputDeviceSetting)) { - selectedInputDevice = inputDeviceSetting; - } else { - print("Error setting audio input device!") - } + print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", selectedInputDevice); + switchAudioDevice(true, inputDeviceSetting); } - print("Audio input devices: " + inputDevices); - for(var i = 0; i < inputDevices.length; i++) { + for (var i = 0; i < inputDevices.length; i++) { var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; Menu.addMenuItem({ @@ -99,18 +100,14 @@ function setupAudioMenus() { /* Setup audio output devices */ Menu.addSeparator("Audio", "Output Audio Device"); - var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var outputDevices = AudioDevice.getOutputDevices(); + print("selectAudioDevice: Audio output devices: " + outputDevices); var selectedOutputDevice = AudioDevice.getOutputDevice(); + var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { - print("Audio output device SETTING does not match Output AudioDevice. Attempting to change Output AudioDevice...") - if (AudioDevice.setOutputDevice(outputDeviceSetting)) { - selectedOutputDevice = outputDeviceSetting; - } else { - print("Error setting audio output device!") - } + print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", selectedOutputDevice); + switchAudioDevice(false, outputDeviceSetting); } - print("Audio output devices: " + outputDevices); for (var i = 0; i < outputDevices.length; i++) { var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; @@ -125,6 +122,10 @@ function setupAudioMenus() { selectedOutputMenu = menuItem; } } + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; + } } function removeAudioMenus() { @@ -141,51 +142,77 @@ function removeAudioMenus() { } function onDevicechanged() { - print("System audio device changed. Removing and replacing Audio Menus..."); + print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); setupAudioMenus(); } function menuItemEvent(menuItem) { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } if (menuItem.startsWith("Use ")) { if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); - print("User selected a new Audio Input Device: " + selectedDevice); - Menu.menuItemEvent.disconnect(menuItemEvent); - Menu.setIsOptionChecked(selectedInputMenu, false); - selectedInputMenu = menuItem; - Menu.setIsOptionChecked(selectedInputMenu, true); - if (AudioDevice.setInputDevice(selectedDevice)) { - Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); - } else { - print("Error setting audio input device!") - } - Menu.menuItemEvent.connect(menuItemEvent); + print("selectAudioDevice: User selected a new Audio Input Device: " + selectedDevice); + switchAudioDevice(true, selectedDevice); } else if (menuItem.endsWith(" for Output")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); - print("User selected a new Audio Output Device: " + selectedDevice); - Menu.menuItemEvent.disconnect(menuItemEvent); - Menu.setIsOptionChecked(selectedOutputMenu, false); - selectedOutputMenu = menuItem; - Menu.setIsOptionChecked(selectedOutputMenu, true); - if (AudioDevice.setOutputDevice(selectedDevice)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); - } else { - print("Error setting audio output device!") - } - Menu.menuItemEvent.connect(menuItemEvent); + print("selectAudioDevice: User selected a new Audio Output Device: " + selectedDevice); + switchAudioDevice(false, selectedDevice); + } else { + print("selectAudioDevice: Invalid Audio menuItem! Doesn't end with 'for Input' or 'for Output'") } + } else { + print("selectAudioDevice: Invalid Audio menuItem! Doesn't start with 'Use '") + } + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; + } +} + +function switchAudioDevice(isInput, device) { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } + if (isInput) { + print("selectAudioDevice: Switching audio INPUT device to:", device); + if (AudioDevice.setInputDevice(device)) { + Menu.setIsOptionChecked(selectedInputMenu, false); + selectedInputMenu = "Use " + device + " for Input"; + Menu.setIsOptionChecked(selectedInputMenu, true); + Settings.setValue(INPUT_DEVICE_SETTING, device); + } else { + print("selectAudioDevice: Error setting audio input device!") + } + } else { + print("selectAudioDevice: Switching audio OUTPUT device to:", device); + if (AudioDevice.setOutputDevice(device)) { + Menu.setIsOptionChecked(selectedOutputMenu, false); + selectedOutputMenu = "Use " + device + " for Output"; + Menu.setIsOptionChecked(selectedOutputMenu, true); + Settings.setValue(OUTPUT_DEVICE_SETTING, device); + } else { + print("selectAudioDevice: Error setting audio output device!") + } + } + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; } } function restoreAudio() { if (switchedAudioInputToHMD) { - print("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); - menuItemEvent("Use " + previousSelectedInputAudioDevice + " for Input"); + print("selectAudioDevice: Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); + switchAudioDevice(true, previousSelectedInputAudioDevice); switchedAudioInputToHMD = false; } if (switchedAudioOutputToHMD) { - print("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); - menuItemEvent("Use " + previousSelectedOutputAudioDevice + " for Output"); + print("selectAudioDevice: Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); + switchAudioDevice(false, previousSelectedOutputAudioDevice); switchedAudioOutputToHMD = false; } } @@ -193,39 +220,38 @@ function restoreAudio() { function checkHMDAudio() { // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { - print("HMD Active state changed!"); + print("selectAudioDevice: HMD Active state changed!"); // We're putting the HMD on; switch to those devices if (HMD.active) { - print("HMD is now Active."); + print("selectAudioDevice: HMD is now Active."); var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); - print("hmdPreferredAudioInput: " + hmdPreferredAudioInput); - print("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); - + print("selectAudioDevice: hmdPreferredAudioInput: " + hmdPreferredAudioInput); + print("selectAudioDevice: hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); if (hmdPreferredAudioInput !== "") { - print("HMD has preferred audio input device."); + print("selectAudioDevice: HMD has preferred audio input device."); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); - print("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); + print("selectAudioDevice: previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { - print("Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); + print("selectAudioDevice: Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); switchedAudioInputToHMD = true; - menuItemEvent("Use " + hmdPreferredAudioInput + " for Input"); + switchAudioDevice(true, hmdPreferredAudioInput); } } if (hmdPreferredAudioOutput !== "") { - print("HMD has preferred audio output device."); + print("selectAudioDevice: HMD has preferred audio output device."); previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); - print("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); + print("selectAudioDevice: previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { - print("Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); + print("selectAudioDevice: Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); switchedAudioOutputToHMD = true; - menuItemEvent("Use " + hmdPreferredAudioOutput + " for Output"); + switchAudioDevice(false, hmdPreferredAudioOutput); } } } else { - print("HMD no longer active. Restoring audio I/O devices..."); + print("selectAudioDevice: HMD no longer active. Restoring audio I/O devices..."); restoreAudio(); } } @@ -240,15 +266,17 @@ function checkHMDAudio() { ****************************************/ // Have a small delay before the menus get setup so the audio devices can switch to the last selected ones Script.setTimeout(function () { - print("Connecting deviceChanged() and displayModeChanged()"); + print("selectAudioDevice: Connecting deviceChanged() and displayModeChanged()"); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - print("Setting up Audio > Devices menu for the first time"); + print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); setupAudioMenus(); -}, 2000); + checkHMDAudio(); +}, 5000); -print("Connecting menuItemEvent() and scriptEnding()"); +print("selectAudioDevice: Connecting menuItemEvent() and scriptEnding()"); Menu.menuItemEvent.connect(menuItemEvent); +menuConnected = true; Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); From 31ae326880b18ff9754989557c4b1990c7ff9914 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 13:05:07 -0700 Subject: [PATCH 04/11] Pretty sure about this now --- scripts/system/selectAudioDevice.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 5d1f44c1f6..cc0f25b005 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -95,6 +95,7 @@ function setupAudioMenus() { audioDevicesList.push(menuItem); if (thisDeviceSelected) { selectedInputMenu = menuItem; + print("selectAudioDevice: selectedInputMenu: " + selectedInputMenu); } } @@ -120,6 +121,7 @@ function setupAudioMenus() { audioDevicesList.push(menuItem); if (thisDeviceSelected) { selectedOutputMenu = menuItem; + print("selectAudioDevice: selectedOutputMenu: " + selectedOutputMenu); } } if (!menuConnected) { @@ -180,9 +182,6 @@ function switchAudioDevice(isInput, device) { if (isInput) { print("selectAudioDevice: Switching audio INPUT device to:", device); if (AudioDevice.setInputDevice(device)) { - Menu.setIsOptionChecked(selectedInputMenu, false); - selectedInputMenu = "Use " + device + " for Input"; - Menu.setIsOptionChecked(selectedInputMenu, true); Settings.setValue(INPUT_DEVICE_SETTING, device); } else { print("selectAudioDevice: Error setting audio input device!") @@ -190,14 +189,12 @@ function switchAudioDevice(isInput, device) { } else { print("selectAudioDevice: Switching audio OUTPUT device to:", device); if (AudioDevice.setOutputDevice(device)) { - Menu.setIsOptionChecked(selectedOutputMenu, false); - selectedOutputMenu = "Use " + device + " for Output"; - Menu.setIsOptionChecked(selectedOutputMenu, true); Settings.setValue(OUTPUT_DEVICE_SETTING, device); } else { print("selectAudioDevice: Error setting audio output device!") } } + setupAudioMenus(); if (!menuConnected) { Menu.menuItemEvent.connect(menuItemEvent); menuConnected = true; @@ -218,6 +215,10 @@ function restoreAudio() { } function checkHMDAudio() { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { print("selectAudioDevice: HMD Active state changed!"); @@ -256,6 +257,10 @@ function checkHMDAudio() { } } wasHmdActive = HMD.active; + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; + } } /**************************************** END FUNCTION DEFINITIONS @@ -269,10 +274,11 @@ Script.setTimeout(function () { print("selectAudioDevice: Connecting deviceChanged() and displayModeChanged()"); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); + print ("selectAudioDevice: Checking HMD audio status...") + checkHMDAudio(); print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); setupAudioMenus(); - checkHMDAudio(); -}, 5000); +}, 3000); print("selectAudioDevice: Connecting menuItemEvent() and scriptEnding()"); Menu.menuItemEvent.connect(menuItemEvent); From 73a77f7f2563c37f8831c751e2d3466cd5011d4d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 18:19:34 -0700 Subject: [PATCH 05/11] OK, how about now --- scripts/system/selectAudioDevice.js | 102 ++++++++++------------------ 1 file changed, 34 insertions(+), 68 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index cc0f25b005..a2246bf1d5 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -50,8 +50,6 @@ if (typeof String.prototype.trimEndsWith != 'function') { ****************************************/ const INPUT_DEVICE_SETTING = "audio_input_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device"; -var selectedInputMenu = ""; -var selectedOutputMenu = ""; var audioDevicesList = []; // Some HMDs (like Oculus CV1) have a built in audio device. If they // do, then this function will handle switching to that device automatically @@ -61,72 +59,59 @@ var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; -var menuConnected = false; /**************************************** BEGIN FUNCTION DEFINITIONS ****************************************/ function setupAudioMenus() { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } - removeAudioMenus(); + Menu.menuItemEvent.disconnect(menuItemEvent); /* Setup audio input devices */ Menu.addSeparator("Audio", "Input Audio Device"); var inputDevices = AudioDevice.getInputDevices(); print("selectAudioDevice: Audio input devices: " + inputDevices); - var selectedInputDevice = AudioDevice.getInputDevice(); - var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); - if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { - print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", selectedInputDevice); - switchAudioDevice(true, inputDeviceSetting); - } for (var i = 0; i < inputDevices.length; i++) { - var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; Menu.addMenuItem({ menuName: "Audio", menuItemName: menuItem, isCheckable: true, - isChecked: thisDeviceSelected + isChecked: inputDevices[i] == AudioDevice.getInputDevice() }); audioDevicesList.push(menuItem); - if (thisDeviceSelected) { - selectedInputMenu = menuItem; - print("selectAudioDevice: selectedInputMenu: " + selectedInputMenu); - } } /* Setup audio output devices */ Menu.addSeparator("Audio", "Output Audio Device"); var outputDevices = AudioDevice.getOutputDevices(); print("selectAudioDevice: Audio output devices: " + outputDevices); - var selectedOutputDevice = AudioDevice.getOutputDevice(); - var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); - if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { - print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", selectedOutputDevice); - switchAudioDevice(false, outputDeviceSetting); - } for (var i = 0; i < outputDevices.length; i++) { - var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; Menu.addMenuItem({ menuName: "Audio", menuItemName: menuItem, isCheckable: true, - isChecked: thisDeviceSelected + isChecked: outputDevices[i] == AudioDevice.getOutputDevice() }); audioDevicesList.push(menuItem); - if (thisDeviceSelected) { - selectedOutputMenu = menuItem; - print("selectAudioDevice: selectedOutputMenu: " + selectedOutputMenu); - } } - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; + + Menu.menuItemEvent.connect(menuItemEvent); +} + +function checkDeviceMismatch() { + var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); + var interfaceInputDevice = AudioDevice.getInputDevice(); + if (interfaceInputDevice != inputDeviceSetting) { + print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", AudioDevice.getInputDevice()); + switchAudioDevice(true, inputDeviceSetting); + } + + var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); + var interfaceOutputDevice = AudioDevice.getOutputDevice(); + if (interfaceOutputDevice != outputDeviceSetting) { + print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", interfaceOutputDevice); + switchAudioDevice(false, outputDeviceSetting); } } @@ -135,7 +120,9 @@ function removeAudioMenus() { Menu.removeSeparator("Audio", "Output Audio Device"); for (var index = 0; index < audioDevicesList.length; index++) { - Menu.removeMenuItem("Audio", audioDevicesList[index]); + if (Menu.menuItemExists("Audio", audioDevicesList[index])) { + Menu.removeMenuItem("Audio", audioDevicesList[index]); + } } Menu.removeMenu("Audio > Devices"); @@ -145,14 +132,12 @@ function removeAudioMenus() { function onDevicechanged() { print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); + removeAudioMenus(); setupAudioMenus(); + checkDeviceMismatch(); } function menuItemEvent(menuItem) { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } if (menuItem.startsWith("Use ")) { if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); @@ -165,20 +150,10 @@ function menuItemEvent(menuItem) { } else { print("selectAudioDevice: Invalid Audio menuItem! Doesn't end with 'for Input' or 'for Output'") } - } else { - print("selectAudioDevice: Invalid Audio menuItem! Doesn't start with 'Use '") - } - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; } } function switchAudioDevice(isInput, device) { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } if (isInput) { print("selectAudioDevice: Switching audio INPUT device to:", device); if (AudioDevice.setInputDevice(device)) { @@ -194,11 +169,9 @@ function switchAudioDevice(isInput, device) { print("selectAudioDevice: Error setting audio output device!") } } + + removeAudioMenus(); setupAudioMenus(); - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; - } } function restoreAudio() { @@ -215,10 +188,6 @@ function restoreAudio() { } function checkHMDAudio() { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { print("selectAudioDevice: HMD Active state changed!"); @@ -257,10 +226,6 @@ function checkHMDAudio() { } } wasHmdActive = HMD.active; - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; - } } /**************************************** END FUNCTION DEFINITIONS @@ -271,23 +236,24 @@ function checkHMDAudio() { ****************************************/ // Have a small delay before the menus get setup so the audio devices can switch to the last selected ones Script.setTimeout(function () { - print("selectAudioDevice: Connecting deviceChanged() and displayModeChanged()"); + print("selectAudioDevice: Connecting deviceChanged(), displayModeChanged(), and menuItemEvent()"); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - print ("selectAudioDevice: Checking HMD audio status...") - checkHMDAudio(); + Menu.menuItemEvent.connect(menuItemEvent); print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); setupAudioMenus(); + checkDeviceMismatch(); + print("selectAudioDevice: Checking HMD audio status...") + checkHMDAudio(); }, 3000); -print("selectAudioDevice: Connecting menuItemEvent() and scriptEnding()"); -Menu.menuItemEvent.connect(menuItemEvent); -menuConnected = true; +print("selectAudioDevice: Connecting scriptEnding()"); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); Menu.menuItemEvent.disconnect(menuItemEvent); HMD.displayModeChanged.disconnect(checkHMDAudio); + AudioDevice.deviceChanged.disconnect(onDevicechanged); }); }()); // END LOCAL_SCOPE From 0ae4ce7e985c86f7a600034c29ef176b84493c3a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 27 Mar 2017 16:15:11 -0700 Subject: [PATCH 06/11] Have I finally tamed the beast? --- scripts/system/selectAudioDevice.js | 198 +++++++++++++++------------- 1 file changed, 110 insertions(+), 88 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index a2246bf1d5..f3d40820cb 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -45,73 +45,78 @@ if (typeof String.prototype.trimEndsWith != 'function') { }; } -/**************************************** - VAR DEFINITIONS -****************************************/ +// +// VAR DEFINITIONS +// +var debugPrintStatements = true; const INPUT_DEVICE_SETTING = "audio_input_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device"; var audioDevicesList = []; -// Some HMDs (like Oculus CV1) have a built in audio device. If they -// do, then this function will handle switching to that device automatically -// when you goActive with the HMD active. var wasHmdActive = false; // assume it's not active to start var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; -/**************************************** - BEGIN FUNCTION DEFINITIONS -****************************************/ -function setupAudioMenus() { - Menu.menuItemEvent.disconnect(menuItemEvent); +// +// BEGIN FUNCTION DEFINITIONS +// +function debug() { + if (debugPrintStatements) { + print.apply(null, [].concat.apply(["selectAudioDevice.js:"], [].map.call(arguments, JSON.stringify))); + } +} - /* Setup audio input devices */ + +function setupAudioMenus() { + Menu.menuItemEvent.disconnect(switchAudioDevice); + + removeAudioMenus(); + + // Setup audio input devices Menu.addSeparator("Audio", "Input Audio Device"); var inputDevices = AudioDevice.getInputDevices(); - print("selectAudioDevice: Audio input devices: " + inputDevices); for (var i = 0; i < inputDevices.length; i++) { - var menuItem = "Use " + inputDevices[i] + " for Input"; + var audioDeviceMenuString = "Use " + inputDevices[i] + " for Input"; Menu.addMenuItem({ menuName: "Audio", - menuItemName: menuItem, + menuItemName: audioDeviceMenuString, isCheckable: true, isChecked: inputDevices[i] == AudioDevice.getInputDevice() }); - audioDevicesList.push(menuItem); + audioDevicesList.push(audioDeviceMenuString); } - /* Setup audio output devices */ + // Setup audio output devices Menu.addSeparator("Audio", "Output Audio Device"); var outputDevices = AudioDevice.getOutputDevices(); - print("selectAudioDevice: Audio output devices: " + outputDevices); for (var i = 0; i < outputDevices.length; i++) { - var menuItem = "Use " + outputDevices[i] + " for Output"; + var audioDeviceMenuString = "Use " + outputDevices[i] + " for Output"; Menu.addMenuItem({ menuName: "Audio", - menuItemName: menuItem, + menuItemName: audioDeviceMenuString, isCheckable: true, isChecked: outputDevices[i] == AudioDevice.getOutputDevice() }); - audioDevicesList.push(menuItem); + audioDevicesList.push(audioDeviceMenuString); } - Menu.menuItemEvent.connect(menuItemEvent); + Menu.menuItemEvent.connect(switchAudioDevice); } function checkDeviceMismatch() { var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var interfaceInputDevice = AudioDevice.getInputDevice(); if (interfaceInputDevice != inputDeviceSetting) { - print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", AudioDevice.getInputDevice()); - switchAudioDevice(true, inputDeviceSetting); + debug("Input Setting & Device mismatch! Input SETTING: " + inputDeviceSetting + "Input DEVICE IN USE: " + interfaceInputDevice); + switchAudioDevice("Use " + inputDeviceSetting + " for Input"); } var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var interfaceOutputDevice = AudioDevice.getOutputDevice(); if (interfaceOutputDevice != outputDeviceSetting) { - print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", interfaceOutputDevice); - switchAudioDevice(false, outputDeviceSetting); + debug("Output Setting & Device mismatch! Output SETTING: " + outputDeviceSetting + "Output DEVICE IN USE: " + interfaceOutputDevice); + switchAudioDevice("Use " + outputDeviceSetting + " for Output"); } } @@ -131,129 +136,146 @@ function removeAudioMenus() { } function onDevicechanged() { - print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); - removeAudioMenus(); + debug("System audio devices changed. Removing and replacing Audio Menus..."); setupAudioMenus(); + AudioDevice.setOutputDevice(AudioDevice.getOutputDevice()); + AudioDevice.setInputDevice(AudioDevice.getInputDevice()); checkDeviceMismatch(); } -function menuItemEvent(menuItem) { - if (menuItem.startsWith("Use ")) { - if (menuItem.endsWith(" for Input")) { - var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); - print("selectAudioDevice: User selected a new Audio Input Device: " + selectedDevice); - switchAudioDevice(true, selectedDevice); - } else if (menuItem.endsWith(" for Output")) { - var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); - print("selectAudioDevice: User selected a new Audio Output Device: " + selectedDevice); - switchAudioDevice(false, selectedDevice); - } else { - print("selectAudioDevice: Invalid Audio menuItem! Doesn't end with 'for Input' or 'for Output'") - } - } -} +function switchAudioDevice(audioDeviceMenuString) { + Menu.menuItemEvent.disconnect(switchAudioDevice); -function switchAudioDevice(isInput, device) { - if (isInput) { - print("selectAudioDevice: Switching audio INPUT device to:", device); - if (AudioDevice.setInputDevice(device)) { - Settings.setValue(INPUT_DEVICE_SETTING, device); + if (audioDeviceMenuString.startsWith("Use ")) { + if (audioDeviceMenuString.endsWith(" for Input")) { + var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Input"); + var currentInputDevice = AudioDevice.getInputDevice(); + if (selectedDevice != currentInputDevice) { + debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentInputDevice + " for Input", false); + if (AudioDevice.setInputDevice(selectedDevice)) { + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); + Menu.setIsOptionChecked(audioDeviceMenuString, true); + } else { + debug("Error setting audio input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); + } + } else { + debug("Selected input device is the same as the current input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + } + } else if (audioDeviceMenuString.endsWith(" for Output")) { + var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Output"); + var currentOutputDevice = AudioDevice.getOutputDevice(); + if (selectedDevice != currentOutputDevice) { + debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentOutputDevice + " for Output", false); + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + Menu.setIsOptionChecked(audioDeviceMenuString, true); + } else { + debug("Error setting audio output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); + } + } else { + debug("Selected output device is the same as the current output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + } } else { - print("selectAudioDevice: Error setting audio input device!") - } - } else { - print("selectAudioDevice: Switching audio OUTPUT device to:", device); - if (AudioDevice.setOutputDevice(device)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, device); - } else { - print("selectAudioDevice: Error setting audio output device!") + debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") } } - removeAudioMenus(); - setupAudioMenus(); + Menu.menuItemEvent.connect(switchAudioDevice); } function restoreAudio() { if (switchedAudioInputToHMD) { - print("selectAudioDevice: Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); - switchAudioDevice(true, previousSelectedInputAudioDevice); + debug("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); + switchAudioDevice("Use " + previousSelectedInputAudioDevice + " for Input"); switchedAudioInputToHMD = false; } if (switchedAudioOutputToHMD) { - print("selectAudioDevice: Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); - switchAudioDevice(false, previousSelectedOutputAudioDevice); + debug("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); + switchAudioDevice("Use " + previousSelectedOutputAudioDevice + " for Output"); switchedAudioOutputToHMD = false; } } +// Some HMDs (like Oculus CV1) have a built in audio device. If they +// do, then this function will handle switching to that device automatically +// when you goActive with the HMD active. function checkHMDAudio() { // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { - print("selectAudioDevice: HMD Active state changed!"); + debug("HMD Active state changed!"); // We're putting the HMD on; switch to those devices if (HMD.active) { - print("selectAudioDevice: HMD is now Active."); + debug("HMD is now Active."); var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); - print("selectAudioDevice: hmdPreferredAudioInput: " + hmdPreferredAudioInput); - print("selectAudioDevice: hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); + debug("hmdPreferredAudioInput: " + hmdPreferredAudioInput); + debug("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); if (hmdPreferredAudioInput !== "") { - print("selectAudioDevice: HMD has preferred audio input device."); + debug("HMD has preferred audio input device."); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); - print("selectAudioDevice: previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); + debug("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { - print("selectAudioDevice: Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); switchedAudioInputToHMD = true; - switchAudioDevice(true, hmdPreferredAudioInput); + switchAudioDevice("Use " + hmdPreferredAudioInput + " for Input"); } } if (hmdPreferredAudioOutput !== "") { - print("selectAudioDevice: HMD has preferred audio output device."); + debug("HMD has preferred audio output device."); previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); - print("selectAudioDevice: previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); + debug("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { - print("selectAudioDevice: Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); switchedAudioOutputToHMD = true; - switchAudioDevice(false, hmdPreferredAudioOutput); + switchAudioDevice("Use " + hmdPreferredAudioOutput + " for Output"); } } } else { - print("selectAudioDevice: HMD no longer active. Restoring audio I/O devices..."); + debug("HMD no longer active. Restoring audio I/O devices..."); restoreAudio(); } } wasHmdActive = HMD.active; } -/**************************************** - END FUNCTION DEFINITIONS -****************************************/ +// +// END FUNCTION DEFINITIONS +// -/**************************************** - BEGIN SCRIPT BODY -****************************************/ -// Have a small delay before the menus get setup so the audio devices can switch to the last selected ones +// +// BEGIN SCRIPT BODY +// +// Wait for the C++ systems to fire up before trying to do anything with audio devices Script.setTimeout(function () { - print("selectAudioDevice: Connecting deviceChanged(), displayModeChanged(), and menuItemEvent()"); + debug("Connecting deviceChanged(), displayModeChanged(), and switchAudioDevice()..."); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - Menu.menuItemEvent.connect(menuItemEvent); - print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); + Menu.menuItemEvent.connect(switchAudioDevice); + debug("Setting up Audio I/O menu for the first time..."); setupAudioMenus(); checkDeviceMismatch(); - print("selectAudioDevice: Checking HMD audio status...") + debug("Checking HMD audio status...") checkHMDAudio(); }, 3000); -print("selectAudioDevice: Connecting scriptEnding()"); +debug("Connecting scriptEnding()"); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); - Menu.menuItemEvent.disconnect(menuItemEvent); + Menu.menuItemEvent.disconnect(switchAudioDevice); HMD.displayModeChanged.disconnect(checkHMDAudio); AudioDevice.deviceChanged.disconnect(onDevicechanged); }); +// +// END SCRIPT BODY +// + }()); // END LOCAL_SCOPE From 1bdef141c3626ea1bd9ab7d8c4140be8c56414b5 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 28 Mar 2017 15:33:54 -0400 Subject: [PATCH 07/11] simplify audio menu parsing --- scripts/system/selectAudioDevice.js | 110 ++++++++++++---------------- 1 file changed, 47 insertions(+), 63 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index f3d40820cb..bc7906712a 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -15,34 +15,19 @@ (function() { // BEGIN LOCAL_SCOPE -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; -} - -if (typeof String.prototype.endsWith != 'function') { - String.prototype.endsWith = function (str){ - return this.slice(-str.length) == str; - }; -} - -if (typeof String.prototype.trimStartsWith != 'function') { - String.prototype.trimStartsWith = function (str){ - if (this.startsWith(str)) { - return this.substr(str.length); - } - return this; - }; -} - -if (typeof String.prototype.trimEndsWith != 'function') { - String.prototype.trimEndsWith = function (str){ - if (this.endsWith(str)) { - return this.substr(0,this.length - str.length); - } - return this; - }; +const INPUT = "Input"; +const OUTPUT = "Output"; +function parseMenuItem(item) { + const USE = "Use "; + const FOR_INPUT = " for " + INPUT; + const FOR_OUTPUT = " for " + OUTPUT; + if (item.slice(0, USE.length) == USE) { + if (item.slice(-FOR_INPUT.length) == FOR_INPUT) { + return { device: item.slice(USE.length, -FOR_INPUT.length), mode: INPUT }; + } else if (item.slice(-FOR_OUTPUT.length) == FOR_OUTPUT) { + return { device: item.slice(USE.length, -FOR_OUTPUT.length), mode: OUTPUT }; + } + } } // @@ -146,45 +131,44 @@ function onDevicechanged() { function switchAudioDevice(audioDeviceMenuString) { Menu.menuItemEvent.disconnect(switchAudioDevice); - if (audioDeviceMenuString.startsWith("Use ")) { - if (audioDeviceMenuString.endsWith(" for Input")) { - var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Input"); - var currentInputDevice = AudioDevice.getInputDevice(); - if (selectedDevice != currentInputDevice) { - debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); - Menu.setIsOptionChecked("Use " + currentInputDevice + " for Input", false); - if (AudioDevice.setInputDevice(selectedDevice)) { - Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); - Menu.setIsOptionChecked(audioDeviceMenuString, true); - } else { - debug("Error setting audio input device!") - Menu.setIsOptionChecked(audioDeviceMenuString, false); - } - } else { - debug("Selected input device is the same as the current input device!") + var selection = parseMenuItem(audioDeviceMenuString); + if (!selection) { + debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") + } else if (selection.mode == INPUT) { + var selectedDevice = selection.device; + var currentInputDevice = AudioDevice.getInputDevice(); + if (selectedDevice != currentInputDevice) { + debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentInputDevice + " for Input", false); + if (AudioDevice.setInputDevice(selectedDevice)) { + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); Menu.setIsOptionChecked(audioDeviceMenuString, true); - AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) - } - } else if (audioDeviceMenuString.endsWith(" for Output")) { - var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Output"); - var currentOutputDevice = AudioDevice.getOutputDevice(); - if (selectedDevice != currentOutputDevice) { - debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); - Menu.setIsOptionChecked("Use " + currentOutputDevice + " for Output", false); - if (AudioDevice.setOutputDevice(selectedDevice)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); - Menu.setIsOptionChecked(audioDeviceMenuString, true); - } else { - debug("Error setting audio output device!") - Menu.setIsOptionChecked(audioDeviceMenuString, false); - } } else { - debug("Selected output device is the same as the current output device!") - Menu.setIsOptionChecked(audioDeviceMenuString, true); - AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + debug("Error setting audio input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); } } else { - debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") + debug("Selected input device is the same as the current input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + } + } else if (selection.mode == OUTPUT) { + var selectedDevice = selection.device; + var currentOutputDevice = AudioDevice.getOutputDevice(); + if (selectedDevice != currentOutputDevice) { + debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentOutputDevice + " for Output", false); + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + Menu.setIsOptionChecked(audioDeviceMenuString, true); + } else { + debug("Error setting audio output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); + } + } else { + debug("Selected output device is the same as the current output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } } From 5e0cfb61376a3a0a7a5876fd0afecef0d5d697f0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 28 Mar 2017 15:34:13 -0400 Subject: [PATCH 08/11] short-circuit audio switching on missing device --- scripts/system/selectAudioDevice.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index bc7906712a..48ab7fea7f 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -129,6 +129,11 @@ function onDevicechanged() { } function switchAudioDevice(audioDeviceMenuString) { + // if the device is not plugged in, short-circuit + if (!~audioDevicesList.indexOf(audioDeviceMenuString)) { + return; + } + Menu.menuItemEvent.disconnect(switchAudioDevice); var selection = parseMenuItem(audioDeviceMenuString); From 06bf5807ae3a0017832db495616d85a518da35e0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 28 Mar 2017 15:34:42 -0400 Subject: [PATCH 09/11] fix audio setting persistence for already selected device --- scripts/system/selectAudioDevice.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 48ab7fea7f..5d1d61b7d3 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -154,6 +154,7 @@ function switchAudioDevice(audioDeviceMenuString) { } } else { debug("Selected input device is the same as the current input device!") + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); Menu.setIsOptionChecked(audioDeviceMenuString, true); AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } @@ -172,6 +173,7 @@ function switchAudioDevice(audioDeviceMenuString) { } } else { debug("Selected output device is the same as the current output device!") + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); Menu.setIsOptionChecked(audioDeviceMenuString, true); AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } From c30ab4de8b3b25ff30cb5c6e4a495e0c9b87891e Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 29 Mar 2017 18:48:22 -0400 Subject: [PATCH 10/11] rm extra setDevice --- scripts/system/selectAudioDevice.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 5d1d61b7d3..e57bf34192 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -123,8 +123,6 @@ function removeAudioMenus() { function onDevicechanged() { debug("System audio devices changed. Removing and replacing Audio Menus..."); setupAudioMenus(); - AudioDevice.setOutputDevice(AudioDevice.getOutputDevice()); - AudioDevice.setInputDevice(AudioDevice.getInputDevice()); checkDeviceMismatch(); } From 4a9fbf2bbd5d7820b39e1efa637c9d344de3a14d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 29 Mar 2017 19:03:05 -0400 Subject: [PATCH 11/11] delay 200ms to avoid recursive audio dev switches --- scripts/system/selectAudioDevice.js | 36 ++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index e57bf34192..2dd426932f 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -42,6 +42,7 @@ var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; +var skipMenuEvents = true; // // BEGIN FUNCTION DEFINITIONS @@ -54,7 +55,9 @@ function debug() { function setupAudioMenus() { - Menu.menuItemEvent.disconnect(switchAudioDevice); + // menu events can be triggered asynchronously; skip them for 200ms to avoid recursion and false switches + skipMenuEvents = true; + Script.setTimeout(function() { skipMenuEvents = false; }, 200); removeAudioMenus(); @@ -85,8 +88,6 @@ function setupAudioMenus() { }); audioDevicesList.push(audioDeviceMenuString); } - - Menu.menuItemEvent.connect(switchAudioDevice); } function checkDeviceMismatch() { @@ -126,19 +127,30 @@ function onDevicechanged() { checkDeviceMismatch(); } +function onMenuEvent(audioDeviceMenuString) { + if (!skipMenuEvents) { + switchAudioDevice(audioDeviceMenuString); + } +} + function switchAudioDevice(audioDeviceMenuString) { // if the device is not plugged in, short-circuit if (!~audioDevicesList.indexOf(audioDeviceMenuString)) { return; } - Menu.menuItemEvent.disconnect(switchAudioDevice); - var selection = parseMenuItem(audioDeviceMenuString); if (!selection) { - debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") - } else if (selection.mode == INPUT) { - var selectedDevice = selection.device; + debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'"); + return; + } + + // menu events can be triggered asynchronously; skip them for 200ms to avoid recursion and false switches + skipMenuEvents = true; + Script.setTimeout(function() { skipMenuEvents = false; }, 200); + + var selectedDevice = selection.device; + if (selection.mode == INPUT) { var currentInputDevice = AudioDevice.getInputDevice(); if (selectedDevice != currentInputDevice) { debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); @@ -157,7 +169,6 @@ function switchAudioDevice(audioDeviceMenuString) { AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } } else if (selection.mode == OUTPUT) { - var selectedDevice = selection.device; var currentOutputDevice = AudioDevice.getOutputDevice(); if (selectedDevice != currentOutputDevice) { debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); @@ -176,8 +187,6 @@ function switchAudioDevice(audioDeviceMenuString) { AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } } - - Menu.menuItemEvent.connect(switchAudioDevice); } function restoreAudio() { @@ -234,6 +243,7 @@ function checkHMDAudio() { } wasHmdActive = HMD.active; } + // // END FUNCTION DEFINITIONS // @@ -246,7 +256,7 @@ Script.setTimeout(function () { debug("Connecting deviceChanged(), displayModeChanged(), and switchAudioDevice()..."); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - Menu.menuItemEvent.connect(switchAudioDevice); + Menu.menuItemEvent.connect(onMenuEvent); debug("Setting up Audio I/O menu for the first time..."); setupAudioMenus(); checkDeviceMismatch(); @@ -258,7 +268,7 @@ debug("Connecting scriptEnding()"); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); - Menu.menuItemEvent.disconnect(switchAudioDevice); + Menu.menuItemEvent.disconnect(onMenuEvent); HMD.displayModeChanged.disconnect(checkHMDAudio); AudioDevice.deviceChanged.disconnect(onDevicechanged); });