jam-cloud/web/app/assets/javascripts/vuHelpers.js

249 lines
9.1 KiB
JavaScript

/**
* Functions related to VU meters.
* These functions are intimately tied to the markup defined in the
* VU templates in _vu_meters.html.erb
*/
(function(context, $) {
"use strict";
context.JK = context.JK || {};
// As these are helper functions, just have a single
// static object with functions. Each function should
// take all necessary arguments to complete its work.
context.JK.VuHelpers = {
registeredMixers: [],
/**
* Render a VU meter into the provided selector.
* vuType can be either "horizontal" or "vertical"
*/
renderVU: function(selector, userOptions) {
selector = $(selector);
/**
* The default options for rendering a VU
*/
var renderVUDefaults = {
vuType: "vertical",
lightCount: 12,
lightWidth: 3,
lightHeight: 17
};
var options = $.extend({}, renderVUDefaults, userOptions);
var templateSelector = "#template-vu-v";
if (options.vuType === "horizontal") {
templateSelector = "#template-vu-h";
}
var templateSource = $(templateSelector).html();
selector.each(function() {
var $track = $(this);
$track.empty();
$track.html(context._.template(templateSource, options, {variable: 'data'}));
})
},
/**
* Given a selector representing a container for a VU meter and
* a value between 0.0 and 1.0, light the appropriate lights.
*/
updateVU: function ($selector, value) {
// There are 13 VU lights. Figure out how many to
// light based on the incoming value.
$selector.each(function() {
var $track = $(this)
var countSelector = 'tr';
var horizontal = ($track.find('table.horizontal').length);
if (horizontal) {
countSelector = 'td';
}
var lightCount = $track.find(countSelector).length;
var i = 0;
var state = 'on';
var lights = Math.round(value * lightCount);
var redSwitch = Math.round(lightCount * 0.6666667);
var $light = null;
var colorClass = 'vu-green-';
var lightSelectorPrefix = $track.find('td.vu');
var thisLightSelector = null;
// Remove all light classes from all lights
var allLightsSelector = $track.find('td.vulight');
$(allLightsSelector).removeClass('vu-green-off vu-green-on vu-red-off vu-red-on');
// Set the lights
for (i = 0; i < lightCount; i++) {
colorClass = 'vu-green-';
state = 'on';
if (i >= redSwitch) {
colorClass = 'vu-red-';
}
if (i >= lights) {
state = 'off';
}
var lightIndex = horizontal ? i : lightCount - i - 1;
allLightsSelector.eq(lightIndex).addClass(colorClass + state);
}
})
},
createQualifiedId: function(mixer) {
return (mixer.mode ? 'M' : 'P') + mixer.id
},
// type can be 'single' or 'double', meaning how the VU is represented (one set of lights, two)
// mixerId is the ID of the mixer
// and someFunction is used to make the registration (equality check).
registerVU: function(type, mixer, someFunction, horizontal, lightCount, lights) {
var fqId = this.createQualifiedId(mixer)
var registrations = this.registeredMixers[fqId]
if (!registrations) {
registrations = []
this.registeredMixers[fqId] = registrations
}
if(type == 'best') {
registrations.push({type:type, ptr: someFunction, ptrCount: 1, horizontal: horizontal, lightCount: lightCount, lights:lights})
}
else {
// find the right registration and add left lights or right lights to it
var found = null
context._.each(registrations, function(registration) {
if(registration.ptr == someFunction) {
found = registration;
return false;
}
})
if(!found) {
found = {type:type, ptr: someFunction, ptrCount: 1, horizontal: horizontal, lightCount: lightCount}
registrations.push(found);
}
else {
found.ptrCount++;
}
if(type == 'left') {
//logger.debug("adding left lights")
found.leftLights = lights;
}
else {
//logger.debug("adding right lights");
found.rightLights = lights;
}
}
},
unregisterVU: function(mixer, someFunction) {
var fqId = this.createQualifiedId(mixer)
var registrations = this.registeredMixers[fqId]
if (!registrations || registrations.length == 0) {
logger.debug("no registration found for:" + fqId, registrations, this.registeredMixers)
return
}
else {
//logger.debug("unregistering " + fqId + ", " + registrations.length)
}
var origLength = registrations.length;
registrations = registrations.filter(function(element) {
var isMatch = element.ptr == someFunction;
if(isMatch) {
// found a registration that matches
//logger.debug("removing matching ptr", element.ptr)
element.ptrCount--;
// keep the registration if any ptr's still left
var keepRegistration = element.ptrCount > 0;
if(!keepRegistration) {
//logger.debug("getting rid of the registration; no more ptrs");
}
return keepRegistration;
}
else {
// keep the registration if this does not match the ptr
return true;
}
})
this.registeredMixers[fqId] = registrations
},
updateSingleVU: function(horizontal, lightCount, $lights, value, isClipping) {
var i = 0;
var state = 'on';
var lights = Math.round(value * lightCount);
var redSwitch = Math.round(lightCount * 0.6666667);
var $light = null;
var colorClass = 'vu-green-';
var thisLightSelector = null;
// Remove all light classes from all lights
$lights.removeClass('vu-green-off vu-green-on vu-red-off vu-red-on');
// Set the lights
for (i = 0; i < lightCount; i++) {
colorClass = 'vu-green-';
state = 'on';
if (i >= redSwitch) {
colorClass = 'vu-red-';
}
if (i >= lights) {
state = 'off';
}
var lightIndex = horizontal ? i : lightCount - i - 1;
$lights.eq(lightIndex).addClass(colorClass + state);
}
},
// sentMixerId ends with vul or vur
updateVU3: function(mixer, leftValue, leftClipping, rightValue, rightClipping) {
var fqId = this.createQualifiedId(mixer)
var registrations = this.registeredMixers[fqId]
if (registrations) {
var j;
for(j = 0; j < registrations.length; j++) {
var registration = registrations[j]
var horizontal = registration.horizontal;
var lightCount = registration.lightCount;
if(registration.type == 'best') {
// TODO: find 'active' VU ... is it left value, or right value?
var $lights = registration.lights;
this.updateSingleVU(horizontal, lightCount, $lights, leftValue, leftClipping)
}
else {
if(mixer.stereo) {
this.updateSingleVU(horizontal, lightCount, registration.leftLights, leftValue, leftClipping)
this.updateSingleVU(horizontal, lightCount, registration.rightLights, rightValue, rightClipping)
}
else {
this.updateSingleVU(horizontal, lightCount, registration.leftLights, leftValue, leftClipping)
this.updateSingleVU(horizontal, lightCount, registration.rightLights, leftValue, leftClipping)
}
}
}
}
},
};
})(window, jQuery);