Tone.js/Tone/instrument/PluckSynth.ts

114 lines
2.7 KiB
TypeScript
Raw Normal View History

2019-09-17 17:37:43 +00:00
import { Param } from "../core/context/Param";
import { Frequency, NormalRange, Time } from "../core/type/Units";
import { LowpassCombFilter } from "../component/filter/LowpassCombFilter";
import { deepMerge } from "../core/util/Defaults";
import { optionsFromArguments } from "../core/util/Defaults";
import { RecursivePartial } from "../core/util/Interface";
import { Signal } from "../signal/Signal";
import { Noise } from "../source/Noise";
2019-09-17 17:40:07 +00:00
import { Instrument, InstrumentOptions } from "./Instrument";
2019-09-17 17:37:43 +00:00
export interface PluckSynthOptions extends InstrumentOptions {
attackNoise: number;
dampening: Frequency;
resonance: NormalRange;
}
/**
2019-09-17 17:37:43 +00:00
* Karplus-String string synthesis. Often out of tune.
*
* @example
2019-09-17 17:37:43 +00:00
* var plucky = new Tone.PluckSynth().toDestination();
* plucky.triggerAttack("C4");
2019-09-17 17:55:51 +00:00
* @category Instrument
*/
2019-09-17 17:37:43 +00:00
export class PluckSynth extends Instrument<PluckSynthOptions> {
readonly name = "PluckSynth";
2019-09-17 17:37:43 +00:00
/**
* Noise burst at the beginning
*/
private _noise: Noise;
private _lfcf: LowpassCombFilter;
/**
2019-09-17 17:37:43 +00:00
* The amount of noise at the attack.
* Nominal range of [0.1, 20]
* @min 0.1
* @max 20
*/
attackNoise: number;
2019-09-17 17:37:43 +00:00
/**
* The resonance control.
*/
readonly resonance: Param<NormalRange>;
2019-09-17 17:37:43 +00:00
/**
* The dampening control. i.e. the lowpass filter frequency of the comb filter
2019-09-24 21:21:59 +00:00
* @min 0
* @max 7000
2019-09-17 17:37:43 +00:00
*/
readonly dampening: Signal<Frequency>;
constructor(options?: RecursivePartial<PluckSynthOptions>)
constructor() {
super(optionsFromArguments(PluckSynth.getDefaults(), arguments));
const options = optionsFromArguments(PluckSynth.getDefaults(), arguments);
2019-09-17 17:37:43 +00:00
this._noise = new Noise({
context: this.context,
type: "pink"
});
this.attackNoise = options.attackNoise;
this._lfcf = new LowpassCombFilter({
2019-09-17 17:37:43 +00:00
context: this.context,
dampening: options.dampening,
resonance: options.resonance,
});
this.resonance = this._lfcf.resonance;
this.dampening = this._lfcf.dampening;
this._noise.connect(this._lfcf);
this._lfcf.connect(this.output);
}
static getDefaults(): PluckSynthOptions {
2019-09-17 17:37:43 +00:00
return deepMerge(Instrument.getDefaults(), {
2019-09-17 17:40:07 +00:00
attackNoise: 1,
dampening: 4000,
resonance: 0.7,
});
}
2019-09-17 17:37:43 +00:00
triggerAttack(note: Frequency, time?: Time): this {
const freq = this.toFrequency(note);
time = this.toSeconds(time);
const delayAmount = 1 / freq;
this._lfcf.delayTime.setValueAtTime(delayAmount, time);
this._noise.start(time);
this._noise.stop(time + delayAmount * this.attackNoise);
return this;
}
2019-09-17 17:37:43 +00:00
/**
* PluckSynths' trigger release method doesn't do anything.
*/
triggerRelease(): this{
2019-09-17 17:40:07 +00:00
// does nothing
2019-09-17 17:37:43 +00:00
return this;
}
dispose(): this {
super.dispose();
this._noise.dispose();
this._lfcf.dispose();
return this;
}
2019-09-17 17:40:07 +00:00
}