vibrato for soundfonts

+ add getVibratoOscillator helper
This commit is contained in:
Felix Roos 2024-01-16 00:07:56 +01:00
parent 32456d6966
commit 3506de8d1a
4 changed files with 24 additions and 28 deletions

View file

@ -5,6 +5,7 @@ import {
getParamADSR, getParamADSR,
getADSRValues, getADSRValues,
getPitchEnvelope, getPitchEnvelope,
getVibratoOscillator,
} from '@strudel.cycles/webaudio'; } from '@strudel.cycles/webaudio';
import gm from './gm.mjs'; import gm from './gm.mjs';
@ -155,6 +156,8 @@ export function registerSoundfonts() {
getParamADSR(node.gain, attack, decay, sustain, release, 0, 0.3, time, holdEnd, 'linear'); getParamADSR(node.gain, attack, decay, sustain, release, 0, 0.3, time, holdEnd, 'linear');
let envEnd = holdEnd + release + 0.01; let envEnd = holdEnd + release + 0.01;
// vibrato
let vibratoOscillator = getVibratoOscillator(bufferSource.detune, value, time);
// pitch envelope // pitch envelope
if (value.penv) { if (value.penv) {
getPitchEnvelope(bufferSource.detune, value, time, holdEnd); getPitchEnvelope(bufferSource.detune, value, time, holdEnd);
@ -164,6 +167,7 @@ export function registerSoundfonts() {
const stop = (releaseTime) => {}; const stop = (releaseTime) => {};
bufferSource.onended = () => { bufferSource.onended = () => {
bufferSource.disconnect(); bufferSource.disconnect();
vibratoOscillator?.stop();
node.disconnect(); node.disconnect();
onended(); onended();
}; };

View file

@ -157,3 +157,19 @@ export function getPitchEnvelope(param, value, t, holdEnd) {
getParamADSR(param, pattack, pdecay, psustain, prelease, 0, cents, t, holdEnd, 'linear'); getParamADSR(param, pattack, pdecay, psustain, prelease, 0, cents, t, holdEnd, 'linear');
} }
} }
export function getVibratoOscillator(param, value, t) {
const { vibmod = 0.5, vib } = value;
let vibratoOscillator;
if (vib > 0) {
vibratoOscillator = getAudioContext().createOscillator();
vibratoOscillator.frequency.value = vib;
const gain = getAudioContext().createGain();
// Vibmod is the amount of vibrato, in semitones
gain.gain.value = vibmod * 100;
vibratoOscillator.connect(gain);
gain.connect(param);
vibratoOscillator.start(t);
return vibratoOscillator;
}
}

View file

@ -1,6 +1,6 @@
import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs'; import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs';
import { getAudioContext, registerSound } from './index.mjs'; import { getAudioContext, registerSound } from './index.mjs';
import { getADSRValues, getParamADSR, getPitchEnvelope } from './helpers.mjs'; import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs';
import { logger } from './logger.mjs'; import { logger } from './logger.mjs';
const bufferCache = {}; // string: Promise<ArrayBuffer> const bufferCache = {}; // string: Promise<ArrayBuffer>
@ -244,8 +244,6 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
loopEnd = 1, loopEnd = 1,
end = 1, end = 1,
duration, duration,
vib,
vibmod = 0.5,
} = value; } = value;
// load sample // load sample
if (speed === 0) { if (speed === 0) {
@ -263,17 +261,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
const bufferSource = await getSampleBufferSource(s, n, note, speed, freq, bank, resolveUrl); const bufferSource = await getSampleBufferSource(s, n, note, speed, freq, bank, resolveUrl);
// vibrato // vibrato
let vibratoOscillator; let vibratoOscillator = getVibratoOscillator(bufferSource.detune, value, t);
if (vib > 0) {
vibratoOscillator = getAudioContext().createOscillator();
vibratoOscillator.frequency.value = vib;
const gain = getAudioContext().createGain();
// Vibmod is the amount of vibrato, in semitones
gain.gain.value = vibmod * 100;
vibratoOscillator.connect(gain);
gain.connect(bufferSource.detune);
vibratoOscillator.start(0);
}
// asny stuff above took too long? // asny stuff above took too long?
if (ac.currentTime > t) { if (ac.currentTime > t) {

View file

@ -1,6 +1,6 @@
import { midiToFreq, noteToMidi } from './util.mjs'; import { midiToFreq, noteToMidi } from './util.mjs';
import { registerSound, getAudioContext } from './superdough.mjs'; import { registerSound, getAudioContext } from './superdough.mjs';
import { gainNode, getADSRValues, getParamADSR, getPitchEnvelope } from './helpers.mjs'; import { gainNode, getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs';
import { getNoiseMix, getNoiseOscillator } from './noise.mjs'; import { getNoiseMix, getNoiseOscillator } from './noise.mjs';
const mod = (freq, range = 1, type = 'sine') => { const mod = (freq, range = 1, type = 'sine') => {
@ -110,8 +110,6 @@ export function getOscillator(s, t, value) {
n: partials, n: partials,
note, note,
freq, freq,
vib = 0,
vibmod = 0.5,
noise = 0, noise = 0,
// fm // fm
fmh: fmHarmonicity = 1, fmh: fmHarmonicity = 1,
@ -181,17 +179,7 @@ export function getOscillator(s, t, value) {
} }
// Additional oscillator for vibrato effect // Additional oscillator for vibrato effect
let vibratoOscillator; let vibratoOscillator = getVibratoOscillator(o.detune, value, t);
if (vib > 0) {
vibratoOscillator = getAudioContext().createOscillator();
vibratoOscillator.frequency.value = vib;
const gain = getAudioContext().createGain();
// Vibmod is the amount of vibrato, in semitones
gain.gain.value = vibmod * 100;
vibratoOscillator.connect(gain);
gain.connect(o.detune);
vibratoOscillator.start(t);
}
// pitch envelope // pitch envelope
if (value.penv) { if (value.penv) {