---
title: Recipes
layout: ../../layouts/MainLayout.astro
---

import { MiniRepl } from '../../docs/MiniRepl';

# 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:

<MiniRepl
  client:visible
  tune={`note("c eb g c4")
.clip(2).s("gm_electric_guitar_clean")`}
  punchcard
/>

...or use scales:

<MiniRepl
  client:visible
  tune={`n("0 2 4 7").scale("C:minor")
.clip(2).s("gm_electric_guitar_clean")`}
  punchcard
/>

...or chord symbols:

<MiniRepl
  client:visible
  tune={`n("0 1 2 3").chord("Cm").mode("above:c3").voicing()
.clip(2).s("gm_electric_guitar_clean")`}
  punchcard
/>

...using off:

<MiniRepl
  client:visible
  tune={`"0"
  .off(1/3, add(2))
  .off(1/2, add(4))
  .n()
  .scale("C:minor")
  .s("gm_electric_guitar_clean")`}
  punchcard
/>

## Chopping Breaks

A sample can be looped and chopped like this:

<MiniRepl
  client:visible
  tune={`await samples('github:yaxu/clean-breaks/main')
s("amen/8").fit().chop(16)`}
  punchcard
/>

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:

<MiniRepl
  client:visible
  tune={`await samples('github:yaxu/clean-breaks/main')
s("amen/8").fit().chop(16).cut(1)
.sometimesBy(.5, ply(2))
.sometimesBy(.25, mul(speed(-1)))`}
  punchcard
/>

If we want to specify the order of samples, we can replace `chop` with `slice`:

<MiniRepl
  client:visible
  tune={`await samples('github:yaxu/clean-breaks/main')
s("amen/8").fit()
  .slice(8, "<0 1 2 3 4*2 5 6 [6 7]>")
  .cut(1).rarely(ply(2))`}
  punchcard
/>

If we use `splice` instead of `slice`, the speed adjusts to the duration of the event:

<MiniRepl
  client:visible
  tune={`await samples('github:yaxu/clean-breaks/main')
s("amen")
  .splice(8, "<0 1 2 3 4*2 5 6 [6 7]>")
  .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:

<MiniRepl
  client:visible
  tune={`note("g1 bb1 <c2 eb2> d2")
  .s("sawtooth")
  .lpf(400).lpa(.2).lpenv(4)
  .scope()`}
/>

We can flip the envelope by setting `lpenv` negative + add some resonance `lpq`:

<MiniRepl
  client:visible
  tune={`note("g1 bb1 <c2 eb2> d2")
  .s("sawtooth").lpq(8)
  .lpf(400).lpa(.2).lpenv(-4)
  .scope()`}
/>

## Layering Sounds

We can layer sounds by separating them with ",":

<MiniRepl
  client:visible
  tune={`note("<g1 bb1 d2 f1>")
.s("sawtooth, square") // <------
.scope()`}
/>

We can control the gain of individual sounds like this:

<MiniRepl
  client:visible
  tune={`note("<g1 bb1 d2 f1>")
.s("sawtooth, square:0:.5") // <--- "name:number:gain"
.scope()`}
/>

For more control over each voice, we can use `layer`:

<MiniRepl
  client:visible
  tune={`note("<g1 bb1 d2 f1>").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:

<MiniRepl
  client:visible
  tune={`note("<g1 bb1 d2 f1>")
.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:

<MiniRepl client:visible tune={`s("bd*2,hh*3")`} punchcard />

A polyrhythm is when 2 different tempos happen at the same time.

## Polymeter

This is a polymeter:

<MiniRepl client:visible tune={`s("<bd rim>,<hh hh oh>").fast(2)`} punchcard />

A polymeter is when 2 different bar lengths play at the same tempo.

## Phasing

This is a phasing:

<MiniRepl client:visible tune={`note("<C D G A Bb D C A G D Bb A>*[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:

<MiniRepl
  client:visible
  tune={`await samples('github:Bubobubobubobubo/Dough-Fox/main')
  n(run(8)).s("ftabla")`}
  punchcard
/>

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`.

<MiniRepl
  client:visible
  tune={`await samples('github:Bubobubobubobubo/Dough-Fox/main')
  n(run(8)).s("ftabla").early(2/8)`}
/>

Let's add some randomness:

<MiniRepl
  client:visible
  tune={`await samples('github:Bubobubobubobubo/Dough-Fox/main')
n(run(8)).s("ftabla").early(2/8)
.sometimes(mul(speed(1.5)))`}
/>

## Tape Warble

We can emulate a pitch warbling effect like this:

<MiniRepl
  client:visible
  tune={`note("c4 bb f eb")
.add(note(perlin.range(0,.5))) // <------ warble
.clip(2).s("gm_electric_guitar_clean")`}
/>

## Sound Duration

There are a number of ways to change the sound duration. Using clip:

<MiniRepl
  client:visible
  tune={`note("f ab bb c")
.clip("<2 1 .5 .25>/2")`}
/>

The value of clip is relative to the duration of each event.
We can also create overlaps using release:

<MiniRepl
  client:visible
  tune={`note("f ab bb c")
.release("<2 1 .5 .002>/2")`}
/>

This will smoothly fade out each sound for the given number of seconds.
We could also make the notes shorter with decay / sustain:

<MiniRepl
  client:visible
  tune={`note("f ab bb c")
.decay("<.2 .1 .02>/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:

<MiniRepl client:visible tune={`s("oh*4").end("<1 .5 .25 .1>")`} />

Compare that to clip:

<MiniRepl client:visible tune={`s("oh*4").clip("<1 .5 .25 .1>")`} />

or decay / sustain

<MiniRepl client:visible tune={`s("oh*4").decay("<.2 .12 .06 .01>").sustain(0)`} />

## Wavetable Synthesis

You can loop a sample with `loop` / `loopEnd`:

<MiniRepl client:visible tune={`note("<c eb g f>").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:

<MiniRepl
  client:visible
  tune={`await samples('github:bubobubobubobubo/dough-waveforms/main')
note("c eb g bb").s("wt_dbass").clip(2)`}
/>

Running through different wavetables can also give interesting variations:

<MiniRepl
  client:visible
  tune={`await samples('github:bubobubobubobubo/dough-waveforms/main')
note("c2*8").s("wt_dbass").n(run(8))`}
/>

...adding a filter envelope + reverb:

<MiniRepl
  client:visible
  tune={`await samples('github:bubobubobubobubo/dough-waveforms/main')
note("c2*8").s("wt_dbass").n(run(8))
.lpf(perlin.range(200,2000).slow(8))
.lpenv(-3).lpa(.1).room(.5)`}
/>
