envelopes on fmsynth

This commit is contained in:
Raphael Forment 2023-08-29 13:46:43 +02:00
parent 94bcfb11de
commit 8fc7688585
2 changed files with 58 additions and 7 deletions

View File

@ -39,6 +39,19 @@ export const getEnvelope = (attack, decay, sustain, release, velocity, begin) =>
};
};
export const getExpEnvelope = (attack, decay, velocity, begin) => {
const gainNode = getAudioContext().createGain();
gainNode.gain.setValueAtTime(0.0001, begin);
gainNode.gain.exponentialRampToValueAtTime(velocity, begin + attack);
gainNode.gain.exponentialRampToValueAtTime(0.0001, begin + attack + decay);
return {
node: gainNode,
stop: (t) => {
gainNode.gain.exponentialRampToValueAtTime(0.0001, t + decay);
},
};
};
export const getADSR = (attack, decay, sustain, release, velocity, begin, end) => {
const gainNode = getAudioContext().createGain();
gainNode.gain.setValueAtTime(0, begin);

View File

@ -1,6 +1,6 @@
import { midiToFreq, noteToMidi } from './util.mjs';
import { registerSound, getAudioContext } from './superdough.mjs';
import { getOscillator, gainNode, getEnvelope } from './helpers.mjs';
import { getOscillator, gainNode, getEnvelope, getExpEnvelope } from './helpers.mjs';
const mod = (freq, range = 1, type) => {
const ctx = getAudioContext();
@ -13,10 +13,38 @@ const mod = (freq, range = 1, type) => {
return { node: g, stop: (t) => osc.stop(t) };
};
const fm = (osc, harmonicityRatio, modulationIndex, wave) => {
const fm = (t,
osc,
harmonicityRatio,
harmonicityAttack,
harmonicityDecay,
modulationIndex,
modulationAttack,
modulationDecay,
wave, ) => {
const carrfreq = osc.frequency.value;
const modfreq = carrfreq * harmonicityRatio;
const modgain = modfreq * modulationIndex;
let modfreq;
let modgain;
// Setting up envelopes if needed
if ((harmonicityAttack !== null) || (harmonicityDecay !== null)) {
let hattack = harmonicityAttack || 0.01;
let hdecay = harmonicityDecay || 0.5;
const harmonicEnv = getExpEnvelope(hattack, hdecay, 1, t);
modfreq = carrfreq * (harmonicityRatio * harmonicEnv);
} else {
modfreq = carrfreq * harmonicityRatio;
}
if ((modulationAttack !== null) || (modulationDecay !== null)) {
let mattack = modulationAttack || 0.01;
let mdecay = modulationDecay || 0.5;
const modulationEnv = getExpEnvelope(mattack, mdecay, 1, t);
modgain = modfreq * (modulationIndex * modulationEnv);
} else {
modgain = modfreq * modulationIndex;
}
return mod(modfreq, modgain, wave);
};
@ -32,8 +60,12 @@ export function registerSynthSounds() {
sustain = 0.6,
release = 0.01,
fmh: fmHarmonicity = 1,
fmhattack: fmHarmonicityAttack = null,
fmhdecay: fmHarmonicityDecay = null,
fmi: fmModulationIndex,
fmwave: fmWaveform = 'sine'
fmiattack: fmModulationAttack = null,
fmidecay: fmModulationDecay = null,
fmwave: fmWaveform = 'sine',
} = value;
let { n, note, freq } = value;
// with synths, n and note are the same thing
@ -52,9 +84,15 @@ export function registerSynthSounds() {
let stopFm;
if (fmModulationIndex) {
const { node: modulator, stop } = fm(
o, fmHarmonicity,
t,
o,
fmHarmonicity,
fmHarmonicityAttack,
fmHarmonicityDecay,
fmModulationIndex,
fmWaveform
fmModulationAttack,
fmModulationDecay,
fmWaveform,
);
modulator.connect(o.frequency);
stopFm = stop;