- JavaScript 97.9%
- CSS 1.4%
- PHP 0.4%
- HTML 0.2%
- Shell 0.1%
| addons | ||
| css | ||
| font | ||
| img | ||
| js | ||
| sheets | ||
| synth-editor | ||
| .gitignore | ||
| index.html | ||
| README.md | ||
| TODO | ||
été
An experimental sound instrument. Try it online.
Live-coding is creating and modifying a program live for an audience, to generate sound and/or visuals.
After making my own live coding tools and experimenting it live, I realized that live coding often leads to a limited range of expressiveness: writing code is slow, even for fast typers. The performer’s body is often limited at the writing scale: an idea has to be translated into code, then type, character, after, character. A lot of intuitive gestures that we can achieve with traditional instruments can’t be performed with live coding, as the time of typing is usually not compatible with the time of reacting to what happens.
été mixes live-coding (real time musical writing with code), and percussive expression. For that, the progam considers the computer keyboard as a percussion instrument. The performer can write both algorithmic instructions and very precise time-related percussive instructions in the same coding environment. été is an experiment that tries to gather in the same program the time of algorithmic composition and the time of spontaneous improvisation.
Usage
- Open index.html in a web browser, a basic web server is needed to open the project in
localhost - A demo code will appear, click the play button to start it
- Modify the code and evaluate the whole document with CTRL + S
Tips
- Three modes allow to perform as you type. See Typing Modes
exeallows to execute basic functions. For instancestart()to start été, ornewPattern()to add a pattern, orcl(0)to clone the pattern0.- Notes, durations, and many other keys can have operations, like
trig: 2 / 8, and can be a list of values interpreted one after the other, likenote: 200, 300, 110. note,gain,durandtypewith value of0will make the parent beat silent.- A synth effect, can be added (delay, reverb…). See Functions.
- Polyfrequencies and polysynths can be achieved with a
_. For instance: you can give a note the value of200_300, or a syth type a value ofsine_noise. - To repeat a value, use either the
re()function, or the shortcut:. To repeat 2 times "C5", you can write2:C5orre(2,C5). Note: repeating with:only works for one value,re()is however more powerful, it can be used with functions inside, and multiple values, likere(2, 200, sh(400 ,200)). - To comment a line, add a
#at its beginning - Drop a yaml file in the browser, été will load and display it
Keyboard shortcuts
CTRL + S: evaluate the whole documentALT + anykey- In
typemode, it will just play notes defined inconfig.percsynth.notes - In
recmode, it will record a new pattern while you keep ALT pressed.
- In
Overview
config:
comment: Hello été // this is a free area, often use for the title of the sheet and/or the version of été
percsynth: // this synth will be used by typing mode or rec mode
note: B3 // "key" or any note value
type: sine // or "square", "sawtooth", "triangle", "noise"…
gain: 0.5 // gain in dB
dur: 0.1 // synth note duration, in seconds
fx: 0 // effects, useful for kicks, reverb, see `Tips` section
env: 0, 1, 0 // envelope as an comma-separated list, or a rep()
itv: .5 // default cycle interval in seconds
exe: null // call js functions here (exe context), such as start(), rm()…
mode: type // "rec", "type" or "perc", respectively record (+ALT), write with sound (a-z, 0-9 keys), and percussive (+ALT only) ; more in the “Modes“ section
patterns:
- id: 0 // pattern ID
state: p // state of the pattern, "p" for playing, "m" for mute
trig: .3 // when the pattern is triggered, can be relative to the default interval using the keyword "itv"
note: 200 // any note value: "350" or "4F, 210, 5F"…
pan: 0 // pan, from -1 to 1
synth: // each pattern.synth property will be use as default for each pattern.beat
type: sine
gain: 0.7
dur: sh(.07,.8)
fx: 0
env: 0,1,0
beats: // pulses part of the pattern, here you can overwrite note, pan, and synth by specifying it for each beat
- id: 1 // beat ID
offset: 0 // beat offset
Typing Modes
You can use three different percussive modes to live perform with été. The mode can be changed in config.mode.
mode: rec
Record a new pattern while the ALT key is pressed. It will synchronize (snap) default config.itv.
mode: type
Play sounds each time you press an alphanumerical key, so writing code becomes part of the sound composition too. config.percsynth.note can take either the value key that will map the keyboard keycode to notes, or any note value. In combination with the ALT key, the sound will be played but nothing will be written.
mode: perc
Will play a sound each time an alphanumerical key is pressed, but only with ALT pressed as well. Useful for percussive typing only when required.
Tip: USB keyboards tend to add delay to keystrokes. You may prefer to use you native computer’s keyboard for percussive modes.
Notes
The notes can take many kinds of values:
- frequencies
220 - note names
F3, following the formatnote,sharp(optional),octave(optional) whereDis the note,#is the sharp symbol, and3is the 3rd octave (16.35Hz base) - note lists
130, 1400, C4, 440or functionsr(200,500),sh(E3,200,F#4)etc. - chords, notes separated by underscores:
200_300_240,G3_B3.
You can freely play notes on key press, without writing anything, by maintaining the ALT key in type mode.
Functions
Été comes with a list of functions that can be used within three contexts. Either by executing it globally, in front of the exe key, or as a value, in front of all keys that require values, such as note, type, pan. Some time-related functions are dedicated to the trig key only.
| FUNCTION | NAME | CONTEXT | COMMENTS |
|---|---|---|---|
r(min, max) |
random | value | Generate a random value between min and max |
sh(list) |
shuffle | value | Pick a random value from comma-separated values, e.g. 100,25,50,300 |
re(occurrence, list) |
repeat | value | Repeat value or list of value a number of occurrence times, e.g. re(2,100,200) |
eucl(beats, steps, val1, val2, $) |
euclidean | value | Generate a euclidean pattern with a number of beats taking either values val1 or val2, spread among a number of steps. Leave the cycle symbol $ |
beads(beads, val1, val2, $) |
beads | value | Handwritten two values patterns like -.--. playing either val1 for - or val2 for .. Leave the cycle symbol $. You can use any character you want expect 01. X different characters will require X val parameters. |
rot(steps, pattern) |
rotate | value | Shift a pattern’s value of a given number of steps that can be negative or null. This function currently works with comma-separated values as a pattern. |
gl(beats, duration, silence, rand) |
glob | trig | Generate a glob of a number of beats gathered within a duration in seconds, and followed by a silence in seconds. rand is a float between 0 and 1 that will make duration and silence less or more approximative (random) |
sometimesby(probability, val1, val2) |
sometimesby | trig | Trigger val1 with a probability between 0 and 1, otherwise, triggers val2. Concept stolen from TidalCycles. |
always |
always | trig | Shortcut for sometimesby() with a probability of 1. Takes two parameters: val1 and val2 |
almostalways |
almostalways | trig | Shortcut for sometimesby() with a probability of 0.9. Takes two parameters: val1 and val2 |
often |
often | trig | Shortcut for sometimesby() with a probability of 0.75. Takes two parameters: val1 and val2 |
sometimes |
sometimes | trig | Shortcut for sometimesby() with a probability of 0.5. Takes two parameters: val1 and val2 |
rarely |
rarely | trig | Shortcut for sometimesby() with a probability of 0.25. Takes two parameters: val1 and val2 |
almostnever |
almostnever | trig | Shortcut for sometimesby() with a probability of 0.1. Takes two parameters: val1 and val2 |
never |
never | trig | Shortcut for sometimesby() with a probability of 0. Takes two parameters: val1 and val2 |
newPattern() |
new pattern | exe | Create new pattern at the begining of the document. You can override rules with newPattern('note:C4') or newPattern(['states:m', 'synth.dur:2']) |
style(CSS) |
style | exe | Inject CSS in the page |
resetStyle() |
reset style | exe | Remove all injected CSS |
load(path) |
load | exe | Load a new sheet, by giving its path. e.g. load("sheets/gelgel.yaml") |
loadAddon(name) |
loadAddon | exe | Load a new addon, by giving its name. e.g. loadAddon("cam") |
start() |
start | exe | Start été, shortcut Ctrl + r |
stop() |
stop | exe | Stop été, shortcut Ctrl + r |
reset() |
reset | exe | Load a default, blank sheet |
theme() |
theme | exe | Change the theme of the interface, currently dark aka 0, or bright aka 1 |
m(ids, key, value) |
modify | exe | Modify one or many existing patterns with id = id or [id,id,…], by changing its key to a new value |
cl(ids) |
clone | exe | Clone one or many existing patterns with id = id or [id,id,…] |
rm(ids) |
remove | exe | Remove one or many existing patterns with id = id or [id,id,…] |
expo(value, time) |
exponential sound curve | fx | Add an exponentialRampToValueAtTime from the current note to the given value, with a factor of time between 0 and 1, that is relative to beat duration. |
del(time, feedback, acceleration) |
delay | fx | Add delay to a synth, where time is the delay length in seconds, feedback the number of occurrences and acceleration a positive factor for the tail compression in time. |
rev(time) |
reverb | fx | Add reverb to a synth. |
Events
Été comes with events you can use for add-ons and other hackitudes.
start: when playing startsstop: when playing stopssave: when the sheet is savedkeyDown: when any key is down
You can use it this way:
document.addEventListener("start", doStuff, false)
Addons
Some add-ons can be added anytime to été’s interface. Addons can be found in addons/ and have their own description in dedicated Readmes.
Ex. To load the “font” addon: exe: loadAddon("fonts")
MIDI
Été can input or output MIDI. Make sure you use a web browser that supports web MIDI, I use Firefox nightly and a localhost based URL.
MIDI input
- To get MIDI input on a pattern, set it
statetom-in - MIDI note number = ete pattern id
- MIDI velocity = ete note gain
- You might have to change
main.jsto select your device
MIDI output
- The way MIDI output is implemented might be not suited for your needs at all. In short, it can only output one pattern after the other, that is how I use it, to record parts one by one.
- To get MIDI output from a pattern, set it
statetom-out - By default, the MIDI output channel is 1.
- You might have to change
webaudio.jsto select your device
Saving, loading
été’s stores and loads sheets in the browser’s localstorage. It is also possible to save sheets in the address bar as base64 data when the “Share” button is clicked.
été can also load an existing sheet saved in /sheets as a yaml document, using ? : https://raphaelbastide.com/ete/?hello-ete.yaml will open sheets/hello-ete.yaml
Yaml files can be dragged and dropped into été interface, and obviously, you can copy / paste yaml text content directly.
Caution: early development
été is in early development and may be subject to important changes in the future. Don’t expect it to run smoothly, be stable or sound “good”. It is still a weird creature in a glass egg. Also, it is possible that your saved sheets may not be compatible with future versions thus it is recommended to add the version of été within your sheet’s comments / title.
Typography
The font used by default with été is été mono. It is a libre font made using the online font editor Brutalita by Javier Byte.
Let’s talk
If you have questions or suggestions, you can ping me on the Prototypes TopLap Discord.
Thanks
- Editor built with Codemirror
- Uses eemeli’s Yaml parser
- A custom webaudio synth, inspired by notes by Nick Briz
- Thanks to @dddoss and @alicericci for the help on regex and syntax enhancement
- Also thanks to the live coding and Toplap communities, and the existing, inspiring tools and prototypes around
Other project
- été demo, a cassette made with été
- Ticklecode, livecoding × MIDI pads
- Cascade, CSS to sound live coding system
License
été is released under GNU AGPL.