jam-cloud/web/app/assets/javascripts/wizard/gear_utils.js

274 lines
8.6 KiB
JavaScript

/**
* Common utility functions.
*/
(function (context, $) {
"use strict";
context.JK = context.JK || {};
var gearUtils = {};
var rest = new context.JK.Rest();
context.JK.GearUtils = gearUtils;
var logger = context.JK.logger;
var ASSIGNMENT = context.JK.ASSIGNMENT;
var VOICE_CHAT = context.JK.VOICE_CHAT;
var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR;
// checks if it's an assigned OUTPUT or ASSIGNED CHAT
gearUtils.isChannelAssigned = function (channel) {
return channel.assignment == ASSIGNMENT.CHAT || channel.assignment == ASSIGNMENT.OUTPUT || channel.assignment > 0;
}
gearUtils.createProfileName = function(deviceInfo, chatName) {
var isSameInOut = deviceInfo.input.id == deviceInfo.output.id;
var name = null;
if(isSameInOut) {
name = "In/Out: " + deviceInfo.input.info.displayName;
}
else {
name = "In: " + deviceInfo.input.info.displayName + ", Out: " + deviceInfo.output.info.displayName
}
logger.debug("creating profile name: " + name);
return name;
}
gearUtils.selectedDeviceInfo = function(audioInputDeviceId, audioOutputDeviceId, deviceInformation) {
if(!audioInputDeviceId) {
logger.debug("gearUtils.selectedDeviceInfo: no active input device");
return null;
}
if(!audioOutputDeviceId) {
logger.debug("gearUtils.selectedDeviceInfo: no active output device");
return null;
}
if(!deviceInformation) {
deviceInformation = gearUtils.loadDeviceInfo();
}
var input = deviceInformation[audioInputDeviceId];
var output = deviceInformation[audioOutputDeviceId];
var inputBehavior = AUDIO_DEVICE_BEHAVIOR[input.type];
var outputBehavior = AUDIO_DEVICE_BEHAVIOR[output.type];
return {
input: {
id: audioInputDeviceId,
info: input,
behavior: inputBehavior
},
output: {
id: audioOutputDeviceId,
info: output,
behavior: outputBehavior
}
}
}
gearUtils.loadDeviceInfo = function() {
var operatingSystem = context.JK.GetOSAsString();
// 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().indexOf("built-in") == 0) {
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";
}
}
var devices = context.jamClient.FTUEGetAudioDevices();
logger.debug("FTUEGetAudioDevices: " + JSON.stringify(devices));
var loadedDevices = {};
// augment these devices by determining their type
context._.each(devices.devices, function (device) {
if (device.name == "JamKazam Virtual Monitor") {
return;
}
var deviceInfo = {};
deviceInfo.id = device.guid;
deviceInfo.type = determineDeviceType(device.guid, device.display_name);
deviceInfo.displayType = AUDIO_DEVICE_BEHAVIOR[deviceInfo.type].display;
deviceInfo.displayName = device.display_name;
deviceInfo.inputCount = device.input_count;
deviceInfo.outputCount = device.output_count;
loadedDevices[device.guid] = deviceInfo;
})
logger.debug(context.JK.dlen(loadedDevices) + " devices loaded.", loadedDevices);
return loadedDevices;
}
gearUtils.ftueSummary = function(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, isAutomated) {
return {
os: operatingSystem,
version: context.jamClient.ClientUpdateVersion(),
success: gearTest.isGoodFtue(),
automated: isAutomated,
score: {
validLatencyScore: gearTest.isValidLatencyScore(),
validIOScore: gearTest.isValidIOScore(),
latencyScore: gearTest.getLatencyScore(),
ioScore : gearTest.getIOScore(),
},
audioParameters: {
frameSize: frameBuffers.selectedFramesize(),
bufferIn: frameBuffers.selectedBufferIn(),
bufferOut: frameBuffers.selectedBufferOut(),
},
devices: deviceInformation,
selectedDevice: selectedDeviceInfo
}
}
/**
* Lists all profiles, but marks profiles good: true/false.
* Also, current:true/false indicates which profile is active. (at most 1 profile will be marked current)
* This is to provide a unified view of FTUEGetAllAudioConfigurations & FTUEGetGoodAudioConfigurations
* @returns an array of profiles, where each profile is: {id: profile-name, good: boolean, class: 'bad' | 'good', current: boolean }
*/
gearUtils.getProfiles = function() {
var all = context.jamClient.FTUEGetAllAudioConfigurations();
var good = context.jamClient.FTUEGetGoodAudioConfigurations();
var current = context.jamClient.FTUEGetMusicProfileName();
var profiles = [];
context._.each(all, function(item) {
profiles.push({id: item, good: false, class:'bad', current: current == item})
});
if(good) {
for(var i = 0; i < good.length; i++) {
for(var j = 0; j < profiles.length; j++) {
if(good[i] == profiles[j].id) {
profiles[j].good = true;
profiles[j].class = 'good';
break;
}
}
}
}
return profiles;
}
gearUtils.postDiagnostic = function(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, isAutomated) {
rest.createDiagnostic({
type: 'GEAR_SELECTION',
data: {
client_type: context.JK.clientType(),
client_id:
context.JK.JamServer.clientID,
summary:gearUtils.ftueSummary(operatingSystem, deviceInformation, selectedDeviceInfo, gearTest, frameBuffers, isAutomated)}
});
}
// complete list of possibly chatInputs, whether currently assigned as the chat channel or not
// each item should be {id: channelId, name: channelName, assignment: channel assignment}
gearUtils.getChatInputs = function(){
var musicPorts = jamClient.FTUEGetChannels();
//var chatsOnCurrentDevice = context.jamClient.FTUEGetChatInputs(true);
var chatsOnOtherDevices = context.jamClient.FTUEGetChatInputs(false);
var chatInputs = [];
//context._.each(musicPorts.inputs, function(input) {
// chatInputs.push({id: input.id, name: input.name, assignment:input.assignment});
//});
var deDupper = {};
context._.each(musicPorts.inputs, function(input) {
var chatInput = {id: input.id, name: input.name, assignment:input.assignment};
if(!deDupper[input.id]) {
if(input.assignment <= 0) {
chatInputs.push(chatInput);
deDupper[input.id] = chatInput;
}
}
});
/**context._.each(chatsOnCurrentDevice, function(chatChannelName, chatChannelId) {
var chatInput = {id: chatChannelId, name: chatChannelName, assignment: ASSIGNMENT.UNASSIGNED};
if(!deDupper[chatInput.id]) {
var assignment = context.jamClient.TrackGetAssignment(chatChannelId, true);
if(assignment <= 0) {
chatInputs.push(chatInput);
deDupper[chatInput.id] = chatInput;
}
}
})*/
context._.each(chatsOnOtherDevices, function(chatChannelName, chatChannelId) {
var chatInput = {id: chatChannelId, name: chatChannelName, assignment: null};
if(!deDupper[chatInput.id]) {
var assignment = context.jamClient.TrackGetAssignment(chatChannelId, true);
chatInput.assignment = assignment;
chatInputs.push(chatInput);
deDupper[chatInput.id] = chatInput;
}
})
return chatInputs;
}
gearUtils.isChannelAvailableForChat = function(chatChannelId, musicPorts) {
var result = true;
context._.each(musicPorts.inputs, function(inputChannel) {
// if the channel is currently assigned to a track, it not unassigned
if(inputChannel.id == chatChannelId && (inputChannel.assignment > 0)) {
result = false;
return false; // break
}
});
return result;
}
gearUtils.updateAudioLatency = function(app) {
var latency = jamClient.FTUEGetExpectedLatency().latency;
return rest.updateAudioLatency({client_id: app.clientId, audio_latency: latency})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to sync audio latency")
});
}
})(window, jQuery);