210 lines
7.4 KiB
JavaScript
210 lines
7.4 KiB
JavaScript
/*
|
|
* 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 invalidate_bands() {
|
|
this.invalid.bands = true;
|
|
this.trigger_draw();
|
|
}
|
|
|
|
function sort_bands() {
|
|
this.bands.sort(function (a, b) {
|
|
return a.options.freq - b.options.freq;
|
|
});
|
|
}
|
|
|
|
function limit_bands () {
|
|
if (this.options.leap) return;
|
|
sort_bands.call(this);
|
|
for (var i = 0; i < this.bands.length; i++)
|
|
_set_freq.call(this, i, this.bands[i]);
|
|
}
|
|
|
|
function set_freq (band) {
|
|
if (this.options.leap) return;
|
|
var i = this.bands.indexOf(band);
|
|
if (i < 0) {
|
|
TK.error("Band no member of crossover");
|
|
return;
|
|
}
|
|
_set_freq.call(this, i, band);
|
|
}
|
|
|
|
function _set_freq (i, band) {
|
|
var freq = band.options.freq;
|
|
var dist = freq * this.get("distance")
|
|
if (i)
|
|
this.bands[i-1].set("x_max", freq - dist);
|
|
if (i < this.bands.length-1)
|
|
this.bands[i+1].set("x_min", freq + dist);
|
|
}
|
|
|
|
TK.Crossover = TK.class({
|
|
/**
|
|
* TK.Crossover is a {@link TK.Equalizer} displaying the response
|
|
* of a multi-band crossover filter. TK.Crossover uses {@link TK.CrossoverBand}
|
|
* as response handles.
|
|
*
|
|
* @class TK.Crossover
|
|
*
|
|
* @extends TK.Equalizer
|
|
*
|
|
* @param {Object} [options={ }] - An object containing initial options.
|
|
*
|
|
* @property {Boolean} [options.leap=true] - Define if bands are allowed to leap over each other.
|
|
* @property {Number} [options.distance=0] - Set a minimal distance between bands if leaping is not allowed.
|
|
* Value is a factor of x. Example: if distance=0.2 a band cannot be moved beyond 800Hz if the upper next
|
|
* band is at 1kHz.
|
|
*/
|
|
_class: "Crossover",
|
|
Extends: TK.Equalizer,
|
|
_options: Object.assign(Object.create(TK.Equalizer.prototype._options), {
|
|
leap: "boolean",
|
|
distance: "number",
|
|
}),
|
|
options: {
|
|
range_y: {min:-60, max: 12, scale: "linear"},
|
|
leap: true,
|
|
distance: 0,
|
|
},
|
|
initialize: function (options) {
|
|
TK.Equalizer.prototype.initialize.call(this, options);
|
|
/**
|
|
* @member {HTMLDivElement} TK.Equalizer#element - The main DIV container.
|
|
* Has class <code>toolkit-response-handler</code>.
|
|
*/
|
|
TK.add_class(this.element, "toolkit-crossover");
|
|
},
|
|
resize: function () {
|
|
invalidate_bands.call(this);
|
|
TK.Equalizer.prototype.resize.call(this);
|
|
},
|
|
redraw: function () {
|
|
var I = this.invalid;
|
|
var O = this.options;
|
|
var lastb = this.bands.length - 1;
|
|
var lastg = this.graphs.length - 1;
|
|
if (I.validate("bands", "accuracy")) {
|
|
I.bands = false;
|
|
I.accuracy = false;
|
|
sort_bands.call(this);
|
|
for (var i = 0; i < this.bands.length; i++) {
|
|
var f = [this.bands[i].lower.get_freq2gain()];
|
|
if (i)
|
|
f.push(this.bands[i-1].upper.get_freq2gain());
|
|
this._draw_graph(this.graphs[i], f);
|
|
}
|
|
this._draw_graph(this.graphs[lastg], [this.bands[lastb].upper.get_freq2gain()]);
|
|
}
|
|
TK.Equalizer.prototype.redraw.call(this);
|
|
},
|
|
add_band: function (options, type) {
|
|
type = type || TK.CrossoverBand;
|
|
this.add_graph();
|
|
var r = TK.Equalizer.prototype.add_band.call(this, options, type);
|
|
var that = this;
|
|
r.add_event("set_freq", function (f) {
|
|
set_freq.call(that, this);
|
|
});
|
|
limit_bands.call(this);
|
|
return r;
|
|
},
|
|
remove_band: function (band) {
|
|
this.remove_graph(this.graphs[this.graphs.length-1]);
|
|
var r = TK.Equalizer.prototype.remove_band.call(this, options);
|
|
limit_bands.call(this);
|
|
return r;
|
|
},
|
|
});
|
|
|
|
TK.CrossoverBand = TK.class({
|
|
/**
|
|
* TK.CrossoverBand is a {@link TK.EqBand} with an additional filter.
|
|
*
|
|
* @param {Object} [options={ }] - An object containing additional options.
|
|
*
|
|
* @property {String|Function} [lower="lowpass3"] - The type of filter for the range below cutoff frequency. See {@link TK.EqBand} for more information.
|
|
* @property {String|Function} [upper="highpass3"] - The type of filter for the range above cutoff frequency. See {@link TK.EqBand} for more information.
|
|
* @property {Function} [label=function (t, x, y, z) { return TK.sprintf("%.2f Hz", x); }] - The function formatting the handles label.
|
|
*
|
|
* @class TK.CrossoverBand
|
|
*
|
|
* @extends TK.EqBand
|
|
*/
|
|
_class: "CrossoverBand",
|
|
Extends: TK.EqBand,
|
|
_options: Object.assign(Object.create(TK.EqBand.prototype._options), {
|
|
lower: "string",
|
|
upper: "string",
|
|
}),
|
|
options: {
|
|
lower: "lowpass3",
|
|
upper: "highpass3",
|
|
label: function (t, x, y, z) { return TK.sprintf("%.2f Hz", x); },
|
|
mode: "line-vertical", // undocumented, just a default differing from TK.ResponseHanlde
|
|
preferences: [ "top-right", "right", "bottom-right", "top-left", "left", "bottom-left"], // undocumented, just a default differing from TK.ResponseHanlde
|
|
},
|
|
initialize: function (options) {
|
|
/**
|
|
* @member {TK.Filter} TK.CrossoverBand#upper - The filter providing the graphical calculations for the upper graph.
|
|
*/
|
|
this.upper = new TK.Filter();
|
|
/**
|
|
* @member {TK.Filter} TK.CrossoverBand#lower - The filter providing the graphical calculations for the lower graph.
|
|
*/
|
|
this.lower = new TK.Filter();
|
|
TK.EqBand.prototype.initialize.call(this, options);
|
|
/**
|
|
* @member {HTMLDivElement} TK.CrossoverBand#element - The main SVG group.
|
|
* Has class <code>toolkit-crossoverband</code>.
|
|
*/
|
|
TK.add_class(this.element, "toolkit-crossoverband");
|
|
|
|
this.set("lower", this.options.lower);
|
|
this.set("upper", this.options.upper);
|
|
},
|
|
set: function (key, val) {
|
|
switch (key) {
|
|
case"lower":
|
|
this.filter = this.lower;
|
|
var r = TK.EqBand.prototype.set.call(this, "type", val);
|
|
this.set("mode", "line-vertical");
|
|
return r;
|
|
case "upper":
|
|
this.filter = this.upper;
|
|
var r = TK.EqBand.prototype.set.call(this, "type", val);
|
|
this.set("mode", "line-vertical");
|
|
return r;
|
|
case "freq":
|
|
case "gain":
|
|
case "q":
|
|
if (this.lower)
|
|
this.filter = this.lower;
|
|
val = TK.EqBand.prototype.set.call(this, key, val);
|
|
this.filter = this.upper;
|
|
return TK.EqBand.prototype.set.call(this, key, val);
|
|
}
|
|
return TK.EqBand.prototype.set.call(this, key, val);
|
|
},
|
|
});
|
|
|
|
})(this, this.TK);
|