Apprendre Nuts
Un tutoriel pas à pas et un lexique de musique pour coder le son. Chaque exemple se joue ici même : appuyez sur ▶ Écouter, modifiez le code, réécoutez.
Nuts s'inspire de Strudel : les motifs s'écrivent de la même façon.
1Démarrer
Un motif Nuts tient souvent en une ligne : quoi jouer (des notes ou des sons), puis comment (le timbre, le filtre, les effets), enchaînés par des points.
note("c3 e3 g3 b3").s("sawtooth").lpf(800)
note(...) donne les notes, .s("sawtooth") choisit une onde en dent de scie, .lpf(800) adoucit le son en coupant les aigus au-dessus de 800 Hz.
Dans l'éditeur
| Action | Comment |
|---|---|
| Jouer / couper | le gros bouton rond, ou Ctrl+Entrée / Ctrl+. |
| Appliquer une modification | automatique pendant la lecture si Direct est coché ; sinon ⟳ Évaluer |
| Voir les fonctions | tapez un . après un motif, ou Ctrl+Espace |
| Suivre la lecture | les notes qui sonnent s'allument dans le code et défilent dans la visualisation |
| Garder son travail | Enregistrer (Ctrl+S) : dans le navigateur, en fichier .nuts, ou en ligne avec un compte |
2Cycle et tempo
Le temps de Nuts se compte en cycles. Un motif entre guillemets remplit exactement un cycle, quel que soit son nombre d'éléments : quatre sons se partagent le cycle en quatre, huit sons en huit.
s("bd sd bd sd")
s("bd sd bd sd hh hh hh hh")
Un cycle correspond le plus souvent à une mesure. Le tempo se règle en cycles par minute avec setcpm (ou par seconde avec setcps) :
setcpm(40)
s("bd sd bd sd")
Convertir des BPM
Les partitions donnent un tempo en battements (noires) par minute. Divisez par le nombre de temps de la mesure :
| Mesure | Formule | Exemple : 120 BPM |
|---|---|---|
| 4/4 | setcpm(bpm / 4) | setcpm(30) |
| 3/4 (valse) | setcpm(bpm / 3) | setcpm(40) |
| 6/8 | setcpm(bpm à la noire pointée / 2) | 60 à la noire pointée → setcpm(30) |
3Mini-notation
C'est la petite langue écrite entre guillemets. Elle décrit le rythme en quelques signes.
| Signe | Effet | Exemple |
|---|---|---|
a b c | enchaîne dans le cycle | "bd sd hh" |
[ ] | range plusieurs éléments dans un seul pas | "bd [sd sd]" |
< > | un seul élément par cycle, à tour de rôle | "bd <sd cp>" |
*n | répète n fois dans le pas | "hh*8" |
/n | étire sur n cycles | "[c3 e3 g3]/2" |
~ | silence | "bd ~ sd ~" |
@n | pas n fois plus long | "c3@3 e3" |
!n | recopie le pas n fois | "bd!3 sd" |
? | une chance sur deux de jouer | "hh? hh? hh? hh?" |
(k,n) | rythme euclidien : k coups sur n pas | "bd(3,8)" |
, | superpose plusieurs couches | "bd*4, hh*8" |
:n | variante d'un son | "bd:2" |
Sous-diviser un pas :
s("bd [sd sd] hh [hh hh hh]")
Alterner d'un cycle à l'autre :
s("bd sd bd <sd cp [cp cp]>")
Répéter, allonger, supprimer au hasard :
s("bd*2 ~ sd ~, hh? hh? hh? hh? hh? hh? hh? hh?")
Les rythmes euclidiens répartissent k coups le plus régulièrement possible sur n pas. (3,8) donne le tresillo des musiques latines ; un troisième nombre fait tourner le rythme :
s("bd(3,8), hh(5,8,2), ~ cp")
4Lexique des notes
Nuts écrit les notes à l'anglo-saxonne : une lettre, une altération éventuelle, puis un numéro d'octave.
| Français | do | ré | mi | fa | sol | la | si |
|---|---|---|---|---|---|---|---|
| Nuts | c | d | e | f | g | a | b |
note("c4 d4 e4 f4 g4 a4 b4 c5")
Dièses et bémols
Un dièse monte d'un demi-ton : # (ou s). Un bémol descend d'un demi-ton : b. Ainsi c#4 et db4 sont la même touche du piano.
note("c4 c#4 d4 eb4 e4 f4 f#4 g4 ab4 a4 bb4 b4")
Octaves
Le chiffre est l'octave. Le do central du piano est c4. Sans chiffre, Nuts prend l'octave 3. On peut aussi donner directement un numéro MIDI : 60 = c4, et chaque demi-ton ajoute 1.
| Note | MIDI | Fréquence | Repère |
|---|---|---|---|
c1 | 24 | 33 Hz | tout en bas d'une basse |
c2 | 36 | 65 Hz | basse |
c3 | 48 | 131 Hz | voix d'homme |
c4 | 60 | 262 Hz | do central |
a4 | 69 | 440 Hz | le la du diapason |
c5 | 72 | 523 Hz | voix de femme, flûte |
c6 | 84 | 1047 Hz | très aigu |
note("c2 c3 c4 c5").s("triangle")
Pour décaler toutes les notes d'un motif, .add(n) ajoute n demi-tons (12 = une octave) :
note("c3 e3 g3 e3").add("<0 5 7 12>").s("square").decay(.15)
5Durées et mesures
Il n'y a pas de symbole de durée : on choisit une grille (par exemple 8 croches pour une mesure à 4/4), puis on allonge les notes avec @.
| Figure | Dans une grille de 8 croches (4/4) | Dans une grille de 16 |
|---|---|---|
| ronde | c4@8 | c4@16 |
| blanche | c4@4 | c4@8 |
| noire pointée | c4@3 | c4@6 |
| noire | c4@2 | c4@4 |
| croche | c4 | c4@2 |
| double croche | [c4 d4] (deux dans un pas) | c4 |
| silence | ~, ~@2, ~@4… | idem |
Une mesure à 4/4 : noire, deux croches, blanche (2 + 1 + 1 + 4 = 8) :
note("[c4@2 d4 e4 f4@4]").s("triangle")
Plusieurs mesures
Mettez chaque mesure entre crochets, et toutes les mesures entre < > : Nuts en joue une par cycle, puis recommence.
note("<[c4@2 e4@2 g4@2 e4@2] [f4@2 a4@2 c5@4] [e4@2 g4@2 d4@2 b3@2] [c4@8]>").s("triangle")
Autres mesures
En 3/4, prenez une grille de 3 (ou 6) pas ; en 6/8, une grille de 6 croches où la noire pointée vaut @3.
setcpm(40)
note("<[c4@2 e4] [g4@2 e4] [f4@3] [d4@2 b3]>").s("sine")
6Accords
La virgule fait sonner des notes ensemble. Entre crochets, un accord occupe un seul pas.
note("<[c3,e3,g3] [a2,c3,e3] [f2,a2,c3] [g2,b2,d3]>").s("supersaw").attack(.1).release(.6).gain(.5)
Construire un accord à partir de sa fondamentale, en demi-tons :
| Accord | Nom | Demi-tons | Sur do |
|---|---|---|---|
| majeur | C | 0 4 7 | c3,e3,g3 |
| mineur | Cm | 0 3 7 | c3,eb3,g3 |
| septième | C7 | 0 4 7 10 | c3,e3,g3,bb3 |
| septième majeure | Cmaj7 | 0 4 7 11 | c3,e3,g3,b3 |
| mineur septième | Cm7 | 0 3 7 10 | c3,eb3,g3,bb3 |
| suspendu 2 | Csus2 | 0 2 7 | c3,d3,g3 |
| suspendu 4 | Csus4 | 0 5 7 | c3,f3,g3 |
| diminué | Cdim | 0 3 6 | c3,eb3,gb3 |
| augmenté | Caug | 0 4 8 | c3,e3,g#3 |
A# et B♭ sont la même chose ; en code, a#3 ou bb3. Un accord « Cm | B♭ | Fm | E♭ » s'écrit <[c3,eb3,g3] [bb2,d3,f3] [f3,ab3,c4] [eb3,g3,bb3]>.Arpèges
Un arpège joue les notes de l'accord l'une après l'autre :
note("<[c3 e3 g3 c4 g3 e3]*2 [a2 c3 e3 a3 e3 c3]*2>").s("triangle").decay(.2)
7Gammes et degrés
Plutôt que des noms de notes, on peut écrire des degrés avec n, puis choisir la gamme avec .scale("tonique:gamme"). Le degré 0 est la tonique, 7 est la tonique une octave plus haut (dans une gamme de 7 notes), et les degrés négatifs descendent.
n("0 1 2 3 4 5 6 7").scale("C4:major").s("triangle")
Le même motif change de couleur avec la gamme :
n("0 2 4 <6 7> 4 2").scale("<C4:major D4:dorian A3:minor E4:phrygian>").s("square").decay(.2)
| Gamme | Nom Nuts | Demi-tons | Couleur |
|---|---|---|---|
| majeure | major | 0 2 4 5 7 9 11 | claire, joyeuse |
| mineure naturelle | minor | 0 2 3 5 7 8 10 | triste, sombre |
| dorienne | dorian | 0 2 3 5 7 9 10 | mineure mais lumineuse, jazz, funk |
| phrygienne | phrygian | 0 1 3 5 7 8 10 | espagnole, tendue |
| lydienne | lydian | 0 2 4 6 7 9 11 | rêveuse, musique de film |
| mixolydienne | mixolydian | 0 2 4 5 7 9 10 | rock, blues |
| locrienne | locrian | 0 1 3 5 6 8 10 | instable |
| mineure harmonique | harmonic:minor | 0 2 3 5 7 8 11 | orientale, classique |
| mineure mélodique | melodic:minor | 0 2 3 5 7 9 11 | jazz |
| pentatonique majeure | major:pentatonic | 0 2 4 7 9 | aucune fausse note possible |
| pentatonique mineure | minor:pentatonic | 0 3 5 7 10 | rock, blues |
| blues | blues | 0 3 5 6 7 10 | blues |
| par tons | whole:tone | 0 2 4 6 8 10 | flottante, étrange |
| chromatique | chromatic | 0 à 11 | toutes les notes |
irand ou ?.n("0 2 4 7 9 7 4 2".add("<0 2 -3>")).scale("A3:minor:pentatonic").s("triangle").decay(.2).delay(.4)
8Les sons
Tous les sons de Nuts sont synthétisés : pas d'échantillons, rien à télécharger. On les choisit avec s().
Oscillateurs
| Nom | Caractère |
|---|---|
sine | sinus : pur, doux, sans harmoniques (sifflet, basse sub) |
triangle | doux et creux (flûte, son par défaut des notes) |
square | carré : creux et nasillard (clarinette, jeux vidéo 8 bits) |
sawtooth | dent de scie : brillant et riche (cordes, basses, leads) |
supersaw | plusieurs dents de scie désaccordées : large et épais (nappes, trance) — .unison(), .detune() |
user | onde construite harmonique par harmonique avec .partials() |
note("c3 e3 g3 b3").s("<sine triangle square sawtooth>")
Bruits
| Nom | Caractère |
|---|---|
white | bruit blanc : dur, comme une télé sans signal |
pink | bruit rose : plus doux, comme une cascade |
brown | bruit brun : grave et sourd, comme le vent ou la mer |
crackle | crépitements, plus ou moins denses avec .density() |
s("<white pink brown>").attack(.3).release(.5).gain(.4)
.noise(0 à 1) ajoute un souffle à n'importe quel oscillateur :
note("c3 g3 c4 g3").s("sine").noise("<0 .3 .7>")
9Batterie
| Nom | Instrument | Onomatopée |
|---|---|---|
bd | grosse caisse | boom |
sd | caisse claire | tchack |
hh / oh | charleston fermé / ouvert | tss / tsssh |
cp | clap | clac |
rim | rimshot (bord de caisse) | tok |
lt mt ht | toms grave, médium, aigu | ba-da-bam |
cr / rd | cymbale crash / ride | kchhh / ting |
cb | cloche (cowbell) | tonk |
sh | shaker | tchik |
cl | claves | tic |
tb | tambourin | tchiing |
cg | conga | poum |
Le rythme de base du rock et de la pop : grosse caisse sur les temps 1 et 3, caisse claire sur 2 et 4, charleston en croches :
s("bd ~ bd ~, ~ sd ~ sd, hh*8")
Un roulement de toms tous les deux cycles, et une boîte à rythmes au choix avec .bank() : "808" (kick long et rond), "909" (sec et claquant), "lofi" (sale et étouffé) :
s("bd ~ [~ bd] ~, ~ sd ~ sd, [~ hh]*4, ~ ~ ~ <~ [ht ht mt lt]>").bank("<808 909 lofi>")
bd:2 choisit une variante accordée différemment ; .speed() accorde la percussion, .decay() la raccourcit ou l'allonge.
s("bd:0 bd:1 bd:2 bd:3, hh*8").speed("<1 1.5>")
10Façonner le son
Enveloppe ADSR
Comment le volume évolue pendant la note : Attaque (montée), Déclin (descente), Soutien ou maintien (niveau tenu, de 0 à 1), Relâchement (extinction après la note). Les temps sont en secondes.
note("c3 eb3 g3 c4").s("sawtooth").adsr("<.001 .4>:.2:<0 .7>:.3").lpf(1500)
Un .decay() seul donne un son pincé (maintien à 0) ; une .attack() lente donne une nappe.
Filtres
.lpf(Hz) passe-bas : coupe les aigus (le son s'assombrit). .hpf(Hz) passe-haut : coupe les graves. .bpf(Hz) ne garde qu'une bande. .lpq() ajoute de la résonance autour de la coupure ; .lpenv(octaves) balaie le filtre à chaque note — le son « acide ».
note("c2*8").s("sawtooth").lpf("<300 700 1500>").lpq(12).lpenv("<0 2 4>").decay(.15)
Un signal fait bouger un réglage en continu :
note("c2 c2 [c3 c2] eb2").s("sawtooth").lpf(sine.range(300, 2500).slow(4)).lpq(10)
Vibrato et FM
.vib(Hz) fait onduler la hauteur, .vibmod() règle la profondeur en demi-tons. La synthèse FM module la fréquence d'une onde par une autre : .fm() règle l'intensité, .fmh() le rapport (entier = harmonieux, décimal = métallique, cloches).
note("<c4 e4 g4 [b4 d5]>*2").s("sine").fm("<2 6>").fmh(1.41).fmdecay(.4).fmsustain(0).decay(1).room(.6)
Synthèse additive
Une onde est une somme de sinus : la fondamentale et ses harmoniques. .partials([...]) donne la force de chacun, comme les tirettes d'un orgue.
note("<[c3,g3,e4] [a2,e3,c4]>").s("user").partials([1, .5, .8, 0, .4, 0, .2]).attack(.05).release(.6).gain(.5)
11Effets
| Fonction | Effet |
|---|---|
.gain(0 à 1.5) | volume |
.pan(0 à 1) | panoramique : 0 à gauche, 1 à droite |
.room(0 à 1) .roomsize(s) | réverbération, taille de la salle |
.delay(0 à 1) .delaytime(s) .delayfeedback(0 à .95) | écho : quantité, écart, nombre de répétitions |
.shape(0 à 1) | saturation douce |
.crush(1 à 16) | bitcrush : son numérique abîmé |
note("c4 ~ g4 ~ eb4 ~ ~ ~").s("triangle").decay(.2).delay(.5).delaytime(.375).delayfeedback(.6).room(.4).pan(sine.slow(2))
12Transformer un motif
| Fonction | Effet |
|---|---|
.fast(n) .slow(n) | accélère, ralentit |
.rev() | joue chaque cycle à l'envers |
.every(n, f) | applique f un cycle sur n |
.sometimesBy(p, f) | applique f au hasard (p de 0 à 1) |
.jux(f) | original à gauche, version transformée à droite |
.off(t, f) | superpose une copie décalée de t cycles |
.ply(n) | répète chaque note n fois |
.degradeBy(p) | retire des notes au hasard |
.struct("x ~ x x") .euclid(k, n) | impose un rythme |
Dans every, jux ou off, la transformation s'écrit rev, fast(2), add(12)… ou comme une petite fonction : x=>x.speed(2).
note("c3 eb3 g3 bb3").s("square").lpf(1400).decay(.12).every(4, rev).off(.125, add(12)).jux(fast(2)).gain(.5)
Signaux
sine, saw, tri, square, rand et perlin varient de 0 à 1 au fil du cycle ; .range(min, max) les étire, .slow(n) les ralentit.
s("hh*16").gain(saw.range(.2, .9)).pan(sine).speed(perlin.range(.8, 1.4))
13Plusieurs pistes
Chaque ligne qui commence par $: est une piste jouée en même temps que les autres. Un commentaire // juste au-dessus lui donne son nom ; _$: la rend muette sans l'effacer.
setcpm(30)
// Batterie
$: s("bd*2 [~ bd] ~ bd, ~ sd, hh*8")
// Basse
$: note("c2 [~ c2] eb2 [g1 bb1]").s("sawtooth").lpf(500).lpenv(3).decay(.2)
// Mélodie (muette : enlevez le _)
_$: n("<0 2 4 [7 9]>*2").scale("C4:minor").s("sine").fm(3).decay(.3)
14Depuis une partition
- Tonalité : comptez les dièses ou bémols à la clé. Trois bémols = mi♭, la♭, si♭ partout (do mineur ou mi♭ majeur).
- Notes : en clé de sol, la ligne du bas est
e4, le do sous la portée estc4. - Rythme : choisissez une grille (8 croches en 4/4), puis une mesure par crochets avec
@pour les notes longues (voir Durées). - Tempo : BPM ÷ temps par mesure →
setcpm. - Accords : une grille comme « Dm | B♭ A » se traduit accord par accord (voir Accords).
Exemple avec un air du domaine public, Korobeiniki (le thème de Tetris), en la mineur :
setcpm(36)
note(`<
[e5@2 b4 c5 d5@2 c5 b4] [a4@2 a4 c5 e5@2 d5 c5] [b4@3 c5 d5@2 e5@2] [c5@2 a4@2 a4@2 ~@2]
[~ d5@2 f5 a5@2 g5 f5] [e5@3 c5 e5@2 d5 c5] [b4@2 b4 c5 d5@2 e5@2] [c5@2 a4@2 a4@2 ~@2]
>`).s("square").decay(.2).sustain(.5).delay(.25).gain(.45)
15Blocs et Godot
Mode Blocs : chaque bloc correspond à une fonction, et chaque piste à une ligne $:. On passe du code aux blocs et inversement sans rien perdre ; ce que les blocs ne savent pas représenter reste dans un bloc « code libre ». La boîte à rythmes se programme case par case.
Godot : bouton Exporter la boucle .wav de l'éditeur (boucle sans couture, à importer avec Loop Mode → Forward), ou greffon Nuts : un nœud NutsPlayer joue directement le code ou un fichier .nuts.
Fonctions de A à Z
| Fonction | Rôle |
|---|
Glossaire
- Accord
- plusieurs notes jouées ensemble.
- Altération
- dièse (♯, monte d'un demi-ton) ou bémol (♭, descend d'un demi-ton).
- Arpège
- les notes d'un accord jouées l'une après l'autre.
- BPM
- battements par minute : le tempo, compté en noires.
- Cycle
- l'unité de temps de Nuts ; un motif entre guillemets remplit un cycle. Souvent une mesure.
- Degré
- position d'une note dans une gamme (0 = tonique).
- Demi-ton
- le plus petit écart entre deux notes : deux touches voisines du piano. 12 demi-tons = une octave.
- Enveloppe
- évolution d'un réglage pendant la note (volume : ADSR ; filtre : lpenv).
- Euclidien (rythme)
- k coups répartis le plus régulièrement possible sur n pas.
- FM
- modulation de fréquence : une onde fait varier la hauteur d'une autre, très vite ; sons de cloches et de pianos électriques.
- Fondamentale
- la note qui donne son nom à un accord, ou la fréquence de base d'un son.
- Gamme
- ensemble de notes choisies dans l'octave (majeure, mineure…).
- Harmonique
- fréquence multiple de la fondamentale ; leur mélange donne le timbre.
- Hertz (Hz)
- vibrations par seconde : 440 Hz est le la du diapason.
- Mesure
- groupe de temps (4 en 4/4, 3 en 3/4) ; sur une partition, entre deux barres verticales.
- Mini-notation
- la notation entre guillemets qui décrit le rythme.
- Motif (pattern)
- une suite d'événements qui se répète de cycle en cycle.
- Nappe
- son tenu, doux, qui remplit le fond (pad).
- Octave
- même note, deux fois plus aiguë (fréquence doublée).
- Panoramique
- position du son entre la gauche et la droite.
- Passe-bas / passe-haut
- filtres qui laissent passer les graves / les aigus.
- Résonance
- accentuation des fréquences autour de la coupure d'un filtre ; le « wouah ».
- Réverbération
- les réflexions d'une salle qui prolongent le son.
- Signal
- valeur qui varie en continu (sine, saw…) pour animer un réglage.
- Tempo
- vitesse de la musique.
- Timbre
- ce qui distingue deux instruments jouant la même note.
- Tonique
- la note de départ et de repos d'une gamme.
- Vibrato
- légère ondulation de la hauteur, comme un chanteur ou un violon.