From fdc201a799b841d4e2be20466fdeb56ae3c8c7d6 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Mon, 4 Sep 2023 06:03:05 +0200 Subject: [PATCH 01/17] Adding vibrato to synth oscillator --- packages/superdough/synth.mjs | 43 ++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index a409d990..b216a427 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -40,6 +40,8 @@ export function registerSynthSounds() { fmrelease: fmRelease, fmvelocity: fmVelocity, fmwave: fmWaveform = 'sine', + vibrato = 0, + vdepth = 100, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing @@ -53,7 +55,7 @@ export function registerSynthSounds() { } // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) // make oscillator - const { node: o, stop } = getOscillator({ t, s: wave, freq, partials: n }); + const { node: o, stop } = getOscillator({ t, s: wave, freq, vibrato, vdepth, partials: n }); // FM + FM envelope let stopFm, fmEnvelope; @@ -137,8 +139,14 @@ export function waveformN(partials, type) { return osc; } -export function getOscillator({ s, freq, t, partials }) { - // make oscillator +export function getOscillator({ s, freq, t, vibrato, vdepth, partials }) { + // Additional oscillator for vibrato effect + if (vibrato > 0) { + var vibrato_oscillator = getAudioContext().createOscillator(); + vibrato_oscillator.frequency.value = vibrato; + } + + // Make oscillator with partial count let o; if (!partials || s === 'sine') { o = getAudioContext().createOscillator(); @@ -146,9 +154,28 @@ export function getOscillator({ s, freq, t, partials }) { } else { o = waveformN(partials, s); } - o.frequency.value = Number(freq); - o.start(t); - //o.stop(t + duration + release); - const stop = (time) => o.stop(time); - return { node: o, stop }; + + if (vibrato > 0) { + // Vibrato by creating a gain node + o.frequency.value = Number(freq); + var gain = getAudioContext().createGain(); + gain.gain.value = vdepth * 100; + vibrato_oscillator.connect(gain); + gain.connect(o.detune); + vibrato_oscillator.start(t); + o.start(t); + return { + node: o, + stop: (time) => { + vibrato_oscillator.stop(time); + o.stop(time); + }, + }; + } else { + // Normal operation, without vibrato + o.frequency.value = Number(freq); + o.start(t); + const stop = (time) => o.stop(time); + return { node: o, stop }; + } } From 60f5032b1270084efa5185f4560e8c70da24e3a9 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Mon, 4 Sep 2023 06:25:49 +0200 Subject: [PATCH 02/17] Implement pitch slide --- packages/superdough/synth.mjs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index b216a427..e1d7905c 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -42,6 +42,8 @@ export function registerSynthSounds() { fmwave: fmWaveform = 'sine', vibrato = 0, vdepth = 100, + slide, + slide_speed = 1, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing @@ -55,7 +57,16 @@ export function registerSynthSounds() { } // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) // make oscillator - const { node: o, stop } = getOscillator({ t, s: wave, freq, vibrato, vdepth, partials: n }); + const { node: o, stop } = getOscillator({ + t, + s: wave, + freq, + vibrato, + vdepth, + slide: slide * freq, + slide_speed: sustain / slide_speed, + partials: n, + }); // FM + FM envelope let stopFm, fmEnvelope; @@ -139,7 +150,7 @@ export function waveformN(partials, type) { return osc; } -export function getOscillator({ s, freq, t, vibrato, vdepth, partials }) { +export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slide_speed, partials }) { // Additional oscillator for vibrato effect if (vibrato > 0) { var vibrato_oscillator = getAudioContext().createOscillator(); @@ -156,8 +167,8 @@ export function getOscillator({ s, freq, t, vibrato, vdepth, partials }) { } if (vibrato > 0) { - // Vibrato by creating a gain node o.frequency.value = Number(freq); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); var gain = getAudioContext().createGain(); gain.gain.value = vdepth * 100; vibrato_oscillator.connect(gain); @@ -174,6 +185,7 @@ export function getOscillator({ s, freq, t, vibrato, vdepth, partials }) { } else { // Normal operation, without vibrato o.frequency.value = Number(freq); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); o.start(t); const stop = (time) => o.stop(time); return { node: o, stop }; From 3ba195c2d91af5cfe5675e0e8b00f3f242af688c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 4 Sep 2023 18:38:05 +0200 Subject: [PATCH 03/17] add new controls + rename slide_speed > slidespeed --- packages/core/controls.mjs | 3 +++ packages/superdough/synth.mjs | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 71f58427..36a5728b 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -664,7 +664,10 @@ const generic_params = [ // TODO: LFO rate see https://tidalcycles.org/docs/patternlib/tutorials/synthesizers/#supersquare ['rate'], // TODO: slide param for certain synths + ['vibrato'], + ['vdepth'], ['slide'], + ['slidespeed'], // TODO: detune? https://tidalcycles.org/docs/patternlib/tutorials/synthesizers/#supersquare ['semitone'], // TODO: dedup with synth param, see https://tidalcycles.org/docs/reference/synthesizers/#superpiano diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index e1d7905c..4ebfb3ac 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -43,7 +43,7 @@ export function registerSynthSounds() { vibrato = 0, vdepth = 100, slide, - slide_speed = 1, + slidespeed = 1, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing @@ -64,7 +64,7 @@ export function registerSynthSounds() { vibrato, vdepth, slide: slide * freq, - slide_speed: sustain / slide_speed, + slidespeed: sustain / slidespeed, partials: n, }); @@ -150,7 +150,7 @@ export function waveformN(partials, type) { return osc; } -export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slide_speed, partials }) { +export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slidespeed, partials }) { // Additional oscillator for vibrato effect if (vibrato > 0) { var vibrato_oscillator = getAudioContext().createOscillator(); @@ -168,7 +168,7 @@ export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slide_speed, if (vibrato > 0) { o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slidespeed); var gain = getAudioContext().createGain(); gain.gain.value = vdepth * 100; vibrato_oscillator.connect(gain); @@ -185,7 +185,7 @@ export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slide_speed, } else { // Normal operation, without vibrato o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slidespeed); o.start(t); const stop = (time) => o.stop(time); return { node: o, stop }; From fc9525e7d80f1a23332c7271c043dcd08be58ea9 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Tue, 5 Sep 2023 11:24:21 +0200 Subject: [PATCH 04/17] saner vibrato default --- packages/core/controls.mjs | 2 ++ packages/superdough/synth.mjs | 27 ++++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 36a5728b..c2cf917e 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -393,6 +393,8 @@ const generic_params = [ */ // currently an alias of 'hcutoff' https://github.com/tidalcycles/strudel/issues/496 // ['hpf'], + [['vib'], 'vib'], + [['vibmod'], 'vibmod'], [['hcutoff', 'hresonance'], 'hpf', 'hp'], /** * Controls the **h**igh-**p**ass **q**-value. diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 4ebfb3ac..f02a1909 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -40,10 +40,10 @@ export function registerSynthSounds() { fmrelease: fmRelease, fmvelocity: fmVelocity, fmwave: fmWaveform = 'sine', - vibrato = 0, - vdepth = 100, + vib = 0, + vibmod = 1, slide, - slidespeed = 1, + slide_speed = 1, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing @@ -61,10 +61,10 @@ export function registerSynthSounds() { t, s: wave, freq, - vibrato, - vdepth, + vib, + vibmod, slide: slide * freq, - slidespeed: sustain / slidespeed, + slide_speed: sustain / slide_speed, partials: n, }); @@ -150,11 +150,11 @@ export function waveformN(partials, type) { return osc; } -export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slidespeed, partials }) { +export function getOscillator({ s, freq, t, vib, vibmod, slide, slide_speed, partials }) { // Additional oscillator for vibrato effect - if (vibrato > 0) { + if (vib > 0) { var vibrato_oscillator = getAudioContext().createOscillator(); - vibrato_oscillator.frequency.value = vibrato; + vibrato_oscillator.frequency.value = vib; } // Make oscillator with partial count @@ -166,11 +166,12 @@ export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slidespeed, o = waveformN(partials, s); } - if (vibrato > 0) { + if (vib > 0) { o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slidespeed); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); var gain = getAudioContext().createGain(); - gain.gain.value = vdepth * 100; + // Vibmod is the amount of vibrato, in semitones + gain.gain.value = vibmod * freq; vibrato_oscillator.connect(gain); gain.connect(o.detune); vibrato_oscillator.start(t); @@ -185,7 +186,7 @@ export function getOscillator({ s, freq, t, vibrato, vdepth, slide, slidespeed, } else { // Normal operation, without vibrato o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slidespeed); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); o.start(t); const stop = (time) => o.stop(time); return { node: o, stop }; From 76051987742f2703c78fab3378fb9e6490cc65d1 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Tue, 5 Sep 2023 11:27:42 +0200 Subject: [PATCH 05/17] parameter renaming --- packages/superdough/synth.mjs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index f02a1909..4101aaee 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -42,8 +42,8 @@ export function registerSynthSounds() { fmwave: fmWaveform = 'sine', vib = 0, vibmod = 1, - slide, - slide_speed = 1, + pitchJump, + pitchJumpSpeed = 1, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing @@ -63,8 +63,8 @@ export function registerSynthSounds() { freq, vib, vibmod, - slide: slide * freq, - slide_speed: sustain / slide_speed, + pitchJump: pitchJump * freq, + pitchJumpSpeed: sustain / pitchJumpSpeed, partials: n, }); @@ -150,7 +150,7 @@ export function waveformN(partials, type) { return osc; } -export function getOscillator({ s, freq, t, vib, vibmod, slide, slide_speed, partials }) { +export function getOscillator({ s, freq, t, vib, vibmod, pitchJump, pitchJumpSpeed, partials }) { // Additional oscillator for vibrato effect if (vib > 0) { var vibrato_oscillator = getAudioContext().createOscillator(); @@ -168,7 +168,7 @@ export function getOscillator({ s, freq, t, vib, vibmod, slide, slide_speed, par if (vib > 0) { o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); + slide > 0 && o.frequency.linearRampToValueAtTime(freq + pitchJump, t + pitchJumpSpeed); var gain = getAudioContext().createGain(); // Vibmod is the amount of vibrato, in semitones gain.gain.value = vibmod * freq; From 34318039807c8d0faa83b3bd032b609704a93ba7 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Fri, 8 Sep 2023 13:08:00 +0200 Subject: [PATCH 06/17] documenting vib and vibmod --- packages/core/controls.mjs | 23 ++++++++++++++++++++--- website/src/pages/learn/synths.mdx | 10 ++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index c2cf917e..f7f029e0 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -393,9 +393,28 @@ const generic_params = [ */ // currently an alias of 'hcutoff' https://github.com/tidalcycles/strudel/issues/496 // ['hpf'], - [['vib'], 'vib'], + /** + * Applies a vibrato to the frequency of the oscillator. + * + * @name vib + * @param {number | Pattern} frequency of the vibrato in hertz + * @synonyms vibrato + * @example + * sound("triangle").freq(300).vib("<1 2 4 8 16>") + */ + [['vibrato'], 'vib'], + /** + * Sets the vibrato depth as a multiple of base frequency (not vibrato speed!). + * + * @name vibmod + * @param {number | Pattern} depth of vibrato (multiple of base frequency) + * @example + * sound("triangle").freq(300).vib("<8 16>").vibmod("<0.25 0.5 0.75 1 2 4>") + */ [['vibmod'], 'vibmod'], [['hcutoff', 'hresonance'], 'hpf', 'hp'], + ['vib'], + ['vibmod'], /** * Controls the **h**igh-**p**ass **q**-value. * @@ -666,8 +685,6 @@ const generic_params = [ // TODO: LFO rate see https://tidalcycles.org/docs/patternlib/tutorials/synthesizers/#supersquare ['rate'], // TODO: slide param for certain synths - ['vibrato'], - ['vdepth'], ['slide'], ['slidespeed'], // TODO: detune? https://tidalcycles.org/docs/patternlib/tutorials/synthesizers/#supersquare diff --git a/website/src/pages/learn/synths.mdx b/website/src/pages/learn/synths.mdx index b24726cf..68bbee34 100644 --- a/website/src/pages/learn/synths.mdx +++ b/website/src/pages/learn/synths.mdx @@ -48,6 +48,16 @@ You can also set `n` directly in mini notation with `sound`: Note for tidal users: `n` in tidal is synonymous to `note` for synths only. In strudel, this is not the case, where `n` will always change timbre, be it though different samples or different waveforms. +### Vibrato + +#### vib + + + +#### vibmod + + + ## FM Synthesis FM Synthesis is a technique that changes the frequency of a basic waveform rapidly to alter the timbre. From 74442b0d76eb12b3a44e824c9422aaba6b8e9eb1 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Fri, 8 Sep 2023 13:43:43 +0200 Subject: [PATCH 07/17] documenting vibrato and removing broken slide/pitchJump mechanism --- packages/core/controls.mjs | 8 ++++++-- packages/superdough/synth.mjs | 8 +------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index f7f029e0..f6fcc89f 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -686,6 +686,7 @@ const generic_params = [ ['rate'], // TODO: slide param for certain synths ['slide'], + ['slidespeed'], // TODO: detune? https://tidalcycles.org/docs/patternlib/tutorials/synthesizers/#supersquare ['semitone'], @@ -893,10 +894,13 @@ const generic_params = [ // ZZFX ['zrand'], ['curve'], - ['slide'], // superdirt duplicate - ['deltaSlide'], ['pitchJump'], ['pitchJumpTime'], + ['slide'], // superdirt duplicate + ['deltaSlide'], + /** + * + */ ['lfo', 'repeatTime'], ['noise'], ['zmod'], diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 4101aaee..8a240340 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -42,8 +42,6 @@ export function registerSynthSounds() { fmwave: fmWaveform = 'sine', vib = 0, vibmod = 1, - pitchJump, - pitchJumpSpeed = 1, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing @@ -63,8 +61,6 @@ export function registerSynthSounds() { freq, vib, vibmod, - pitchJump: pitchJump * freq, - pitchJumpSpeed: sustain / pitchJumpSpeed, partials: n, }); @@ -150,7 +146,7 @@ export function waveformN(partials, type) { return osc; } -export function getOscillator({ s, freq, t, vib, vibmod, pitchJump, pitchJumpSpeed, partials }) { +export function getOscillator({ s, freq, t, vib, vibmod, partials }) { // Additional oscillator for vibrato effect if (vib > 0) { var vibrato_oscillator = getAudioContext().createOscillator(); @@ -168,7 +164,6 @@ export function getOscillator({ s, freq, t, vib, vibmod, pitchJump, pitchJumpSpe if (vib > 0) { o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + pitchJump, t + pitchJumpSpeed); var gain = getAudioContext().createGain(); // Vibmod is the amount of vibrato, in semitones gain.gain.value = vibmod * freq; @@ -186,7 +181,6 @@ export function getOscillator({ s, freq, t, vib, vibmod, pitchJump, pitchJumpSpe } else { // Normal operation, without vibrato o.frequency.value = Number(freq); - slide > 0 && o.frequency.linearRampToValueAtTime(freq + slide, t + slide_speed); o.start(t); const stop = (time) => o.stop(time); return { node: o, stop }; From 78ccec5d7b4922cc211fa5244601d9d68197da18 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Sun, 10 Sep 2023 09:14:41 +0200 Subject: [PATCH 08/17] adding test run --- test/__snapshots__/examples.test.mjs.snap | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 60b39c53..76a7cf11 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -4557,6 +4557,24 @@ exports[`runs examples > example "velocity" example index 0 1`] = ` ] `; +exports[`runs examples > example "vib" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | s:triangle freq:300 vib:1 ]", + "[ 1/1 → 2/1 | s:triangle freq:300 vib:2 ]", + "[ 2/1 → 3/1 | s:triangle freq:300 vib:4 ]", + "[ 3/1 → 4/1 | s:triangle freq:300 vib:8 ]", +] +`; + +exports[`runs examples > example "vibmod" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | s:triangle freq:300 vib:8 vibmod:0.25 ]", + "[ 1/1 → 2/1 | s:triangle freq:300 vib:16 vibmod:0.5 ]", + "[ 2/1 → 3/1 | s:triangle freq:300 vib:8 vibmod:0.75 ]", + "[ 3/1 → 4/1 | s:triangle freq:300 vib:16 vibmod:1 ]", +] +`; + exports[`runs examples > example "voicing" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:E4 ]", From 5c5df748600891860811bac1805bb0edbacf22e8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:15:02 +0200 Subject: [PATCH 09/17] fix: control naming --- packages/core/controls.mjs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 69c43bfa..57ed4b91 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -649,7 +649,7 @@ const generic_params = [ * @example * sound("triangle").freq(300).vib("<1 2 4 8 16>") */ - [['vibrato'], 'vib'], + ['vib', 'vibrato'], /** * Sets the vibrato depth as a multiple of base frequency (not vibrato speed!). * @@ -658,10 +658,8 @@ const generic_params = [ * @example * sound("triangle").freq(300).vib("<8 16>").vibmod("<0.25 0.5 0.75 1 2 4>") */ - [['vibmod'], 'vibmod'], - [['hcutoff', 'hresonance'], 'hpf', 'hp'], - ['vib'], ['vibmod'], + [['hcutoff', 'hresonance'], 'hpf', 'hp'], /** * Controls the **h**igh-**p**ass **q**-value. * @@ -933,8 +931,6 @@ const generic_params = [ ['rate'], // TODO: slide param for certain synths ['slide'], - - ['slidespeed'], // TODO: detune? https://tidalcycles.org/docs/patternlib/tutorials/synthesizers/#supersquare ['semitone'], // TODO: dedup with synth param, see https://tidalcycles.org/docs/reference/synthesizers/#superpiano From c354ee32e3d391f53c4819f8f4373e1b200c8793 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:15:33 +0200 Subject: [PATCH 10/17] simplify vibrato logic --- packages/superdough/synth.mjs | 39 ++++++++++++++--------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 8a240340..2e2b7cb2 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -147,12 +147,6 @@ export function waveformN(partials, type) { } export function getOscillator({ s, freq, t, vib, vibmod, partials }) { - // Additional oscillator for vibrato effect - if (vib > 0) { - var vibrato_oscillator = getAudioContext().createOscillator(); - vibrato_oscillator.frequency.value = vib; - } - // Make oscillator with partial count let o; if (!partials || s === 'sine') { @@ -161,28 +155,27 @@ export function getOscillator({ s, freq, t, vib, vibmod, partials }) { } else { o = waveformN(partials, s); } + o.frequency.value = Number(freq); + o.start(t); + // Additional oscillator for vibrato effect + let vibrato_oscillator; if (vib > 0) { - o.frequency.value = Number(freq); - var gain = getAudioContext().createGain(); + vibrato_oscillator = getAudioContext().createOscillator(); + vibrato_oscillator.frequency.value = vib; + const gain = getAudioContext().createGain(); // Vibmod is the amount of vibrato, in semitones - gain.gain.value = vibmod * freq; + gain.gain.value = vibmod * 100; vibrato_oscillator.connect(gain); gain.connect(o.detune); vibrato_oscillator.start(t); - o.start(t); - return { - node: o, - stop: (time) => { - vibrato_oscillator.stop(time); - o.stop(time); - }, - }; - } else { - // Normal operation, without vibrato - o.frequency.value = Number(freq); - o.start(t); - const stop = (time) => o.stop(time); - return { node: o, stop }; } + + return { + node: o, + stop: (time) => { + vibrato_oscillator?.stop(time); + o.stop(time); + }, + }; } From cd6d1fb2d21f05d70605d3af5db1c6bfc8ae67d5 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:41:02 +0200 Subject: [PATCH 11/17] fix: headings --- website/src/pages/learn/synths.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/src/pages/learn/synths.mdx b/website/src/pages/learn/synths.mdx index a9cf094c..9f21204f 100644 --- a/website/src/pages/learn/synths.mdx +++ b/website/src/pages/learn/synths.mdx @@ -48,13 +48,13 @@ You can also set `n` directly in mini notation with `sound`: Note for tidal users: `n` in tidal is synonymous to `note` for synths only. In strudel, this is not the case, where `n` will always change timbre, be it though different samples or different waveforms. -### Vibrato +## Vibrato -#### vib +### vib -#### vibmod +### vibmod From c2560e0cf8b521443a12c846e0e39c3d72fb9b5b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:41:13 +0200 Subject: [PATCH 12/17] set vib default to .5 --- packages/superdough/synth.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 2e2b7cb2..5ca62105 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -41,7 +41,7 @@ export function registerSynthSounds() { fmvelocity: fmVelocity, fmwave: fmWaveform = 'sine', vib = 0, - vibmod = 1, + vibmod = .5, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing From f052adb93a7ded3c3161031b6779842bb5d3988a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:41:22 +0200 Subject: [PATCH 13/17] simplify examples --- packages/core/controls.mjs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 57ed4b91..072dc83f 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -644,21 +644,24 @@ const generic_params = [ * Applies a vibrato to the frequency of the oscillator. * * @name vib + * @synonyms vibrato, v * @param {number | Pattern} frequency of the vibrato in hertz - * @synonyms vibrato * @example - * sound("triangle").freq(300).vib("<1 2 4 8 16>") + * note("a") + * .vib("<.5 1 2 4 8 16>") */ - ['vib', 'vibrato'], + [['vib', 'vibmod'], 'vibrato', 'v'], /** - * Sets the vibrato depth as a multiple of base frequency (not vibrato speed!). + * Sets the vibrato depth in semitones. * * @name vibmod - * @param {number | Pattern} depth of vibrato (multiple of base frequency) + * @synonyms vmod + * @param {number | Pattern} depth of vibrato (in semitones) * @example - * sound("triangle").freq(300).vib("<8 16>").vibmod("<0.25 0.5 0.75 1 2 4>") + * note("a").vib(4) + * .vibmod("<.25 .5 1 2 12>") */ - ['vibmod'], + [['vibmod', 'vib'], 'vmod'], [['hcutoff', 'hresonance'], 'hpf', 'hp'], /** * Controls the **h**igh-**p**ass **q**-value. From a97384cec1ec3a0a92637a509ea89ac9edf07dfc Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:42:21 +0200 Subject: [PATCH 14/17] format --- packages/superdough/synth.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 5ca62105..633d0113 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -41,7 +41,7 @@ export function registerSynthSounds() { fmvelocity: fmVelocity, fmwave: fmWaveform = 'sine', vib = 0, - vibmod = .5, + vibmod = 0.5, } = value; let { n, note, freq } = value; // with synths, n and note are the same thing From c6a74c040e258db1dd2684e48384422285fefd57 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:42:51 +0200 Subject: [PATCH 15/17] snapshot --- test/__snapshots__/examples.test.mjs.snap | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index d146a065..858e30e7 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -4760,19 +4760,19 @@ exports[`runs examples > example "velocity" example index 0 1`] = ` exports[`runs examples > example "vib" example index 0 1`] = ` [ - "[ 0/1 → 1/1 | s:triangle freq:300 vib:1 ]", - "[ 1/1 → 2/1 | s:triangle freq:300 vib:2 ]", - "[ 2/1 → 3/1 | s:triangle freq:300 vib:4 ]", - "[ 3/1 → 4/1 | s:triangle freq:300 vib:8 ]", + "[ 0/1 → 1/1 | note:a vib:0.5 ]", + "[ 1/1 → 2/1 | note:a vib:1 ]", + "[ 2/1 → 3/1 | note:a vib:2 ]", + "[ 3/1 → 4/1 | note:a vib:4 ]", ] `; exports[`runs examples > example "vibmod" example index 0 1`] = ` [ - "[ 0/1 → 1/1 | s:triangle freq:300 vib:8 vibmod:0.25 ]", - "[ 1/1 → 2/1 | s:triangle freq:300 vib:16 vibmod:0.5 ]", - "[ 2/1 → 3/1 | s:triangle freq:300 vib:8 vibmod:0.75 ]", - "[ 3/1 → 4/1 | s:triangle freq:300 vib:16 vibmod:1 ]", + "[ 0/1 → 1/1 | note:a vib:4 vibmod:0.25 ]", + "[ 1/1 → 2/1 | note:a vib:4 vibmod:0.5 ]", + "[ 2/1 → 3/1 | note:a vib:4 vibmod:1 ]", + "[ 3/1 → 4/1 | note:a vib:4 vibmod:2 ]", ] `; From 32fee6313b4f1ac41eb4b00c58f3d998e1666eb8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 10:44:15 +0200 Subject: [PATCH 16/17] move stuff back --- packages/core/controls.mjs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 072dc83f..edbb77d4 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1140,13 +1140,10 @@ const generic_params = [ // ZZFX ['zrand'], ['curve'], - ['pitchJump'], - ['pitchJumpTime'], ['slide'], // superdirt duplicate ['deltaSlide'], - /** - * - */ + ['pitchJump'], + ['pitchJumpTime'], ['lfo', 'repeatTime'], ['noise'], ['zmod'], From 0e7c9a4001c3acf50c5f56f0c5555d95668fbbce Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 17 Sep 2023 11:01:12 +0200 Subject: [PATCH 17/17] add vib examples for : notation --- packages/core/controls.mjs | 10 +++++++++- test/__snapshots__/examples.test.mjs.snap | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index edbb77d4..6cac6e54 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -649,10 +649,14 @@ const generic_params = [ * @example * note("a") * .vib("<.5 1 2 4 8 16>") + * @example + * // change the modulation depth with ":" + * note("a") + * .vib("<.5 1 2 4 8 16>:12") */ [['vib', 'vibmod'], 'vibrato', 'v'], /** - * Sets the vibrato depth in semitones. + * Sets the vibrato depth in semitones. Only has an effect if `vibrato` | `vib` | `v` is is also set * * @name vibmod * @synonyms vmod @@ -660,6 +664,10 @@ const generic_params = [ * @example * note("a").vib(4) * .vibmod("<.25 .5 1 2 12>") + * @example + * // change the vibrato frequency with ":" + * note("a") + * .vibmod("<.25 .5 1 2 12>:8") */ [['vibmod', 'vib'], 'vmod'], [['hcutoff', 'hresonance'], 'hpf', 'hp'], diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 858e30e7..e026f9c4 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -4767,6 +4767,15 @@ exports[`runs examples > example "vib" example index 0 1`] = ` ] `; +exports[`runs examples > example "vib" example index 1 1`] = ` +[ + "[ 0/1 → 1/1 | note:a vib:0.5 vibmod:12 ]", + "[ 1/1 → 2/1 | note:a vib:1 vibmod:12 ]", + "[ 2/1 → 3/1 | note:a vib:2 vibmod:12 ]", + "[ 3/1 → 4/1 | note:a vib:4 vibmod:12 ]", +] +`; + exports[`runs examples > example "vibmod" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:a vib:4 vibmod:0.25 ]", @@ -4776,6 +4785,15 @@ exports[`runs examples > example "vibmod" example index 0 1`] = ` ] `; +exports[`runs examples > example "vibmod" example index 1 1`] = ` +[ + "[ 0/1 → 1/1 | note:a vibmod:0.25 vib:8 ]", + "[ 1/1 → 2/1 | note:a vibmod:0.5 vib:8 ]", + "[ 2/1 → 3/1 | note:a vibmod:1 vib:8 ]", + "[ 3/1 → 4/1 | note:a vibmod:2 vib:8 ]", +] +`; + exports[`runs examples > example "voicing" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:E4 ]",