);
}
+
+function cx(...classes) {
+ // : Array
+ return classes.filter(Boolean).join(' ');
+}
+
+function s4() {
+ return Math.floor((1 + Math.random()) * 0x10000)
+ .toString(16)
+ .substring(1);
+}
diff --git a/website/src/pages/recipes/recipes-next.mdx b/website/src/pages/recipes/recipes-next.mdx
deleted file mode 100644
index 4230063f..00000000
--- a/website/src/pages/recipes/recipes-next.mdx
+++ /dev/null
@@ -1,312 +0,0 @@
----
-title: Recipes
-layout: ../../layouts/MainLayout.astro
----
-
-import { MicroRepl } from '../../docs/MicroRepl';
-
-# Recipes
-
-This page shows possible ways to achieve common (or not so common) musical goals.
-There are often many ways to do a thing and there is no right or wrong.
-The fun part is that each representation will give you different impulses when improvising.
-
-## Arpeggios
-
-An arpeggio is when the notes of a chord are played in sequence.
-We can either write the notes by hand:
-
-
-
-...or use scales:
-
-
-
-...or chord symbols:
-
-
-
-...using off:
-
-
-
-## Chopping Breaks
-
-A sample can be looped and chopped like this:
-
-
-
-This fits the break into 8 cycles + chops it in 16 pieces.
-The chops are not audible yet, because we're not doing any manipulation.
-Let's add randmized doubling + reversing:
-
-
-
-If we want to specify the order of samples, we can replace `chop` with `slice`:
-
-")
- .cut(1).rarely(ply(2))`}
- punchcard
-/>
-
-If we use `splice` instead of `slice`, the speed adjusts to the duration of the event:
-
-")
- .cut(1).rarely(ply(2))`}
- punchcard
-/>
-
-Note that we don't need `fit`, because `splice` will do that by itself.
-
-## Filter Envelopes
-
-A minimal filter envelope looks like this:
-
- d2")
- .s("sawtooth")
- .lpf(400).lpa(.2).lpenv(4)
- .scope()`}
-/>
-
-We can flip the envelope by setting `lpenv` negative + add some resonance `lpq`:
-
- d2")
- .s("sawtooth").lpq(8)
- .lpf(400).lpa(.2).lpenv(-4)
- .scope()`}
-/>
-
-## Layering Sounds
-
-We can layer sounds by separating them with ",":
-
-")
-.s("sawtooth, square") // <------
-.scope()`}
-/>
-
-We can control the gain of individual sounds like this:
-
-")
-.s("sawtooth, square:0:.5") // <--- "name:number:gain"
-.scope()`}
-/>
-
-For more control over each voice, we can use `layer`:
-
-").layer(
- x=>x.s("sawtooth").vib(4),
- x=>x.s("square").add(note(12))
-).scope()`}
-/>
-
-Here, we give the sawtooth a vibrato and the square is moved an octave up.
-With `layer`, you can use any pattern method available on each voice, so sky is the limit..
-
-## Oscillator Detune
-
-We can fatten a sound by adding a detuned version to itself:
-
-")
-.add(note("0,.1")) // <------ chorus
-.s("sawtooth").scope()`}
- punchcard
-/>
-
-Try out different values, or add another voice!
-
-## Polyrhythms
-
-Here is a simple example of a polyrhythm:
-
-
-
-A polyrhythm is when 2 different tempos happen at the same time.
-
-## Polymeter
-
-This is a polymeter:
-
-,").fast(2)`} punchcard />
-
-A polymeter is when 2 different bar lengths play at the same tempo.
-
-## Phasing
-
-This is a phasing:
-
-*[6,6.1]").piano()`} punchcard />
-
-Phasing happens when the same sequence plays at slightly different tempos.
-
-## Running through samples
-
-Using `run` with `n`, we can rush through a sample bank:
-
-
-
-This works great with sample banks that contain similar sounds, like in this case different recordings of a tabla.
-Often times, you'll hear the beginning of the phrase not where the pattern begins.
-In this case, I hear the beginning at the third sample, which can be accounted for with `early`.
-
-
-
-Let's add some randomness:
-
-
-
-## Tape Warble
-
-We can emulate a pitch warbling effect like this:
-
-
-
-## Sound Duration
-
-There are a number of ways to change the sound duration. Using clip:
-
-/2")`}
-/>
-
-The value of clip is relative to the duration of each event.
-We can also create overlaps using release:
-
-/2")`}
-/>
-
-This will smoothly fade out each sound for the given number of seconds.
-We could also make the notes shorter with decay / sustain:
-
-/2").sustain(0)`}
-/>
-
-For now, there is a limitation where decay values that exceed the event duration may cause little cracks, so use higher numbers with caution..
-
-When using samples, we also have `.end` to cut relative to the sample length:
-
-")`} />
-
-Compare that to clip:
-
-")`} />
-
-or decay / sustain
-
-").sustain(0)`} />
-
-## Wavetable Synthesis
-
-You can loop a sample with `loop` / `loopEnd`:
-
-").s("bd").loop(1).loopEnd(.05).gain(.2)`} />
-
-This allows us to play the first 5% of the bass drum as a synth!
-To simplify loading wavetables, any sample that starts with `wt_` will be looped automatically:
-
-
-
-Running through different wavetables can also give interesting variations:
-
-
-
-...adding a filter envelope + reverb:
-
-
diff --git a/website/src/pages/technical-manual/patterns.mdx b/website/src/pages/technical-manual/patterns.mdx
index 45664ad7..49ede526 100644
--- a/website/src/pages/technical-manual/patterns.mdx
+++ b/website/src/pages/technical-manual/patterns.mdx
@@ -14,7 +14,7 @@ Example:
e.show()))
silence`}
diff --git a/website/src/repl/idbutils.mjs b/website/src/repl/idbutils.mjs
index 18e15d20..7613b767 100644
--- a/website/src/repl/idbutils.mjs
+++ b/website/src/repl/idbutils.mjs
@@ -77,6 +77,9 @@ async function bufferToDataUrl(buf) {
//open db and initialize it if necessary
const openDB = (config, onOpened) => {
const { dbName, version, table, columns } = config;
+ if (typeof window === 'undefined') {
+ return;
+ }
if (!('indexedDB' in window)) {
console.log('IndexedDB is not supported.');
return;