nutsthis wiki
nutsthis<wiki> Ouvrir l'éditeur

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

ActionComment
Jouer / couperle gros bouton rond, ou Ctrl+Entrée / Ctrl+.
Appliquer une modificationautomatique pendant la lecture si Direct est coché ; sinon ⟳ Évaluer
Voir les fonctionstapez un . après un motif, ou Ctrl+Espace
Suivre la lectureles notes qui sonnent s'allument dans le code et défilent dans la visualisation
Garder son travailEnregistrer (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 :

MesureFormuleExemple : 120 BPM
4/4setcpm(bpm / 4)setcpm(30)
3/4 (valse)setcpm(bpm / 3)setcpm(40)
6/8setcpm(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.

SigneEffetExemple
a b cenchaî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>"
*nrépète n fois dans le pas"hh*8"
/nétire sur n cycles"[c3 e3 g3]/2"
~silence"bd ~ sd ~"
@npas n fois plus long"c3@3 e3"
!nrecopie 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"
:nvariante 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çaisdorémifasollasi
Nutscdefgab
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.

NoteMIDIFréquenceRepère
c12433 Hztout en bas d'une basse
c23665 Hzbasse
c348131 Hzvoix d'homme
c460262 Hzdo central
a469440 Hzle la du diapason
c572523 Hzvoix de femme, flûte
c6841047 Hztrè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 @.

FigureDans une grille de 8 croches (4/4)Dans une grille de 16
rondec4@8c4@16
blanchec4@4c4@8
noire pointéec4@3c4@6
noirec4@2c4@4
crochec4c4@2
double croche[c4 d4] (deux dans un pas)c4
silence~, ~@2, ~@4…idem

Lire ~@2 : un silence qui dure

On combine les deux symboles : ~ veut dire « silence », @2 veut dire « dure 2 pas ». Donc ~@2 est un silence de deux pas : un soupir (silence d'une noire) dans une grille de 8 croches. De même, ~@4 est une demi-pause et ~@8 une pause (toute la mesure).

Exemple : [c5@2 a4@2 a4@2 ~@2] = do (noire), la (noire), la (noire), silence (noire). Les poids s'additionnent : 2 + 2 + 2 + 2 = 8 pas, la mesure est pleine.

note("<[c5@2 a4@2 a4@2 ~@2] [e5@2 ~ d5 c5@4]>").s("square").decay(.2).sustain(.5).gain(.4)

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")

6Rythme : placer les coups

Savoir écrire les notes ne suffit pas : il faut aussi décider quand elles tombent. Trois outils suffisent, du plus simple au plus précis.

Le principe : la mesure est toujours pleine

Un cycle vaut une mesure, et ce que vous écrivez entre guillemets la remplit, quel que soit le nombre d'éléments. La vitesse, elle, ne dépend que de setcpm.

Ce que vous écrivezCe que ça donne
s("bd sd")2 coups : deux blanches
s("bd sd bd sd")4 coups : quatre noires
s("bd*8")8 coups : huit croches
setcpm(30)
$: s("bd sd")
$: s("hh*8").gain(.4)

Les quatre symboles du rythme

SymboleRôleExemple
~silence : on ne joue pas ce pas"bd ~ sd ~"
@nce pas dure n fois plus longtemps"bd@3 sd" : trois temps, puis un
[ ]plusieurs coups dans un seul pas"bd [sd sd]"
*nrépète le pas n fois"bd*2 sd"

Les poids s'additionnent : dans une grille de 8 croches, x@3 x x@3 x fait bien 3 + 1 + 3 + 1 = 8.

struct : le rythme séparé des notes

C'est l'outil le plus utile pour les accords. chord() (ou note()) donne les hauteurs, struct() donne le rythme : x = on frappe, ~ = on ne frappe pas. Les deux sont indépendants, donc on change l'un sans toucher à l'autre.

setcpm(24)
// 8 cases = 8 croches : 1 et 2 et 3 et 4 et
$: chord("<G3 B3 C4 Cm4>").struct("x ~ ~ x ~ ~ x ~")
  .s("supersaw").attack(.01).decay(.4).sustain(.4).release(.3).room(.3).gain(.5)
$: s("bd ~ ~ ~ bd ~ ~ ~, ~ ~ sd ~ ~ ~ sd ~, hh*8").gain(.8)

Quatre rythmes de guitare à copier

Effet recherchéÀ écrire
accords tenus, nappepas de struct, mais un release long
bien carré.struct("x x x x")
pompage rock : long, court.struct("x@3 x x@3 x")
syncopé, ballade.struct("x ~ ~ x ~ x ~ ~")
setcpm(26)
// Le pompage : un coup long, un coup court
$: chord("<Am3 F3 C4 G3>").struct("x@3 x x@3 x")
  .s("supersaw").unison(3).detune(.06).amp(.6).ampmid(4)
  .decay(.3).sustain(.5).release(.15).gain(.5)
$: note("<a1 f1 c2 g1>*4").s("sawtooth").lpf(600).decay(.12).sustain(.6).gain(.7)
$: s("bd ~ ~ bd ~ ~ bd ~, ~ sd ~ sd, hh*8").bank("909")

Arpéger au lieu de plaquer

Plaqué, l'accord sonne d'un coup ; arpégé, les notes arrivent l'une après l'autre. Il suffit de les écrire dans un groupe.

setcpm(22)
$: note("<[a3 c4 e4 c4] [f3 a3 c4 a3] [c4 e4 g4 e4] [g3 b3 d4 b3]>")
  .s("triangle").chorus(.5).decay(.5).sustain(.2).release(.4).room(.35).gain(.5)

Trouver le rythme que vous avez en tête

  1. Comptez les croches de la mesure : 8 cases en 4/4, 6 en 6/8, 3 ou 6 en 3/4.
  2. Chantez la partie et notez un x à chaque coup, un ~ partout ailleurs. Les huit cases se comptent : 1, et, 2, et, 3, et, 4, et.
  3. Recopiez la suite dans struct, puis écoutez.
  4. Trop rapide ou trop lent ? Ce n'est pas le rythme, c'est setcpm.
  5. Un coup qui dure ? Remplacez deux cases par x@2.

Exemple : « pam — pam-pam — — pam — » donne "x ~ x x ~ ~ x ~".

Deux raccourcis

euclid(k, n) répartit k coups le plus régulièrement possible sur n pas : c'est la base de beaucoup de rythmes traditionnels. off(t, f) ajoute une copie décalée, utile pour un contretemps.

setcpm(30)
$: s("bd").euclid(3, 8)
$: s("hh").euclid(7, 8).gain(.4)
$: chord("<Em3 C4>").struct("x ~ x ~ ~ x ~ ~").s("triangle").decay(.3).sustain(.2).gain(.45)

7Accords

Le plus simple : chord() écrit les notes à votre place, à partir du nom de l'accord. Gm3 = sol mineur, fondamentale à l'octave 3 (3 par défaut si vous ne mettez rien).

chord("<Gm3 Eb3 Bb3 F3>").s("supersaw").attack(.1).release(.6).room(.4).gain(.5)

Noms reconnus : C (majeur), Cm, C7, Cm7, Cmaj7, C6, Cm6, C9, Cm9, Cmaj9, Cadd9, Csus2, Csus4, Cdim, Cdim7, Caug, et C5 pour le power chord des guitares. Les altérations s'écrivent F#m ou Bb, et le reste de la mini-notation fonctionne : chord("<Am3 F3>*2"), chord("[C3 G3] ~ Am3").

Une erreur fréquente : note("Gm3") ne marche pas, car note() attend une note seule. Écrivez chord("Gm3"), ou les notes à la main.

À la main, 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 :

AccordNomDemi-tonsSur do
majeurC0 4 7c3,e3,g3
mineurCm0 3 7c3,eb3,g3
septièmeC70 4 7 10c3,e3,g3,bb3
septième majeureCmaj70 4 7 11c3,e3,g3,b3
mineur septièmeCm70 3 7 10c3,eb3,g3,bb3
suspendu 2Csus20 2 7c3,d3,g3
suspendu 4Csus40 5 7c3,f3,g3
diminuéCdim0 3 6c3,eb3,gb3
augmentéCaug0 4 8c3,e3,g#3
Sur une grille d'accords, 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)

Gratter les accords, lier les notes

Un accord joué par l'ordinateur démarre toutes ses notes exactement au même instant : ça sonne raide, comme un orgue, et l'attaque fait un petit « clap ». Une guitare, elle, balaie ses cordes l'une après l'autre, et la note précédente vibre encore quand la suivante arrive. Deux fonctions suffisent à retrouver ça.

FonctionCe qu'elle faitValeurs utiles
strum(n)étale les notes qui démarrent ensemble, comme un médiator sur les cordes. n = fraction de cycle entre deux cordes ; négatif = de la dernière note vers la première (coup vers le haut)1/64 léger, 1/32 bien marqué, -1/64 à l'envers
clip(n)longueur de la note par rapport à son pas : au-dessus de 1, elle sonne par-dessus la suivante (jeu lié)1.3 à 1.8
release(s)traîne de la note après sa fin : c'est elle qui fait la « vibration » qui reste.4 à .8
attack(s)douceur du départ. Une valeur un peu plus haute adoucit encore le grattage.02 à .05
setcpm(30)
// Raide : tout démarre ensemble, tout s'arrête ensemble
$: chord("<Am F C G>").struct("x@2 x x").s("triangle").decay(.3).sustain(.4)

// Gratté et lié : les cordes se suivent, les accords se chevauchent
_$: chord("<Am F C G>").struct("x@2 x x")
  .strum(1/64).clip(1.6)
  .s("triangle").attack(.02).decay(.4).sustain(.35).release(.5)
  .lpf(2600).chorus(.4).room(.4).gain(.4)

Ces réglages se comptent en fractions de mesure : en mode Blocs, leur curseur saute de division en division (1/128, 1/96, 1/64, 1/48, 1/32…) et écrit la fraction telle quelle dans le code, plutôt qu'un nombre à virgule. C'est vrai aussi pour l'écho décalé, off(1/8, …).

Enlevez le _ de la deuxième piste (et mettez-le sur la première) pour comparer les deux. Le grattage suit l'ordre d'écriture des notes : chord() donne les notes de la plus grave à la plus aiguë, donc strum positif = coup vers le bas, négatif = coup vers le haut. Avec note("[e3,b3,g4]"), c'est l'ordre que vous avez écrit qui décide.

Le petit « clap » au départ de chaque note a été corrigé dans le moteur : toute note monte maintenant en 4 ms minimum, avec une courbe douce. C'est inaudible comme retard, mais ça supprime le claquement, surtout quand plusieurs notes démarrent ensemble.

8Gammes 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)
GammeNom NutsDemi-tonsCouleur
majeuremajor0 2 4 5 7 9 11claire, joyeuse
mineure naturelleminor0 2 3 5 7 8 10triste, sombre
doriennedorian0 2 3 5 7 9 10mineure mais lumineuse, jazz, funk
phrygiennephrygian0 1 3 5 7 8 10espagnole, tendue
lydiennelydian0 2 4 6 7 9 11rêveuse, musique de film
mixolydiennemixolydian0 2 4 5 7 9 10rock, blues
locriennelocrian0 1 3 5 6 8 10instable
mineure harmoniqueharmonic:minor0 2 3 5 7 8 11orientale, classique
mineure mélodiquemelodic:minor0 2 3 5 7 9 11jazz
pentatonique majeuremajor:pentatonic0 2 4 7 9aucune fausse note possible
pentatonique mineureminor:pentatonic0 3 5 7 10rock, blues
bluesblues0 3 5 6 7 10blues
par tonswhole:tone0 2 4 6 8 10flottante, étrange
chromatiquechromatic0 à 11toutes les notes
Astuce : avec une gamme pentatonique, toutes les combinaisons de degrés sonnent bien. Idéal pour improviser au hasard avec 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)

9Les sons

Tous les sons de Nuts sont synthétisés : pas d'échantillons, rien à télécharger. On les choisit avec s().

Oscillateurs

NomCaractère
sinesinus : pur, doux, sans harmoniques (sifflet, basse sub)
triangledoux et creux (flûte, son par défaut des notes)
squarecarré : creux et nasillard (clarinette, jeux vidéo 8 bits)
sawtoothdent de scie : brillant et riche (cordes, basses, leads)
supersawplusieurs dents de scie désaccordées : large et épais (nappes, trance) — .unison(), .detune()
useronde construite harmonique par harmonique avec .partials()
note("c3 e3 g3 b3").s("<sine triangle square sawtooth>")

Bruits

NomCaractère
whitebruit blanc : dur, comme une télé sans signal
pinkbruit rose : plus doux, comme une cascade
brownbruit brun : grave et sourd, comme le vent ou la mer
cracklecré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>")

10Batterie

NomInstrumentOnomatopée
bdgrosse caisseboom
sdcaisse clairetchack
hh / ohcharleston fermé / ouverttss / tsssh
cpclapclac
rimrimshot (bord de caisse)tok
lt mt httoms grave, médium, aiguba-da-bam
cr / rdcymbale crash / ridekchhh / ting
cbcloche (cowbell)tonk
shshakertchik
clclavestic
tbtambourintchiing
cgcongapoum

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>")

11Faç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 (la note que vous entendez) et ses harmoniques, qui sonnent 2, 3, 4… fois plus haut. .partials([…]) donne la force de chacun, comme les tirettes d'un orgue. Il faut le son user, qui est justement l'onde que vous construisez.

Position dans la listeCe qu'elle règleNote entendue si la fondamentale est un do3
1rela fondamentaledo3
2el'octave (×2)do4
3ela quinte au-dessus (×3)sol4
4ela double octave (×4)do5
5ela tierce (×5)mi5

Les valeurs vont de 0 (harmonique absente) à 1 (aussi forte que la fondamentale) ; au-delà de 1, ça marche aussi, mais pensez à baisser le gain. Un 0 au milieu de la liste supprime purement et simplement cette harmonique, c'est ce qui change le caractère du son.

RecetteÀ écrireCe qu'on entend
sinus pur[1]doux, sans couleur
dent de scie[1, .5, .33, .25, .2, .17]riche et brillant : 1/n
onde carrée[1, 0, .33, 0, .2, 0, .14]creux, façon clarinette : que les impaires
orgue[1, .8, 0, .6, 0, 0, 0, .4]les tirettes d'un orgue : octaves et quintes
cloche[1, 0, 0, .6, 0, 0, .35, 0, 0, .2]harmoniques éloignées, son métallique
setcpm(20)
// La même mélodie, quatre timbres : sinus, dent de scie, carrée, orgue
$: note("c3 e3 g3 c4").s("user")
  .partials("<[1] [1 .5 .33 .25 .2 .17] [1 0 .33 0 .2 0 .14] [1 .8 0 .6 0 0 0 .4]>")
  .attack(.02).decay(.4).sustain(.3).release(.4).gain(.5)

Deux points pratiques. Plus la liste est longue, plus le son est brillant, mais au-delà d'une quinzaine d'harmoniques, les plus aiguës passent au-dessus de l'audible et n'apportent plus rien. Et sur une note grave, une liste longue reste propre, alors que sur une note aiguë elle peut devenir criarde : baissez alors le lpf.

.phases([…]) décale le départ de chaque harmonique, de 0 à 6,28 (un tour complet). Cela ne change presque rien à l'oreille sur une note tenue, mais modifie la forme de l'onde et l'attaque. À réserver aux curieux.

note("c2 ~ c2 ~").s("user").partials([1, .6, .4, .3]).phases([0, 3.14, 0, 3.14]).decay(.5).sustain(.2).gain(.6)

12Effets

FonctionEffet
.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))

Ampli et pédales de guitare

Comme sur un pédalier, le son traverse les effets dans cet ordre : wah → fuzz → overdrive (shape) → ampli → baffle → phaser → chorus → trémolo. Le secret d'un gros son de guitare : des accords sur supersaw ou sawtooth, un ampli poussé, et le baffle qui retire les aigus qui grésillent.

FonctionEffet
.amp(0 à 1)ampli à lampes : 0 clair, 1 hard rock. Ajoute automatiquement un baffle
.ampbass(dB) .ampmid(dB) .amptreble(dB)boutons graves, médiums (le mordant), aigus, de −12 à +12
.cab(Hz)baffle (haut-parleur) : plus bas = son plus sombre ; 4500 par défaut
.fuzz(0 à 1)pédale fuzz : saturation extrême et granuleuse
.wah(0 à 1) .wahrate(Hz)wah-wah : position de la pédale ; ou qui bouge toute seule
.phaser(Hz) .phaserdepth(0 à 1)phaser : tourbillon qui balaie le son
.chorus(0 à 1)chorus : son doublé, qui flotte légèrement
.tremolo(Hz) .tremdepth(0 à 1)trémolo : le volume palpite
setcpm(30)
// Rythmique : ampli poussé, médiums en avant
$: note("<[[e2,b2,e3]@2 ~ [e2,b2,e3] [g2,d3,g3]@2 [a2,e3,a3]@2] [[c3,g3,c4]@3 [b2,f#3,b3] ~ [a2,e3,a3]@3]>")
  .s("supersaw").unison(3).detune(.06).amp(.8).ampmid(5).decay(.3).sustain(.6).gain(.7)
// Solo : wah automatique et une pointe de fuzz
$: note("<[b4@2 d5 e5@3 d5 b4] [g4@2 a4@2 b4@4]>").s("sawtooth").wah(.5).wahrate(1.5).fuzz(.35).amp(.5).delay(.3).gain(.5)
$: s("bd ~ [~ bd] ~, ~ sd ~ sd, hh*8")

Montage type : guitare électrique, son clair

Un son de guitare, c'est une chaîne : corde → pédales → ampli → baffle → effets de salle. Pour un son clair, l'ampli est à peine effleuré (amp entre .08 et .2) : c'est lui qui donne le côté « électrique » plutôt que synthétique.

setcpm(26)

// Guitare électrique, son clair
$: note("<[e3 b3 e4 g4] [c4 g4 c5 e5] [a2 e3 a3 c4] [d3 a3 d4 f4]>*2")
  .s("sawtooth").noise(.05)
  .lpf(3200).lpq(1.5)
  .amp(.14).ampbass(2).ampmid(-1).amptreble(3).cab(5200)
  .attack(.004).decay(.45).sustain(.3).release(.5)
  .chorus(.45).delay(.18).delaytime(.33).delayfeedback(.35).room(.35)
  .pan(.4).gain(1.1)

// Basse discrète
$: note("<e1 c2 a1 d2>*2").s("sine").lpf(500).decay(.3).sustain(.5).gain(.75)

// Batterie aux balais
$: s("bd ~ ~ ~ bd ~ ~ ~, ~ ~ sd ~ ~ ~ sd ~, hh*8").gain(.55).lpf(4500)
RéglageCe qu'il faitPour changer
s("sawtooth")la corde, riche en harmoniques (micro simple)triangle : plus doux, plus jazz
noise(.05)le bruit du médiator sur la corde.1 : attaque plus marquée
lpf(3200).lpq(1.5)arrondit les aigus, avec une légère bosse2400 plus chaud, 4000 plus cristallin
amp(.14)l'ampli juste effleuréau-delà de .3, ça croustille
ampbass / ampmid / amptrebleles trois boutons de tonalitéampmid(4) : plus nasillard, façon funk
cab(5200)le haut-parleur, qui enlève le grésillement4000 : plus sombre
attack … releasel'attaque du médiator, puis la corde qui s'éteintsustain(.6) : notes plus tenues
chorus(.45)le côté brillant et flottant0 sec, .8 très années 80
delay / rooml'écho et la salledelay(.35), room(.6) : très ambiant

Trois variantes du même montage

Funk : coups secs, médiums en avant, pas d'écho.

setcpm(30)
$: chord("<Am3 F3 C4 G3>").struct("x ~ x x ~ x ~ x").s("triangle")
  .lpf(2800).amp(.1).ampmid(5).cab(5000)
  .attack(.003).decay(.25).sustain(.2).release(.25).chorus(.5).room(.3).gain(1.05)
$: s("bd ~ ~ bd ~ ~ bd ~, ~ sd ~ sd, hh*16").gain(.6)

Surf : trémolo et grande réverb.

setcpm(28)
$: note("<e3 g3 a3 c4>*4").s("sawtooth").lpf(2600).amp(.12).cab(4800)
  .tremolo(5).tremdepth(.6).decay(.4).sustain(.4).release(.4).room(.5).gain(1.8)

Jazz : très rond, aucun effet, accords de septième.

setcpm(24)
$: chord("<Dm7 G7 Cmaj7 Cmaj7>").s("triangle").lpf(1800).amp(.08).cab(3600)
  .attack(.01).decay(.6).sustain(.3).release(.6).room(.25).gain(1)

Son grunge : le mur de guitares des années 90

La recette tient en cinq points : des power chords graves (chord("E5").add(-12)), une fuzz devant l'ampli poussé, des médiums creusés avec des graves et des aigus relevés, un baffle sombre, et surtout deux guitares légèrement désaccordées et décalées, une à gauche, une à droite. Le contraste couplet presque clair / refrain saturé fait le reste.

setcpm(25)
// Refrain : le mur de guitares (gauche)
$: chord("<E5 E5 G5 A5>").add(-12).struct("x@3 x x@3 x")
  .s("supersaw").unison(4).detune(.08).noise(.05)
  .hpf(110).lpf(3400).lpq(2.5).lpenv(2.5).lpdecay(.05)
  .fuzz(.5).shape(.5).amp(.95).ampbass(4).ampmid(-2).amptreble(4).cab(3400).crush(13)
  .attack(.001).decay(.22).sustain(.6).release(.12).pan(.25).room(.2).gain(.95)
// La même, doublée à droite : désaccord et décalage différents
$: chord("<E5 E5 G5 A5>").add(-12).struct("x@3 x x@3 x").late(.011)
  .s("supersaw").unison(4).detune(.12).noise(.05)
  .hpf(120).lpf(3100).lpq(2.5).lpenv(2.5).lpdecay(.05)
  .fuzz(.5).shape(.5).amp(.95).ampbass(4).ampmid(-2).amptreble(4).cab(3100).crush(13)
  .attack(.001).decay(.22).sustain(.6).release(.12).pan(.75).room(.2).gain(.95)
$: note("<e1*8 e1*8 g1*8 a1*8>").s("sawtooth").shape(.3).lpf(700).decay(.1).sustain(.7).gain(.85)
$: s("bd ~ ~ bd ~ ~ bd ~, ~ sd ~ sd, hh*8, <cr ~ ~ ~>").bank("909").gain(.8)
IngrédientÀ quoi ça sert
add(-12)descend l'accord d'une octave : les power chords sonnent bas
fuzz(.5) devant amp(.95)deux étages de saturation : c'est ce qui épaissit
ampmid(-2)médiums creusés, signature du son 90
lpenv(2.5).lpdecay(.05)un coup de filtre à chaque attaque : le médiator qui mord
noise(.05) et crush(13)le grain, la saleté
deux pistes, pan(.25) et pan(.75), late(.011)le mur stéréo : deux prises, jamais identiques

L'exemple « Rock — Grunge 90 » de l'éditeur enchaîne un couplet presque clair et ce refrain, avec arrange.

Pour le son saturé (crunch, hard rock), c'est le même montage avec amp entre .6 et 1, des médiums poussés, et un cab plus bas : voir l'exemple « Gros riff façon AC/DC » dans la liste des exemples de l'éditeur.

La position de la wah se programme comme n'importe quel réglage : .wah(sine.slow(2)) la fait monter et descendre sur deux cycles, note après note.

13Transformer un motif

FonctionEffet
.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))

Conditions : when et otherwise

every(4, rev) applique une transformation un cycle sur quatre. when va plus loin : il dit à quelles mesures une transformation s'applique, avec des mots-clés courts. Les mesures se comptent à partir de 1.

Mot-cléMesures concernées
even / oddpaires (2, 4, 6…) / impaires (1, 3, 5…)
%4une sur quatre : 1, 5, 9…
%4+2une sur quatre, décalée : 2, 6, 10…
5-8de la 5e à la 8e
9-à partir de la 9e
7seulement la 7e
1/3une fois sur trois, au hasard
even, 7la virgule veut dire « ou » : les paires ou la 7e

otherwise se place juste après et dit ce qui se passe les autres mesures. Sans lui, elles jouent le motif tel quel.

setcpm(30)
// Une mesure sur deux à l'envers, l'autre deux fois plus vite
$: n("0 2 4 7").scale("C4:minor").s("triangle")
  .when("even", rev).otherwise(fast(2))
  .decay(.3).gain(.5)
// La batterie se densifie à partir de la 5e mesure
$: s("bd ~ sd ~").when("5-", ply(2)).bank("909")

Le hasard, lui, dépend du numéro de mesure : « une fois sur trois » tombe toujours sur les mêmes mesures, donc le morceau sonne pareil à chaque écoute, dans le navigateur comme dans Godot.

setcpm(30)
$: s("hh*8").when("1/3", x => x.crush(4)).gain(.5)
$: s("bd ~ ~ bd ~ ~ bd ~, ~ sd ~ sd").bank("909")

En mode Blocs et en mode Nodes, ce sont deux blocs de la famille « Temps » : condition et sinon.

14Plusieurs 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)

Briques nommées : écrire une fois, réutiliser partout

Quand le même motif revient dans plusieurs pistes, on lui donne un nom : une brique. Une ligne qui commence par @nom: définit la brique ; elle ne joue pas toute seule. Ensuite, @nom la rappelle où l'on veut, et on peut continuer la chaîne derrière : @basse.fast(2).

setcpm(30)

// La brique : elle ne joue pas, elle attend qu'on l'appelle
@riff: note("c2 ~ [c2 eb2] g1").s("sawtooth").lpf(600).decay(.2)

// Basse
$: @riff

// La même, une octave plus haut et deux fois plus vite
$: @riff.add(12).fast(2).gain(.4)

// Batterie
$: s("bd ~ sd ~, hh*8")

Une brique peut en utiliser une autre, du moment qu'elle est définie plus haut dans le code. Le nom s'écrit sans espace ni accent (@refrain, @basse_2).

setcpm(32)
@accords: note("<[c3,eb3,g3] [ab2,c3,eb3]>").s("supersaw").attack(.2).gain(.3)
@couplet: stack(@accords, note("c2 ~ c2 g1").s("sawtooth").lpf(500))
$: arrange([2, @couplet], [2, @couplet.rev()])
$: s("bd ~ sd ~, hh*8")

En mode Blocs, une brique est une piste marquée d'une pastille @nom : le bouton brique transforme une piste en brique et inversement. Pour la réutiliser, ajoutez le bloc brique (famille Sources) en tête d'une piste et choisissez son nom dans la liste. En mode Nodes, le module brique (famille Structure) nomme ce qui y entre, et le bloc brique le rappelle ailleurs.

Différence avec let : une brique fait partie du langage. Elle se traduit en blocs et en modules, et fonctionne pareil dans Godot — let reste réservé au mode Code.

15Morceaux longs : enchaîner des sections

Avec < >, on écrit plusieurs mesures d'affilée (voir Durées). Pour un vrai morceau, on découpe plutôt en sections (couplet, refrain, pont…) écrites séparément, puis on les enchaîne avec arrange : chaque section est jouée pendant le nombre de cycles (de mesures) indiqué, puis la suivante, et tout recommence.

arrange([2, couplet], [2, refrain]) : le couplet pendant 2 mesures, le refrain pendant 2 mesures, soit une boucle de 4 mesures. Une section de plusieurs mesures (écrite avec < >) se déroule normalement : elle ne recommence pas à chaque mesure.

setcpm(32)
$: arrange(
  [2, n("<[0 2 4 2] [0 2 4 7]>")],
  [2, n("<[5 4 2 0] [4 2 1 -1]>")]
).scale("C4:minor").s("triangle").room(.3)
$: s("bd ~ sd ~, hh*8")
FonctionCe qu'elle faitChaque élément dure
cat(a, b)a, puis b, puis a…1 cycle
arrange([n, a], [m, b])a pendant n cycles, puis b pendant mce que vous choisissez
seq(a, b)a et b serrés dans un seul cycleune fraction de cycle
stack(a, b)a et b en même temps—

Astuce : une section peut elle-même être un stack (mélodie + accords), et chaque piste $: peut avoir son propre arrange, du moment que les longueurs totales tombent juste.

setcpm(30)
// Couplet (4 mesures) puis refrain (4 mesures), la basse suit
$: arrange(
  [4, note("<[c4,e4,g4] [a3,c4,e4] [f3,a3,c4] [g3,b3,d4]>").s("supersaw").attack(.1).release(.4).gain(.3)],
  [4, note("<[f3,a3,c4] [g3,b3,d4] [e3,g3,b3] [a3,c4,e4]>").s("supersaw").attack(.1).release(.4).gain(.35)]
).room(.4)
$: arrange([4, note("<c2*4 a1*4 f1*4 g1*4>")], [4, note("<f1*4 g1*4 e1*4 a1*4>")]).s("sawtooth").lpf(600)
$: s("bd*2 [~ bd] ~, ~ sd, hh*8")

16Depuis une partition

  1. Tonalité : comptez les dièses ou bémols à la clé. Trois bémols = mi♭, la♭, si♭ partout (do mineur ou mi♭ majeur).
  2. Notes : en clé de sol, la ligne du bas est e4, le do sous la portée est c4.
  3. Rythme : choisissez une grille (8 croches en 4/4), puis une mesure par crochets avec @ pour les notes longues (voir Durées).
  4. Tempo : BPM ÷ temps par mesure → setcpm.
  5. 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)
Les chansons récentes sont protégées par le droit d'auteur : transcrire leur mélodie pour la publier (dans la galerie par exemple) n'est pas permis sans autorisation. Les grilles d'accords courantes et les airs anciens du domaine public (classique, folklore) sont libres.

17Écouter en faisant autre chose

La lecture continue quand vous changez d'onglet ou réduisez la fenêtre : nutsthis programme alors le son plus loin d'avance, parce qu'un onglet masqué n'est réveillé qu'une fois par seconde. Les touches lecture/pause du clavier commandent la page, et l'onglet affiche le petit haut-parleur.

Si vous préférez que le son s'arrête dès que vous partez, décochez Réglages › Lecture › Continuer à jouer quand l'onglet est masqué : la lecture se met en pause et reprend à votre retour.

Barre d'espace : pause et reprise au même endroit, tant que vous n'êtes pas en train d'écrire dans l'éditeur ou dans un champ. Le bouton ▶, lui, repart du début. Ctrl+Entrée réévalue le code sans couper le son.

Fermer l'onglet coupe toujours le son : aucun son ne peut continuer après la fermeture de la page. Aucune extension à installer, et ça marche dans Chrome, Firefox, Edge et Safari.

18Blocs 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

FonctionRô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.