optimization by moving child objects into constructor

means that in many cases the param won't be assigned twice
This commit is contained in:
Yotam Mann 2019-08-08 14:15:56 -04:00
parent a7d37ce720
commit 38d6f9d242
12 changed files with 167 additions and 121 deletions

View file

@ -1,6 +1,6 @@
import { Gain } from "../../core/context/Gain"; import { Gain } from "../../core/context/Gain";
import { Param } from "../../core/context/Param"; import { Param } from "../../core/context/Param";
import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode"; import { InputNode, ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode";
import { Decibels } from "../../core/type/Units"; import { Decibels } from "../../core/type/Units";
import { optionsFromArguments } from "../../core/util/Defaults"; import { optionsFromArguments } from "../../core/util/Defaults";
import { readOnly } from "../../core/util/Interface"; import { readOnly } from "../../core/util/Interface";
@ -27,16 +27,12 @@ export class Volume extends ToneAudioNode<VolumeOptions> {
/** /**
* the output node * the output node
*/ */
output: Gain<Decibels> = new Gain({ output: Gain<Decibels>;
context: this.context,
gain: 0,
units: "decibels",
});
/** /**
* Input and output are the same * Input and output are the same
*/ */
input = this.output; input: Gain;
/** /**
* The unmuted volume * The unmuted volume
@ -46,7 +42,7 @@ export class Volume extends ToneAudioNode<VolumeOptions> {
/** /**
* The volume control in decibels. * The volume control in decibels.
*/ */
volume: Param<Decibels> = this.output.gain; volume: Param<Decibels>;
constructor(options?: Decibels | Partial<VolumeOptions>); constructor(options?: Decibels | Partial<VolumeOptions>);
constructor() { constructor() {
@ -54,7 +50,12 @@ export class Volume extends ToneAudioNode<VolumeOptions> {
super(optionsFromArguments(Volume.getDefaults(), arguments, ["volume"])); super(optionsFromArguments(Volume.getDefaults(), arguments, ["volume"]));
const options = optionsFromArguments(Volume.getDefaults(), arguments, ["volume"]); const options = optionsFromArguments(Volume.getDefaults(), arguments, ["volume"]);
this.volume.setValueAtTime(options.volume, 0); this.input = this.output = new Gain({
context: this.context,
gain: options.volume,
units: "decibels",
});
this.volume = this.output.gain;
readOnly(this, "volume"); readOnly(this, "volume");
this._unmutedVolume = options.volume; this._unmutedVolume = options.volume;

View file

@ -46,7 +46,6 @@ export class Destination extends ToneAudioNode<DestinationOptions> {
connectSeries(this.input, this.output, this.context.rawContext.destination); connectSeries(this.input, this.output, this.context.rawContext.destination);
this.volume.setValueAtTime(options.volume, 0);
this.mute = options.mute; this.mute = options.mute;
} }

View file

@ -49,12 +49,11 @@ export abstract class Instrument<Options extends InstrumentOptions> extends Tone
super(optionsFromArguments(Instrument.getDefaults(), arguments)); super(optionsFromArguments(Instrument.getDefaults(), arguments));
const options = optionsFromArguments(Instrument.getDefaults(), arguments); const options = optionsFromArguments(Instrument.getDefaults(), arguments);
this._volume = new Volume({ this._volume = this.output = new Volume({
context: this.context, context: this.context,
volume: options.volume, volume: options.volume,
}); });
this.volume = this._volume.volume; this.volume = this._volume.volume;
this.output = this._volume;
readOnly(this, "volume"); readOnly(this, "volume");
} }

View file

@ -1,6 +1,7 @@
import { Signal } from "Tone/signal";
import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope"; import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope";
import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope"; import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope";
import { Time } from "../core/type/Units"; import { Cents, Frequency, Time } from "../core/type/Units";
import { omitFromObject, optionsFromArguments } from "../core/util/Defaults"; import { omitFromObject, optionsFromArguments } from "../core/util/Defaults";
import { readOnly } from "../core/util/Interface"; import { readOnly } from "../core/util/Interface";
import { RecursivePartial } from "../core/util/Interface"; import { RecursivePartial } from "../core/util/Interface";
@ -33,31 +34,35 @@ export class Synth extends Monophonic<SynthOptions> {
/** /**
* The oscillator. * The oscillator.
*/ */
readonly oscillator = new OmniOscillator({ context: this.context }); readonly oscillator: OmniOscillator<any>;
/** /**
* The frequency signal * The frequency signal
*/ */
readonly frequency = this.oscillator.frequency; readonly frequency: Signal<Frequency>;
/** /**
* The detune signal * The detune signal
*/ */
readonly detune = this.oscillator.detune; readonly detune: Signal<Cents>;
/** /**
* The envelope * The envelope
*/ */
readonly envelope: AmplitudeEnvelope = new AmplitudeEnvelope({ context: this.context }); readonly envelope: AmplitudeEnvelope = new AmplitudeEnvelope({ context: this.context });
protected _internalChannels = [this.oscillator, this.envelope];
constructor(options?: RecursivePartial<SynthOptions>); constructor(options?: RecursivePartial<SynthOptions>);
constructor() { constructor() {
super(optionsFromArguments(Synth.getDefaults(), arguments)); super(optionsFromArguments(Synth.getDefaults(), arguments));
const options = optionsFromArguments(Synth.getDefaults(), arguments); const options = optionsFromArguments(Synth.getDefaults(), arguments);
this.oscillator.set(options.oscillator); this.oscillator = new OmniOscillator(Object.assign({
context: this.context,
}, options.oscillator));
this.frequency = this.oscillator.frequency;
this.detune = this.oscillator.detune;
this.envelope.set(options.envelope); this.envelope.set(options.envelope);
// connect the oscillators to the output // connect the oscillators to the output

View file

@ -1,5 +1,6 @@
import { Volume } from "../component/channel/Volume"; import { Volume } from "../component/channel/Volume";
import { ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode"; import { Param } from "../core/context/Param";
import { OutputNode, ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode";
import { Decibels, Seconds, Time } from "../core/type/Units"; import { Decibels, Seconds, Time } from "../core/type/Units";
import { defaultArg, optionsFromArguments } from "../core/util/Defaults"; import { defaultArg, optionsFromArguments } from "../core/util/Defaults";
import { noOp, readOnly } from "../core/util/Interface"; import { noOp, readOnly } from "../core/util/Interface";
@ -38,17 +39,15 @@ export abstract class Source<Options extends SourceOptions> extends ToneAudioNod
/** /**
* The output volume node * The output volume node
*/ */
private _volume: Volume = new Volume({ private _volume: Volume;
context: this.context,
});
/** /**
* The output note * The output note
*/ */
output = this._volume; output: OutputNode;
/** /**
* There is no input * Sources have no inputs
*/ */
input = undefined; input = undefined;
@ -57,7 +56,7 @@ export abstract class Source<Options extends SourceOptions> extends ToneAudioNod
* @example * @example
* source.volume.value = -6; * source.volume.value = -6;
*/ */
volume = this._volume.volume; volume: Param<Decibels>;
/** /**
* Keep track of the scheduled state. * Keep track of the scheduled state.
@ -92,12 +91,15 @@ export abstract class Source<Options extends SourceOptions> extends ToneAudioNod
constructor(options: SourceOptions) { constructor(options: SourceOptions) {
super(options); super(options);
readOnly(this, "volume");
this._state.memory = 100; this._state.memory = 100;
this.volume.setValueAtTime(options.volume, 0);
// set mute initially
this.mute = options.mute;
this._volume = this.output = new Volume({
context: this.context,
mute: options.mute,
volume: options.volume,
});
this.volume = this._volume.volume;
readOnly(this, "volume");
} }
static getDefaults(): SourceOptions { static getDefaults(): SourceOptions {

View file

@ -39,22 +39,22 @@ export class AMOscillator extends Source<AMOscillatorOptions> implements ToneOsc
/** /**
* The carrier oscillator * The carrier oscillator
*/ */
private _carrier: Oscillator = new Oscillator({context : this.context }); private _carrier: Oscillator;
/** /**
* The oscillator's frequency * The oscillator's frequency
*/ */
readonly frequency: Signal<Frequency> = this._carrier.frequency; readonly frequency: Signal<Frequency>;
/** /**
* The detune control signal. * The detune control signal.
*/ */
readonly detune: Signal<Cents> = this._carrier.detune; readonly detune: Signal<Cents>;
/** /**
* The modulating oscillator * The modulating oscillator
*/ */
private _modulator = new Oscillator({ context : this.context }); private _modulator: Oscillator;
/** /**
* convert the -1,1 output to 0,1 * convert the -1,1 output to 0,1
@ -69,10 +69,7 @@ export class AMOscillator extends Source<AMOscillatorOptions> implements ToneOsc
* //pitch the modulator an octave below carrier * //pitch the modulator an octave below carrier
* synth.harmonicity.value = 0.5; * synth.harmonicity.value = 0.5;
*/ */
readonly harmonicity: Signal<Positive> = new Multiply({ readonly harmonicity: Signal<Positive>;
context: this.context,
units: "positive",
});
/** /**
* the node where the modulation happens * the node where the modulation happens
@ -88,19 +85,33 @@ export class AMOscillator extends Source<AMOscillatorOptions> implements ToneOsc
super(optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"])); super(optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));
const options = optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]); const options = optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);
this._carrier.type = options.type; this._carrier = new Oscillator({
this._modulator.type = options.modulationType; context : this.context,
this.frequency.setValueAtTime(options.frequency, 0); detune: options.detune,
this.detune.setValueAtTime(options.detune, 0); frequency: options.frequency,
this.harmonicity.setValueAtTime(options.harmonicity, 0); phase: options.phase,
type: options.type,
} as OscillatorOptions);
this.frequency = this._carrier.frequency,
this.detune = this._carrier.detune;
this._modulator = new Oscillator({
context : this.context,
phase: options.phase,
type: options.modulationType,
} as OscillatorOptions);
this.harmonicity = new Multiply({
context: this.context,
units: "positive",
value: options.harmonicity,
});
// connections // connections
this.frequency.chain(this.harmonicity, this._modulator.frequency); this.frequency.chain(this.harmonicity, this._modulator.frequency);
this._modulator.chain(this._modulationScale, this._modulationNode.gain); this._modulator.chain(this._modulationScale, this._modulationNode.gain);
this._carrier.chain(this._modulationNode, this.output); this._carrier.chain(this._modulationNode, this.output);
this.phase = options.phase;
readOnly(this, ["frequency", "detune", "harmonicity"]); readOnly(this, ["frequency", "detune", "harmonicity"]);
} }

View file

@ -37,28 +37,22 @@ export class FMOscillator extends Source<FMOscillatorOptions> implements ToneOsc
/** /**
* The carrier oscillator * The carrier oscillator
*/ */
private _carrier: Oscillator = new Oscillator({ private _carrier: Oscillator;
context : this.context,
frequency: 0,
});
/** /**
* The oscillator's frequency * The oscillator's frequency
*/ */
readonly frequency: Signal<Frequency> = new Signal({ readonly frequency: Signal<Frequency>;
context: this.context,
units: "frequency",
});
/** /**
* The detune control signal. * The detune control signal.
*/ */
readonly detune: Signal<Cents> = this._carrier.detune; readonly detune: Signal<Cents>;
/** /**
* The modulating oscillator * The modulating oscillator
*/ */
private _modulator = new Oscillator({ context : this.context }); private _modulator: Oscillator;
/** /**
* Harmonicity is the frequency ratio between the carrier and the modulator oscillators. * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.
@ -68,25 +62,19 @@ export class FMOscillator extends Source<FMOscillatorOptions> implements ToneOsc
* //pitch the modulator an octave below carrier * //pitch the modulator an octave below carrier
* synth.harmonicity.value = 0.5; * synth.harmonicity.value = 0.5;
*/ */
readonly harmonicity: Signal<Positive> = new Multiply({ readonly harmonicity: Signal<Positive>;
context: this.context,
units: "positive",
});
/** /**
* The modulation index which is in essence the depth or amount of the modulation. In other terms it is the * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the
* ratio of the frequency of the modulating signal (mf) to the amplitude of the * ratio of the frequency of the modulating signal (mf) to the amplitude of the
* modulating signal (ma) -- as in ma/mf. * modulating signal (ma) -- as in ma/mf.
*/ */
readonly modulationIndex: Signal<Positive> = new Multiply({ readonly modulationIndex: Signal<Positive>;
context: this.context,
units: "positive",
});
/** /**
* the node where the modulation happens * the node where the modulation happens
*/ */
private _modulationNode = new Gain({ private _modulationNode: Gain = new Gain({
context: this.context, context: this.context,
gain: 0, gain: 0,
}); });
@ -98,12 +86,39 @@ export class FMOscillator extends Source<FMOscillatorOptions> implements ToneOsc
super(optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"])); super(optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));
const options = optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]); const options = optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);
this._carrier.type = options.type; this._carrier = new Oscillator({
this._modulator.type = options.modulationType; context : this.context,
this.frequency.setValueAtTime(options.frequency, 0); detune: options.detune,
this.detune.setValueAtTime(options.detune, 0); frequency: 0,
this.harmonicity.setValueAtTime(options.harmonicity, 0); phase: options.phase,
this.modulationIndex.setValueAtTime(options.modulationIndex, 0); type: options.type,
} as OscillatorOptions);
this.detune = this._carrier.detune;
this.frequency = new Signal({
context: this.context,
units: "frequency",
value: options.frequency,
});
this._modulator = new Oscillator({
context : this.context,
phase: options.phase,
type: options.modulationType,
} as OscillatorOptions);
this.harmonicity = new Multiply({
context: this.context,
units: "positive",
value: options.harmonicity,
});
this.modulationIndex = new Multiply({
context: this.context,
units: "positive",
value: options.modulationIndex,
});
// connections // connections
this.frequency.connect(this._carrier.frequency); this.frequency.connect(this._carrier.frequency);
@ -114,8 +129,6 @@ export class FMOscillator extends Source<FMOscillatorOptions> implements ToneOsc
this._carrier.connect(this.output); this._carrier.connect(this.output);
this.detune.connect(this._modulator.detune); this.detune.connect(this._modulator.detune);
this.phase = options.phase;
readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]); readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]);
} }

View file

@ -24,18 +24,12 @@ export class FatOscillator extends Source<FatOscillatorOptions> implements ToneO
/** /**
* The oscillator's frequency * The oscillator's frequency
*/ */
readonly frequency: Signal<Frequency> = new Signal<Cents>({ readonly frequency: Signal<Frequency>;
context: this.context,
units: "frequency",
});
/** /**
* The detune control signal. * The detune control signal.
*/ */
readonly detune: Signal<Cents> = new Signal<Cents>({ readonly detune: Signal<Cents>;
context: this.context,
units: "cents",
});
/** /**
* The array of oscillators * The array of oscillators
@ -74,8 +68,16 @@ export class FatOscillator extends Source<FatOscillatorOptions> implements ToneO
super(optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"])); super(optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]));
const options = optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]); const options = optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]);
this.frequency.setValueAtTime(options.frequency, 0); this.frequency = new Signal({
this.detune.setValueAtTime(options.detune, 0); context: this.context,
units: "frequency",
value: options.frequency,
});
this.detune = new Signal({
context: this.context,
units: "cents",
value: options.detune,
});
this._spread = options.spread; this._spread = options.spread;
this._type = options.type; this._type = options.type;
@ -168,7 +170,6 @@ export class FatOscillator extends Source<FatOscillatorOptions> implements ToneO
get count(): number { get count(): number {
return this._oscillators.length; return this._oscillators.length;
} }
set count(count: number) { set count(count: number) {
count = Math.max(count, 1); count = Math.max(count, 1);
if (this._oscillators.length !== count) { if (this._oscillators.length !== count) {

View file

@ -1,5 +1,5 @@
import { AudioRange, Cents, Degrees, Frequency, Positive, Time } from "../../core/type/Units"; import { AudioRange, Cents, Degrees, Frequency, Positive, Time } from "../../core/type/Units";
import { optionsFromArguments } from "../../core/util/Defaults"; import { optionsFromArguments } from "../../core/util/Defaults";
import { readOnly } from "../../core/util/Interface"; import { readOnly } from "../../core/util/Interface";
import { isNumber, isString } from "../../core/util/TypeCheck"; import { isNumber, isString } from "../../core/util/TypeCheck";
import { Signal } from "../../signal/Signal"; import { Signal } from "../../signal/Signal";
@ -105,18 +105,12 @@ implements Omit<ToneOscillatorInterface, "type"> {
/** /**
* The frequency control. * The frequency control.
*/ */
readonly frequency: Signal<Frequency> = new Signal({ readonly frequency: Signal<Frequency>;
context: this.context,
units: "frequency",
});
/** /**
* The detune control. * The detune control.
*/ */
readonly detune: Signal<Cents> = new Signal<Cents>({ readonly detune: Signal<Cents>;
context: this.context,
units: "cents",
});
/** /**
* The oscillator that can switch types * The oscillator that can switch types
@ -135,8 +129,16 @@ implements Omit<ToneOscillatorInterface, "type"> {
super(optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"])); super(optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"]));
const options = optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"]); const options = optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"]);
this.frequency.setValueAtTime(options.frequency, 0); this.frequency = new Signal({
this.detune.setValueAtTime(options.detune, 0); context: this.context,
value: options.frequency,
units: "frequency",
});
this.detune = new Signal({
context: this.context,
value: options.detune,
units: "cents",
});
readOnly(this, ["frequency", "detune"]); readOnly(this, ["frequency", "detune"]);
// set the options // set the options
@ -152,7 +154,6 @@ implements Omit<ToneOscillatorInterface, "type"> {
PulseOscillator.getDefaults(), PulseOscillator.getDefaults(),
PWMOscillator.getDefaults(), PWMOscillator.getDefaults(),
); );
// return Oscillator.getDefaults() as OmniOscillatorConstructorOptions;
} }
/** /**

View file

@ -57,7 +57,7 @@ export class ToneOscillatorNode extends OneShotSource<ToneOscillatorNodeOptions>
context: this.context, context: this.context,
param : this._oscillator.frequency, param : this._oscillator.frequency,
units : "frequency", units : "frequency",
value : this.toFrequency(options.frequency), value : options.frequency,
}); });
this.detune = new Param({ this.detune = new Param({

View file

@ -28,13 +28,11 @@ export class PWMOscillator extends Source<PWMOscillatorOptions> implements ToneO
/** /**
* the pulse oscillator * the pulse oscillator
*/ */
private _pulse: PulseOscillator = new PulseOscillator({ context: this.context }); private _pulse: PulseOscillator;
/** /**
* the modulator * the modulator
* @type {Tone.Oscillator}
* @private
*/ */
private _modulator: Oscillator = new Oscillator({ context: this.context }); private _modulator: Oscillator;
/** /**
* Scale the oscillator so it doesn't go silent * Scale the oscillator so it doesn't go silent
@ -48,17 +46,17 @@ export class PWMOscillator extends Source<PWMOscillatorOptions> implements ToneO
/** /**
* The frequency control. * The frequency control.
*/ */
readonly frequency: Signal<Frequency> = this._modulator.frequency; readonly frequency: Signal<Frequency>;
/** /**
* The detune of the oscillator. * The detune of the oscillator.
*/ */
readonly detune: Signal<Cents> = this._modulator.detune; readonly detune: Signal<Cents>;
/** /**
* The modulation rate of the oscillator. * The modulation rate of the oscillator.
*/ */
readonly modulationFrequency: Signal<Frequency> = this._pulse.frequency; readonly modulationFrequency: Signal<Frequency>;
constructor(options?: Partial<PWMOscillatorOptions>); constructor(options?: Partial<PWMOscillatorOptions>);
constructor(frequency?: Frequency, modulationFrequency?: Frequency); constructor(frequency?: Frequency, modulationFrequency?: Frequency);
@ -66,14 +64,25 @@ export class PWMOscillator extends Source<PWMOscillatorOptions> implements ToneO
super(optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"])); super(optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]));
const options = optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]); const options = optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]);
this._pulse = new PulseOscillator({
context: this.context,
frequency: options.modulationFrequency,
});
// change the pulse oscillator type // change the pulse oscillator type
// @ts-ignore // @ts-ignore
this._pulse._sawtooth.type = "sine"; this._pulse._sawtooth.type = "sine";
this._pulse.frequency.setValueAtTime(options.modulationFrequency, 0); this.modulationFrequency = this._pulse.frequency;
this._modulator.frequency.setValueAtTime(options.frequency, 0);
this._modulator.detune.setValueAtTime(options.detune, 0); this._modulator = new Oscillator({
this._modulator.phase = options.phase; context: this.context,
detune: options.detune,
frequency: options.frequency,
phase: options.phase,
});
this.frequency = this._modulator.frequency;
this.detune = this._modulator.detune;
// connections // connections
this._modulator.chain(this._scale, this._pulse.width); this._modulator.chain(this._scale, this._pulse.width);

View file

@ -49,10 +49,7 @@ export class PulseOscillator extends Source<PulseOscillatorOptions> implements T
/** /**
* The width of the pulse. * The width of the pulse.
*/ */
width: Signal<AudioRange> = new Signal<AudioRange>({ width: Signal<AudioRange>;
context: this.context,
units: "audioRange",
});
/** /**
* gate the width amount * gate the width amount
@ -65,20 +62,17 @@ export class PulseOscillator extends Source<PulseOscillatorOptions> implements T
/** /**
* the sawtooth oscillator * the sawtooth oscillator
*/ */
private _sawtooth: Oscillator = new Oscillator({ private _sawtooth: Oscillator;
context: this.context,
type : "sawtooth",
});
/** /**
* The frequency control. * The frequency control.
*/ */
frequency: Signal<Frequency> = this._sawtooth.frequency; frequency: Signal<Frequency>;
/** /**
* The detune in cents. * The detune in cents.
*/ */
detune: Signal<Cents> = this._sawtooth.detune; detune: Signal<Cents>;
/** /**
* Threshold the signal to turn it into a square * Threshold the signal to turn it into a square
@ -95,10 +89,21 @@ export class PulseOscillator extends Source<PulseOscillatorOptions> implements T
super(optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"])); super(optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]));
const options = optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]); const options = optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]);
this.width.setValueAtTime(options.width, 0); this.width = new Signal({
this._sawtooth.frequency.setValueAtTime(options.frequency, 0); context: this.context,
this._sawtooth.detune.setValueAtTime(options.detune, 0); units: "audioRange",
this._sawtooth.phase = options.phase; value: options.width,
});
this._sawtooth = new Oscillator({
context: this.context,
detune: options.detune,
frequency: options.frequency,
phase: options.phase,
type : "sawtooth",
});
this.frequency = this._sawtooth.frequency;
this.detune = this._sawtooth.detune;
// connections // connections
this._sawtooth.chain(this._thresh, this.output); this._sawtooth.chain(this._thresh, this.output);