diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs
index 866be4fb..a03658a8 100644
--- a/packages/core/controls.mjs
+++ b/packages/core/controls.mjs
@@ -380,6 +380,62 @@ const generic_params = [
*
*/
['coarse'],
+
+ ['phaserrate', 'phasr'], // superdirt only
+
+ /**
+ * Phaser audio effect that approximates popular guitar pedals.
+ *
+ * @name phaser
+ * @synonyms ph
+ * @param {number | Pattern} speed speed of modulation
+ * @example
+ * n(run(8)).scale("D:pentatonic").s("sawtooth").release(0.5)
+ * .phaser("<1 2 4 8>")
+ *
+ */
+ [['phaser', 'phaserdepth', 'phasercenter', 'phasersweep'], 'ph'],
+
+ /**
+ * The frequency sweep range of the lfo for the phaser effect. Defaults to 2000
+ *
+ * @name phasersweep
+ * @synonyms phs
+ * @param {number | Pattern} phasersweep most useful values are between 0 and 4000
+ * @example
+ * n(run(8)).scale("D:pentatonic").s("sawtooth").release(0.5)
+ * .phaser(2).phasersweep("<800 2000 4000>")
+ *
+ */
+ ['phasersweep', 'phs'],
+
+ /**
+ * The center frequency of the phaser in HZ. Defaults to 1000
+ *
+ * @name phasercenter
+ * @synonyms phc
+ * @param {number | Pattern} centerfrequency in HZ
+ * @example
+ * n(run(8)).scale("D:pentatonic").s("sawtooth").release(0.5)
+ * .phaser(2).phasercenter("<800 2000 4000>")
+ *
+ */
+
+ ['phasercenter', 'phc'],
+
+ /**
+ * The amount the signal is affected by the phaser effect. Defaults to 0.75
+ *
+ * @name phaserdepth
+ * @synonyms phd
+ * @param {number | Pattern} depth number between 0 and 1
+ * @example
+ * n(run(8)).scale("D:pentatonic").s("sawtooth").release(0.5)
+ * .phaser(2).phaserdepth("<0 .5 .75 1>")
+ *
+ */
+ ['phaserdepth', 'phd', 'phasdp'], // also a superdirt control
+
/**
* choose the channel the pattern is sent to in superdirt
*
@@ -1036,7 +1092,8 @@ const generic_params = [
*/
['roomfade', 'rfade'],
/**
- * Sets the sample to use as an impulse response for the reverb. * * @name iresponse
+ * Sets the sample to use as an impulse response for the reverb.
+ * @name iresponse
* @param {string | Pattern} sample to use as an impulse response
* @synonyms ir
* @example
@@ -1174,9 +1231,6 @@ const generic_params = [
*/
['tremolodepth', 'tremdp'],
['tremolorate', 'tremr'],
- // TODO: doesn't seem to do anything
- ['phaserdepth', 'phasdp'],
- ['phaserrate', 'phasr'],
['fshift'],
['fshiftnote'],
diff --git a/packages/superdough/README.md b/packages/superdough/README.md
index c5950dbf..f32aa32d 100644
--- a/packages/superdough/README.md
+++ b/packages/superdough/README.md
@@ -67,6 +67,10 @@ superdough({ s: 'bd', delay: 0.5 }, 0, 1);
- `crush`: amplitude bit crusher using given number of bits
- `shape`: distortion effect from 0 (none) to 1 (full). might get loud!
- `pan`: stereo panning from 0 (left) to 1 (right)
+ - `phaser`: sets the speed of the modulation
+ - `phaserdepth`: the amount the signal is affected by the phaser effect.
+ - `phasersweep`: the frequency sweep range of the lfo for the phaser effect.
+ - `phasercenter`: the amount the signal is affected by the phaser effect.
- `vowel`: vowel filter. possible values: "a", "e", "i", "o", "u"
- `delay`: delay mix
- `delayfeedback`: delay feedback
diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs
index e3033afe..00e2f42c 100644
--- a/packages/superdough/superdough.mjs
+++ b/packages/superdough/superdough.mjs
@@ -112,6 +112,48 @@ function getDelay(orbit, delaytime, delayfeedback, t) {
return delays[orbit];
}
+// each orbit will have its own lfo
+const phaserLFOs = {};
+function getPhaser(orbit, t, speed = 1, depth = 0.5, centerFrequency = 1000, sweep = 2000) {
+ //gain
+ const ac = getAudioContext();
+ const lfoGain = ac.createGain();
+ lfoGain.gain.value = sweep;
+
+ //LFO
+ if (phaserLFOs[orbit] == null) {
+ phaserLFOs[orbit] = ac.createOscillator();
+ phaserLFOs[orbit].frequency.value = speed;
+ phaserLFOs[orbit].type = 'sine';
+ phaserLFOs[orbit].start();
+ }
+
+ phaserLFOs[orbit].connect(lfoGain);
+ if (phaserLFOs[orbit].frequency.value != speed) {
+ phaserLFOs[orbit].frequency.setValueAtTime(speed, t);
+ }
+
+ //filters
+ const numStages = 2; //num of filters in series
+ let fOffset = 0;
+ const filterChain = [];
+ for (let i = 0; i < numStages; i++) {
+ const filter = ac.createBiquadFilter();
+ filter.type = 'notch';
+ filter.gain.value = 1;
+ filter.frequency.value = centerFrequency + fOffset;
+ filter.Q.value = 2 - Math.min(Math.max(depth * 2, 0), 1.9);
+
+ lfoGain.connect(filter.detune);
+ fOffset += 282;
+ if (i > 0) {
+ filterChain[i - 1].connect(filter);
+ }
+ filterChain.push(filter);
+ }
+ return filterChain[filterChain.length - 1];
+}
+
let reverbs = {};
let hasChanged = (now, before) => now !== undefined && now !== before;
@@ -226,6 +268,12 @@ export const superdough = async (value, deadline, hapDuration) => {
bpsustain = 1,
bprelease = 0.01,
bandq = 1,
+
+ //phaser
+ phaser,
+ phaserdepth = 0.75,
+ phasersweep,
+ phasercenter,
//
coarse,
crush,
@@ -260,6 +308,7 @@ export const superdough = async (value, deadline, hapDuration) => {
if (bank && s) {
s = `${bank}_${s}`;
}
+
// get source AudioNode
let sourceNode;
if (source) {
@@ -377,6 +426,11 @@ export const superdough = async (value, deadline, hapDuration) => {
panner.pan.value = 2 * pan - 1;
chain.push(panner);
}
+ // phaser
+ if (phaser !== undefined && phaserdepth > 0) {
+ const phaserFX = getPhaser(orbit, t, phaser, phaserdepth, phasercenter, phasersweep);
+ chain.push(phaserFX);
+ }
// last gain
const post = gainNode(postgain);
diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap
index d02acdef..a12fcb65 100644
--- a/test/__snapshots__/examples.test.mjs.snap
+++ b/test/__snapshots__/examples.test.mjs.snap
@@ -2439,6 +2439,19 @@ exports[`runs examples > example "irand" example index 0 1`] = `
]
`;
+exports[`runs examples > example "iresponse" example index 0 1`] = `
+[
+ "[ 0/1 → 1/2 | s:bd room:0.8 ir:shaker_large i:0 ]",
+ "[ 1/2 → 1/1 | s:sd room:0.8 ir:shaker_large i:0 ]",
+ "[ 1/1 → 3/2 | s:bd room:0.8 ir:shaker_large i:2 ]",
+ "[ 3/2 → 2/1 | s:sd room:0.8 ir:shaker_large i:2 ]",
+ "[ 2/1 → 5/2 | s:bd room:0.8 ir:shaker_large i:0 ]",
+ "[ 5/2 → 3/1 | s:sd room:0.8 ir:shaker_large i:0 ]",
+ "[ 3/1 → 7/2 | s:bd room:0.8 ir:shaker_large i:2 ]",
+ "[ 7/2 → 4/1 | s:sd room:0.8 ir:shaker_large i:2 ]",
+]
+`;
+
exports[`runs examples > example "iter" example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:A3 ]",
@@ -3306,6 +3319,154 @@ exports[`runs examples > example "perlin" example index 0 1`] = `
]
`;
+exports[`runs examples > example "phaser" example index 0 1`] = `
+[
+ "[ 0/1 → 1/8 | note:D3 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 1/8 → 1/4 | note:E3 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 1/4 → 3/8 | note:F#3 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 3/8 → 1/2 | note:A3 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 1/2 → 5/8 | note:B3 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 5/8 → 3/4 | note:D4 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 3/4 → 7/8 | note:E4 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 7/8 → 1/1 | note:F#4 s:sawtooth release:0.5 phaser:1 ]",
+ "[ 1/1 → 9/8 | note:D3 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 9/8 → 5/4 | note:E3 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 5/4 → 11/8 | note:F#3 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 11/8 → 3/2 | note:A3 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 3/2 → 13/8 | note:B3 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 13/8 → 7/4 | note:D4 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 7/4 → 15/8 | note:E4 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 15/8 → 2/1 | note:F#4 s:sawtooth release:0.5 phaser:2 ]",
+ "[ 2/1 → 17/8 | note:D3 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 17/8 → 9/4 | note:E3 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 9/4 → 19/8 | note:F#3 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 19/8 → 5/2 | note:A3 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 5/2 → 21/8 | note:B3 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 21/8 → 11/4 | note:D4 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 11/4 → 23/8 | note:E4 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 23/8 → 3/1 | note:F#4 s:sawtooth release:0.5 phaser:4 ]",
+ "[ 3/1 → 25/8 | note:D3 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 25/8 → 13/4 | note:E3 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 13/4 → 27/8 | note:F#3 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 27/8 → 7/2 | note:A3 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 7/2 → 29/8 | note:B3 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 29/8 → 15/4 | note:D4 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 15/4 → 31/8 | note:E4 s:sawtooth release:0.5 phaser:8 ]",
+ "[ 31/8 → 4/1 | note:F#4 s:sawtooth release:0.5 phaser:8 ]",
+]
+`;
+
+exports[`runs examples > example "phasercenter" example index 0 1`] = `
+[
+ "[ 0/1 → 1/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 1/8 → 1/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 1/4 → 3/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 3/8 → 1/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 1/2 → 5/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 5/8 → 3/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 3/4 → 7/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 7/8 → 1/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 1/1 → 9/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 9/8 → 5/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 5/4 → 11/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 11/8 → 3/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 3/2 → 13/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 13/8 → 7/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 7/4 → 15/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 15/8 → 2/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasercenter:2000 ]",
+ "[ 2/1 → 17/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 17/8 → 9/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 9/4 → 19/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 19/8 → 5/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 5/2 → 21/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 21/8 → 11/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 11/4 → 23/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 23/8 → 3/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasercenter:4000 ]",
+ "[ 3/1 → 25/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 25/8 → 13/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 13/4 → 27/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 27/8 → 7/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 7/2 → 29/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 29/8 → 15/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 15/4 → 31/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+ "[ 31/8 → 4/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasercenter:800 ]",
+]
+`;
+
+exports[`runs examples > example "phaserdepth" example index 0 1`] = `
+[
+ "[ 0/1 → 1/8 | note:D3 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 1/8 → 1/4 | note:E3 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 1/4 → 3/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 3/8 → 1/2 | note:A3 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 1/2 → 5/8 | note:B3 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 5/8 → 3/4 | note:D4 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 3/4 → 7/8 | note:E4 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 7/8 → 1/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phaserdepth:0 ]",
+ "[ 1/1 → 9/8 | note:D3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 9/8 → 5/4 | note:E3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 5/4 → 11/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 11/8 → 3/2 | note:A3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 3/2 → 13/8 | note:B3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 13/8 → 7/4 | note:D4 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 7/4 → 15/8 | note:E4 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 15/8 → 2/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phaserdepth:0.5 ]",
+ "[ 2/1 → 17/8 | note:D3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 17/8 → 9/4 | note:E3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 9/4 → 19/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 19/8 → 5/2 | note:A3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 5/2 → 21/8 | note:B3 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 21/8 → 11/4 | note:D4 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 11/4 → 23/8 | note:E4 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 23/8 → 3/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phaserdepth:0.75 ]",
+ "[ 3/1 → 25/8 | note:D3 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 25/8 → 13/4 | note:E3 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 13/4 → 27/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 27/8 → 7/2 | note:A3 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 7/2 → 29/8 | note:B3 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 29/8 → 15/4 | note:D4 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 15/4 → 31/8 | note:E4 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+ "[ 31/8 → 4/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phaserdepth:1 ]",
+]
+`;
+
+exports[`runs examples > example "phasersweep" example index 0 1`] = `
+[
+ "[ 0/1 → 1/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 1/8 → 1/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 1/4 → 3/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 3/8 → 1/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 1/2 → 5/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 5/8 → 3/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 3/4 → 7/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 7/8 → 1/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 1/1 → 9/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 9/8 → 5/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 5/4 → 11/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 11/8 → 3/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 3/2 → 13/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 13/8 → 7/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 7/4 → 15/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 15/8 → 2/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasersweep:2000 ]",
+ "[ 2/1 → 17/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 17/8 → 9/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 9/4 → 19/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 19/8 → 5/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 5/2 → 21/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 21/8 → 11/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 11/4 → 23/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 23/8 → 3/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasersweep:4000 ]",
+ "[ 3/1 → 25/8 | note:D3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 25/8 → 13/4 | note:E3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 13/4 → 27/8 | note:F#3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 27/8 → 7/2 | note:A3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 7/2 → 29/8 | note:B3 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 29/8 → 15/4 | note:D4 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 15/4 → 31/8 | note:E4 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+ "[ 31/8 → 4/1 | note:F#4 s:sawtooth release:0.5 phaser:2 phasersweep:800 ]",
+]
+`;
+
exports[`runs examples > example "pianoroll" example index 0 1`] = `
[
"[ 0/1 → 1/8 | note:C2 s:piano clip:1 ]",
diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx
index b1323a8e..a3ae91d7 100644
--- a/website/src/pages/learn/effects.mdx
+++ b/website/src/pages/learn/effects.mdx
@@ -240,3 +240,21 @@ global effects use the same chain for all events of the same orbit:
Next, we'll look at strudel's support for [Csound](/learn/csound).
+
+## Phaser
+
+### phaser
+
+
+
+### phaserdepth
+
+
+
+### phasercenter
+
+
+
+### phasersweep
+
+