UNPKG

sw-synth

Version:

Lightweight sound synthesizer designed for real-time user interaction using the Web Audio API

108 lines 4.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AperiodicVoice = exports.UnisonVoice = exports.OscillatorVoice = exports.OscillatorVoiceBase = exports.defaultUnisonParams = exports.defaultParams = exports.AperiodicWave = void 0; const aperiodic_oscillator_1 = require("aperiodic-oscillator"); const base_1 = require("./base"); var aperiodic_oscillator_2 = require("aperiodic-oscillator"); Object.defineProperty(exports, "AperiodicWave", { enumerable: true, get: function () { return aperiodic_oscillator_2.AperiodicWave; } }); function defaultParams() { return { audioDelay: 0.001, type: 'triangle', attackTime: 0.01, decayTime: 0.3, sustainLevel: 0.8, releaseTime: 0.01, }; } exports.defaultParams = defaultParams; function defaultUnisonParams() { const result = defaultParams(); result.type = 'sawtooth'; result.stackSize = 3; result.spread = 1.5; return result; } exports.defaultUnisonParams = defaultUnisonParams; class OscillatorVoiceBase extends base_1.VoiceBase { constructor(context, destination, log, oscillatorClass) { super(context, destination, log); this.oscillator = new oscillatorClass(this.context); this.oscillator.connect(this.envelope); const now = this.context.currentTime; this.oscillator.start(now); this.oscillator.addEventListener('ended', () => { this.envelope.disconnect(); this.oscillator.disconnect(); }); } noteOn(frequency, velocity, noteId, params) { const now = this.context.currentTime + params.audioDelay; this.oscillator.frequency.setValueAtTime(frequency, now); return super.noteOn(frequency, velocity, noteId, params); } dispose() { this.oscillator.stop(); if (this.oscillator instanceof aperiodic_oscillator_1.UnisonOscillator || this.oscillator instanceof aperiodic_oscillator_1.AperiodicOscillator) { this.oscillator.dispose(); } } } exports.OscillatorVoiceBase = OscillatorVoiceBase; class OscillatorVoice extends OscillatorVoiceBase { constructor(audioContext, destination, log) { super(audioContext, destination, log, OscillatorNode); } noteOn(frequency, velocity, noteId, params) { if (params.periodicWave) { if (params.type !== 'custom') { throw new Error("Oscillator type must be set to 'custom' when periodic wave is used."); } this.oscillator.setPeriodicWave(params.periodicWave); } else { if (params.type === 'custom') { throw new Error("Periodic wave must be given when oscillator type is set to 'custom'"); } this.oscillator.type = params.type; } return super.noteOn(frequency, velocity, noteId, params); } } exports.OscillatorVoice = OscillatorVoice; class UnisonVoice extends OscillatorVoiceBase { constructor(audioContext, destination, log) { super(audioContext, destination, log, aperiodic_oscillator_1.UnisonOscillator); } noteOn(frequency, velocity, noteId, params) { this.oscillator.numberOfVoices = params.stackSize; const now = this.context.currentTime + params.audioDelay; this.oscillator.spread.setValueAtTime(params.spread, now); if (params.periodicWave) { if (params.type !== 'custom') { throw new Error("Oscillator type must be set to 'custom' when periodic wave is used."); } this.oscillator.setPeriodicWave(params.periodicWave); } else { if (params.type === 'custom') { throw new Error("Periodic wave must be given when oscillator type is set to 'custom'"); } this.oscillator.type = params.type; } return super.noteOn(frequency, velocity, noteId, params); } } exports.UnisonVoice = UnisonVoice; class AperiodicVoice extends OscillatorVoiceBase { constructor(audioContext, destination, log) { super(audioContext, destination, log, aperiodic_oscillator_1.AperiodicOscillator); } noteOn(frequency, velocity, noteId, params) { this.oscillator.setAperiodicWave(params.aperiodicWave); return super.noteOn(frequency, velocity, noteId, params); } } exports.AperiodicVoice = AperiodicVoice; //# sourceMappingURL=oscillator.js.map