/** * 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);