sw-synth
Version:
Lightweight sound synthesizer designed for real-time user interaction using the Web Audio API
108 lines • 4.48 kB
JavaScript
;
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