converting FeedbackDelay to ts

This commit is contained in:
Yotam Mann 2019-07-25 10:46:28 -04:00
parent 3e6484eef6
commit 40727ee650
4 changed files with 208 additions and 1 deletions

View file

@ -53,7 +53,7 @@ extends ToneAudioNode<Options> {
*/
output = this._dryWet;
protected _internalChannels = [this.input, this.output, this.effectReturn, this.effectSend];
protected _internalChannels: ToneAudioNode[] = [this.input, this.output, this.effectReturn, this.effectSend];
constructor(options: EffectOptions) {
super(options);

View file

@ -0,0 +1,64 @@
import { expect } from "chai";
import { BasicTests } from "test/helper/Basic";
import { FeedbackDelay } from "./FeedbackDelay";
// import {EffectTests} from "test/helper/EffectTests";
import { FeedbackEffect } from "./FeedbackEffect";
describe("FeedbackDelay", () => {
BasicTests(FeedbackDelay);
// EffectTests(FeedbackDelay, 0.01);
context("API", () => {
it("extends FeedbackEffect", () => {
const feedbackDelay = new FeedbackDelay(0.2, 0.3);
expect(feedbackDelay).to.be.instanceOf(FeedbackEffect);
feedbackDelay.dispose();
});
it("parses constructor arguments correctly", () => {
const feedbackDelay = new FeedbackDelay(0.1, 0.4);
expect(feedbackDelay.delayTime.value).to.be.closeTo(0.1, 0.01);
expect(feedbackDelay.feedback.value).to.be.closeTo(0.4, 0.01);
feedbackDelay.dispose();
});
it("can pass in options in the constructor", () => {
const feedbackDelay = new FeedbackDelay({
delayTime : 0.2,
feedback : 0.3,
});
expect(feedbackDelay.delayTime.value).to.be.closeTo(0.2, 0.01);
expect(feedbackDelay.feedback.value).to.be.closeTo(0.3, 0.01);
feedbackDelay.dispose();
});
it("can get/set the options", () => {
const feedbackDelay = new FeedbackDelay();
feedbackDelay.set({
feedback : 0.4,
});
expect(feedbackDelay.get().feedback).to.be.closeTo(0.4, 0.01);
feedbackDelay.dispose();
});
it("can set the delayTime", () => {
const feedbackDelay = new FeedbackDelay();
feedbackDelay.delayTime.value = "4n";
expect(feedbackDelay.delayTime.value).to.be.closeTo(0.5, 0.001);
feedbackDelay.delayTime.value = 0.22;
expect(feedbackDelay.delayTime.value).to.be.closeTo(0.22, 0.001);
feedbackDelay.dispose();
});
it("can set the feedback amount", () => {
const feedbackDelay = new FeedbackDelay();
feedbackDelay.feedback.value = 1;
expect(feedbackDelay.feedback.value).to.be.closeTo(1, 0.001);
feedbackDelay.feedback.value = 0.22;
expect(feedbackDelay.feedback.value).to.be.closeTo(0.22, 0.001);
feedbackDelay.dispose();
});
});
});

View file

@ -0,0 +1,76 @@
import { Delay } from "Tone/core";
import { Param } from "Tone/core/context/Param";
import { optionsFromArguments } from "Tone/core/util/Defaults";
import { readOnly } from "Tone/core/util/Interface";
import { FeedbackEffect, FeedbackEffectOptions } from "./FeedbackEffect";
interface FeedbackDelayOptions extends FeedbackEffectOptions {
delayTime: Time;
maxDelay: Time;
}
/**
* FeedbackDelay is a DelayNode in which part of output signal is fed back into the delay.
*
* @param delayTime The delay applied to the incoming signal.
* @param feedback The amount of the effected signal which is fed back through the delay.
* @example
* var feedbackDelay = new FeedbackDelay("8n", 0.5).toMaster();
* var tom = new Tone.MembraneSynth({
* "octaves" : 4,
* "pitchDecay" : 0.1
* }).connect(feedbackDelay);
* tom.triggerAttackRelease("A2","32n");
*/
export class FeedbackDelay extends FeedbackEffect<FeedbackDelayOptions> {
/**
* the delay node
*/
private _delayNode: Delay;
/**
* The delayTime of the DelayNode.
*/
delayTime: Param<Time>;
constructor(delayTime?: Time, feedback?: NormalRange);
constructor(options?: Partial<FeedbackDelayOptions>);
constructor() {
super(optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]));
const options = optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]);
this._delayNode = new Delay({
context: this.context,
delayTime: options.delayTime,
maxDelay: options.maxDelay,
});
this._internalChannels.push(this._delayNode);
/**
* The delayTime of the DelayNode.
* @type {Time}
* @signal
*/
this.delayTime = this._delayNode.delayTime;
// connect it up
this.connectEffect(this._delayNode);
readOnly(this, "delayTime");
}
static getDefaults(): FeedbackDelayOptions {
return Object.assign(FeedbackEffect.getDefaults(), {
delayTime: 0.25,
maxDelay: 1,
});
}
dispose(): this {
super.dispose();
this._delayNode.dispose();
this.delayTime.dispose();
return this;
}
}

View file

@ -0,0 +1,67 @@
import { Gain } from "../core/context/Gain";
import { Param } from "../core/context/Param";
import { readOnly } from "../core/util/Interface";
import { Effect, EffectOptions } from "./Effect";
export interface FeedbackEffectOptions extends EffectOptions {
/**
* The feedback from the output back to the input
* ```
* +---<--------<---+
* | |
* | +----------+ |
* +--> feedback +>-+
* +----------+
* ```
*/
feedback: NormalRange;
}
/**
* FeedbackEffect provides a loop between an audio source and its own output.
* This is a base-class for feedback effects.
*/
export abstract class FeedbackEffect<Options extends FeedbackEffectOptions> extends Effect<Options> {
name = "FeedbackEffect";
/**
* the gain which controls the feedback
*/
private _feedbackGain: Gain<NormalRange>;
/**
* The amount of signal which is fed back into the effect input.
*/
feedback: Param<NormalRange>;
constructor(options: FeedbackEffectOptions) {
super(options);
this._feedbackGain = new Gain({
context: this.context,
gain: options.feedback,
units: "normalRange",
});
this.feedback = this._feedbackGain.gain;
readOnly(this, "feedback");
// the feedback loop
this.effectReturn.chain(this._feedbackGain, this.effectSend);
}
static getDefaults(): FeedbackEffectOptions {
return Object.assign(Effect.getDefaults(), {
feedback: 0.125,
});
}
dispose(): this {
super.dispose();
this._feedbackGain.dispose();
this.feedback.dispose();
return this;
}
}