Have I finally tamed the beast?

This commit is contained in:
Zach Fox 2017-03-27 16:15:11 -07:00
parent 73a77f7f25
commit 0ae4ce7e98

View file

@ -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 INPUT_DEVICE_SETTING = "audio_input_device";
const OUTPUT_DEVICE_SETTING = "audio_output_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device";
var audioDevicesList = []; 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 wasHmdActive = false; // assume it's not active to start
var switchedAudioInputToHMD = false; var switchedAudioInputToHMD = false;
var switchedAudioOutputToHMD = false; var switchedAudioOutputToHMD = false;
var previousSelectedInputAudioDevice = ""; var previousSelectedInputAudioDevice = "";
var previousSelectedOutputAudioDevice = ""; var previousSelectedOutputAudioDevice = "";
/**************************************** //
BEGIN FUNCTION DEFINITIONS // BEGIN FUNCTION DEFINITIONS
****************************************/ //
function setupAudioMenus() { function debug() {
Menu.menuItemEvent.disconnect(menuItemEvent); 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"); Menu.addSeparator("Audio", "Input Audio Device");
var inputDevices = AudioDevice.getInputDevices(); var inputDevices = AudioDevice.getInputDevices();
print("selectAudioDevice: Audio input devices: " + inputDevices);
for (var i = 0; i < inputDevices.length; i++) { for (var i = 0; i < inputDevices.length; i++) {
var menuItem = "Use " + inputDevices[i] + " for Input"; var audioDeviceMenuString = "Use " + inputDevices[i] + " for Input";
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Audio", menuName: "Audio",
menuItemName: menuItem, menuItemName: audioDeviceMenuString,
isCheckable: true, isCheckable: true,
isChecked: inputDevices[i] == AudioDevice.getInputDevice() 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"); Menu.addSeparator("Audio", "Output Audio Device");
var outputDevices = AudioDevice.getOutputDevices(); var outputDevices = AudioDevice.getOutputDevices();
print("selectAudioDevice: Audio output devices: " + outputDevices);
for (var i = 0; i < outputDevices.length; i++) { for (var i = 0; i < outputDevices.length; i++) {
var menuItem = "Use " + outputDevices[i] + " for Output"; var audioDeviceMenuString = "Use " + outputDevices[i] + " for Output";
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Audio", menuName: "Audio",
menuItemName: menuItem, menuItemName: audioDeviceMenuString,
isCheckable: true, isCheckable: true,
isChecked: outputDevices[i] == AudioDevice.getOutputDevice() isChecked: outputDevices[i] == AudioDevice.getOutputDevice()
}); });
audioDevicesList.push(menuItem); audioDevicesList.push(audioDeviceMenuString);
} }
Menu.menuItemEvent.connect(menuItemEvent); Menu.menuItemEvent.connect(switchAudioDevice);
} }
function checkDeviceMismatch() { function checkDeviceMismatch() {
var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING);
var interfaceInputDevice = AudioDevice.getInputDevice(); var interfaceInputDevice = AudioDevice.getInputDevice();
if (interfaceInputDevice != inputDeviceSetting) { if (interfaceInputDevice != inputDeviceSetting) {
print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", AudioDevice.getInputDevice()); debug("Input Setting & Device mismatch! Input SETTING: " + inputDeviceSetting + "Input DEVICE IN USE: " + interfaceInputDevice);
switchAudioDevice(true, inputDeviceSetting); switchAudioDevice("Use " + inputDeviceSetting + " for Input");
} }
var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING);
var interfaceOutputDevice = AudioDevice.getOutputDevice(); var interfaceOutputDevice = AudioDevice.getOutputDevice();
if (interfaceOutputDevice != outputDeviceSetting) { if (interfaceOutputDevice != outputDeviceSetting) {
print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", interfaceOutputDevice); debug("Output Setting & Device mismatch! Output SETTING: " + outputDeviceSetting + "Output DEVICE IN USE: " + interfaceOutputDevice);
switchAudioDevice(false, outputDeviceSetting); switchAudioDevice("Use " + outputDeviceSetting + " for Output");
} }
} }
@ -131,129 +136,146 @@ function removeAudioMenus() {
} }
function onDevicechanged() { function onDevicechanged() {
print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); debug("System audio devices changed. Removing and replacing Audio Menus...");
removeAudioMenus();
setupAudioMenus(); setupAudioMenus();
AudioDevice.setOutputDevice(AudioDevice.getOutputDevice());
AudioDevice.setInputDevice(AudioDevice.getInputDevice());
checkDeviceMismatch(); checkDeviceMismatch();
} }
function menuItemEvent(menuItem) { function switchAudioDevice(audioDeviceMenuString) {
if (menuItem.startsWith("Use ")) { Menu.menuItemEvent.disconnect(switchAudioDevice);
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(isInput, device) { if (audioDeviceMenuString.startsWith("Use ")) {
if (isInput) { if (audioDeviceMenuString.endsWith(" for Input")) {
print("selectAudioDevice: Switching audio INPUT device to:", device); var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Input");
if (AudioDevice.setInputDevice(device)) { var currentInputDevice = AudioDevice.getInputDevice();
Settings.setValue(INPUT_DEVICE_SETTING, device); 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 { } else {
print("selectAudioDevice: Error setting audio input device!") debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'")
}
} 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!")
} }
} }
removeAudioMenus(); Menu.menuItemEvent.connect(switchAudioDevice);
setupAudioMenus();
} }
function restoreAudio() { function restoreAudio() {
if (switchedAudioInputToHMD) { if (switchedAudioInputToHMD) {
print("selectAudioDevice: Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); debug("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice);
switchAudioDevice(true, previousSelectedInputAudioDevice); switchAudioDevice("Use " + previousSelectedInputAudioDevice + " for Input");
switchedAudioInputToHMD = false; switchedAudioInputToHMD = false;
} }
if (switchedAudioOutputToHMD) { if (switchedAudioOutputToHMD) {
print("selectAudioDevice: Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); debug("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice);
switchAudioDevice(false, previousSelectedOutputAudioDevice); switchAudioDevice("Use " + previousSelectedOutputAudioDevice + " for Output");
switchedAudioOutputToHMD = false; 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() { function checkHMDAudio() {
// HMD Active state is changing; handle switching // HMD Active state is changing; handle switching
if (HMD.active != wasHmdActive) { 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 // We're putting the HMD on; switch to those devices
if (HMD.active) { if (HMD.active) {
print("selectAudioDevice: HMD is now Active."); debug("HMD is now Active.");
var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioInput = HMD.preferredAudioInput();
var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput();
print("selectAudioDevice: hmdPreferredAudioInput: " + hmdPreferredAudioInput); debug("hmdPreferredAudioInput: " + hmdPreferredAudioInput);
print("selectAudioDevice: hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); debug("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput);
if (hmdPreferredAudioInput !== "") { if (hmdPreferredAudioInput !== "") {
print("selectAudioDevice: HMD has preferred audio input device."); debug("HMD has preferred audio input device.");
previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING);
print("selectAudioDevice: previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); debug("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice);
if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) {
print("selectAudioDevice: Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput);
switchedAudioInputToHMD = true; switchedAudioInputToHMD = true;
switchAudioDevice(true, hmdPreferredAudioInput); switchAudioDevice("Use " + hmdPreferredAudioInput + " for Input");
} }
} }
if (hmdPreferredAudioOutput !== "") { if (hmdPreferredAudioOutput !== "") {
print("selectAudioDevice: HMD has preferred audio output device."); debug("HMD has preferred audio output device.");
previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING);
print("selectAudioDevice: previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); debug("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice);
if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) {
print("selectAudioDevice: Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput);
switchedAudioOutputToHMD = true; switchedAudioOutputToHMD = true;
switchAudioDevice(false, hmdPreferredAudioOutput); switchAudioDevice("Use " + hmdPreferredAudioOutput + " for Output");
} }
} }
} else { } else {
print("selectAudioDevice: HMD no longer active. Restoring audio I/O devices..."); debug("HMD no longer active. Restoring audio I/O devices...");
restoreAudio(); restoreAudio();
} }
} }
wasHmdActive = HMD.active; wasHmdActive = HMD.active;
} }
/**************************************** //
END FUNCTION DEFINITIONS // END FUNCTION DEFINITIONS
****************************************/ //
/**************************************** //
BEGIN SCRIPT BODY // BEGIN SCRIPT BODY
****************************************/ //
// Have a small delay before the menus get setup so the audio devices can switch to the last selected ones // Wait for the C++ systems to fire up before trying to do anything with audio devices
Script.setTimeout(function () { Script.setTimeout(function () {
print("selectAudioDevice: Connecting deviceChanged(), displayModeChanged(), and menuItemEvent()"); debug("Connecting deviceChanged(), displayModeChanged(), and switchAudioDevice()...");
AudioDevice.deviceChanged.connect(onDevicechanged); AudioDevice.deviceChanged.connect(onDevicechanged);
HMD.displayModeChanged.connect(checkHMDAudio); HMD.displayModeChanged.connect(checkHMDAudio);
Menu.menuItemEvent.connect(menuItemEvent); Menu.menuItemEvent.connect(switchAudioDevice);
print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); debug("Setting up Audio I/O menu for the first time...");
setupAudioMenus(); setupAudioMenus();
checkDeviceMismatch(); checkDeviceMismatch();
print("selectAudioDevice: Checking HMD audio status...") debug("Checking HMD audio status...")
checkHMDAudio(); checkHMDAudio();
}, 3000); }, 3000);
print("selectAudioDevice: Connecting scriptEnding()"); debug("Connecting scriptEnding()");
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
restoreAudio(); restoreAudio();
removeAudioMenus(); removeAudioMenus();
Menu.menuItemEvent.disconnect(menuItemEvent); Menu.menuItemEvent.disconnect(switchAudioDevice);
HMD.displayModeChanged.disconnect(checkHMDAudio); HMD.displayModeChanged.disconnect(checkHMDAudio);
AudioDevice.deviceChanged.disconnect(onDevicechanged); AudioDevice.deviceChanged.disconnect(onDevicechanged);
}); });
//
// END SCRIPT BODY
//
}()); // END LOCAL_SCOPE }()); // END LOCAL_SCOPE