* wip on new ftue

This commit is contained in:
Seth Call 2014-04-16 17:11:30 +00:00
parent ac1b5d2e42
commit d1267dff53
3 changed files with 300 additions and 88 deletions

View File

@ -157,6 +157,10 @@
return 'Good Device';
}
function FTUEIsMusicDeviceWDM() {
return false;
}
function RegisterVolChangeCallBack(functionName) {
dbg('RegisterVolChangeCallBack');
}
@ -684,6 +688,7 @@
this.FTUEGetAllAudioConfigurations = FTUEGetAllAudioConfigurations;
this.FTUEGetGoodAudioConfigurations = FTUEGetGoodAudioConfigurations;
this.FTUEGetConfigurationDevice = FTUEGetConfigurationDevice;
this.FTUEIsMusicDeviceWDM = FTUEIsMusicDeviceWDM;
// Session
this.SessionAddTrack = SessionAddTrack;

View File

@ -16,6 +16,9 @@
var self = null;
var operatingSystem = null;
// populated by loadDevices
var deviceInformation = null;
// SELECT DEVICE STATE
var validScore = false;
@ -32,18 +35,27 @@
var audioDeviceBehavior = {
MacOSX_builtin : {
display: 'MacOSX Built-In',
videoURL: undefined
},
MACOSX_interface : {
display: 'MacOSX external interface',
videoURL: undefined
},
Win32_wdm : {
display: 'Windows WDM',
videoURL: undefined
},
Win32_asio : {
display: 'Windows ASIO',
videoURL: undefined
},
Win32_asio4all : {
display: 'Windows ASIO4ALL',
videoURL: undefined
},
Linux : {
display: 'Linux',
videoURL: undefined
}
}
@ -65,8 +77,66 @@
var $audioOutput = $currentWizardStep.find('.select-audio-output-device');
var $bufferIn = $currentWizardStep.find('.select-buffer-in');
var $bufferOut = $currentWizardStep.find('.select-buffer-out');
var $nextButton = $ftueButtons.find('.btn-next');
var $frameSize = $currentWizardStep.find('.select-frame-size');
var $inputPorts = $currentWizardStep.find('.input-ports');
var $outputPorts = $currentWizardStep.find('.output-ports');
var $scoreReport = $currentWizardStep.find('.results');
var $nextButton = $ftueButtons.find('.btn-next');
// should return one of:
// * MacOSX_builtin
// * MACOSX_interface
// * Win32_wdm
// * Win32_asio
// * Win32_asio4all
// * Linux
function determineDeviceType(deviceId, displayName) {
if(operatingSystem == "MacOSX") {
if(displayName.toLowerCase().trim() == "built-in") {
return "MacOSX_builtin";
}
else {
return "MacOSX_interface";
}
}
else if(operatingSystem == "Win32") {
if(context.jamClient.FTUEIsMusicDeviceWDM(deviceId)) {
return "Win32_wdm";
}
else if(displayName.toLowerCase().indexOf("asio4all") > -1) {
return "Win32_asio4all"
}
else {
return "Win32_asio";
}
}
else {
return "Linux";
}
}
function loadDevices() {
var devices = context.jamClient.FTUEGetDevices(false);
var loadedDevices = {};
// augment these devices by determining their type
context._.each(devices, function(displayName, deviceId) {
var deviceInfo = {};
deviceInfo.id = deviceId;
deviceInfo.type = determineDeviceType(deviceId, displayName);
deviceInfo.displayType = audioDeviceBehavior[deviceInfo.type].display;
deviceInfo.displayName = deviceInfo.displayName;
loadedDevices[deviceId] = deviceInfo;
})
deviceInformation = context._.keys(loadedDevices).sort();
logger.debug(context.JK.dlen(deviceInformation) + " devices loaded." , deviceInformation);
}
// returns a deviceInfo hash for the device matching the deviceId, or null.
function findDevice(deviceId) {
@ -81,18 +151,214 @@
return $audioOutput.val();
}
function selectedFramesize() {
return parseFloat($frameSize.val());
}
function selectedBufferIn() {
return parseFloat($frameSize.val());
}
function selectedBufferOut() {
return parseFloat($frameSize.val());
}
function initializeNextButtonState() {
console.log(context.jamClient.FTUEGetDevices(false));
console.log("chat devices", jamClient.FTUEGetChatInputs());
$nextButton.removeClass('button-orange button-grey');
if(validScore) $nextButton.addClass('button-orange');
else $nextButton.addClass('button-grey');
}
function audioDeviceUnselected() {
function initializeAudioInput() {
var optionsHtml = '';
optionsHtml = '<option selected="selected" value="">Choose...</option>';
context._.each(deviceInformation, function(deviceInfo, deviceId) {
optionsHtml += '<option title="' + deviceInfo.displayName + '" value="' + deviceId + '">' + deviceInfo.displayName + '</option>';
});
$audioInput.html(optionsHtml);
alert(optionsHtml)
context.JK.dropdown($audioInput);
initializeAudioInputChanged();
}
function initializeAudioOutput() {
var optionsHtml = '';
optionsHtml = '<option selected="selected" value="">Same as Input...</option>';
context._.each(deviceInformation, function(deviceInfo, deviceId) {
optionsHtml += '<option title="' + deviceInfo.displayName + '" value="' + deviceId + '">' + deviceInfo.displayName + '</option>';
});
$audioOutput.html(optionsHtml);
context.JK.dropdown($audioOutput);
initializeAudioOutputChanged();
}
function initializeFramesize() {
}
function initializeFormElements() {
if(!deviceInformation) throw "devices are not initialized";
initializeAudioInput();
initializeAudioOutput();
initializeFramesize();
initializeBuffers();
}
function resetFrameBuffers() {
$frameSize.val('2.5');
$bufferIn.val('0');
$bufferOut.val('0');
}
function clearInputPorts() {
$inputPorts.empty();
}
function clearOutputPorts() {
$outputPorts.empty();
}
function resetScoreReport() {
$scoreReport.empty();
}
function updateScoreReport(latencyResult) {
var latencyClass = "neutral";
var latencyValue = 'N/A';
var validLatency = false;
if (latencyResult && latencyResult.latencyknown) {
var latency = latencyResult.latency;
latencyValue = Math.round(latencyValue * 100) / 100;
if (latency.latency <= 10) {
latencyClass = "good";
validLatency = true;
} else if (latency.latency <= 20) {
latencyClass = "acceptable";
validLatency = true;
} else {
latencyClass = "bad";
}
}
validScore = validLatency; // validScore may become based on IO variance too
$scoreReport.html(latencyValue);
}
function loadAudioDrivers() {
var drivers = context.jamClient.FTUEGetDevices(false);
var chatDrivers = jamClient.FTUEGetChatInputs();
var optionsHtml = '<option selected="selected" value="">Choose...</option>';
var chatOptionsHtml = '<option selected="selected" value="">Choose...</option>';
var driverOptionFunc = function (driverKey, index, list) {
if(!drivers[driverKey]) {
logger.debug("skipping unknown device:", driverKey)
}
else {
optionsHtml += '<option title="' + drivers[driverKey] + '" value="' + driverKey + '">' + drivers[driverKey] + '</option>';
}
};
var chatOptionFunc = function (driverKey, index, list) {
chatOptionsHtml += '<option value="' + driverKey + '">' + chatDrivers[driverKey]+ '</option>';
};
var selectors = [
'[layout-wizard-step="0"] .settings-2-device select',
'[layout-wizard-step="2"] .settings-driver select'
];
// handle standard devices
var sortedDeviceKeys = context._.keys(drivers).sort();
context._.each(sortedDeviceKeys, driverOptionFunc);
$.each(selectors, function (index, selector) {
var $select = $(selector);
$select.empty();
$select.html(optionsHtml);
context.JK.dropdown($select);
});
selectors = ['[layout-wizard-step="0"] .settings-2-voice select'];
var sortedVoiceDeviceKeys = context._.keys(chatDrivers).sort();
// handle voice inputs
context._.each(sortedVoiceDeviceKeys, chatOptionFunc);
$.each(selectors, function (index, selector) {
var $select = $(selector);
$select.empty();
$select.html(chatOptionsHtml);
context.JK.dropdown($select);
});
}
function audioInputDeviceUnselected() {
validScore = false;
initializeNextButtonState();
resetFrameBuffers();
clearInputPorts();
}
function renderScoringStarted() {
validScore = false;
initializeNextButtonState();
resetScoreReport();
}
function renderScoringStopped() {
initializeNextButtonState();
}
// Given a latency structure, update the view.
function newFtueUpdateLatencyView(latency) {
var $report = $('.ftue-new .latency .report');
var $instructions = $('.ftue-new .latency .instructions');
var latencyClass = "neutral";
var latencyValue = "N/A";
var $saveButton = $('#btn-ftue-2-save');
if (latency && latency.latencyknown) {
latencyValue = latency.latency;
// Round latency to two decimal places.
latencyValue = Math.round(latencyValue * 100) / 100;
if (latency.latency <= 10) {
latencyClass = "good";
setSaveButtonState($saveButton, true);
} else if (latency.latency <= 20) {
latencyClass = "acceptable";
setSaveButtonState($saveButton, true);
} else {
latencyClass = "bad";
setSaveButtonState($saveButton, false);
}
} else {
latencyClass = "unknown";
setSaveButtonState($saveButton, false);
}
$('.ms-label', $report).html(latencyValue);
$('p', $report).html('milliseconds');
$report.removeClass('good acceptable bad unknown');
$report.addClass(latencyClass);
var instructionClasses = ['neutral', 'good', 'acceptable', 'unknown', 'bad', 'start', 'loading'];
$.each(instructionClasses, function (idx, val) {
$('p.' + val, $instructions).hide();
});
if (latency === 'loading') {
$('p.loading', $instructions).show();
} else {
$('p.' + latencyClass, $instructions).show();
renderStopNewFtueLatencyTesting();
}
}
function initializeWatchVideo() {
@ -103,7 +369,7 @@
context.JK.Banner.showAlert('You must first choose an Audio Input Device so that we can determine which video to show you.');
}
else {
var videoURL = audioDeviceBehavior[audioDevice.type];
var videoURL = audioDeviceBehavior[audioDevice.type].videoURL;
if(videoURL) {
$(this).attr('href', videoURL);
@ -124,7 +390,7 @@
throw "this button should be hidden";
}
else {
var videoURL = audioDeviceBehavior[audioDevice.type];
var videoURL = audioDeviceBehavior[audioDevice.type].videoURL;
if(videoURL) {
$(this).attr('href', videoURL);
@ -143,102 +409,43 @@
$audioInput.unbind('change').change(function(evt) {
var audioDeviceId = selectedAudioInput();
if(!audioDeviceId) {
audioDeviceUnselected();
audioInputDeviceUnselected();
return false;
}
var audioDevice = findDevice(selectedAudioInput());
if(!audioDevice) {
context.JK.alertSupportedNeeded('Unable to find device information for: ' + audioDevice);
context.JK.alertSupportedNeeded('Unable to find device information for: ' + audioDeviceId);
return false;
}
releaseDropdown(function () {
renderStartNewFtueLatencyTesting();
var $select = $(evt.currentTarget);
renderScoringStarted();
var $audioSelect = $('.ftue-new .settings-2-device select');
var audioDriverId = $audioSelect.val();
jamClient.FTUESetMusicDevice(audioDeviceId);
jamClient.FTUESetInputLatency(selectedAudioInput());
jamClient.FTUESetOutputLatency(selectedAudioOutput());
jamClient.FTUESetFrameSize(selectedFramesize());
if (!audioDriverId) {
context.JK.alertSupportNeeded();
logger.debug("Calling FTUESave(false)");
jamClient.FTUESave(false);
renderStopNewFtueLatencyTesting();
// reset back to 'Choose...'
newFtueEnableControls(false);
return;
}
jamClient.FTUESetMusicDevice(audioDriverId);
var latency = jamClient.FTUEGetExpectedLatency();
console.log("FTUEGetExpectedLatency: %o", latency);
var musicInputs = jamClient.FTUEGetMusicInputs();
var musicOutputs = jamClient.FTUEGetMusicOutputs();
// set the music input to the first available input,
// and output to the first available output
var kin = null, kout = null, k = null;
// TODO FIXME - this jamClient call returns a dictionary.
// It's difficult to know what to auto-choose.
// For example, with my built-in audio, the keys I get back are
// digital in, line in, mic in and stereo mix. Which should we pick for them?
for (k in musicInputs) {
kin = k;
break;
}
for (k in musicOutputs) {
kout = k;
break;
}
var result;
if (kin && kout) {
jamClient.FTUESetMusicInput(kin);
jamClient.FTUESetMusicOutput(kout);
} else {
// TODO FIXME - how to handle a driver selection where we are unable to
// autoset both inputs and outputs? (I'd think this could happen if either
// the input or output side returned no values)
renderStopNewFtueLatencyTesting();
console.log("invalid kin/kout %o/%o", kin, kout);
return;
}
newFtueUpdateLatencyView('loading');
newFtueEnableControls(true);
newFtueOsSpecificSettings();
// make sure whatever the user sees in the frontend is what the backend thinks
// this is necesasry because if you do a FTUE pass, close the client, and pick the same device
// the backend will *silently* use values from before, because the frontend does not query the backend
// for these values anywhere.
// setting all 3 of these cause 3 FTUE's. Instead, we set batchModify to true so that they don't call FtueSave(false), and call later ourselves
batchModify = true;
newFtueAsioFrameSizeToBackend($('#ftue-2-asio-framesize'));
newFtueAsioInputLatencyToBackend($('#ftue-2-asio-input-latency'));
newFtueAsioOutputLatencyToBackend($('#ftue-2-asio-output-latency'));
batchModify = false;
//setLevels(0);
renderVolumes();
logger.debug("Calling FTUESave(" + false + ")");
jamClient.FTUESave(false)
pendingFtueSave = false; // this is not really used in any real fashion. just setting back to false due to batch modify above
setVuCallbacks();
var latency = jamClient.FTUEGetExpectedLatency();
console.log("FTUEGetExpectedLatency: %o", latency);
newFtueUpdateLatencyView(latency);
});
})
renderScoringStopped();
});
}
function initializeAudioOutputChanged() {
}
function initializeStep() {
loadDevices();
initializeFormElements();
initializeNextButtonState();
initializeWatchVideo();
initializeAudioInputChanged();
}
initializeStep();

View File

@ -38,7 +38,7 @@
%select.w100.select-audio-input-device
%option None
%h2 Audio Input Ports
.ftue-box.list.ports.output-ports
.ftue-box.list.ports.input-ports
%a.button-orange.asio-settings-btn ASIO SETTINGS...
%a.button-orange.resync-btn RESYNC
.wizard-step-column
@ -46,7 +46,7 @@
%select.w100.select-audio-output-device
%option Same as input
%h2 Audio Output Ports
.ftue-box.list.ports.input-ports
.ftue-box.list.ports.output-ports
.frame-and-buffers
.framesize
%h2 Frame