mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-10 21:28:31 +00:00
149 lines
4.7 KiB
Plaintext
149 lines
4.7 KiB
Plaintext
---
|
|
title: Strudel vs Tidal
|
|
layout: ../../layouts/MainLayout.astro
|
|
---
|
|
|
|
import { MiniRepl } from '../../docs/MiniRepl';
|
|
import { JsDoc } from '../../docs/JsDoc';
|
|
|
|
# Comparing Strudel and Tidal
|
|
|
|
This page is dedicated to exisiting tidal users, giving an overview of all the differences between Strudel and Tidal.
|
|
|
|
## Language
|
|
|
|
Strudel is written in JavaScript, while Tidal is written in Haskell.
|
|
|
|
### Example
|
|
|
|
This difference is most obvious when looking at the syntax:
|
|
|
|
```haskell
|
|
iter 4 $ every 3 (||+ n "10 20") $ (n "0 1 3") # s "triangle" # crush 4
|
|
```
|
|
|
|
One _could_ express that pattern to Strudel like so:
|
|
|
|
```
|
|
iter(4, every(3, add.squeeze("10 20"), n("0 1 3").s("triangle").crush(4)))
|
|
```
|
|
|
|
- The `$` operator does not exist, so the `iter` function has to wrap everything in parens.
|
|
- Custom operators like `||+` are explicit function calls, `add.squeeze` in this case
|
|
- The `#` operator is replaced with a chained function call `# crush 4` => `.crush(4)`
|
|
|
|
Unlike Haskell, JavaScript lacks the ability to define custom infix
|
|
operators, or change the meaning of existing ones.
|
|
|
|
Before you discard Strudel as an unwieldy paren monster, look at this alternative way to write the above:
|
|
|
|
```
|
|
n("0 1 3").every(3, add.squeeze("10 20")).iter(4).s("triangle").crush(4)
|
|
```
|
|
|
|
By reordering calls, the parens are much less nested.
|
|
As a general rule by thumb, you could say that everything Tidal does with `$` is reversed in Strudel:
|
|
|
|
`iter 4 $ every 3 (||+ n "10 20") $ (n "0 1 3")`
|
|
|
|
becomes
|
|
|
|
`n("0 1 3").every(3, add.squeeze("10 20")).iter(4)`
|
|
|
|
Simply put, `foo x $ bar x` becomes `bar(x).foo(x)`.
|
|
|
|
### Operators
|
|
|
|
The [custom operators of tidal](https://tidalcycles.org/docs/reference/pattern_structure/#all-the-operators) are normal functions in strudel:
|
|
|
|
| function | tidal | strudel |
|
|
| ----------- | ------ | ------- |
|
|
| add | \|+ n | .add(n) |
|
|
| subtract | \|- n | .sub(n) |
|
|
| multiply | \|\* n | .mul(n) |
|
|
| divide | \|\/ n | .div(n) |
|
|
| modulo | \|\% n | .mod(n) |
|
|
| left values | \|\< n | .set(n) |
|
|
|
|
The above list only displays the operators taking the structure comes from the `left`.
|
|
For each of those, a `right` and `both` variant also exists.
|
|
As this directional thinking only works with code, strudel calls these `in` / `out` / `mix`:
|
|
|
|
| direction | tidal | strudel |
|
|
| --------- | ------- | ----------- |
|
|
| left | \|+ n | .add.in(n) |
|
|
| right | +\| n | .add.out(n) |
|
|
| both | \|+\| n | .add.mix(n) |
|
|
|
|
Instead of `+` / `add`, you can use any of the available operators of the first list.
|
|
|
|
## Function Compatibility
|
|
|
|
[This issue](https://github.com/tidalcycles/strudel/issues/31) tracks which Tidal functions are implemented in Strudel.
|
|
The list might not be 100% up to date and probably also misses some functions completely..
|
|
Feel encouraged to search the source code for a function you're looking for.
|
|
If you find a function that's not on the list, please tell!
|
|
|
|
## Control Params
|
|
|
|
As seen in the example, the `#` operator (shorthand for `|>`) is also just a function call in strudel.
|
|
So `note "c5" # s "gtr"` becomes `note("c5").s('gtr')`.
|
|
|
|
[This file](https://github.com/tidalcycles/strudel/blob/main/packages/core/controls.mjs) lists all available control params.
|
|
Note that not all of those work in the Webaudio Output of Strudel.
|
|
If you find a tidal control that's not on the list, please tell!
|
|
|
|
## Sound
|
|
|
|
Tidal is commonly paired with Superdirt / Supercollider for sound generation.
|
|
While Strudel also has a way of [communicating with Superdirt](./learn/input-output),
|
|
it aims to provide a standalone live coding environment that runs entirely in the browser.
|
|
|
|
### Audio Effects
|
|
|
|
Many of SuperDirt's effects have been reimplemented in Strudel, using the Web Audio API.
|
|
You can find a [list of available effects here](./learn/effects).
|
|
|
|
### Sampler
|
|
|
|
Strudel's sampler supports [a subset](/learn/samples) of Superdirt's sampler.
|
|
Also, samples are always loaded from a URL rather than from the disk, although [that might be possible in the future](https://github.com/tidalcycles/strudel/issues/118).
|
|
|
|
## Evaluation
|
|
|
|
The Strudel REPL does not support [block based evaluation](https://github.com/tidalcycles/strudel/issues/34) yet.
|
|
You can use the following "workaround" to create multiple patterns that can be turned on and off:
|
|
|
|
```
|
|
let a = note("c a f e")
|
|
|
|
let b = s("bd sd")
|
|
|
|
stack(
|
|
a,
|
|
// b
|
|
)
|
|
```
|
|
|
|
Alternatively, you could write everything as one `stack` and use `.hush()` to silence a pattern:
|
|
|
|
```
|
|
stack(
|
|
note("c a f e"),
|
|
s("bd sd").hush()
|
|
)
|
|
```
|
|
|
|
Note that strudel will always use the last statement in your code as the pattern for querying
|
|
|
|
## Tempo
|
|
|
|
Strudels tempo is 1 cycle per second, while tidal defaults to `0.5625`.
|
|
You can get the same tempo as tidal with:
|
|
|
|
```
|
|
note("c a f e").fast(.5625);
|
|
```
|
|
|
|
Next up: the [REPL](/technical-manual/repl)
|