From 08aab9d4d80099d4330549ee732c0ba9ec701297 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Wed, 20 Sep 2023 19:44:32 +0200 Subject: [PATCH] Adding vibrato to Superdough sampler Modulating the `playbackRate` to simulate a vibrato! --- packages/superdough/sampler.mjs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 76b6a542..365d397c 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -22,7 +22,7 @@ function humanFileSize(bytes, si) { return bytes.toFixed(1) + ' ' + units[u]; } -export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resolveUrl) => { +export const getSampleBufferSource = async (s, n, note, speed, freq, vib, vibmod, bank, resolveUrl) => { let transpose = 0; if (freq !== undefined && note !== undefined) { logger('[sampler] hap has note and freq. ignoring note', 'warning'); @@ -57,8 +57,20 @@ export const getSampleBufferSource = async (s, n, note, speed, freq, bank, resol const bufferSource = ac.createBufferSource(); bufferSource.buffer = buffer; const playbackRate = 1.0 * Math.pow(2, transpose / 12); - // bufferSource.playbackRate.value = Math.pow(2, transpose / 12); - bufferSource.playbackRate.value = playbackRate; + if (vib > 0) { + let vibrato_oscillator = getAudioContext().createOscillator(); + vibrato_oscillator.frequency.value = vib; + const gain = getAudioContext().createGain(); + // Vibmod is the amount of vibrato, in semitones + bufferSource.playbackRate.value = Math.pow(2, transpose / 12); + gain.gain.value = vibmod / 4; + vibrato_oscillator.connect(gain); + gain.connect(bufferSource.playbackRate); + vibrato_oscillator.start(0); + } else { + bufferSource.playbackRate.value = Math.pow(2, transpose / 12); + bufferSource.playbackRate.value = playbackRate; + } return bufferSource; }; @@ -211,6 +223,8 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { begin = 0, loopEnd = 1, end = 1, + vib, + vibmod = 0.5, } = value; // load sample if (speed === 0) { @@ -224,7 +238,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { //const soundfont = getSoundfontKey(s); const time = t + nudge; - const bufferSource = await getSampleBufferSource(s, n, note, speed, freq, bank, resolveUrl); + const bufferSource = await getSampleBufferSource(s, n, note, speed, freq, vib, vibmod, bank, resolveUrl); // asny stuff above took too long? if (ac.currentTime > t) { @@ -255,7 +269,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { bufferSource.connect(envelope); const out = ac.createGain(); // we need a separate gain for the cutgroups because firefox... envelope.connect(out); - bufferSource.onended = function () { + bufferSource.onended = function() { bufferSource.disconnect(); envelope.disconnect(); out.disconnect();