Tone.js/Tone/source/oscillator/ToneOscillatorNode.ts

129 lines
3.1 KiB
TypeScript
Raw Normal View History

2019-07-11 13:57:06 +00:00
import { connect } from "../../core/Connect";
import { Param } from "../../core/context/Param";
import { Cents, Frequency, Seconds, Time } from "../../core/type/Units";
2019-07-11 13:57:06 +00:00
import { optionsFromArguments } from "../../core/util/Defaults";
import { OneShotSource, OneShotSourceOptions } from "../OneShotSource";
2019-06-17 18:03:02 +00:00
2019-09-04 22:34:42 +00:00
export interface ToneOscillatorNodeOptions extends OneShotSourceOptions {
2019-06-17 18:03:02 +00:00
frequency: Frequency;
detune: Cents;
type: OscillatorType;
}
/**
* Wrapper around the native fire-and-forget OscillatorNode.
* Adds the ability to reschedule the stop method.
2019-08-27 15:47:52 +00:00
* ***[[Oscillator]] is better for most use-cases***
2019-09-16 14:15:23 +00:00
* @category Source
2019-06-17 18:03:02 +00:00
*/
export class ToneOscillatorNode extends OneShotSource<ToneOscillatorNodeOptions> {
2019-09-04 23:18:44 +00:00
readonly name: string = "ToneOscillatorNode";
2019-06-17 18:03:02 +00:00
/**
2019-09-14 20:39:18 +00:00
* The oscillator
2019-06-17 18:03:02 +00:00
*/
private _oscillator = this.context.createOscillator();
protected _internalChannels = [this._oscillator];
2019-06-17 18:03:02 +00:00
/**
2019-09-14 20:39:18 +00:00
* The frequency of the oscillator
2019-06-17 18:03:02 +00:00
*/
readonly frequency: Param<"frequency">;
2019-06-17 18:03:02 +00:00
/**
2019-09-14 20:39:18 +00:00
* The detune of the oscillator
2019-06-17 18:03:02 +00:00
*/
readonly detune: Param<"cents">;
2019-06-17 18:03:02 +00:00
2019-08-27 15:47:52 +00:00
/**
* @param frequency The frequency value
* @param type The basic oscillator type
2019-08-27 15:47:52 +00:00
*/
2019-06-17 18:03:02 +00:00
constructor(
frequency: Frequency,
type: OscillatorType,
);
constructor(options?: Partial<ToneOscillatorNodeOptions>);
2019-06-17 18:03:02 +00:00
constructor() {
super(optionsFromArguments(ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]));
const options = optionsFromArguments(ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]);
connect(this._oscillator, this._gainNode);
this.type = options.type;
this.frequency = new Param({
context: this.context,
2019-09-16 03:32:40 +00:00
param: this._oscillator.frequency,
units: "frequency",
value: options.frequency,
2019-06-17 18:03:02 +00:00
});
this.detune = new Param({
context: this.context,
2019-09-16 03:32:40 +00:00
param: this._oscillator.detune,
units: "cents",
value: options.detune,
2019-06-17 18:03:02 +00:00
});
}
static getDefaults(): ToneOscillatorNodeOptions {
return Object.assign(OneShotSource.getDefaults(), {
detune: 0,
frequency: 440,
type: "sine" as OscillatorType,
});
}
/**
* Start the oscillator node at the given time
* @param time When to start the oscillator
*/
start(time?: Time): this {
const computedTime = this.toSeconds(time);
2019-08-14 14:02:22 +00:00
this.log("start", computedTime);
2019-06-17 18:03:02 +00:00
this._startGain(computedTime);
this._oscillator.start(computedTime);
return this;
}
2019-07-23 15:46:08 +00:00
protected _stopSource(time?: Seconds): void {
2019-06-17 18:03:02 +00:00
this._oscillator.stop(time);
}
/**
* Sets an arbitrary custom periodic waveform given a PeriodicWave.
* @param periodicWave PeriodicWave should be created with context.createPeriodicWave
*/
setPeriodicWave(periodicWave: PeriodicWave): this {
this._oscillator.setPeriodicWave(periodicWave);
return this;
}
/**
* The oscillator type. Either 'sine', 'sawtooth', 'square', or 'triangle'
*/
get type(): OscillatorType {
return this._oscillator.type;
}
set type(type: OscillatorType) {
this._oscillator.type = type;
}
/**
2019-09-14 20:39:18 +00:00
* Clean up.
2019-06-17 18:03:02 +00:00
*/
dispose(): this {
super.dispose();
2019-08-08 20:32:22 +00:00
if (this.state === "started") {
this.stop();
}
this._oscillator.disconnect();
2019-06-17 18:03:02 +00:00
this.frequency.dispose();
this.detune.dispose();
return this;
}
}