diff --git a/Tone/component/channel/Volume.ts b/Tone/component/channel/Volume.ts index 2bcd4b9a..33bc4c9a 100644 --- a/Tone/component/channel/Volume.ts +++ b/Tone/component/channel/Volume.ts @@ -1,6 +1,6 @@ import { Gain } from "../../core/context/Gain"; 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 { optionsFromArguments } from "../../core/util/Defaults"; import { readOnly } from "../../core/util/Interface"; @@ -27,16 +27,12 @@ export class Volume extends ToneAudioNode { /** * the output node */ - output: Gain = new Gain({ - context: this.context, - gain: 0, - units: "decibels", - }); + output: Gain; /** * Input and output are the same */ - input = this.output; + input: Gain; /** * The unmuted volume @@ -46,7 +42,7 @@ export class Volume extends ToneAudioNode { /** * The volume control in decibels. */ - volume: Param = this.output.gain; + volume: Param; constructor(options?: Decibels | Partial); constructor() { @@ -54,7 +50,12 @@ export class Volume extends ToneAudioNode { super(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"); this._unmutedVolume = options.volume; diff --git a/Tone/core/context/Destination.ts b/Tone/core/context/Destination.ts index 49efa234..cb7770d1 100644 --- a/Tone/core/context/Destination.ts +++ b/Tone/core/context/Destination.ts @@ -46,7 +46,6 @@ export class Destination extends ToneAudioNode { connectSeries(this.input, this.output, this.context.rawContext.destination); - this.volume.setValueAtTime(options.volume, 0); this.mute = options.mute; } diff --git a/Tone/instrument/Instrument.ts b/Tone/instrument/Instrument.ts index c865c161..6b47ace3 100644 --- a/Tone/instrument/Instrument.ts +++ b/Tone/instrument/Instrument.ts @@ -49,12 +49,11 @@ export abstract class Instrument extends Tone super(optionsFromArguments(Instrument.getDefaults(), arguments)); const options = optionsFromArguments(Instrument.getDefaults(), arguments); - this._volume = new Volume({ + this._volume = this.output = new Volume({ context: this.context, volume: options.volume, }); this.volume = this._volume.volume; - this.output = this._volume; readOnly(this, "volume"); } diff --git a/Tone/instrument/Synth.ts b/Tone/instrument/Synth.ts index 24fda87c..40b36883 100644 --- a/Tone/instrument/Synth.ts +++ b/Tone/instrument/Synth.ts @@ -1,6 +1,7 @@ +import { Signal } from "Tone/signal"; import { AmplitudeEnvelope } from "../component/envelope/AmplitudeEnvelope"; 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 { readOnly } from "../core/util/Interface"; import { RecursivePartial } from "../core/util/Interface"; @@ -33,31 +34,35 @@ export class Synth extends Monophonic { /** * The oscillator. */ - readonly oscillator = new OmniOscillator({ context: this.context }); + readonly oscillator: OmniOscillator; /** * The frequency signal */ - readonly frequency = this.oscillator.frequency; + readonly frequency: Signal; /** * The detune signal */ - readonly detune = this.oscillator.detune; + readonly detune: Signal; /** * The envelope */ readonly envelope: AmplitudeEnvelope = new AmplitudeEnvelope({ context: this.context }); - protected _internalChannels = [this.oscillator, this.envelope]; - constructor(options?: RecursivePartial); constructor() { super(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); // connect the oscillators to the output diff --git a/Tone/source/Source.ts b/Tone/source/Source.ts index d5d0bc3e..54cad5fa 100644 --- a/Tone/source/Source.ts +++ b/Tone/source/Source.ts @@ -1,5 +1,6 @@ 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 { defaultArg, optionsFromArguments } from "../core/util/Defaults"; import { noOp, readOnly } from "../core/util/Interface"; @@ -38,17 +39,15 @@ export abstract class Source extends ToneAudioNod /** * The output volume node */ - private _volume: Volume = new Volume({ - context: this.context, - }); + private _volume: Volume; /** * The output note */ - output = this._volume; + output: OutputNode; /** - * There is no input + * Sources have no inputs */ input = undefined; @@ -57,7 +56,7 @@ export abstract class Source extends ToneAudioNod * @example * source.volume.value = -6; */ - volume = this._volume.volume; + volume: Param; /** * Keep track of the scheduled state. @@ -92,12 +91,15 @@ export abstract class Source extends ToneAudioNod constructor(options: SourceOptions) { super(options); - readOnly(this, "volume"); 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 { diff --git a/Tone/source/oscillator/AMOscillator.ts b/Tone/source/oscillator/AMOscillator.ts index d6db2159..77deaba7 100644 --- a/Tone/source/oscillator/AMOscillator.ts +++ b/Tone/source/oscillator/AMOscillator.ts @@ -39,22 +39,22 @@ export class AMOscillator extends Source implements ToneOsc /** * The carrier oscillator */ - private _carrier: Oscillator = new Oscillator({context : this.context }); + private _carrier: Oscillator; /** * The oscillator's frequency */ - readonly frequency: Signal = this._carrier.frequency; + readonly frequency: Signal; /** * The detune control signal. */ - readonly detune: Signal = this._carrier.detune; + readonly detune: Signal; /** * The modulating oscillator */ - private _modulator = new Oscillator({ context : this.context }); + private _modulator: Oscillator; /** * convert the -1,1 output to 0,1 @@ -69,10 +69,7 @@ export class AMOscillator extends Source implements ToneOsc * //pitch the modulator an octave below carrier * synth.harmonicity.value = 0.5; */ - readonly harmonicity: Signal = new Multiply({ - context: this.context, - units: "positive", - }); + readonly harmonicity: Signal; /** * the node where the modulation happens @@ -88,19 +85,33 @@ export class AMOscillator extends Source implements ToneOsc super(optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"])); const options = optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]); - this._carrier.type = options.type; - this._modulator.type = options.modulationType; - this.frequency.setValueAtTime(options.frequency, 0); - this.detune.setValueAtTime(options.detune, 0); - this.harmonicity.setValueAtTime(options.harmonicity, 0); + this._carrier = new Oscillator({ + context : this.context, + detune: options.detune, + frequency: options.frequency, + 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 this.frequency.chain(this.harmonicity, this._modulator.frequency); this._modulator.chain(this._modulationScale, this._modulationNode.gain); this._carrier.chain(this._modulationNode, this.output); - this.phase = options.phase; - readOnly(this, ["frequency", "detune", "harmonicity"]); } diff --git a/Tone/source/oscillator/FMOscillator.ts b/Tone/source/oscillator/FMOscillator.ts index 94baa92c..922f27ff 100644 --- a/Tone/source/oscillator/FMOscillator.ts +++ b/Tone/source/oscillator/FMOscillator.ts @@ -37,28 +37,22 @@ export class FMOscillator extends Source implements ToneOsc /** * The carrier oscillator */ - private _carrier: Oscillator = new Oscillator({ - context : this.context, - frequency: 0, - }); + private _carrier: Oscillator; /** * The oscillator's frequency */ - readonly frequency: Signal = new Signal({ - context: this.context, - units: "frequency", - }); + readonly frequency: Signal; /** * The detune control signal. */ - readonly detune: Signal = this._carrier.detune; + readonly detune: Signal; /** * 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. @@ -68,25 +62,19 @@ export class FMOscillator extends Source implements ToneOsc * //pitch the modulator an octave below carrier * synth.harmonicity.value = 0.5; */ - readonly harmonicity: Signal = new Multiply({ - context: this.context, - units: "positive", - }); + readonly harmonicity: Signal; /** * 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 * modulating signal (ma) -- as in ma/mf. */ - readonly modulationIndex: Signal = new Multiply({ - context: this.context, - units: "positive", - }); + readonly modulationIndex: Signal; /** * the node where the modulation happens */ - private _modulationNode = new Gain({ + private _modulationNode: Gain = new Gain({ context: this.context, gain: 0, }); @@ -98,12 +86,39 @@ export class FMOscillator extends Source implements ToneOsc super(optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"])); const options = optionsFromArguments(FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]); - this._carrier.type = options.type; - this._modulator.type = options.modulationType; - this.frequency.setValueAtTime(options.frequency, 0); - this.detune.setValueAtTime(options.detune, 0); - this.harmonicity.setValueAtTime(options.harmonicity, 0); - this.modulationIndex.setValueAtTime(options.modulationIndex, 0); + this._carrier = new Oscillator({ + context : this.context, + detune: options.detune, + frequency: 0, + phase: options.phase, + 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 this.frequency.connect(this._carrier.frequency); @@ -114,8 +129,6 @@ export class FMOscillator extends Source implements ToneOsc this._carrier.connect(this.output); this.detune.connect(this._modulator.detune); - this.phase = options.phase; - readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]); } diff --git a/Tone/source/oscillator/FatOscillator.ts b/Tone/source/oscillator/FatOscillator.ts index 7a337f8b..59c822b8 100644 --- a/Tone/source/oscillator/FatOscillator.ts +++ b/Tone/source/oscillator/FatOscillator.ts @@ -24,18 +24,12 @@ export class FatOscillator extends Source implements ToneO /** * The oscillator's frequency */ - readonly frequency: Signal = new Signal({ - context: this.context, - units: "frequency", - }); + readonly frequency: Signal; /** * The detune control signal. */ - readonly detune: Signal = new Signal({ - context: this.context, - units: "cents", - }); + readonly detune: Signal; /** * The array of oscillators @@ -74,8 +68,16 @@ export class FatOscillator extends Source implements ToneO super(optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"])); const options = optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]); - this.frequency.setValueAtTime(options.frequency, 0); - this.detune.setValueAtTime(options.detune, 0); + this.frequency = new Signal({ + 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._type = options.type; @@ -168,7 +170,6 @@ export class FatOscillator extends Source implements ToneO get count(): number { return this._oscillators.length; } - set count(count: number) { count = Math.max(count, 1); if (this._oscillators.length !== count) { diff --git a/Tone/source/oscillator/OmniOscillator.ts b/Tone/source/oscillator/OmniOscillator.ts index 60d73bca..40d58c7f 100644 --- a/Tone/source/oscillator/OmniOscillator.ts +++ b/Tone/source/oscillator/OmniOscillator.ts @@ -1,5 +1,5 @@ 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 { isNumber, isString } from "../../core/util/TypeCheck"; import { Signal } from "../../signal/Signal"; @@ -105,18 +105,12 @@ implements Omit { /** * The frequency control. */ - readonly frequency: Signal = new Signal({ - context: this.context, - units: "frequency", - }); + readonly frequency: Signal; /** * The detune control. */ - readonly detune: Signal = new Signal({ - context: this.context, - units: "cents", - }); + readonly detune: Signal; /** * The oscillator that can switch types @@ -135,8 +129,16 @@ implements Omit { super(optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"])); const options = optionsFromArguments(OmniOscillator.getDefaults(), arguments, ["frequency", "type"]); - this.frequency.setValueAtTime(options.frequency, 0); - this.detune.setValueAtTime(options.detune, 0); + this.frequency = new Signal({ + context: this.context, + value: options.frequency, + units: "frequency", + }); + this.detune = new Signal({ + context: this.context, + value: options.detune, + units: "cents", + }); readOnly(this, ["frequency", "detune"]); // set the options @@ -152,7 +154,6 @@ implements Omit { PulseOscillator.getDefaults(), PWMOscillator.getDefaults(), ); - // return Oscillator.getDefaults() as OmniOscillatorConstructorOptions; } /** diff --git a/Tone/source/oscillator/OscillatorNode.ts b/Tone/source/oscillator/OscillatorNode.ts index 85452424..1dbb2cb6 100644 --- a/Tone/source/oscillator/OscillatorNode.ts +++ b/Tone/source/oscillator/OscillatorNode.ts @@ -57,7 +57,7 @@ export class ToneOscillatorNode extends OneShotSource context: this.context, param : this._oscillator.frequency, units : "frequency", - value : this.toFrequency(options.frequency), + value : options.frequency, }); this.detune = new Param({ diff --git a/Tone/source/oscillator/PWMOscillator.ts b/Tone/source/oscillator/PWMOscillator.ts index 8354bf80..ae3ab01b 100644 --- a/Tone/source/oscillator/PWMOscillator.ts +++ b/Tone/source/oscillator/PWMOscillator.ts @@ -28,13 +28,11 @@ export class PWMOscillator extends Source implements ToneO /** * the pulse oscillator */ - private _pulse: PulseOscillator = new PulseOscillator({ context: this.context }); + private _pulse: PulseOscillator; /** * 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 @@ -48,17 +46,17 @@ export class PWMOscillator extends Source implements ToneO /** * The frequency control. */ - readonly frequency: Signal = this._modulator.frequency; + readonly frequency: Signal; /** * The detune of the oscillator. */ - readonly detune: Signal = this._modulator.detune; + readonly detune: Signal; /** * The modulation rate of the oscillator. */ - readonly modulationFrequency: Signal = this._pulse.frequency; + readonly modulationFrequency: Signal; constructor(options?: Partial); constructor(frequency?: Frequency, modulationFrequency?: Frequency); @@ -66,14 +64,25 @@ export class PWMOscillator extends Source implements ToneO super(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 // @ts-ignore this._pulse._sawtooth.type = "sine"; - this._pulse.frequency.setValueAtTime(options.modulationFrequency, 0); - this._modulator.frequency.setValueAtTime(options.frequency, 0); - this._modulator.detune.setValueAtTime(options.detune, 0); - this._modulator.phase = options.phase; + this.modulationFrequency = this._pulse.frequency; + + this._modulator = new Oscillator({ + context: this.context, + detune: options.detune, + frequency: options.frequency, + phase: options.phase, + }); + + this.frequency = this._modulator.frequency; + this.detune = this._modulator.detune; // connections this._modulator.chain(this._scale, this._pulse.width); diff --git a/Tone/source/oscillator/PulseOscillator.ts b/Tone/source/oscillator/PulseOscillator.ts index ce6b5a08..b0820e7a 100644 --- a/Tone/source/oscillator/PulseOscillator.ts +++ b/Tone/source/oscillator/PulseOscillator.ts @@ -49,10 +49,7 @@ export class PulseOscillator extends Source implements T /** * The width of the pulse. */ - width: Signal = new Signal({ - context: this.context, - units: "audioRange", - }); + width: Signal; /** * gate the width amount @@ -65,20 +62,17 @@ export class PulseOscillator extends Source implements T /** * the sawtooth oscillator */ - private _sawtooth: Oscillator = new Oscillator({ - context: this.context, - type : "sawtooth", - }); + private _sawtooth: Oscillator; /** * The frequency control. */ - frequency: Signal = this._sawtooth.frequency; + frequency: Signal; /** * The detune in cents. */ - detune: Signal = this._sawtooth.detune; + detune: Signal; /** * Threshold the signal to turn it into a square @@ -95,10 +89,21 @@ export class PulseOscillator extends Source implements T super(optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"])); const options = optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]); - this.width.setValueAtTime(options.width, 0); - this._sawtooth.frequency.setValueAtTime(options.frequency, 0); - this._sawtooth.detune.setValueAtTime(options.detune, 0); - this._sawtooth.phase = options.phase; + this.width = new Signal({ + context: this.context, + units: "audioRange", + 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 this._sawtooth.chain(this._thresh, this.output);