(function (context, $) { "use strict"; context.JK = context.JK || {}; context.JK.StepLoopbackTest = function (app, dialog) { var ASSIGNMENT = context.JK.ASSIGNMENT; var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR; var gearUtils = context.JK.GearUtils; var logger = context.JK.logger; var $step = null; var frameBuffers = new context.JK.FrameBuffers(app); var gearTest = new context.JK.GearTest(app); var deviceInformation = null; var operatingSystem = null; var selectedDeviceInfo = null; var musicPorts = null; var $asioInputControlBtn = null; var $asioOutputControlBtn = null; var $resyncBtn = null; var $runTestBtn = null; var $audioInputDevice = null; var $audioOutputDevice = null; var $inputChannels = null; var $outputChannels = null; var $templateAudioPort = null; var $scoreReport = null; var $audioInputVuLeft = null; var $audioInputVuRight = null; var $audioInputFader = null; var $audioOutputVuLeft = null; var $audioOutputVuRight = null; var $audioOutputFader = null; var faderMap = { 'loopback-audio-input-fader': jamClient.FTUESetInputVolume, 'loopback-audio-output-fader': jamClient.FTUESetOutputVolume }; var faderReadMap = { 'loopback-audio-input-fader': jamClient.FTUEGetInputVolume, 'loopback-audio-output-fader': jamClient.FTUEGetOutputVolume }; function attemptScore() { gearTest.attemptScore(selectedDeviceInfo); } function invalidateScore() { gearTest.invalidateScore(); initializeNextButtonState(); } function updateDefaultBuffers() { // handle specific framesize settings if(selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm')) { var framesize = frameBuffers.selectedFramesize(); if(framesize == 2.5) { logger.debug("setting default buffers to 1/1"); frameBuffers.setBufferIn('1'); frameBuffers.setBufferOut('1'); } else if(framesize == 5) { logger.debug("setting default buffers to 3/2"); frameBuffers.setBufferIn('3'); frameBuffers.setBufferOut('2'); } else { logger.debug("setting default buffers to 6/5"); frameBuffers.setBufferIn('6'); frameBuffers.setBufferOut('5'); } } else { logger.debug("setting default buffers to 0/0"); frameBuffers.setBufferIn(0); frameBuffers.setBufferOut(0); } jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn()); jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut()); } function onFramesizeChanged() { context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']}); updateDefaultBuffers(); jamClient.FTUESetFrameSize(frameBuffers.selectedFramesize()); invalidateScore(); } function onBufferInChanged() { context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']}); jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn()); invalidateScore(); } function onBufferOutChanged() { context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']}); jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut()); invalidateScore(); } function freezeAudioInteraction() { logger.debug("loopback: freezing audio interaction"); frameBuffers.disable(); $asioInputControlBtn.on("click", false); $asioOutputControlBtn.on("click", false); $resyncBtn.on('click', false); $runTestBtn.on('click', false); } function unfreezeAudioInteraction() { logger.debug("unfreezing audio interaction"); frameBuffers.enable(); $asioInputControlBtn.off("click", false); $asioOutputControlBtn.off("click", false); $resyncBtn.off('click', false); $runTestBtn.off('click', false); } function getGearTest() { return gearTest; } function handleNext() { return true; } function handleBack() { return true; } function render(){ if(selectedDeviceInfo) { var inputBehavior = selectedDeviceInfo.input.behavior; var outputBehavior = selectedDeviceInfo.output.behavior; } else { var inputBehavior = null; var outputBehavior = null; } // handle ASIO visibility if (inputBehavior) { if (inputBehavior.showASIO) { $asioInputControlBtn.show(); } else { $asioInputControlBtn.hide(); } if(outputBehavior.showASIO && (selectedDeviceInfo.input.id != selectedDeviceInfo.output.id)) { $asioOutputControlBtn.show(); } else { $asioOutputControlBtn.hide(); } } else { // show no ASIO buttons $asioInputControlBtn.hide(); $asioOutputControlBtn.hide(); } if(selectedDeviceInfo) { $audioInputDevice.text(selectedDeviceInfo.input.info.displayName); $audioOutputDevice.text(selectedDeviceInfo.output.info.displayName); } else { $audioInputDevice.text('Unassigned'); $audioOutputDevice.text('Unassigned'); } $inputChannels.empty(); context._.each(musicPorts.inputs, function (inputChannel) { var $inputChannel = $(context._.template($templateAudioPort.html(), inputChannel, { variable: 'data' })); var $checkbox = $inputChannel.find('input'); if (gearUtils.isChannelAssigned(inputChannel)) { $checkbox.attr('checked', 'checked'); } context.JK.checkbox($checkbox).iCheck('disable'); $inputChannels.append($inputChannel); }); $outputChannels.empty(); context._.each(musicPorts.outputs, function (outputChannel) { var $outputPort = $(context._.template($templateAudioPort.html(), outputChannel, { variable: 'data' })); var $checkbox = $outputPort.find('input'); if (gearUtils.isChannelAssigned(outputChannel)) { $checkbox.attr('checked', 'checked'); } context.JK.checkbox($checkbox).iCheck('disable'); $outputChannels.append($outputPort); }); initializeVUMeters(); renderVolumes(); registerVuCallbacks(); } function initializeASIOButtons() { $asioInputControlBtn.unbind('click').click(function () { context.jamClient.FTUEOpenControlPanel(selectedDeviceInfo.input.id); }); $asioOutputControlBtn.unbind('click').click(function () { context.jamClient.FTUEOpenControlPanel(selectedDeviceInfo.output.id); }); } function initializeResync() { $resyncBtn.unbind('click').click(function () { attemptScore(); return false; }) } function initializeVUMeters() { var vuOptions = {vuType: "horizontal", lightCount: 12, lightWidth: 15, lightHeight: 3}; context.JK.VuHelpers.renderVU($audioInputVuLeft, vuOptions); context.JK.VuHelpers.renderVU($audioInputVuRight, vuOptions); context.JK.VuHelpers.renderVU($audioOutputVuLeft, vuOptions); context.JK.VuHelpers.renderVU($audioOutputVuRight, vuOptions); var faderOptions = {faderId: '', faderType: "horizontal", width: 163}; context.JK.FaderHelpers.renderFader($audioInputFader, faderOptions); context.JK.FaderHelpers.renderFader($audioOutputFader, faderOptions); $audioInputFader.on('fader_change', inputFaderChange); $audioOutputFader.on('fader_change', outputFaderChange); } // renders volumes based on what the backend says function renderVolumes() { // input var $inputFader = $audioInputFader.find('[control="fader"]'); var db = context.jamClient.FTUEGetInputVolume(); var faderPct = db + 80; context.JK.FaderHelpers.setHandlePosition($inputFader, faderPct); // output var $outputFader = $audioOutputFader.find('[control="fader"]'); var db = context.jamClient.FTUEGetOutputVolume(); var faderPct = db + 80; context.JK.FaderHelpers.setHandlePosition($outputFader, faderPct); } function inputFaderChange(e, data) { var mixerLevel = data.percentage - 80; // Convert our [0-100] to [-80 - +20] range context.jamClient.FTUESetInputVolume(mixerLevel); } function outputFaderChange(e, data) { var mixerLevel = data.percentage - 80; context.jamClient.FTUESetOutputVolume(mixerLevel); } function registerVuCallbacks() { logger.debug("loopback-wizard: registering vu callbacks"); jamClient.FTUERegisterVUCallbacks( "JK.loopbackAudioOutputVUCallback", "JK.loopbackAudioInputVUCallback", "JK.loopbackChatInputVUCallback" ); jamClient.SetVURefreshRate(200); } function initializeNextButtonState() { dialog.setNextState(gearTest.isGoodFtue()); } function initializeBackButtonState() { dialog.setBackState(!gearTest.isScoring()); } function renderScoringStarted() { initializeBackButtonState(); initializeNextButtonState(); freezeAudioInteraction(); } function renderScoringStopped() { initializeNextButtonState(); initializeBackButtonState(); unfreezeAudioInteraction(); } function onGearTestStarted(e, data) { renderScoringStarted(); } function onGearTestDone(e, data) { renderScoringStopped(); gearUtils.postDiagnostic(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, true); } function onGearTestFail(e, data) { renderScoringStopped(); gearUtils.postDiagnostic(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, true); } function beforeShow() { selectedDeviceInfo = gearUtils.selectedDeviceInfo(context.jamClient.FTUEGetInputMusicDevice(), context.jamClient.FTUEGetOutputMusicDevice()); deviceInformation = gearUtils.loadDeviceInfo(); musicPorts = jamClient.FTUEGetChannels(); render(); } function beforeHide() { logger.debug("loopback-wizard: unregistering vu callbacks"); jamClient.FTUERegisterVUCallbacks('', '', ''); } function initialize(_$step) { $step = _$step; $asioInputControlBtn = $step.find('.asio-settings-input-btn'); $asioOutputControlBtn = $step.find('.asio-settings-output-btn'); $resyncBtn = $step.find('.resync-btn'); $runTestBtn = $step.find('.run-test-btn'); $audioInputDevice = $step.find('.audio-device.input') $audioOutputDevice = $step.find('.audio-device.output') $inputChannels = $step.find('.input-ports') $outputChannels = $step.find('.output-ports') $templateAudioPort = $('#template-audio-port'); $scoreReport = $step.find('.results'); $audioInputVuLeft = $step.find('.audio-input-vu-left'); $audioInputVuRight = $step.find('.audio-input-vu-right'); $audioInputFader= $step.find('.audio-input-fader'); $audioOutputVuLeft = $step.find('.audio-output-vu-left'); $audioOutputVuRight = $step.find('.audio-output-vu-right'); $audioOutputFader= $step.find('.audio-output-fader'); operatingSystem = context.JK.GetOSAsString(); frameBuffers.initialize($step.find('.frame-and-buffers')); $(frameBuffers) .on(frameBuffers.FRAMESIZE_CHANGED, onFramesizeChanged) .on(frameBuffers.BUFFER_IN_CHANGED, onBufferInChanged) .on(frameBuffers.BUFFER_OUT_CHANGED, onBufferOutChanged) gearTest.initialize($scoreReport, false) $(gearTest) .on(gearTest.GEAR_TEST_START, onGearTestStarted) .on(gearTest.GEAR_TEST_DONE, onGearTestDone) .on(gearTest.GEAR_TEST_FAIL, onGearTestFail) $runTestBtn.click(attemptScore); initializeASIOButtons(); initializeResync(); context.JK.loopbackAudioInputVUCallback = function (dbValue) { context.JK.ftueVUCallback(dbValue, $audioInputVuLeft); context.JK.ftueVUCallback(dbValue, $audioInputVuRight); }; context.JK.loopbackAudioOutputVUCallback = function (dbValue) { context.JK.ftueVUCallback(dbValue, $audioOutputVuLeft); context.JK.ftueVUCallback(dbValue, $audioOutputVuRight); }; context.JK.loopbackChatInputVUCallback = function (dbValue) { }; } this.getGearTest = getGearTest; this.handleNext = handleNext; this.handleBack = handleBack; this.beforeShow = beforeShow; this.beforeHide = beforeHide; this.initialize = initialize; return this; } })(window, jQuery);