mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-21 22:26:29 +01:00
WS: Improve mixer demo
This commit is contained in:
parent
2987350892
commit
1109fc7983
192 changed files with 29395 additions and 548 deletions
346
share/web_surfaces/builtin/mixer/toolkit/widgets/equalizer.js
Normal file
346
share/web_surfaces/builtin/mixer/toolkit/widgets/equalizer.js
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* This file is part of Toolkit.
|
||||
*
|
||||
* Toolkit is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* Toolkit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General
|
||||
* Public License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
(function(w, TK){
|
||||
function fast_draw_plinear(X, Y) {
|
||||
var ret = [];
|
||||
var i, len = X.length;
|
||||
var dy = 0, x, y, tmp;
|
||||
|
||||
var accuracy = 20;
|
||||
var c = 0;
|
||||
|
||||
if (len < 2) return "";
|
||||
|
||||
x = +X[0];
|
||||
y = +Y[0];
|
||||
|
||||
ret.push("M", x.toFixed(2), ",", y.toFixed(2));
|
||||
|
||||
x = +X[1];
|
||||
y = +Y[1];
|
||||
|
||||
dy = ((y - Y[0])*accuracy)|0;
|
||||
|
||||
for (i = 2; i < len; i++) {
|
||||
tmp = ((Y[i] - y)*accuracy)|0;
|
||||
if (tmp !== dy) {
|
||||
ret.push("L", x.toFixed(2), ",", y.toFixed(2));
|
||||
dy = tmp;
|
||||
c++;
|
||||
}
|
||||
x = +X[i];
|
||||
y = +Y[i];
|
||||
}
|
||||
|
||||
ret.push("L", x.toFixed(2), ",", y.toFixed(2));
|
||||
|
||||
return ret.join("");
|
||||
}
|
||||
function draw_graph (graph, bands) {
|
||||
var O = this.options;
|
||||
var c = 0;
|
||||
var end = this.range_x.get("basis") | 0;
|
||||
var step = O.accuracy;
|
||||
var over = O.oversampling;
|
||||
var thres = O.threshold;
|
||||
var x_px_to_val = this.range_x.px2val;
|
||||
var y_val_to_px = this.range_y.val2px;
|
||||
var i, j, k;
|
||||
var x, y;
|
||||
var pursue;
|
||||
var diff;
|
||||
|
||||
var X = new Array(end / step);
|
||||
for (i = 0; i < X.length; i++) {
|
||||
X[i] = c;
|
||||
c += step;
|
||||
}
|
||||
var Y = new Array(end / step);
|
||||
var y;
|
||||
|
||||
for (i = 0; i < X.length; i++) {
|
||||
x = x_px_to_val(X[i]);
|
||||
y = 0.0;
|
||||
for (j = 0; j < bands.length; j++) y += bands[j](x);
|
||||
Y[i] = y_val_to_px(y);
|
||||
var diff = Math.abs(Y[i] - Y[i-1]) >= thres;
|
||||
if (i && over > 1 && (diff || pursue)) {
|
||||
if (diff) pursue = true;
|
||||
else if (!diff && pursue) pursue = false;
|
||||
for (k = 1; k < over; k++) {
|
||||
x = X[i-k] + ((step / over) * k);
|
||||
X.splice(i, 0, x);
|
||||
x = x_px_to_val(x);
|
||||
y = 0.0;
|
||||
for (j = 0; j < bands.length; j++) y += bands[j](x);
|
||||
Y.splice(i, 0, y_val_to_px(y));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFinite(Y[i])) {
|
||||
TK.warn("Singular filter in Equalizer.");
|
||||
graph.set("dots", void(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
graph.set("dots", fast_draw_plinear(X, Y));
|
||||
}
|
||||
function invalidate_bands() {
|
||||
this.invalid.bands = true;
|
||||
this.trigger_draw();
|
||||
}
|
||||
function show_bands() {
|
||||
var b = this.bands;
|
||||
for (var i = 0; i < b.length; i ++) {
|
||||
this.add_child(b[i]);
|
||||
}
|
||||
}
|
||||
function hide_bands() {
|
||||
var b = this.bands;
|
||||
for (var i = 0; i < b.length; i ++) {
|
||||
this.remove_child(b[i]);
|
||||
}
|
||||
}
|
||||
TK.Equalizer = TK.class({
|
||||
/**
|
||||
* TK.Equalizer is a {@link TK.ResponseHandler}, utilizing {@link TK.EqBand}s instead of
|
||||
* simple {@link TK.ResponseHandle}s.
|
||||
*
|
||||
* @property {Object} options
|
||||
*
|
||||
* @param {Number} [options.accuracy=1] - The distance between points on
|
||||
* the x axis. Reduces CPU load in favour of accuracy and smoothness.
|
||||
* @param {Array} [options.bands=[]] - A list of bands to add on init.
|
||||
* @param {Boolean} [options.show_bands=true] - Show or hide all bands.
|
||||
* @param {Number} [options.oversampling=5] - If slope of the curve is too
|
||||
* steep, oversample n times in order to not miss e.g. notch filters.
|
||||
* @param {Number} [options.threshold=5] - Steepness of slope to oversample,
|
||||
* i.e. y pixels difference per x pixel
|
||||
* @class TK.Equalizer
|
||||
*
|
||||
* @extends TK.ResponseHandler
|
||||
*/
|
||||
_class: "Equalizer",
|
||||
Extends: TK.ResponseHandler,
|
||||
_options: Object.assign(Object.create(TK.ResponseHandler.prototype._options), {
|
||||
accuracy: "number",
|
||||
oversampling: "number",
|
||||
threshold: "number",
|
||||
bands: "array",
|
||||
show_bands: "boolean",
|
||||
}),
|
||||
options: {
|
||||
accuracy: 1, // the distance between points of curves on the x axis
|
||||
oversampling: 4, // if slope of the curve is too steep, oversample
|
||||
// n times in order to not miss a notch filter
|
||||
threshold: 10, // steepness of slope, i.e. amount of y pixels difference
|
||||
bands: [], // list of bands to create on init
|
||||
show_bands: true,
|
||||
},
|
||||
static_events: {
|
||||
set_bands: function(value) {
|
||||
if (this.bands.length) this.remove_bands();
|
||||
this.add_bands(value);
|
||||
},
|
||||
set_show_bands: function(value) {
|
||||
(value ? show_bands : hide_bands).call(this);
|
||||
},
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
TK.ResponseHandler.prototype.initialize.call(this, options);
|
||||
/**
|
||||
* @member {Array} TK.Equalizer#bands - Array of {@link TK.EqBand} instances.
|
||||
*/
|
||||
this.bands = this.handles;
|
||||
|
||||
/**
|
||||
* @member {HTMLDivElement} TK.Equalizer#element - The main DIV container.
|
||||
* Has class <code>toolkit-equalizer</code>.
|
||||
*/
|
||||
TK.add_class(this.element, "toolkit-equalizer");
|
||||
|
||||
/**
|
||||
* @member {SVGGroup} TK.Equalizer#_bands - The SVG group containing all the bands SVG elements.
|
||||
* Has class <code>toolkit-eqbands</code>.
|
||||
*/
|
||||
this._bands = this._handles;
|
||||
TK.add_class(this._bands, "toolkit-eqbands");
|
||||
|
||||
/**
|
||||
* @member {TK.Graph} TK.Equalizer#baseline - The graph drawing the zero line.
|
||||
* Has class <code>toolkit-baseline</code>
|
||||
*/
|
||||
this.baseline = this.add_graph({
|
||||
range_x: this.range_x,
|
||||
range_y: this.range_y,
|
||||
container: this._bands,
|
||||
dots: [{x: 20, y: 0}, {x: 20000, y: 0}],
|
||||
"class": "toolkit-baseline"
|
||||
});
|
||||
this.add_bands(this.options.bands);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.empty(); // Arne: ??? <- Markus: removes all graphs, defined in Chart
|
||||
this._bands.remove();
|
||||
TK.ResponseHandler.prototype.destroy.call(this);
|
||||
},
|
||||
redraw: function () {
|
||||
var I = this.invalid;
|
||||
var O = this.options;
|
||||
TK.ResponseHandler.prototype.redraw.call(this);
|
||||
if (I.validate("bands", "accuracy")) {
|
||||
if (this.baseline) {
|
||||
var f = [];
|
||||
for (var i = 0; i < this.bands.length; i++) {
|
||||
if (this.bands[i].get("active")) {
|
||||
f.push(this.bands[i].filter.get_freq2gain());
|
||||
}
|
||||
}
|
||||
draw_graph.call(this, this.baseline, f);
|
||||
}
|
||||
}
|
||||
|
||||
if (I.show_bands) {
|
||||
I.show_bands = false;
|
||||
if (O.show_bands) {
|
||||
this._bands.style.removeProperty("display");
|
||||
} else {
|
||||
this._bands.style.display = "none";
|
||||
}
|
||||
}
|
||||
},
|
||||
resize: function () {
|
||||
invalidate_bands.call(this);
|
||||
TK.ResponseHandler.prototype.resize.call(this);
|
||||
},
|
||||
/**
|
||||
* Add a new band to the equalizer. Options is an object containing
|
||||
* options for the {@link TK.EqBand}
|
||||
*
|
||||
* @method TK.Equalizer#add_band
|
||||
*
|
||||
* @param {Object} [options={ }] - An object containing initial options for the {@link TK.EqBand}.
|
||||
* @param {Object} [type=TK.EqBand] - A widget class to be used for the new band.
|
||||
*
|
||||
* @emits TK.Equalizer#bandadded
|
||||
*/
|
||||
add_band: function (options, type) {
|
||||
var b;
|
||||
type = type || TK.EqBand;
|
||||
if (type.prototype.isPrototypeOf(options)) {
|
||||
b = options;
|
||||
} else {
|
||||
options.container = this._bands;
|
||||
if (options.range_x === void(0))
|
||||
options.range_x = function () { return this.range_x; }.bind(this);
|
||||
if (options.range_y === void(0))
|
||||
options.range_y = function () { return this.range_y; }.bind(this);
|
||||
if (options.range_z === void(0))
|
||||
options.range_z = function () { return this.range_z; }.bind(this);
|
||||
|
||||
options.intersect = this.intersect.bind(this);
|
||||
b = new type(options);
|
||||
}
|
||||
|
||||
this.bands.push(b);
|
||||
b.add_event("set", invalidate_bands.bind(this));
|
||||
/**
|
||||
* Is fired when a new band was added.
|
||||
*
|
||||
* @event TK.Equalizer#bandadded
|
||||
*
|
||||
* @param {TK.Band} band - The {@link TK.EqBand} which was added.
|
||||
*/
|
||||
this.fire_event("bandadded", b);
|
||||
if (this.options.show_bands)
|
||||
this.add_child(b);
|
||||
invalidate_bands.call(this);
|
||||
return b;
|
||||
},
|
||||
/**
|
||||
* Add multiple new {@link TK.EqBand}s to the equalizer. Options is an array
|
||||
* of objects containing options for the new instances of {@link TK.EqBand}
|
||||
*
|
||||
* @method TK.Equalizer#add_bands
|
||||
*
|
||||
* @param {Array<Object>} options - An array of options objects for the {@link TK.EqBand}.
|
||||
* @param {Object} [type=TK.EqBand] - A widget class to be used for the new band.
|
||||
*/
|
||||
add_bands: function (bands, type) {
|
||||
for (var i = 0; i < bands.length; i++)
|
||||
this.add_band(bands[i], type);
|
||||
},
|
||||
/**
|
||||
* Remove a band from the widget.
|
||||
*
|
||||
* @method TK.Equalizer#remove_handle
|
||||
*
|
||||
* @param {TK.EqBand} band - The {@link TK.EqBand} to remove.
|
||||
*
|
||||
* @emits TK.Equalizer#bandremoved
|
||||
*/
|
||||
remove_band: function (h) {
|
||||
for (var i = 0; i < this.bands.length; i++) {
|
||||
if (this.bands[i] === h) {
|
||||
if (this.options.show_bands)
|
||||
this.remove_child(h);
|
||||
|
||||
this.bands.splice(i, 1);
|
||||
/**
|
||||
* Is fired when a band was removed.
|
||||
*
|
||||
* @event TK.Equalizer#bandremoved
|
||||
*
|
||||
* @param {TK.EqBand} band - The {@link TK.EqBand} which was removed.
|
||||
*/
|
||||
this.fire_event("bandremoved", h);
|
||||
h.destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Remove multiple {@link TK.EqBand} from the equalizer. Options is an array
|
||||
* of {@link TK.EqBand} instances.
|
||||
*
|
||||
* @method TK.Equalizer#remove_bands
|
||||
*
|
||||
* @param {Array<TK.EqBand>} bands - An array of {@link TK.EqBand} instances.
|
||||
*/
|
||||
remove_bands: function () {
|
||||
while (this.bands.length) {
|
||||
this.remove_band(this.bands[0]);
|
||||
}
|
||||
this.bands = [];
|
||||
/**
|
||||
* Is fired when all bands are removed.
|
||||
*
|
||||
* @event TK.Equalizer#emptied
|
||||
*/
|
||||
this.fire_event("emptied");
|
||||
invalidate_bands.call(this);
|
||||
},
|
||||
_draw_graph: draw_graph,
|
||||
});
|
||||
})(this, this.TK);
|
||||
Loading…
Add table
Add a link
Reference in a new issue