709 lines
23 KiB
JavaScript
709 lines
23 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 ALERT_NAMES = context.JK.ALERT_NAMES;
|
|
var ASSIGNMENT = context.JK.ASSIGNMENT;
|
|
var VOICE_CHAT = context.JK.VOICE_CHAT;
|
|
var AUDIO_DEVICE_BEHAVIOR = context.JK.AUDIO_DEVICE_BEHAVIOR;
|
|
var EVENTS = context.JK.EVENTS;
|
|
var SYSTEM_DEFAULT_PLAYBACK_ONLY = 'System Default (Playback Only)';
|
|
var JAMKAZAM_VIRTUAL_INPUT = "JamKazam Virtual Input";
|
|
|
|
|
|
context.JK.GearUtilsInstance = gearUtils;
|
|
|
|
gearUtils.SKIPPED_NETWORK_TEST = -1; // we store a negative 1 to mean that we let the user skip.
|
|
gearUtils.SYSTEM_DEFAULT_PLAYBACK_ONLY = SYSTEM_DEFAULT_PLAYBACK_ONLY;
|
|
gearUtils.JAMKAZAM_VIRTUAL_INPUT = JAMKAZAM_VIRTUAL_INPUT;
|
|
|
|
gearUtils.skippedNetworkTest = false; // we allow someone to play in session (for one client run) if it's our fault they can't network test score
|
|
var reloadAudioTimeout = null;
|
|
var currentAudioRestartLocation = null;
|
|
|
|
// 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.resyncAudio = function() {
|
|
|
|
function backendMixerChange (e, data) {
|
|
|
|
if (data.text == 'deferred') {
|
|
context.JK.offBackendEvent(ALERT_NAMES.BACKEND_MIXER_CHANGE, 'gearUtilsResyncAudio', backendMixerChange)
|
|
console.log("context.jamClient.FTUEGetExpectedLatency()", context.jamClient.FTUEGetExpectedLatency().latency)
|
|
deferred.resolve();
|
|
}
|
|
;
|
|
}
|
|
|
|
var deferred = new $.Deferred();
|
|
|
|
context.JK.onBackendEvent(ALERT_NAMES.BACKEND_MIXER_CHANGE, 'gearUtilsResyncAudio', backendMixerChange);
|
|
|
|
context.jamClient.SessionAudioResync();
|
|
|
|
// give backend 5 seconds to timeout
|
|
deferred.timer = setTimeout(function() {
|
|
deferred.rejectWith('timeout');
|
|
context.JK.offBackendEvent(ALERT_NAMES.BACKEND_MIXER_CHANGE, 'gearUtilsResyncAudio', backendMixerChange)
|
|
}, 5000);
|
|
|
|
return deferred;
|
|
}
|
|
|
|
|
|
// to play with others, you have to have inputs,
|
|
// as well have a score below 20 ms
|
|
gearUtils.canPlayWithOthers = function(profile) {
|
|
|
|
|
|
var isNoInputProfile = gearUtils.isNoInputProfile(profile);
|
|
var expectedLatency = context.jamClient.FTUEGetExpectedLatency();
|
|
var audioLatency = expectedLatency ? expectedLatency.latency : null;
|
|
|
|
// only compute high latency if the value is known. Also don't accept insanely largue values
|
|
var highLatency = false;
|
|
if(audioLatency) {
|
|
highLatency = audioLatency > 20 && audioLatency < 1000;
|
|
}
|
|
|
|
var networkScore = context.jamClient.GetNetworkTestScore();
|
|
var badNetworkScore = networkScore < 2;
|
|
|
|
// for now, ignore latency
|
|
if(gon.global.gear_check_ignore_high_latency) {
|
|
highLatency = false
|
|
}
|
|
|
|
return {
|
|
canPlay: !isNoInputProfile && !highLatency,
|
|
isNoInputProfile: isNoInputProfile,
|
|
badNetworkScore: badNetworkScore,
|
|
highLatency: highLatency,
|
|
audioLatency: audioLatency,
|
|
networkScore: networkScore,
|
|
}
|
|
}
|
|
|
|
gearUtils.isNoInputProfile = function(profile) {
|
|
|
|
if (profile === undefined) {
|
|
profile = context.jamClient.LastUsedProfileName();
|
|
}
|
|
|
|
return profile == SYSTEM_DEFAULT_PLAYBACK_ONLY;
|
|
}
|
|
|
|
gearUtils.canBeConfigured = function(profile) {
|
|
return profile != SYSTEM_DEFAULT_PLAYBACK_ONLY;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
if (device.name == JAMKAZAM_VIRTUAL_INPUT) {
|
|
return;
|
|
}
|
|
|
|
var deviceInfo = {};
|
|
|
|
deviceInfo.id = device.guid;
|
|
deviceInfo.port_audio_name = device.port_audio_name;
|
|
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.updateDefaultBuffers = function (selectedDeviceInfo, frameBuffers) {
|
|
function hasWDMAssociated() {
|
|
return selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_wdm' || selectedDeviceInfo.output.info.type == 'Win32_wdm')
|
|
}
|
|
|
|
function hasASIOAssociated() {
|
|
return selectedDeviceInfo && (selectedDeviceInfo.input.info.type == 'Win32_asio' || selectedDeviceInfo.output.info.type == 'Win32_asio')
|
|
}
|
|
|
|
// handle specific framesize settings
|
|
if (hasWDMAssociated() || hasASIOAssociated()) {
|
|
var framesize = frameBuffers.selectedFramesize();
|
|
|
|
if (framesize == 2.5) {
|
|
// if there is a WDM device, start off at 1/1 due to empirically observed issues with 0/0
|
|
if (hasWDMAssociated()) {
|
|
logger.debug("setting default buffers to 1/1");
|
|
frameBuffers.setBufferIn('1');
|
|
frameBuffers.setBufferOut('1');
|
|
}
|
|
else {
|
|
// otherwise, it's ASIO, so go with 0/0
|
|
logger.debug("setting default buffers to 0/0");
|
|
frameBuffers.setBufferIn('0');
|
|
frameBuffers.setBufferOut('0');
|
|
}
|
|
}
|
|
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 2/2");
|
|
frameBuffers.setBufferIn('2');
|
|
frameBuffers.setBufferOut('2');
|
|
}
|
|
}
|
|
else {
|
|
logger.debug("setting default buffers to 0/0");
|
|
frameBuffers.setBufferIn(0);
|
|
frameBuffers.setBufferOut(0);
|
|
}
|
|
|
|
context.jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
|
|
context.jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
|
|
}
|
|
|
|
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.LastUsedProfileName();
|
|
|
|
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;
|
|
}
|
|
|
|
// if the user has a good user network score, immediately returns with a resolved deferred object.
|
|
// if not, the user will have the network test dialog prompted... once it's closed, then you'll be told reject() if score is still bad, or resolve() if now good
|
|
gearUtils.guardAgainstBadNetworkScore = function (app) {
|
|
var deferred = new $.Deferred();
|
|
|
|
if (!gearUtils.validNetworkScore()) {
|
|
// invalid network test score. They have to score to move on
|
|
app.layout.showDialog('network-test').one(EVENTS.DIALOG_CLOSED, function () {
|
|
if (gearUtils.validNetworkScore()) {
|
|
deferred.resolve();
|
|
}
|
|
else {
|
|
deferred.reject();
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
deferred.resolve();
|
|
}
|
|
return deferred;
|
|
}
|
|
|
|
// XXX this isn't quite right... it needs to check if a good device is *active*
|
|
// but seen too many problems so far with the backend not reporting any profile active
|
|
gearUtils.hasGoodActiveProfile = function (verifyTracks) {
|
|
var hasOneConfigureDevice = context.JK.hasOneConfiguredDevice();
|
|
logger.debug("hasGoodActiveProfile: " + hasOneConfigureDevice ? "devices='has at least one configured device' " : "devices='has no configured device' ")
|
|
return hasOneConfigureDevice;
|
|
}
|
|
|
|
// if the user does not have any profiles, show the FTUE
|
|
gearUtils.guardAgainstInvalidGearConfiguration = function (app) {
|
|
var deferred = new $.Deferred();
|
|
|
|
if (context.jamClient.FTUEGetAllAudioConfigurations().length == 0) {
|
|
app.layout.showDialog('gear-wizard').one(EVENTS.DIALOG_CLOSED, function () {
|
|
if (gearUtils.hasGoodActiveProfile() && gearUtils.validNetworkScore()) {
|
|
deferred.resolve();
|
|
}
|
|
else {
|
|
deferred.reject();
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
deferred.resolve();
|
|
}
|
|
|
|
return deferred;
|
|
}
|
|
|
|
context.JK.guardAgainstSinglePlayerProfile = function(app, beforeCallback) {
|
|
|
|
var deferred = new $.Deferred();
|
|
|
|
var canPlayWithOthers = context.JK.GearUtilsInstance.canPlayWithOthers();
|
|
|
|
if(!canPlayWithOthers.canPlay) {
|
|
logger.debug("guarding against single player profile")
|
|
|
|
var $dialog = app.layout.showDialog('single-player-profile-dialog');
|
|
|
|
// so that callers can check dialog result
|
|
canPlayWithOthers.dialog = $dialog;
|
|
|
|
// allow callers to take action before default behavior
|
|
if(beforeCallback) {
|
|
$dialog.one(EVENTS.DIALOG_CLOSED, beforeCallback);
|
|
}
|
|
|
|
$dialog.one(EVENTS.DIALOG_CLOSED, function(e, data) {
|
|
|
|
if(data.canceled) {
|
|
deferred.rejectWith(canPlayWithOthers, [{ reason: 'canceled', controlled_location:false }])
|
|
}
|
|
else {
|
|
if(data.result.choice == 'private_session') {
|
|
var data = {
|
|
createType: 'quick-start',
|
|
timezone: {},
|
|
recurring_mode: {},
|
|
language: {},
|
|
band: {},
|
|
musician_access: {},
|
|
fans_access: {},
|
|
rsvp_slots: [],
|
|
open_rsvps: false
|
|
};
|
|
|
|
context.JK.privateSessionSettings(data)
|
|
|
|
context.JK.createSession(app, data)
|
|
.done(function(response) {
|
|
var sessionId = response.id;
|
|
|
|
context.JK.GA.trackSessionCount(true, true, 0);
|
|
|
|
deferred.rejectWith(canPlayWithOthers, [{ reason: 'private_session', controlled_location:true }])
|
|
// we redirect to the session screen, which handles the REST call to POST /participants.
|
|
logger.debug("joining session screen: " + sessionId)
|
|
context.location = '/client#/session/' + sessionId;
|
|
})
|
|
.fail(function(jqXHR) {
|
|
deferred.rejectWith(canPlayWithOthers, [{ reason: 'gear_setup', controlled_location:false }])
|
|
logger.debug("unable to schedule a private session")
|
|
app.notifyServerError(jqXHR, "Unable to schedule a private session");
|
|
})
|
|
}
|
|
else if(data.result.choice == 'gear_setup') {
|
|
deferred.rejectWith(canPlayWithOthers, [{ reason: data.result.choice,controlled_location:true }])
|
|
window.location = '/client#/account/audio'
|
|
}
|
|
else
|
|
{
|
|
deferred.rejectWith(canPlayWithOthers, [{ reason: 'unknown', controlled_location:false }])
|
|
logger.error("unknown choice: " + data.result.choice)
|
|
alert("unknown choice: " + data.result.choice)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
else {
|
|
deferred.resolveWith(canPlayWithOthers)
|
|
}
|
|
|
|
|
|
return deferred;
|
|
}
|
|
|
|
gearUtils.guardAgainstActiveProfileMissing = function (app, backendInfo) {
|
|
|
|
|
|
var deferred = new $.Deferred();
|
|
logger.debug("guardAgainstActiveProfileMissing: backendInfo %o", backendInfo);
|
|
if (backendInfo.error && backendInfo['reason'] == 'no_profile' && context.jamClient.FTUEGetAllAudioConfigurations().length > 0) {
|
|
// if the backend says we have no_profile, but we have profiles , send them to the audio profile screen
|
|
// this should be a very rare path
|
|
deferred.reject({reason: 'handled', nav: '/client#/account/audio'});
|
|
context.JK.Banner.showAlert('No Active Profile', 'We\'ve sent you to the audio profile screen to remedy the fact that you have no active audio profile. Please select ACTIVATE on an existing profile, or select ADD NEW GEAR to add a new profile.');
|
|
}
|
|
else if (backendInfo.error && backendInfo['reason'] == 'device_failure') {
|
|
app.layout.showDialog('audio-profile-invalid-dialog')
|
|
.one(EVENTS.DIALOG_CLOSED, function (e, data) {
|
|
if (!data.result || data.result == 'cancel') {
|
|
deferred.reject({reason: 'handled', nav: 'BACK'});
|
|
}
|
|
else if (data.result == 'configure_gear') {
|
|
deferred.reject({reason: 'handled', nav: '/client#/account/audio'});
|
|
}
|
|
else if (data.result == 'session') {
|
|
deferred.resolve();
|
|
}
|
|
else {
|
|
logger.error("unknown result condition in audio-profile-invalid-dialog: " + data.result)
|
|
deferred.reject()
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
deferred.resolve();
|
|
}
|
|
return deferred;
|
|
}
|
|
|
|
// tests both device config, and network score
|
|
gearUtils.guardAgainstInvalidConfiguration = function (app, verifyNetworkScore) {
|
|
var deferred = new $.Deferred();
|
|
gearUtils.guardAgainstInvalidGearConfiguration(app)
|
|
.fail(function () {
|
|
deferred.reject();
|
|
})
|
|
.done(function () {
|
|
if(verifyNetworkScore) {
|
|
gearUtils.guardAgainstBadNetworkScore(app)
|
|
.fail(function () {
|
|
deferred.reject();
|
|
})
|
|
.done(function () {
|
|
deferred.resolve();
|
|
})
|
|
}
|
|
else {
|
|
deferred.resolve();
|
|
}
|
|
|
|
})
|
|
|
|
return deferred;
|
|
}
|
|
|
|
gearUtils.skipNetworkTest = function () {
|
|
context.jamClient.SetNetworkTestScore(gearUtils.SKIPPED_NETWORK_TEST);
|
|
gearUtils.skippedNetworkTest = true;
|
|
}
|
|
|
|
gearUtils.isNetworkTestSkipped = function () {
|
|
return gearUtils.skippedNetworkTest;
|
|
}
|
|
|
|
gearUtils.validNetworkScore = function () {
|
|
return gearUtils.skippedNetworkTest || context.jamClient.GetNetworkTestScore() >= 2;
|
|
}
|
|
|
|
gearUtils.isRestartingAudio = function () {
|
|
return !!reloadAudioTimeout;
|
|
}
|
|
|
|
gearUtils.scheduleAudioRestart = function (location, initial_delay, beforeScan, afterScan, cancelScan) {
|
|
|
|
logger.debug("scheduleAudioRestart: (from " + location + ")")
|
|
|
|
var cancellable = true;
|
|
|
|
function clearAudioReloadTimer() {
|
|
|
|
if (!cancellable) {
|
|
return;
|
|
}
|
|
|
|
if (cancelScan) {
|
|
cancelScan();
|
|
}
|
|
else if (afterScan) {
|
|
afterScan(true);
|
|
}
|
|
|
|
clearTimeout(reloadAudioTimeout);
|
|
reloadAudioTimeout = null;
|
|
currentAudioRestartLocation = null;
|
|
cancellable = false;
|
|
}
|
|
|
|
// refresh timer if outstanding
|
|
if (reloadAudioTimeout) {
|
|
logger.debug("scheduleAudioRestart: clearing timeout (from " + location + ")")
|
|
clearTimeout(reloadAudioTimeout);
|
|
}
|
|
|
|
currentAudioRestartLocation = location;
|
|
|
|
if (beforeScan) {
|
|
beforeScan();
|
|
}
|
|
|
|
reloadAudioTimeout = setTimeout(function () {
|
|
logger.debug("scheduleAudioRestart: rescan beginning (from " + location + ")")
|
|
reloadAudioTimeout = null;
|
|
currentAudioRestartLocation = null;
|
|
cancellable = false;
|
|
|
|
if (afterScan) {
|
|
afterScan(false);
|
|
}
|
|
}, initial_delay ? initial_delay : 5000);
|
|
|
|
return clearAudioReloadTimer;
|
|
}
|
|
|
|
gearUtils.bootstrapDefaultPlaybackProfile = function () {
|
|
|
|
var profiles = gearUtils.getProfiles();
|
|
|
|
var foundSystemDefaultPlaybackOnly = false
|
|
context._.each(profiles, function (profile) {
|
|
if (profile.id == SYSTEM_DEFAULT_PLAYBACK_ONLY) {
|
|
foundSystemDefaultPlaybackOnly = true
|
|
return false;
|
|
}
|
|
})
|
|
|
|
if (!foundSystemDefaultPlaybackOnly) {
|
|
logger.debug("creating system default profile (playback only)")
|
|
if(!gearUtils.createDefaultPlaybackOnlyProfile()) {
|
|
logger.error("unable to create the default playback profile!");
|
|
}
|
|
}
|
|
}
|
|
gearUtils.createDefaultPlaybackOnlyProfile = function () {
|
|
|
|
var eMixerInputSampleRate = {
|
|
JAMKAZAM_AUTO_SR: 0,
|
|
USE_DEVICE_DEFAULT_SR: 1,
|
|
PREFER_44: 2,
|
|
PREFER_48: 3,
|
|
PREFER_96: 4
|
|
}
|
|
|
|
// null//upgrade protect
|
|
if(context.jamClient.FTUECreateUpdatePlayBackProfile) {
|
|
return context.jamClient.FTUECreateUpdatePlayBackProfile(SYSTEM_DEFAULT_PLAYBACK_ONLY,
|
|
eMixerInputSampleRate.USE_DEVICE_DEFAULT_SR,
|
|
0, // buffering
|
|
false); // start audio
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
})(window, jQuery); |