mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-15 08:17:07 +00:00
converting vibrato to typescript
This commit is contained in:
parent
1738307e8a
commit
1d334f9a80
4 changed files with 155 additions and 103 deletions
|
@ -1,103 +0,0 @@
|
|||
import Tone from "../core/Tone";
|
||||
import "../effect/Effect";
|
||||
import "../core/Delay";
|
||||
import "../component/LFO";
|
||||
|
||||
/**
|
||||
* @class A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO
|
||||
* modulates the delayTime of the delay, causing the pitch to rise
|
||||
* and fall.
|
||||
* @extends {Tone.Effect}
|
||||
* @param {Frequency} frequency The frequency of the vibrato.
|
||||
* @param {NormalRange} depth The amount the pitch is modulated.
|
||||
*/
|
||||
Tone.Vibrato = function(){
|
||||
|
||||
var options = Tone.defaults(arguments, ["frequency", "depth"], Tone.Vibrato);
|
||||
Tone.Effect.call(this, options);
|
||||
|
||||
/**
|
||||
* The delay node used for the vibrato effect
|
||||
* @type {Tone.Delay}
|
||||
* @private
|
||||
*/
|
||||
this._delayNode = new Tone.Delay(0, options.maxDelay);
|
||||
|
||||
/**
|
||||
* The LFO used to control the vibrato
|
||||
* @type {Tone.LFO}
|
||||
* @private
|
||||
*/
|
||||
this._lfo = new Tone.LFO({
|
||||
"type" : options.type,
|
||||
"min" : 0,
|
||||
"max" : options.maxDelay,
|
||||
"frequency" : options.frequency,
|
||||
"phase" : -90 //offse the phase so the resting position is in the center
|
||||
}).start().connect(this._delayNode.delayTime);
|
||||
|
||||
/**
|
||||
* The frequency of the vibrato
|
||||
* @type {Frequency}
|
||||
* @signal
|
||||
*/
|
||||
this.frequency = this._lfo.frequency;
|
||||
|
||||
/**
|
||||
* The depth of the vibrato.
|
||||
* @type {NormalRange}
|
||||
* @signal
|
||||
*/
|
||||
this.depth = this._lfo.amplitude;
|
||||
|
||||
this.depth.value = options.depth;
|
||||
this._readOnly(["frequency", "depth"]);
|
||||
this.effectSend.chain(this._delayNode, this.effectReturn);
|
||||
};
|
||||
|
||||
Tone.extend(Tone.Vibrato, Tone.Effect);
|
||||
|
||||
/**
|
||||
* The defaults
|
||||
* @type {Object}
|
||||
* @const
|
||||
*/
|
||||
Tone.Vibrato.defaults = {
|
||||
"maxDelay" : 0.005,
|
||||
"frequency" : 5,
|
||||
"depth" : 0.1,
|
||||
"type" : "sine"
|
||||
};
|
||||
|
||||
/**
|
||||
* Type of oscillator attached to the Vibrato.
|
||||
* @memberOf Tone.Vibrato#
|
||||
* @type {string}
|
||||
* @name type
|
||||
*/
|
||||
Object.defineProperty(Tone.Vibrato.prototype, "type", {
|
||||
get : function(){
|
||||
return this._lfo.type;
|
||||
},
|
||||
set : function(type){
|
||||
this._lfo.type = type;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Clean up.
|
||||
* @returns {Tone.Vibrato} this
|
||||
*/
|
||||
Tone.Vibrato.prototype.dispose = function(){
|
||||
Tone.Effect.prototype.dispose.call(this);
|
||||
this._delayNode.dispose();
|
||||
this._delayNode = null;
|
||||
this._lfo.dispose();
|
||||
this._lfo = null;
|
||||
this._writable(["frequency", "depth"]);
|
||||
this.frequency = null;
|
||||
this.depth = null;
|
||||
};
|
||||
|
||||
export default Tone.Vibrato;
|
||||
|
52
Tone/effect/Vibrato.test.ts
Normal file
52
Tone/effect/Vibrato.test.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { Vibrato } from "./Vibrato";
|
||||
import { BasicTests } from "test/helper/Basic";
|
||||
import { EffectTests } from "test/helper/EffectTests";
|
||||
import { expect } from "chai";
|
||||
import { CompareToFile } from "test/helper/CompareToFile";
|
||||
import { Oscillator } from "Tone/source/oscillator/Oscillator";
|
||||
|
||||
describe("Effect", () => {
|
||||
BasicTests(Vibrato);
|
||||
EffectTests(Vibrato);
|
||||
|
||||
it("matches a file", () => {
|
||||
return CompareToFile(() => {
|
||||
const vibrato = new Vibrato(4, 1).toDestination();
|
||||
const osc = new Oscillator().connect(vibrato).start();
|
||||
}, "vibrato.wav", 0.01);
|
||||
});
|
||||
|
||||
context("API", () => {
|
||||
|
||||
it("can pass in options in the constructor", () => {
|
||||
const vibrato = new Vibrato({
|
||||
maxDelay: 0.02,
|
||||
depth: 0.25,
|
||||
type: "sawtooth"
|
||||
});
|
||||
expect(vibrato.depth.value).to.be.closeTo(0.25, 0.001);
|
||||
expect(vibrato.type).to.equal("sawtooth");
|
||||
vibrato.dispose();
|
||||
});
|
||||
|
||||
it("can get/set the options", () => {
|
||||
const vibrato = new Vibrato();
|
||||
vibrato.set({
|
||||
frequency: 2.4,
|
||||
type: "triangle"
|
||||
});
|
||||
expect(vibrato.get().frequency).to.be.closeTo(2.4, 0.01);
|
||||
expect(vibrato.get().type).to.equal("triangle");
|
||||
vibrato.dispose();
|
||||
});
|
||||
|
||||
it("can set the frequency and depth", () => {
|
||||
const vibrato = new Vibrato();
|
||||
vibrato.depth.value = 0.4;
|
||||
vibrato.frequency.value = 0.4;
|
||||
expect(vibrato.depth.value).to.be.closeTo(0.4, 0.01);
|
||||
expect(vibrato.frequency.value).to.be.closeTo(0.4, 0.01);
|
||||
vibrato.dispose();
|
||||
});
|
||||
});
|
||||
});
|
103
Tone/effect/Vibrato.ts
Normal file
103
Tone/effect/Vibrato.ts
Normal file
|
@ -0,0 +1,103 @@
|
|||
import { Effect, EffectOptions } from "./Effect";
|
||||
import { ToneOscillatorType } from "../source/oscillator/OscillatorInterface";
|
||||
import { Frequency, NormalRange, Seconds } from "../core/type/Units";
|
||||
import { optionsFromArguments } from "../core/util/Defaults";
|
||||
import { LFO } from "../source/oscillator/LFO";
|
||||
import { Delay } from "../core/context/Delay";
|
||||
import { Signal } from "../signal/Signal";
|
||||
import { Param } from "../core/context/Param";
|
||||
import { readOnly } from "../core/util/Interface";
|
||||
|
||||
export interface VibratoOptions extends EffectOptions {
|
||||
maxDelay: Seconds;
|
||||
frequency: Frequency;
|
||||
depth: NormalRange;
|
||||
type: ToneOscillatorType;
|
||||
}
|
||||
/**
|
||||
* A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO
|
||||
* modulates the delayTime of the delay, causing the pitch to rise and fall.
|
||||
*/
|
||||
export class Vibrato extends Effect<VibratoOptions> {
|
||||
|
||||
readonly name: string = "Vibrato";
|
||||
/**
|
||||
* The delay node used for the vibrato effect
|
||||
*/
|
||||
private _delayNode: Delay;
|
||||
|
||||
/**
|
||||
* The LFO used to control the vibrato
|
||||
*/
|
||||
private _lfo: LFO;
|
||||
|
||||
/**
|
||||
* The frequency of the vibrato
|
||||
*/
|
||||
readonly frequency: Signal<"frequency">;
|
||||
|
||||
/**
|
||||
* The depth of the vibrato.
|
||||
*/
|
||||
readonly depth: Param<"normalRange">;
|
||||
|
||||
/**
|
||||
* @param frequency The frequency of the vibrato.
|
||||
* @param depth The amount the pitch is modulated.
|
||||
*/
|
||||
constructor(frequency?: Frequency, depth?: NormalRange);
|
||||
constructor(options?: Partial<VibratoOptions>);
|
||||
constructor() {
|
||||
|
||||
super(optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]));
|
||||
const options = optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]);
|
||||
|
||||
this._delayNode = new Delay({
|
||||
context: this.context,
|
||||
delayTime: 0,
|
||||
maxDelay: options.maxDelay,
|
||||
});
|
||||
this._lfo = new LFO({
|
||||
context: this.context,
|
||||
type: options.type,
|
||||
min: 0,
|
||||
max: options.maxDelay,
|
||||
frequency: options.frequency,
|
||||
phase: -90 // offse the phase so the resting position is in the center
|
||||
}).start().connect(this._delayNode.delayTime);
|
||||
this.frequency = this._lfo.frequency;
|
||||
this.depth = this._lfo.amplitude;
|
||||
|
||||
this.depth.value = options.depth;
|
||||
readOnly(this, ["frequency", "depth"]);
|
||||
this.effectSend.chain(this._delayNode, this.effectReturn);
|
||||
}
|
||||
|
||||
static getDefaults(): VibratoOptions {
|
||||
return Object.assign(Effect.getDefaults(), {
|
||||
maxDelay: 0.005,
|
||||
frequency: 5,
|
||||
depth: 0.1,
|
||||
type: "sine" as "sine"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of oscillator attached to the Vibrato.
|
||||
*/
|
||||
get type(): ToneOscillatorType {
|
||||
return this._lfo.type;
|
||||
}
|
||||
set type(type) {
|
||||
this._lfo.type = type;
|
||||
}
|
||||
|
||||
dispose(): this {
|
||||
super.dispose();
|
||||
this._delayNode.dispose();
|
||||
this._lfo.dispose();
|
||||
this.frequency.dispose();
|
||||
this.depth.dispose();
|
||||
return this;
|
||||
}
|
||||
}
|
BIN
test/audio/compare/vibrato.wav
Normal file
BIN
test/audio/compare/vibrato.wav
Normal file
Binary file not shown.
Loading…
Reference in a new issue