Thanks to visit codestin.com
Credit goes to github.com

Skip to content

njourdane/jaffle

Repository files navigation

Jaffle

Just another flat file livecoding environment.

Introduction

Jaffle is a yaml-based syntax for Tidal-cycles, based on Strudel.

It is used to write tunes in yaml instead of JavaScript or Haskel, resulting in a lighter syntax. Its purpose is to make algorithmic music more accessible for people who are not familiar with programming languages.

Under the hood, Jaffle is a transpiler generating JavaScript code, which is then interpreted by Strudel.

Syntax

This chapter aims to provide an overview of the Jaffle syntax, for people already familiar with Strudel. If necessary, read the Strudel documentation.

Comments

Yaml comments starts with a #:

StrudelJaffle
// I'm a comment
# I'm a comment

Quotes

Most of the time, quotes are optional (although many yaml syntax highlighters sucks are render them correctly):

StrudelJaffle
note("c@3 eb")
Note: c@3 eb

But be careful, some mini-notations could me misinterpreted by the yaml parser, for instance when starting the notation with [ (used to define arrays):

Sound: hh*8
    gain: [.25 1]*2 # not working

To address this, you can use simple or double quotes, or prepend the mini-notation with the / character, which is ignored:

- S: '~ sd ~'
- S: "tb*2 cb*2 ~"
- S: /bd ~ hh*2

Function chaining

The chained functions are on the same indentation level:

StrudelJaffle
note("c@3 eb")
  .lpf(600)
  .delay(.5)
  .gain(2)
Note: c@3 eb
lpf: 600
delay: .5
gain: 2

Also, because dictionnaries are not ordered, the first instruction is capitalized (here Note instead note).

Functions without parameters

It's totally safe to have a yaml attribute without value (just don't forget the :):

StrudelJaffle
note("c@3 eb")
  .piano()
  .log()
Note: c@3 eb
piano:
log:

Functions with multiple parameters

Use yaml arrays:

StrudelJaffle
stack(
  s("oh*2 cb*2 ~"),
  s("bd sd hh*2")
)
Stack:
- S: oh*2 cb*2 ~
- S: bd sd hh*2

You could eventually use an inline array:

Stack: [ S: oh*2 cb*2 ~, S: bd sd hh*2 ]

If the root node is an array, the surrounding function is Stack by default. The code above can also be written like this:

- S: oh*2 cb*2 ~
- S: bd sd hh*2

Mini-notation

When applying functions directly to a mini-notation, the M keyword must be used:

StrudelJaffle
"c3 [eb3,g3]"
  .note()
M: c3 [eb3,g3]
note:

Escaping mini-notation

While Strudel distinguish mini-notations and strings by using simple or double quotes, Jaffle analyses strings as mini-notations by default. You must prepend them by the : sign to avoid this behavior.

StrudelJaffle
n("1 2 3")
  .scale('C minor')
N: 1 2 3
scale: :C minor

Data serialization

To pass a dictionnary as a function parameter, you must append the ^ sign to the attribute name.

StrudelJaffle
s("sd oh*2 hh")
  .pianoroll({ fold: 1 })
S: sd oh*2 hh
pianoroll^: { fold: 1 }

You may want to pass a dictionnary on a specific argument, by adding its index next to ^, starting from 1.

StrudelJaffle
samples({
  bd: '...',
  sd: '...',
  hh: '...' }
  , '...')
samples^1:
- bd: ...
  sd: ...
  hh: ...
- ...

Note: the sample example above does not work as is, see below.

Out of scope functions

Some functions like samples are not part of the main music structure like Stack or Cat. You must prepend their name with the . sign:

Strudel
samples({
  bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav'],
  sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
  hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
s("<bd:0 bd:1>,~ <sd:0 sd:1>,[hh:0 hh:1]*2")
Jaffle
.samples^1:
- bd: [ bd/BT0AADA.wav, bd/BT0AAD0.wav ]
  sd: [ sd/rytm-01-classic.wav, sd/rytm-00-hard.wav ]
  hh: [ hh27/000_hh27closedhh.wav, hh/000_hh3closedhh.wav ]
- :github:tidalcycles/Dirt-Samples/master/
S: <bd:0 bd:1>,~ <sd:0 sd:1>,[hh:0 hh:1]*2

Not the both use of the prefix . and the suffix ^1 to serialize the first parameter.

You can add an extra . to await functions:

StrudelJaffle
await samples({
  bd: '...',
  sd: '...',
  hh: '...' }
  , '...')
..samples^1:
- bd: ...
  sd: ...
  hh: ...
- ...

Signals

Signals are written like they was functions:

StrudelJaffle
saw
  .range(50, 80)
  .segment(24)
  .note()
Saw:
range: [50, 80]
segment: 24
note:

Note the clever use of the inline array in the range function to avoid line returns.

Expressions

If you want to put an expression in a parameter, prepend it by the = sign:

StrudelJaffle
"c3 [eb3,g3]"
  .add(1/3)
  .note()
M: c3 [eb3,g3]
add: =1/3
note:

Such expressions are limited to simple mathematics (+, =, *, /).

Function in parameter

Use the Set keyword to pass a function as parameter, such as in accumulation modifiers (here with an inline dictionnary):

StrudelJaffle
note("c3 eb3 g3 a3")
  .sometimes(x=>x.gain(8))
Note: c3 eb3 g3 a3
sometimes: { Set: , gain: 8 }

If necessary, the number of additional parameters must be passed to the Set value:

Strudel
"<0 [2 4]>"
  .echoWith(4, 1/8, (p,n) => p.add(n*2))
  .scale('C minor')
  .note()
Jaffle
M: <0 [2 4]>
echoWith: [ 4, =1/8, { Set: 1, add: =a*2 } ]
scale: C minor
note:

Such parameters are named a, then b, then c.

Contributing

See the contribution guide!

Authorship

Jaffle transpiler and demo website

Strudel engine

Pre-loaded sounds

About

An hybrid yaml/node editor for Tidal Cycles, based on Strudel.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Languages