Skip to content

Commit

Permalink
Merge pull request #411 from tidalcycles/docs
Browse files Browse the repository at this point in the history
improve samples doc
  • Loading branch information
felixroos committed Feb 5, 2023
2 parents a104335 + 3e99f34 commit f7ac033
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 20 deletions.
10 changes: 10 additions & 0 deletions packages/core/controls.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,16 @@ const generic_params = [
['f', 'uid', ''],
['f', 'val', ''],
['f', 'cps', ''],
/**
* If set to 1, samples will be cut to the duration of their event.
* In tidal, this would be done with legato, which [is about to land in strudel too](https://github.com/tidalcycles/strudel/issues/111)
*
* @name clip
* @param {number | Pattern} active 1 or 0
* @example
* note("c a f e ~").s("piano").clip(1)
*
*/
['f', 'clip', ''],
];

Expand Down
21 changes: 21 additions & 0 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,27 @@ exports[`runs examples > example "chunkBack" example index 0 1`] = `
]
`;

exports[`runs examples > example "clip" example index 0 1`] = `
[
"[ 0/1 → 1/5 | note:c s:piano clip:1 ]",
"[ 1/5 → 2/5 | note:a s:piano clip:1 ]",
"[ 2/5 → 3/5 | note:f s:piano clip:1 ]",
"[ 3/5 → 4/5 | note:e s:piano clip:1 ]",
"[ 1/1 → 6/5 | note:c s:piano clip:1 ]",
"[ 6/5 → 7/5 | note:a s:piano clip:1 ]",
"[ 7/5 → 8/5 | note:f s:piano clip:1 ]",
"[ 8/5 → 9/5 | note:e s:piano clip:1 ]",
"[ 2/1 → 11/5 | note:c s:piano clip:1 ]",
"[ 11/5 → 12/5 | note:a s:piano clip:1 ]",
"[ 12/5 → 13/5 | note:f s:piano clip:1 ]",
"[ 13/5 → 14/5 | note:e s:piano clip:1 ]",
"[ 3/1 → 16/5 | note:c s:piano clip:1 ]",
"[ 16/5 → 17/5 | note:a s:piano clip:1 ]",
"[ 17/5 → 18/5 | note:f s:piano clip:1 ]",
"[ 18/5 → 19/5 | note:e s:piano clip:1 ]",
]
`;

exports[`runs examples > example "coarse" example index 0 1`] = `
[
"[ 0/1 → 1/2 | s:bd coarse:1 ]",
Expand Down
116 changes: 96 additions & 20 deletions website/src/pages/learn/samples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,90 @@ import { JsDoc } from '../../docs/JsDoc';

# Samples

# Default Sample Map
Samples are the most common way to make sound with tidal and strudel.
A sample is a (commonly short) piece of audio that is used as a basis for sound generation, undergoing various transformations.
Music that is based on samples can be thought of as a collage of sound. [Read more about Sampling](<https://en.wikipedia.org/wiki/Sampling_(music)>)

As we have seen, `s` can play back audio samples:
Strudel allows loading samples in the form of audio files of various formats (wav, mp3, ogg) from any publicly available URL.

<MiniRepl client:idle client:idle tune={`s("bd sd,hh*8,misc/2")`} />
# Default Samples

These sounds come from Strudel's in-built default "sample map".
To know which sounds are available, open the [default sample map](https://strudel.tidalcycles.org/EmuSP12.json).
By default, strudel comes with a built-in "sample map", providing a solid base to play with.

# Custom Sample Maps
<MiniRepl client:idle tune={`s("bd sd,hh*8, misc/2")`} />

Here, we are using the `s` function to play back different default samples (`bd`, `sd`, `hh` and `misc`) to get a drum beat.

For drum sounds, strudel uses the comprehensive [tidal-drum-machines](https://github.com/ritchse/tidal-drum-machines) library, with the following naming convention:

| Drum | Abbreviation |
| ----------------------------------- | ------------ |
| Bass drum, Kick drum | bd |
| Snare drum | sd |
| Rimshot | rim |
| Clap | cp |
| Closed hi-hat | hh |
| Open hi-hat | oh |
| Crash | cr |
| Ride | rd |
| Shakers (and maracas, cabasas, etc) | sh |
| High tom | ht |
| Medium tom | mt |
| Low tom | lt |
| Cowbell | cb |
| Tambourine | tb |
| Other percussions | perc |
| Miscellaneous samples | misc |
| Effects | fx |

Furthermore, strudel also loads instrument samples from [VCSL](https://github.com/sgossner/VCSL) by default.

To see which sample names are available, open the `samples` tab in the [REPL](https://strudel.tidalcycles.org/).

Note that only the sample maps (mapping names to URLs) are loaded initially, while the audio samples itself are not loaded until they are actually played.
This behaviour of loading things only when they are needed is also called `lazy loading`.
While it saves resources, it can also lead to sounds not being audible the first time they are triggered, because the sound is still loading.
[This might be fixed in the future](https://github.com/tidalcycles/strudel/issues/187)

# Sound Banks

If we look at the `samples` tab, we can see that the drum samples are all prefixed with drum machine names: `RolandTR808_bd`, `RolandTR808_sd`, `RolandTR808_hh` etc..

We _could_ use them like this:

<MiniRepl client:idle tune={`s("RolandTR808_bd RolandTR808_sd,RolandTR808_hh*8")`} />

... but thats obviously a bit much to write. Using the `bank` function, we can shorten this to:

<MiniRepl client:idle tune={`s("bd sd,hh*8").bank("RolandTR808")`} />

You could even pattern the bank to switch between different drum machines:

<MiniRepl client:idle tune={`s("bd sd,hh*8").bank("<RolandTR808 RolandTR909>")`} />

Behind the scenes, `bank` will just prepend the drum machine name to the sample name with `_` to get the full name.
This of course only works because the name after `_` (`bd`, `sd` etc..) is standardized.
Also note that some banks won't have samples for all sounds!

# Selecting Sounds

If we look again at the `samples` tab, there is also a number behind each name, indicating how many individual samples are available.
For example `RolandTR909_hh(4)` means there are 4 samples of a TR909 hihat available.
By default, `s` will play the first sample, but we can selecting the other ones using `n`, starting from 0:

<MiniRepl client:idle tune={`s("hh*4").bank("RolandTR909").n("<0 1 2 3>")`} />

Numbers that are too high will just wrap around to the beginning

<MiniRepl client:idle tune={`s("hh*4").bank("RolandTR909").n("<0 1 2 3 4 5 6 7>")`} />

Here, 0-3 will play the same sounds as 4-7, because `RolandTR909_hh` only has 4 sounds.

Selecting sounds also works inside the mini notation, using "`:`" like this:

<MiniRepl client:idle tune={`s("bd:1 bd:2,hh:0 hh:1 hh:2 hh:3").bank("RolandTR909")`} />

# Loading Custom Samples

You can load your own sample map using the `samples` function.
In this example we create a map using sounds from the default sample map:
Expand Down Expand Up @@ -48,7 +122,7 @@ s("bassdrum snaredrum, hihat*8")`}

Here we have changed the "map" to include longer sample names.

# Loading Custom Samples
## The `samples` function

The `samples` function has two arguments:

Expand Down Expand Up @@ -87,7 +161,7 @@ We can see there are some guitar samples inside the `/samples` folder, so let's
s("[g0 g1 g2 g3 g4]/5")`}
/>

# Loading Multiple Samples per Sound
## Multiple Samples per Sound

It is also possible, to declare multiple files for one sound, using the array notation:

Expand Down Expand Up @@ -146,7 +220,7 @@ And as above, we can choose the sample number using `n` for even more flexibilit
n("<0 1 2 3 4>").s("guitar")`}
/>

# Pitched Sounds
## Pitched Sounds

For pitched sounds, you can use `note`, just like with synths:

Expand All @@ -170,7 +244,7 @@ note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').clip(1)
.gain(.5)`}
/>

# Base Pitch
## Base Pitch

If we have 2 samples with different base pitches, we can make them in tune by specifying the pitch like this:

Expand Down Expand Up @@ -203,7 +277,7 @@ note("g2!2 <bb2 c3>!2, <c4@3 [<eb4 bb3> g4 f4]>")

The sampler will always pick the closest matching sample for the current note!

# Shabda
## Shabda

If you don't want to select samples by hand, there is also the wonderful tool called [shabda](https://shabda.ndre.gr/).
With it, you can enter any sample name(s) to query from [freesound.org](https://freesound.org/). Example:
Expand All @@ -220,30 +294,32 @@ stack(

# Sampler Effects

Below are four different examples of sampler "effects" which are functions that can be used to change the behaviour of sample playback.
Note that most of what you've learned already about Tidal mini-notation can be used with these functions too.
Almost everything in Tidal can be patterned using strings!
Sampler effects are functions that can be used to change the behaviour of sample playback.

### `begin`
### begin

<JsDoc client:idle name="Pattern.begin" h={0} />

### `end`
### end

<JsDoc client:idle name="Pattern.end" h={0} />

### `cut`
### cut

<JsDoc client:idle name="cut" h={0} />

### `loopAt`
### clip

<JsDoc client:idle name="clip" h={0} />

### loopAt

<JsDoc client:idle name="Pattern.loopAt" h={0} />

### `chop`
### chop

<JsDoc client:idle name="Pattern.chop" h={0} />

### `speed`
### speed

<JsDoc client:idle name="speed" h={0} />

0 comments on commit f7ac033

Please sign in to comment.