1 - Bienvenue Ami :-)

Bienvenue à Sonic Pi. Heureusement vous êtes excité pour commencer à faire des sons délirants comme je le suis pour vous le montrer. Ça va être réellement un parcours amusant où vous allez tout apprendre de la musique, de la synthèse, de la programmation, de l’interprétation et plus encore.

Mais attendez, comme je suis impoli ! Je me présente. Je suis Sam Aaron - le gars qui a créé Sonic Pi. Vous pouvez me joindre à @samaaron sur Twitter et je serai plus qu’heureux de vous saluer. Vous pourriez aussi être intéressé par mon orchestre “Live Coding” Meta-eX où j’interprète de la musique avec du code devant un public. Vous pouvez trouver un de mes morceaux Meta-eX dans les exemples.

Si vous avez des observations ou des idées pour améliorer Sonic Pi - Faîtes m’en part s’il vous plait - les retours sont tellement utiles. Vous ne le savez probablement pas, mais votre idée pourrait être la prochaine fonctionnalité importante !

Finalement, ce tutoriel est divisé en sections groupées par catégories. Même si je l’ai écrit pour avoir une progression d’apprentissage facile du début jusqu’à la fin, sentez-vous vraiment libre de plonger dans l’une ou l’autre section comme cela vous convient. Si vous pensez qu’il manque quelque chose, n’hésitez pas à me le faire savoir et je le prendrai en compte dans une prochaine version.

OK, démarrons…


1.1 - Codage en “Live”

Un des aspects les plus passionnants de Sonic Pi est qu’il vous permet d’écrire et de modifier du code en “live” pour faire de la musique, juste comme si vous jouiez de la guitare. Cela veut dire qu’au moyen de quelque expérience, vous pouvez prendre Sonic PI sur scène et jouez avec.

Libérez vos méninges

Avant que vous ne plongiez dans les détails réels du fonctionnement de Sonic Pi dans la suite de ce tutoriel, j’aimerais vous faire part d’une expérience montrant à quoi ressemble le code en “live”. Ne vous inquiétez pas si vous ne comprenez pas beaucoup ou rien de ceci. Essayez juste de rester assis sur votre siège et de profiter…

Une boucle en “live”

Démarrons, copiez le code suivant dans un “buffer” libre :

live_loop :flibble do
  sample :bd_haus, rate: 1
  sleep 0.5
end

Maintenant, pressez le bouton Run et vous entendrez un joli battement de grosse caisse. Si vous souhaitez arrêter le son à un moment quelconque, pressez simplement le bouton Stop. Plutôt, ne le pressez pas encore… A la place, suivez les étapes suivantes :

  1. Assurez-vous que le son de la grosse caisse est encore présent
  2. Changez la valeur de sleep de 0.5 à quelque chose plus élevé comme 1
  3. Pressez à nouveau le bouton Run
  4. Remarquez le changement de vitesse de la batterie
  5. Finalement, rappelez-vous de cet instant, c’est la première fois que vous avez codé en “live” avec Sonic Pi et ce n’est certainement pas la dernière…

Ok, c’était assez simple. Ajoutons quelque chose au mixage. Au dessus de sample :bd_haus ajoutez la ligne sample :ambi_choir, rate: 0.3. Votre code devrait ressembler à ceci :

live_loop :flibble do
  sample :ambi_choir, rate: 0.3
  sample :bd_haus, rate: 1
  sleep 1
end

Maintenant, exécutez-le. Changez les “rates” - Que se passe-t-il lorsque vous utilisez des valeurs élevées ou des valeurs négatives ? Regardez ce qui se passe quand vous changez légèrement la valeur de rate: pour l’échantillon :ambi_choir (disons 0.29). Que se passe-t-il lorsque vous choisissez une valeur véritablement petite de sleep ? Regardez si vous arrivez à le faire aller si vite au point que votre ordinateur s’arrêtera avec une erreur parce que ne pouvant plus continuer comme cela (si cela arrive, choisissez juste une durée sleep plus grande et pressez Run à nouveau).

Essayez de commenter une des lignes sample en ajoutant un # au début :

live_loop :flibble do
  sample :ambi_choir, rate: 0.3
#  sample :bd_haus, rate: 1
  sleep 1
end

Remarquez comment cela indique à l’ordinateur de l’ignorer, ainsi nous ne l’entendons pas. On l’appelle commentaire. Dans Sonic Pi, nous pouvons utilisez des commentaires pour enlever ou additionner des choses au mixage.

Finalement, je vous laisse avec quelque chose de sympa à jouer. Prenez le code ci-dessous et copiez-le dans un autre “buffer”. Maintenant essayez de le comprendre bien plus que de voir qu’il y a deux boucles - ainsi deux choses marchent en même temps. Maintenant, faites ce que vous faites le mieux - expérimenter et jouez. Voici quelques suggestions :

Rappelez-vous de presser Run et vous entendrez le changement la fois suivante où la boucle tournera. Si vous êtes dans le pétrin, ne vous inquiétez pas - pressez Stop, effacez le code dans le “buffer”, collez une copie originale et vous serez prêt à improviser à nouveau. En faisant des fautes, c’est ainsi que vous apprendrez le plus vite…

live_loop :guit do
  with_fx :echo, mix: 0.3, phase: 0.25 do
    sample :guit_em9, rate: 0.5
  end
#  sample :guit_em9, rate: -0.5
  sleep 8
end

live_loop :boom do
  with_fx :reverb, room: 1 do
    sample :bd_boom, amp: 10, rate: 1
  end
  sleep 8
end

Maintenant, continuez à jouer et à expérimenter jusqu’à ce que votre curiosité sur comment ça fonctionne s’avive réellement et vous commencerez à vous demander quoi d’autre puis-je faire avec ceci. Vous êtes maintenant prêt à lire le reste du tutoriel.

Aussi, qu’attendez-vous…


1.2 - L’Interface de Sonic Pi

Sonic Pi a une interface très simple pour coder de la musique. Passons un peu de temps à l’explorer. Sonic Pi Interface

A. Contrôles de jeu

Ces boutons roses sont les principaux contrôles pour démarrer et arrêter les sons. Il y a le bouton Run pour exécuter le code présent dans l’éditeur, Stop pour arrêter tous les codes en cours d’exécution, Save pour sauvegarder le code dans un fichier externe et Record pour créer un enregistrement du son (un fichier WAV) en cours de jeu.

B. Contrôles d’édition

Ces boutons oranges vous permettent de piloter l’éditeur de code. Les boutons Size + et Size - vous permettent d’agrandir ou de rétrécir le texte. Le bouton Align vous arrangera votre code pour lui donner une présentation plus professionnelle.

C. Info, Help et Prefs

Ces boutons bleus vous donnent accès à l’information, à l’aide et aux préférences. Le bouton Info ouvre la fenêtre d’information qui contient de l’information sur Sonic Pi lui-même - le noyau de l’équipe, l’historique, les contributeurs, et la communauté. Le bouton Help active le système d’aide (G) et le bouton Prefs active la fenêtre des préférences qui vous permet de contrôler quelques paramètres systèmes basiques.

D. Éditeur de code

C’est une zone dans laquelle vous écrirez votre code et composerez / interpréterez de la musique. C’est un simple éditeur de texte où vous pourrez écrire votre code, l’effacer, couper et coller, etc. Pensez à lui comme à une version très basique de Word ou de Google Docs. L’éditeur coloriera automatiquement les mots selon leur signification dans le code. Ceci peut paraître étrange au début, mais vous le trouverez vite très utile. Par exemple, vous saurez que quelque chose est un nombre parce qu’elle sera bleue.

E. Panneau des préférences

Sonic Pi supporte quelques préférences ajustables qui peuvent être accédées en pressant le bouton Prefs à droite des boutons Info et Help. Cela activera l’affichage du panneau des préférences qui inclut un nombre d’options modifiables. Par exemple pour forcer le mode mono, inverser la stéréo, activer le mode verbeux de la trace et aussi régler un curseur de volume et le sélecteur audio du Raspberry Pi (par défaut, il est sur “auto”. Si vous n’entendez plus le son de votre Pi en étant branchés sur la prise jack, modifiez ce paramètre).

F. Visualisateur de la trace

Quand vous exécutez votre code, l’information sur ce que le programme est en train de faire est affichée dans le visualisateur de la trace. Par défaut, vous verrez un message pour chaque son que vous créez avec l’heure exacte à laquelle le son a été déclenché. C’est très utile pour déboguer votre code et comprendre ce qu’il fait.

G. Système d’aide

Finalement, un des aspects les plus importants de l’interface de Sonic Pi est le système d’aide qui apparaît au bas de la fenêtre. Il peut être activé ou désactivé en cliquant sur le bouton Help bleu. Le système d’aide contient de l’aide et de l’information sur tous les aspects de Sonic Pi, y compris ce tutoriel, une liste des synthétiseurs, des échantillons (“samples”), des exemples, et des effets (“FX”) disponibles, et une liste complète de toutes les fonctions que Sonic Pi fournit pour coder de la musique.


1.3 - Apprendre en jouant

Sonic Pi vous encourage à apprendre à la fois sur la programmation et sur la musique au travers du jeu et de l’expérimentation. La plus importante chose est que vous vous amusiez, et avant que vous vous en rendiez compte, vous aurez appris comment coder, composer et interpréter sans le faire exprès.

Il n’y a pas de fautes

Alors que nous abordons ce sujet, laissez-moi vous donner un petit conseil. J’ai appris pendant des années à coder de la musique en “live” - il n’y a pas de fautes, seulement des opportunités. C’est ce que j’ai souvent entendu à propos du jazz mais cela fonctionne aussi avec le codage en “live”. Peu importe votre niveau d’expérience - du débutant complet jusqu’à “l’algoraver” (codeur de musique) chevronné, vous exécuterez un jour un code qui aura une sortie totalement inattendue. Cela pourrait sonner extrêmement “cool” - auquel cas continuez avec. Toutefois, cela pourrait aussi sonner discordant et à côté de la plaque. Peu importe ce qui se passe - ce qui importe est ce que vous allez faire avec ensuite. Prenez le son, manipulez-le et transformez-le en quelque chose de génial. Le public deviendra déchaîné.

Commencez simple

Quand vous apprenez, il est tentant de vouloir faire des choses étonnantes immédiatement. Cependant, conservez l’idée et voyez-la comme un but distant à atteindre plus tard. Pour l’instant, pensez à la chose la plus simple que vous pourriez écrire qui serait amusante et gratifiante, c’est un petit pas vers la chose étonnante que vous avez en tête. Une fois que vous avez l’éclairage sur cette simple étape, essayez de la construire, jouez avec et pensez aux nouvelles idées que cela vous donne. Sous peu, vous serez trop occupé à vous amuser et à faire de réels progrès.

Assurez-vous simplement de partager votre travail avec les autres !


2 - Synthétiseurs

OK, assez d’introduction, plongeons dans les sons.

Dans cette section, nous allons couvrir les bases du déclenchement et de la manipulation des “synths”. “Synth” ou “synthé” sont les abréviations de synthétiseur, lequel est un mot fantaisiste pour quelque chose qui crée des sons. Typiquement, les synthétiseurs sont assez compliqués à utiliser - particulièrement les synthés analogiques avec beaucoup de “patches” et de modules à connecter. Toutefois, Sonic Pi vous offre beaucoup de cette puissance d’une manière très simple et abordable.

Ne soyez pas dupe de l’immédiate simplicité de l’interface de Sonic Pi. Vous pouvez aller très en profondeur dans une manipulation très sophistiquée des sons si c’est votre dada. Tenez bien vos chapeaux…


2.1 - Vos premiers Beeps

Jetez un œil sur le code suivant :

play 70

C’est là que tout commence. Allez de l’avant, copiez et collez-le dans la fenêtre de code en haut de l’application (le grand espace blanc en dessous du bouton Run). Maintenant, pressez Run…

Beep!

Intense. Pressez-le une nouvelle fois. Et encore. Et encore…

Woah, fou, je suis sûr que vous pourrez continuer à faire cela toute la journée. Mais attendez, avant que vous ne vous perdiez dans un flot infini de beeps, essayez de changer le nombre :

play 75

Entendez-vous la différence ? Essayez un nombre plus petit :

play 60

Ainsi, des nombres plus petits font des beeps plus grave et des nombres plus grands font des beeps plus aigus. Juste comme sur un piano, les touches de la partie basse (côté main gauche) font des notes plus graves et celles de la partie haute (côté main droite) font des notes plus aiguës. En fait, les nombres représentent réellement l’ordre des notes sur le piano. play 47 signifie réellement “joue la 47ème note” sur le piano. Ce qui signifie que play 48 désigne la note supérieure (la note suivante vers la droite). Il faut juste noter que le 4ème octave du Do (C en notation anglaise) est identifié par le nombre 60. Poursuivez et jouez-le : play 60

Ne vous inquiétez pas si cela ne signifie rien pour vous - c’est ce qu’il m’est arrivé au début quand j’ai commencé. Tout ce qui importe maintenant est que vous sachiez que les petits nombres font des beeps graves et que les grands nombres font des beeps aigus.

Accords

Jouez une note est vraiment plaisant, mais en jouer plusieurs en même temps est encore mieux. Essayez-le :

play 72
play 75
play 79

Jazzy ! Ainsi quand vous écrivez plusieurs plays, ils sont tous joués en même temps. Essayez-le vous-même - quels sont les nombres qui sonnent bien ensemble ? Lesquels sonnent terrible ? Expérimentez, explorez et trouvez ce qui est bien pour vous.

Mélodie

Ainsi, jouer des notes et des accords est plaisant - mais comment jouer une mélodie ? Que faire si vous voulez jouer une note après une autre et pas en même temps ? Eh bien, c’est facile, vous avez juste besoin de sleep entre les notes :

play 72
sleep 1
play 75
sleep 1
play 79

Comme c’est charmant, un petit arpège. Alors que signifie le 1 dans sleep 1 ? Eh bien, cela représente la durée du sleep. Ça signifie réellement “dors pendant un temps musical”, mais pour l’instant nous pouvons penser qu’il s’agit de dormir pendant 1 seconde. Alors que faire si nous voulons que notre arpège soit un peu plus rapide ? Eh bien, nous devons utiliser des valeurs de sleep plus petites. Quel résultat pour la moitié, c’est-à-dire 0.5 :

play 72
sleep 0.5
play 75
sleep 0.5
play 79

Remarquez comment ça joue plus rapidement. Maintenant, essayez vous-même, changez les durées - utilisez différentes durées et différentes notes.

Une chose à essayer est les notes intermédiaires comme play 52.3 et play 52.63. Il n’est absolument pas nécessaire de coller aux notes standardisées. Jouez et faites-vous plaisir.

Les noms traditionnels des notes

Ceux qui connaissent déjà la notation musicale (ne vous inquiétez pas si ce n’est pas votre cas - vous n’en n’avez pas besoin pour vous amuser) pourraient aimer écrire une mélodie en utilisant les noms des notes comme “Do” ou “Fa#” plutôt que des nombres. Sonic Pi a ce qu’il faut, mais en notation anglaise (A pour “La”, B pour “Si”, C pour “Do”, D pour “Ré”, E pour “Mi”, F pour “Fa”, G pour “Sol”). Vous pouvez faire la chose suivante :

play :C
sleep 0.5
play :D
sleep 0.5
play :E

Notez de mettre des deux-points : devant votre nom de note de manière qu’elle apparaisse en rose. Vous pouvez également spécifier l’octave en ajoutant un nombre derrière le nom de la note :

play :C3
sleep 0.5
play :D3
sleep 0.5
play :E4

Si vous voulez faire un dièse, ajoutez un s (pour “sharp”) derrière le nom de la note, comme play :Fs3 et si vous vouler faire un bémol, ajoutez un b comme play :Eb3.

Maintenant défoulez-vous et faites-vous plaisir en faisant vos morceaux.


2.2 - Paramètres des synthés : Amp and Pan

De la même manière qu’il vous permet de contrôler chaque note ou chaque échantillon à jouer, Sonic Pi fournit un large éventail de paramètres pour confectionner ou contrôler les sons. Nous couvrirons beaucoup d’entre eux dans ce tutoriel et il y a une documentation exhaustive pour chacun d’eux dans le système d’aide. Toutefois pour l’instant, nous allons introduire deux des plus utiles : amplitude et pan. Regardons en premier ce que les paramètres sont réellement.

Paramètres

Sonic Pi supporte la notion de paramètres pour ses synthés. Les paramètres sont des informations de contrôle que vous passez à play et qui modifient et contrôlent les aspects du son que vous entendez. Chaque synthé a son propre jeu de paramètres pour ajuster finement ses sons. Cependant, il y a un ensemble commun de paramètres partagés par beaucoup de sons comme amp: et les paramètres d’enveloppe (couverts dans une autre section).

Les paramètres ont deux parties principales, leur nom (le nom du contrôle) et leur valeur (la valeur que vous voulez affecter au contrôle). Par exemple, vous pourriez avoir un paramètre appelé cheese: et vouloir lui affecter la valeur 1.

Les paramètres sont passés aux appels à play en utilisant une virgule , et ensuite le nom du paramètre comme amp: (n’oubliez pas les deux-points :) et ensuite un espace et la valeur du paramètre. Par exemple :

play 50, cheese: 1

(Notez que cheese: n’est pas un paramètre valide, il est juste utilisé pour l’exemple).

Vous pouvez passer plusieurs paramètres en les séparant par une virgule :

play 50, cheese: 1, beans: 0.5

L’ordre des paramètres n’est pas imposé, ainsi, ce qui suit est identique :

play 50, beans: 0.5, cheese: 1

Les paramètres qui ne sont pas reconnus par le synthé sont simplement ignorés (comme cheese et beans qui sont clairement des noms de paramètres ridicules !)

Si vous utilisez accidentellement 2 fois le même paramètre avec des valeurs différentes, la dernière gagne. Par exemple, beans: aura ici la valeur 2 plutôt que 0.5 :

play 50, beans: 0.5, cheese: 3, eggs: 0.1, beans: 2

Beaucoup de choses dans Sonic Pi acceptent des paramètres, aussi passez un peu de temps à apprendre comment les utiliser et vous serez au point ! Jouons avec notre premier paramètre : amp:.

Amplitude

L’amplitude est la représentation informatique du volume d’un son. Une amplitude élevée produit un son fort et une amplitude basse produit un son faible. A la manière dont Sonic Pi utilise des nombres pour représenter les durées et les notes, des nombres sont aussi utilisés pour représenter l’amplitude. Une amplitude 0 est le silence (vous n’entendez rien) tandis qu’une amplitude de 1 désigne le volume normal. Vous pouvez monter l’amplitude à 2, 10, 100. Toutefois, vous devez noter que lorsque l’amplitude globale de tous les sons devient trop élevée, Sonic Pi utilise ce qui est appelé un compresseur pour l’aplatir, de manière à s’assurer que le volume ne soit pas trop fort pour vos oreilles. Cela peut fréquemment rendre le son distordu et étrange. Aussi essayez d’utiliser des amplitudes basses, c’est-à-dire dans l’intervalle 0 à 0.5 pour éviter la compression.

Amp-ez le

Pour changer l’amplitude d’un son, vous pouvez utiliser le paramètre amp:. Par exemple, pour jouer à moitié amplitude, passez 0.5 :

play 60, amp: 0.5

Pour jouer à double amplitude, passez 2 :

play 60, amp: 2

Le paramètre amp: ne modifie que l’appel au play auquel il est associé. Aussi, dans l’exemple suivant, le premier appel à play est à moitié volume et le second revient à la valeur par défaut (1) :

play 60, amp: 0.5
sleep 0.5
play 65

Bien entendu, vous pouvez utiliser différentes valeurs de amp: pour chaque appel à play :

play 50, amp: 0.1
sleep 0.25
play 55, amp: 0.2
sleep 0.25
play 57, amp: 0.4
sleep 0.25
play 62, amp: 1

Balance stéréo

Un autre paramètre agréable à utiliser est pan: qui contrôle la balance du son en stéréo. Balancer un son vers la gauche signifie que votre oreille va l’entendre sortir du haut-parleur de gauche, et le balancer vers la droite que vous l’entendrez sortir par le haut-parleur de droite. Pour nos valeurs, nous utilisons -1 pour représenter complètement à gauche, 0 pour représenter le centre et 1 pour représenter complètement à droite dans le champ stéréo. Bien entendu, vous êtes libre d’utiliser toute valeur entre -1 et 1 pour contrôler le positionnement précis de votre son.

Jouons un beep à destination du haut-parleur de gauche :

play 60, pan: -1

Maintenant, jouons-le à destination du haut-parleur de droite :

play 60, pan: 1

Finalement, jouons-le à destination du centre des deux (la position par défaut) :

play 60, pan: 0

Maintenant, allez et prenez plaisir à changer l’amplitude et la balance de vos sons !


2.3 - Changement de synthés

Jusqu’à maintenant, nous nous sommes bien amusés à faire des beeps. Cependant, vous commencez probablement à être ennuyé par le bruit basique du beep. Sonic Pi n’a-t-il que cela à offir en tout et pour tout ? Il y a certainement plus dans le codage en “live” que de jouer seulement des beeps. Oui, et dans cette section nous allons explorer l’étendue des sons que Sonic Pi a à offrir.

Synthés

Sonic Pi dispose d’un lot d’instruments qu’il appelle synths raccourci pour synthétiseurs. Tandis que les échantillons (samples) représentent des sons pré-enregistrés, les synthés (synths) sont capables de générer des nouveaux sons en fonction de la façon dont vous les contrôlez (ce que nous explorerons plus tard dans ce tutoriel). Les synthés de Sonic Pi sont très puissants et expressifs, et vous aurez grand plaisir à les explorer et à jouer avec. En premier lieu, apprenons à sélectionner le synthé en cours à utiliser.

Dents de scie vibrantes et prophets

Un son sympathique est l’onde en dent de scie (saw) - essayons-le :

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
play 62
sleep 0.25

Essayons un autre son - le prophet :

use_synth :prophet
play 38
sleep 0.25
play 50
sleep 0.25
play 62
sleep 0.25

Comment combiner deux sons. D’abord l’un après l’autre :

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
use_synth :prophet
play 57
sleep 0.25

Maintenant en même temps :

use_synth :tb303
play 38
sleep 0.25
use_synth :dsaw
play 50
sleep 0.25
use_synth :prophet
play 57
sleep 0.25

Notez que la commande use_synth n’agit que sur les appels suivants à play. Pensez à elle comme un gros commutateur - les nouveaux appels à play vont jouer tout synthé qui est désigné “en cours”. Vous pouvez enclencher le commutateur sur un nouveau synthé avec use_synth.

Découverte des synthés

Pour voir quels synthés Sonic Pi met à votre disposition pour jouer, jetez un œil sur les options de Synths dans le menu horizontal tout à fait en bas (à gauche de Fx). Il y en a 33 au choix. Voici mes préférés :

Maintenant jouez en commutant les synthés au cours de votre jeu. Prenez plaisir à combiner des synthés pour faire de nouveaux sons et aussi en untilisant différents synthés selon les sections de votre musique.


2.4 - Durées avec enveloppes

Dans une section précédente, nous avons vu comment nous pouvions utiliser la commande sleep pour contrôler le moment du déclenchement de nos sons. Toutefois, nous n’avons pas encore été capables de contrôler la durée des sons.

Dans le but de nous offrir des moyens simples mais puissants de contrôle de durée de nos sons, Sonic Pi fournit la technique d’enveloppe d’amplitude ADSR (nous expliquerons ce que ADSR signifie plus loin dans cette section). Une enveloppe d’amplitude offre deux moyens utiles de contrôle :

Durée

La durée est le temps pendant lequel le son se maintient. Une longue durée signifie que vous entendez le son plus longtemps. Les sons de Sonic Pi ont tous une enveloppe d’amplitude, et la durée totale de cette enveloppe est la durée du son. Ainsi, en contrôlant l’enveloppe, vous contrôlez la durée.

Amplitude

L’enveloppe ADSR non seulement contrôle la durée, mais vous donne aussi un contrôle fin sur l’amplitude du son. Tous les sons commencent et finissent par le silence, avec une part non silencieuse entre. Les enveloppes vous permettent de faire évoluer ou de maintenir l’amplitude des parties non-silencieuses du son. C’est comme si vous donniez à quelqu’un des instructions sur comment augmenter ou diminuer le volume d’une musique. Par exemple, vous pourriez demander à quelqu’un de commencer en silence, d’augmenter lentement le volume jusqu’au maximum, le maintenir un moment, puis revenir rapidement au silence. Sonic Pi vous permet de programmer ceci avec les enveloppes.

Comme nous l’avions vu dans une section précédente, une amplitude de 0 est le silence et une amplitude de 1 est le volume normal.

Durée d’extinction (Release)

Par défaut, tous les synthés ont une durée de “release” de 1. Ce qui signifie qu’ils ont une durée d’un temps musical (qui par défaut est 1 seconde) avant extinction. Nous pouvons changer cette durée en passant l’argument release: à nos appels à play. Par exemple, pour faire jouer un synthé pendant 2 temps, nous spécifions un release: de 2:

play 60, release: 2

Nous pouvons faire jouer un synthé pendant une très courte durée en utilisant une durée de “release” très petite :

play 60, release: 0.2

Ainsi, qu’est-ce que la durée de “release” ? C’est la durée que prend le son pour passer de l’amplitude totale (typiquement une valeur de 1) à l’amplitude 0. C’est appelé la phase d’extinction et c’est une transition linéaire (une courbe en ligne droite). Le schéma suivant illustre cette transition :

release envelope

La ligne verticale à gauche du schéma montre que le son part de l’amplitude 0, mais monte jusqu’à l’amplitude totale immédiatement (c’est la phase d’attaque que nous couvrirons en suivant). Une fois à l’amplitude totale, il évolue en ligne droite jusqu’à zéro en prenant le temps spécifié par release:. Des durées de “release” longues produisent des fondus d’extinction de synthé longs.

Vous pouvez ainsi changer la durée de vos sons en changeant la durée d’extinction. Jouez un moment en ajoutant des durées de “release” à votre musique.

Durée d’Attaque

Par défaut, la phase d’attaque est fixée à 0 pour tous les synthés, ce qui signifie qu’ils évoluent de l’amplitude 0 à l’amplitude 1 immédiatement. Cela donne initialement au synthé un son percussif. Toutefois, vous pouvez souhaiter une montée progressive de votre son. Ceci peut être obtenu avec l’argument attack:. Essayez des montées progressives de quelques sons :

play 60, attack: 2
sleep 3
play 65, attack: 0.5

Vous pouvez utiliser des arguments multiples en même temps. Par exemple, pour une attaque courte et une lente extinction, essayez :

play 60, attack: 0.7, release: 4

Cette courte attaque et cette lente extinction sont illustrées dans le schéma suivant :

attack release envelope

Bien entendu, vous pouvez inverser les choses. Essayez une attaque longue et une exctinction rapide :

play 60, attack: 4, release: 0.7

long attack short release envelope

Finalement, vous pouvez aussi avoir à la fois une attaque et une exctinction rapides pour des sons plus courts :

play 60, attack: 0.5, release: 0.5

short attack short release envelope

Durée de soutien (“Sustain”)

En plus de spécifier des durées d’attaque et d’extinction, vous pouvez aussi spécifier une durée de soutien. C’est la durée pendant laquelle le son est maintenu à l’amplitude totale entre les phases d’attaque et d’extinction.

play 60, attack: 0.3, sustain: 1, release: 1

ASR envelope

La durée de soutien est utile pour des sons importants auxquels vous voulez donner une présence permanente dans le mixage avant d’entrer dans une optionnelle phase d’extinction. Bien entendu, c’est entièrement valide de fixer à la fois les arguments d’attaque et d’extinction à 0 et d’utiliser seulement le soutien pour n’avoir absolument pas de montée et d’extinction progressives. Cependant, faites attention, une durée d’extinction de 0 peut produire des clics dans l’écoute et c’est souvent mieux d’utiliser une très petite valeur comme 0.2.

Durée de déclin (“Decay”)

Finalement, pour les cas où vous aurez besoin d’un niveau de contrôle supplémentaire, vous pourrez aussi spécifier une durée de déclin. C’est la phase de l’enveloppe qui s’intercale entre les phases d’attaque et de soutien et qui spécifie la durée pendant laquelle l’amplitude va descendre du niveau attack_level jusqu’au niveau sustain_level. Par défaut, l’argument “decay” est à 0 et à la fois les niveaux “attack” et “sustain” sont à 1. Ainsi vous aurez besoin de les spécifier en plus de la durée de déclin pour obtenir un effet :

play 60, attack: 0.1, attack_level: 1, decay: 0.2, sustain_level: 0.4, sustain: 1, release: 0.5

ADSR envelope

Enveloppes ADSR

Ainsi pour résumer, les enveloppes de Sonic Pi ont les phases suivantes :

  1. attack - durée de passage de l’amplitude 0 jusqu’au niveau attack_level,
  2. decay - durée pour passer l’amplitude du niveau attack_level jusqu’au niveau sustain_level,
  3. sustain - durée pour maintenir l’amplitude au niveau sustain_level,
  4. release - durée pour passer l’amplitude du niveau sustain_level au niveau 0

Il est important de noter que la durée d’un son est la somme des durées de chacune de ces phases. Ainsi le son suivant aura une durée de 0.5 + 1 + 2 + 0.5 = 4 temps musicaux :

play 60, attack: 0.5, decay: 1, sustain_level: 0.4, sustain: 2, release: 0.5

Maintenant, allez et jouez un moment en ajoutant des enveloppes à vos sons.


3 - Échantillons (“Samples”)

Un autre grand moyen de développer votre musique est d’utiliser des sons pré-enregistrés. Dans la grande tradition hip-hop, on appelle ces sons pré-enregistrés samples. Aussi, si vous prenez un micro à l’extérieur, et allez enregistrer le son de la pluie frappant une toile, vous avez tout simplement créé un “sample”.

Sonic Pi vous offre des tas de choses amusantes à faire avec les “samples”. Non seulement il est livré avec plus de 90 échantillons du domaine public, prêts pour faire un boeuf, mais il vous permet de jouer et de manipuler les vôtres propres. Allons voir…


3.1 - Lecture des échantillons

Jouer des beeps est seulement un début. Une chose qui est très plaisante est de déclencher des échantillons pré-enregistrés. Essayez-le :

sample :ambi_lunar_land

Sonic Pi inclut beaucoup d’échantillons à jouer. Vous pouvez les utiliser juste comme vous utilisez la commande play. Pour jouer des échantillons et des notes multiples, écrivez-les simplement les uns après les autres :

play 36
play 48
sample :ambi_lunar_land
sample :ambi_drone

Si vous voulez les espacer dans le temps, utilisez la commande sleep :

sample :ambi_lunar_land
sleep 1
play 48
sleep 0.5
play 36
sample :ambi_drone
sleep 1
play 36

Notez que Sonic Pi n’attend pas la fin d’un son pour démarrer le suivant. La commande sleep décrit uniquement la séparation du déclenchement des sons. Ceci vous permet de superposer les sons en couches en créant d’intéressants effets de chevauchement. Plus tard dans ce tutoriel, nous jetterons un œil sur le contrôle de la durée de ces sons avec des enveloppes.

Découverte des échantillons

Il y a deux manière de découvrir l’étendue des échantillons fournis par Sonic Pi. En premier lieu, on peut utiliser le système d’aide. Cliquez sur “Échantillons” dans le menu horizontal du bas, choisissez votre catégorie et vous verrez une liste des sons disponibles.

Alternativement, vous pouvez utiliser le système d’auto-complétion. Tapez simplement le début d’un groupe d’échantillons comme : sample :ambi_ et vous verrez apparaître une liste de noms d’échantillons qui vous permettra d’en sélectionner un. Essayez les préfixes de catégorie suivants :

Maintenant commencez à introduire des échantillons dans vos compositions !


3.2 - Paramètres des échantillons : Amp et Pan

Comme nous l’avons vu avec les synthés, nous pouvons aisément contrôler nos sons avec des paramètres. Les “Samples” supportent exactement le même mécanisme de paramètrage. Revisitons nos amis amp: et pan:.

Amplitude des échantillons

Vous pouvez changer l’amplitude des échantillons avec exactement la même approche que vous avez utilisée pour les synthés :

sample :ambi_lunar_land, amp: 0.5

Balance des échantillons

Nous pouvons aussi utiliser le paramètre pan: avec les échantillons. Par exemple, voici comment nous jouerions l’amen au début vers la droite, puis à motié parcours, vers la gauche :

sample :loop_amen, pan: -1
sleep 0.877
sample :loop_amen, pan: 1

Notez que 0.877 est la moitié de la durée en secondes de l’échantillon :loop_amen.

Finalement, notez que si vous fixez des valeurs par défaut avec use_synth_defaults (que nous détaillerons plus tard), ils seront ignorés par sample.


3.3 - Étirement des échantillons

Maintenant que nous pouvons jouer une variété de synthés et d’échantillons pour créer une musique, il est temps d’apprendre comment modifier à la fois les synthés et les échantillons pour faire de la musique encore plus originale et intéressante. En premier, explorons la faculté d’étirer et de compresser les échantillons.

Représentation des échantillons

Les échantillons (“samples”) sont des sons pré-enregistrés stockés à l’aide de nombres qui représentent comment se déplace la membrane du haut-parleur pour reproduire le son. La membrane du haut-parleur peut avancer et reculer, et ainsi les nombres ont juste besoin de représenter la distance d’avancée ou de recul que la membrane doit avoir pour chaque moment dans le temps. Pour être capable de reproduire fidèlement un son enregistré, un échantillon a typiquement besoin de stocker des milliers de nombres par seconde. Sonic Pi prend cette liste de nombres et en alimente à la bonne vitesse l’ordinateur pour faire avancer et reculer comme il le faut la membrane de son haut-parleur pour reproduire le son. Cependant, c’est aussi amusant de changer la vitesse à laquelle est alimenté le haut-parleur pour changer le son.

Changement de vitesse (“Rate”)

Jouons avec un des sons d’ambiance : :ambi_choir. Pour le jouer avec la vitesse par défaut, vous pouvez passer un argument rate: au sample :

sample :ambi_choir, rate: 1

Ceci le joue à la vitesse normale (1), aussi rien de spécial pour l’instant. Cependant, vous êtes libre de changer ce nombre pour une autre valeur. Que dire de 0.5 :

sample :ambi_choir, rate: 0.5

Wooh ! Que se passe-t-il ici ? Eh bien, deux choses. Premièrement, l’échantillon est joué pendant 2 fois plus de temps, deuxièmement le son est a un octave en-dessous. Explorons ces choses un peu plus en détails.

Étirons

Un échantillon qui est amusant à étirer ou à compresser est Amen. A vitesse normale, on pourrait imaginer de l’insérer dans une piste de batterie et de basse :

sample :loop_amen

Toutefois en modifiant la vitesse on peut changer de genre. Essayez de réduire de moitié la vitesse pour une vieille école hip-hop :

sample :loop_amen, rate: 0.5

Si nous l’accélérons, nous entrons dans le territoire de la jungle :

sample :loop_amen, rate: 1.5

Maintenant pour notre astuce finale - voyons ce qui se passe lorsque nous utilisons un “rate” négatif :

sample :loop_amen, rate: -1

Wooh ! Il le joue à l’envers ! Maintenant, essayez de jouer avec des tas d’échantillons différents. Essayez des vitesses très rapides et des vitesses insensément lentes. Voyez quels sons intéressants vous pouvez produire.

Une simple explication de la vitesse d’échantillon (“sample rate”)

Un moyen imagé d’assimiler les échantillons est de penser aux ressorts.
La vitesse de lecture est comme l’étirement et la compression du ressort. Si vous jouez l’échantillon à la vitesse 2, vous compressez le ressort à la moitié de sa longueur normale. Ainsi l’échantillon met la moitié du temps à être joué puisqu’il est plus court. Si vous jouez l’échantillon à la moitié de la vitesse, vous étirez le ressort au double de sa longueur. Ainsi l’échantillon met deux fois plus de temps à être joué puisqu’il est plus long. Plus vous compressez (vitesse plus élevée), plus il devient court, plus vous étirez (vitesse plus lente), plus il devient long.

Compresser un ressort augmente sa densité (le nombre de spires par cm) - ceci est similaire à l’échantillon sonnant plus aigu. Étirer le ressort diminue sa densité, c’est similaire à un son plus grave.

Les maths derrière la vitesse d’échantillon

(Cette section est fournie pour ceux que les détails intéressent. Soyez libre de la sauter…)

Comme nous l’avons vu ci-dessus, un échantillon est représenté par une longue liste de nombres qui représentent la position où devrait être la membrane du haut-parleur dans le temps. Nous pouvons prendre cette liste de nombres et l’utiliser pour tracer un graphique qui ressemblerait à ceci :

sample graph

Vous devriez avoir déjà vu des images comme cela. C’est appelé la forme d’onde d’un échantillon. C’est juste un graphique de nombres. Typiquement, une forme d’onde comme cela aura 44100 points de données par seconde (en application du théorème d’échantillonnage de Nyquist-Shannon). Ainsi, si l’échantillon dure 2 secondes, la forme d’onde sera représentée par 88200 nombres qui alimenteront le haut-parleur à la vitesse de 44100 points par seconde. Bien sûr, nous pouvons l’alimenter à une vitesse double qui serait de 88200 points par seconde. Ceci prendrait ainsi une seconde à être joué. Nous pourrions aussi le jouer à la moitié de la vitesse qui serait donc de 22050 points par seconde, en prenant 4 secondes pour être joué.

La durée d’un échantillon est affecté par la vitesse de jeu :

On peut représenter ceci avec la formule :

nouvelle_durée  = (1 / rate) * durée_normale 

Changer la vitesse de jeu affecte aussi la hauteur du son. La fréquence ou le ton d’une forme d’onde est déterminé par la vitesse à laquelle elle monte et descend. Notre cerveau curieusement change le mouvement rapide de la membrane du haut-parleur en notes hautes et le mouvement lent en notes basses. C’est pourquoi vous pouvez quelquefois voir un gros haut-parleur de basse bouger en émettant une super basse - il va et vient beaucoup moins vite qu’un haut-parleur produisant des notes plus aiguës.

Si vous prenez une forme d’onde et que vous la compressez, elle va monter et descendre plus de fois par seconde. Ceci va faire un son
plus aigu. On en déduit que doubler le montant des mouvements de montée et descente (oscillations) double la fréquence. Ainsi, jouer votre échantillon à double vitesse double la fréquence que vous entendez. De même, diminuer de moitié la vitesse va diminuer de moitié la fréquence. D’autres vitesses affecterons la fréquence dans le même sens.


3.4 - Échantillons enveloppés

Il est aussi possible de modifier la durée et l’amplitude d’un échantillon en utilisant une enveloppe ADSR. Toutefois, ceci fonctionne d’une manière légèrement différente de l’enveloppe ADSR applicable aux synthés. Les enveloppes d’échantillon permettent uniquement de réduire l’amplitude et la durée de l’échantillon - et jamais de les augmenter. Le jeu de l’échantillon s’arrêtera soit quand l’échantillon arrivera à sa fin, soit quand la fin l’enveloppe sera atteinte. Donc si vous utilisez une phase de release: très longue, cela n’allongera pas la durée de l’échantillon.

Des enveloppes pour Amen

Retournons à notre fidèle ami Amen :

sample :loop_amen

Sans paramètres, nous entendons la totalité de l’échantillon à son amplitude totale. Si nous voulons une attaque progressive, nous pouvons utiliser le paramètre attack: :

sample :loop_amen, attack: 1

Pour une attaque plus courte, choisissez une valeur attack: plus petite :

sample :loop_amen, attack: 0.3

Soutien automatique (“Auto Sustain”)

Où le comportement de l’enveloppe ADSR diffère de l’enveloppe standard des synthés est dans la valeur de sustain. Dans l’enveloppe standard des synthés, la valeur par défaut du soutien est 0 à moins que vous ne la fixiez manuellement. Avec les échantillons, la valeur par défaut du soutien est une valeur auto-magique - le temps qu’il reste pour finir l’échantillon. C’est pour cela que nous entendons l’échantillon en entier quand une valeur n’est pas spécifiée. Si les valeurs de l’attaque, du déclin, du soutien et de l’extinction sont toutes à 0, nous n’entendrons pas le moindre gazouillis. Donc, de la longueur de l’échantillon, Sonic Pi déduit les éventuelles durées d’attaque, de déclin et d’extinction et utilise le résultat pour votre durée de soutien. Si la somme des durées d’attaque, de déclin et d’extinction est supérieure à la durée de l’échantillon, le soutien est simplement fixé à 0.

Extinctions progressives

Pour explorer ceci, regardons notre Amen de manière plus détaillée. Si nous demandons à Sonic Pi quelle est la longueur de l’échantillon :

print sample_duration :loop_amen

Il affichera 1.753310657596372, ce qui est la longueur de l’échantillon en secondes. Arrondissons-le ici à 1.75 par commodité. Maintenant si nous fixons l’extinction à 0.75, quelque chose de surprenant va se passer :

sample :loop_amen, release: 0.75

La première seconde de l’échantillon va être jouée à l’amplitude totale avant de s’estomper progressivement sur une durée de 0.75 secondes. C’est l’auto-soutien en action. Par défaut, la phase d’extinction fonctionne de manière à s’achever à la fin de l’échantillon. Si notre échantillon avait 10.75 secondes de longueur, il serait joué 10 seconde à l’amplitude totale avant de s’estomper progressivement pendant 0.75 secondes.

Rappelez-vous : par défaut, la phase release: amène à l’extinction complète à la fin de l’échantillon.

Attaque et extinction preogressive

On peut utiliser à la fois les paramètres attack: et release: ensemble grâce au comportement du soutien automatique pour des attaques et des extinctions progressives :

sample :loop_amen, attack: 0.75, release: 0.75

Comme la durée totale de l’échantillon est de 1.75 s et que la somme des phases d’attaque et d’extinction fait 1.5 s, le soutien est automatiquement ajusté à 0.25 s. Ceci nous permet de programmer facilement une attaque et une extinction progressives de l’échantillon.

Soutien explicite

Nous pouvons facilement revenir au comportement normal de l’enveloppe ADSR des synthés en fixant manuellement sustain: à une valeur comme 0 :

sample :loop_amen, sustain: 0, release: 0.75

Maintenant, notre échantillon n’est joué que pendant 0.75 s au total. Avec les valeurs 0 par défaut pour attack: et decay: , l’échantillon monte directement à l’amplitude totale, se maintient là pendant 0 s et redescend progressivement à l’amplitude 0 pendant une durée de 0.75 s.

Cymbales percussives

Nous pouvons utiliser ce comportement pour obtenir de bons effets en transformant un échantillon qui sonne longtemps en versions plus percussives. Intéressons-nous à l’échantillon :drum_cymbal_open:

sample :drum_cymbal_open

Vous pouvez entendre la cymbale sonnant pendant une certaine durée. Toutefois, nous pouvons utiliser notre enveloppe pour la rendre plus percussive :

sample :drum_cymbal_open, attack: 0.01, sustain: 0, release: 0.1

Vous pouvez émuler la frappe de la cymbale suivie d’un étouffement en augmentant la phase de soutien :

sample :drum_cymbal_open, attack: 0.01, sustain: 0.3, release: 0.1

Maintenant allez et prenez plaisir à mettre des enveloppes sur vos échantillons. Essayez aussi de changer la vitesse pour des résultats vraiment intéressants.


3.5 - Échantillons partiels

Cette section va conclure notre exploration du lecteur d’échantillons de Sonic Pi. Faisons un rapide résumé. Jusqu’à maintenant nous avons vu comment lire des échantillons :

sample :loop_amen

Nous avons ensuite vu comment changer la vitesse de lecture des échantillons en les jouant par exemple à moitié vitesse :

sample :loop_amen, rate: 0.5

Ensuite, nous avons vu comment nous pouvions obtenir une attaque progressive (faisons-le à moitié vitesse) :

sample :loop_amen, rate: 0.5, attack: 1

Nous avons aussi vu comment nous pouvions utiliser le début d’un échantillon de manière percussive en donnant à sustain: une valeur explicite et en assignant des valeurs faibles à la fois à attack: et à release: :

sample :loop_amen, rate: 2, attack: 0.01, sustain: 0, release: 0.35

Toutefois ne serait-il pas sympathique de ne pas avoir à toujours démarrer au début de l’échantillon ? Ne serait-ce pas également sympathique de ne pas avoir à finir toujours à la fin de l’échantillon ?

Choix d’un point de départ

Il est possible de choisir un point arbitraire de départ dans l’échantillon au moyen d’une valeur comprise entre 0 et 1 où 0 est le début de l’échantillon et 1 la fin et 0.5 le milieu. Essayons de jouer seulement la dernière moitié de “Amen” :

sample :loop_amen, start: 0.5

Ou pour le dernier quart de l’échantillon :

sample :loop_amen, start: 0.75

Choix d’un point de terminaison

De manière similaire, il est possible de choisir un point de terminaison arbitraire au moyen d’une valeur comprise entre 0 et 1. Terminons l’“Amen” à la moitié de son parcours :

sample :loop_amen, finish: 0.5

Spécification du départ et de la terminaison

Bien sûr, nous pouvons combiner ces deux paramètres pour jouer des segments arbitraires. Comment jouer uniquement une petite section au milieu :

sample :loop_amen, start: 0.4, finish: 0.6

Que se passe-t-il si nous choisissons une position de départ postérieure au point de terminaison ?

sample :loop_amen, start: 0.6, finish: 0.4

Cool ! Ça joue à l’envers !

Combinaison avec la vitesse

Nous pouvons combiner cette nouvelle possibilité avec l’ami rate: pour jouer des segments arbitraires. Par exemple, nous pouvons jouer une très petite section d’“Amen” très lentement :

sample :loop_amen, start: 0.5, finish: 0.7, rate: 0.2

Combinaison avec les enveloppes

Finalement, nous pouvons combiner tout ceci avec nos enveloppes ADSR pour produire des résultats intéressants :

sample :loop_amen, start: 0.5, finish: 0.8, rate: -0.2, attack: 0.3, release: 1

Maintenant allez et jouez un moment en triturant les échantillons avec ces choses amusantes.


3.6 - Échantillons externes

Bien que les échantillons fournis en interne puissent vous motiver et vous faire démarrer rapidement, vous pourriez souhaiter d’expérimenter d’autres sons pré-enregistrés dans votre musique. Sonic Pi supporte complètement cela. En premier lieu toutefois ayons une rapide discussion sur la portabilité de votre oeuvre.

Portabilité

Quand vous composez votre morceau uniquement avec des synthés et des échantillons internes, le code est tout ce dont vous avez besoin pour reproduire fidèlement votre musique. Pensez à cela un instant - C’est étonnant ! Un simple morceau de texte que vous pouvez envoyer par mail ou coller dans un Gist représente tout ce que vous avez besoin pour reproduire vos sons. Cela le rend vraiment facile à partager avec vos amis puisqu’ils ont juste besoin de se procurer le code.

Toutefois, si vous commencez à utiliser vos propres échantillons pré-enregistrés, vous perdez cette portabilité. C’est parce que non seulement les autres ont besoin de votre code, mais aussi de vos échantillons. Ceci limite la capacité pour les autres de manipuler, triturer et expérimenter votre oeuvre. Bien entendu, ceci ne devrait pas vous faire arrêter d’utiliser vos propres échantillons, c’est juste quelque chose à prendre en compte.

Échantillons locaux

Alors comment jouez-vous n’importe quel fichier WAV, AIFF ou FLAC sur votre ordinateur ? Tout ce dont vous avez besoin est de passer le chemin de ce fichier à sample :

sample "/home/sam/Desktop/my-sound.wav"

Sonic Pi chargera automatiquement et jouera votre échantillon. Vous pouvez aussi passer tous les paramètres que vous avez l’habitude de passer à sample :

sample "/home/sam/Desktop/my-sound.wav", rate: 0.5, amp: 0.3

3.7 - Paquets de samples

Note: cette section du tutoriel couvre le sujet avancé de travailler avec des grands dossiers de vos propres samples. Ce sera le cas si vous avez téléchargé ou acheté vos propre paquets de samples et souhaitez les utiliser dans Sonic Pi.

N’hésitez pas à sauter cette section si vous vous contentez des samples fournis dans Sonic Pi.

Quand on travaille avec de grands dossiers de samples externes il peut être ennuyeux de taper le chemin entier chaque fois qu’on veut déclencher un sample particulier.

Par exemple, imaginons que vous avez le dossier suivant sur votre machine :

/path/to/my/samples/

Quand on regarde dans ce dossier on voit les samples suivants :

Typiquement pour jouer le sample de piano on peut utiliser le chemin complet :

sample "/path/to/my/samples/120_Bb_piano1.wav"

Si on veut jouer le sample de guitare on peut aussi utiliser son chemin complet :

sample "/path/to/my/samples/120_Bb_guit.wav"

Cependant ces deux appels de samples nous forcent à connaître le nom de chacun des samples de notre dossier. Et si on voulait juste écouter chaque sample à son tour rapidement ?

Indexer les paquets de samples

Si on veut jouer le premier sample d’un dossier on peut juste passer le nom du dossier à sample et l’index 0 comme suit :

sample "/path/to/my/samples/", 0

On peut même construire un raccourci vers notre chemin de dossier en utilisant une variable :

samps = "/path/to/my/samples/"
sample samps, 0

Maintenant, si on veut jouer le deuxième sample de notre dossier, on peut juste incrémenter notre index :

samps = "/path/to/my/samples/"
sample samps, 1

Remarquez qu’on n’a plus besoin de connaître le nom des samples du dossier : on doit juste connaître le dossier lui-même (ou avoir un raccourci vers lui). Si on demande un index qui est plus grand que le nombre de samples, il va juste boucler comme pour les anneaux. Ainsi, quel que soit le nombre qu’on utilise on a la garantie de récupérer un des samples de ce dossier.

Filtrer des paquets de samples

D’habitude indexer suffit, mais parfois on a besoin de plus de puissance pour trier et organiser nos samples. Heureusement de nombreux paquets de samples ajoutent des informations utiles dans les noms de fichiers. Jetons un autre oeil aux noms de fichier des samples de notre dossier :

Remarquez que dans ces noms de fichier nous avons pas mal d’informations. On a le BPM du sample (nombre de battements par minute) au début. Donc le sample de piano est à 120 BPM et nos trois premières mélodies sont à 100 BPM. Nos noms de samples contiennent aussi la clef. Donc le sample de guitare est en Bb (si bémol) et les mélodies sont en A# (la dièse). Cette information est très utile pour mélanger ces samples avec le reste de notre code. Par exemple, on sait qu’on ne peut jouer le sample de piano que dans du code qui est à 120 BPM et dans la clef de Bb.

Il se trouve qu’on peut utiliser cette convention de nommage particulière de nos ensembles de samples dans le code pour nous aider à ne garder que ceux qu’on veut. Par exemple, si nous travaillons à 120 BPM, on peut ne garder que les samples qui contiennent la chaîne "120" avec le code suivant :

samps = "/path/to/my/samples/"
sample samps, "120"

Cela jouera le premier sample qui correspond. Si on veut le deuxième, on n’a qu’à utiliser l’index :

samps = "/path/to/my/samples/"
sample samps, "120", 1

On peut même utiliser de multiples filtres en même temps. Par exemple, si on veut un sample dont le nom de fichier contient à la fois les sous-chaînes “120” et “A#”, on peut le trouver facilement avec le code suivant :

samps = "/path/to/my/samples/"
sample samps, "120", "A#"

Enfin, on a toujours la possibilité d’ajouter nos options habituelles lors de l’appel à sample:

samps = "/path/to/my/samples/"
sample samps, "120", "Bb", 1, lpf: 70, amp: 2

Sources

Le système de pré-argument de filtre de samples comprend deux types d’information : les sources et les filtres. Les sources sont des informations utilisées pour créer la liste des candidats potentiels. Une source peut prendre deux formes :

  1. “/path/to/samples” : une chaîne représentant un chemin valide vers un dossier
  2. “/path/to/samples/foo.wav” : une chaîne représentant un chemin valide vers un sample

La fonction sample va d’abord rassembler toutes les sources et les utiliser pour créer une grande liste de candidats. Cette liste est construite en ajoutant d’abord tous les chemins valides et puis en ajoutant tous les fichiers valides .flac, .aif, .aiff, .wav, et .wave contenus dans les dossiers.

Par exemple, regardez le code suivant :

samps = "/path/to/my/samples/"
samps2 = "/path/to/my/samples2/"
path = "/path/to/my/samples3/foo.wav"

sample samps, samps2, path, 0

Ici nous combinons les contenus des samples de deux dossiers en y ajoutant un sample en particulier. Si "/path/to/my/samples/" contient trois samples et "/path/to/my/samples2/" en contient douze, on aurait seize samples potentiels à indexer et filtrer (3 + 12 + 1).

Par défaut, seuls les fichiers de samples d’un dossier sont rassemblés dans la liste de candidats. Parfois vous pourriez avoir un certain nombre de dossiers imbriqués dans lesquels vous aimeriez chercher et filtrer. Vous pouvez faire une recherche récursive dans tous les samples de tous les sous-dossiers d’un dossier en particulier en ajoutant ** à la fin du chemin :

samps = "/path/to/nested/samples/**"
sample samps, 0

Attention parce que chercher dans un très grand ensemble de dossiers peut prendre beaucoup de temps. Cela dit, le contenu des dossiers sources est mis en cache, donc le retard n’arrivera que la première fois.

Filtres

Une fois qu’on a une liste de candidats on peut utiliser les types de filtres suivants pour réduire la sélection :

Composites

Enfin vous pouvez utiliser des listes partout où on peut placer une source ou un filtre. La liste sera automatiquement aplatie et son contenu sera traité comme des sources et filtres. Ainsi les appels suivants à sample sont sémantiquement équivalents :

sample "/path/to/dir", "100", "C#"
sample ["/path/to/dir", "100", "C#"]
sample "/path/to/dir", ["100", "C#"]
sample ["/path/to/dir", ["100", ["C#"]]]

Résumé

C’était une section avancée pour les gens qui ont besoin de vraie puissance pour manipuler et utiliser des paquets de samples. Si la plupart de cette section n’avait pas trop de sens pour vous, ne vous inquiétez pas. Vous n’avez probablement pas encore besoin de cette fonctionnalité. Mais vous vous rendrez compte quand vous en aurez besoin et vous pourrez revenir et relire ceci quand vous commencerez à travailler avec de grands dossiers de samples.


4 - Randomisation

Un grand moyen d’ajouter de l’intérêt à votre musique est d’utiliser quelques nombres aléatoires (“random”). Sonic Pi a des fonctions remarquables pour ajouter de l’aléatoire à votre musique, mais avant de commencer, nous devons apprendre une vérité choquante : dans Sonic Pi aléatoire n’est pas vraiment aléatoire. Qu’est-ce qu’ici-bas cela signifie ? Eh bien, voyons-le.

Répétabilité

Une fonction vraiment utile est rrand qui vous donnera une valeur aléatoire comprise entre deux nombres - un min et un max. (rrand est l’abréviation de “ranged random”). Essayons de jouer une note aléatoire :

play rrand(50, 100)

Ooh, une note aléatoire a été jouée. La note 77.4407 a été jouée - une note aléatoire sympathique entre 50 et 100. Wooh , attendez, est-ce que je viens juste de prédire exactement la note que vous avez obtenue ? Quelque chose de louche se passe ici. Essayez d’exécuter le code une nouvelle fois. Quoi ? 77.4407 a encore été choisi ? Ce ne peut être aléatoire !

La réponse est que ce n’est pas vraiment aléatoire, c’est pseudo-aléatoire. Sonic Pi vous donne une suite d’un semblant de nombres aléatoires de manière reproductible. C’est très utile pour s’assurer que la musique que vous avez créée sur votre machine sonnera de façon identique sur n’importe quelle autre machine - même si vous utilisez de l’aléatoire dans votre composition.

Bien sûr, dans un morceau de musique donné, si 77.4407 était choisi ‘aléatoirement’ à chaque fois, ce ne serait pas très intéressant. Ce n’est cependant pas le cas. Essayez ce qui suit :

loop do
  play rrand(50, 100)
  sleep 0.5
end 

Oui ! ça sonne aléatoire finalement. A l’intérieur d’un run donné, des appels successifs à des fonction aléatoires retournent des valeurs aléatoires. Cependant, une nouvelle exécution produira exactement la même séquence de valeurs aléatoires et sonnera exactement pareil. C’est comme si tout le code de Sonic Pi revenait en arrière exactement au même point de départ chaque fois que le bouton “Run” était pressé. C’est le jour de la marmotte de la synthèse musicale.

Cloches hantées

Une agréable illustration de la randomisation en action est l’exemple des cloches hantées en faisant boucler l’échantillon :perc_bell avec une vitesse et un temps de repos aléatoires entre les sons de cloche :

loop do
  sample :perc_bell, rate: (rrand 0.125, 1.5)
  sleep rrand(0.2, 2)
end

Limite (“cutoff”) aléatoire

Un autre exemple sympathique de randomisation est de modifier la limite d’un son de synthé aléatoirement. Un synthé super pour essayer cela est l’émulateur du :tb303 :

use_synth :tb303

loop do
  play 50, release: 0.1, cutoff: rrand(60, 120)
  sleep 0.125
end

Tête de série aléatoire

Alors que faire si vous n’aimez pas cette particulière séquence de nombres aléatoires que fournit Sonic Pi ? Eh bien, c’est tout à fait possible de choisir un point de départ via use_random_seed. Il est établi que la tête de série par défaut est 0, aussi choisissez une autre tête de série pour une expérience aléatoire différente !

Envisagez ce qui suit :

5.times do
  play rrand(50, 100)
  sleep 0.5
end

Chaque fois que vous exécuterez ce code, vous entendrez la même séquence de 5 notes. Pour obtenir une séquence différente, changez simplement la tête de série :

use_random_seed 40
5.times do
  play rrand(50, 100)
  sleep 0.5
end

Ceci va produire une séquence différente de 5 notes. En changeant le tête de série et en écoutant les résultats, vous pouvez trouver quelque chose que vous aimez - et quand vous le partagerez avec d’autres, ils entendront exactement ce que vous avez aussi écouté.

Jetons un œil sur d’autres fonctions de randomisation utiles.

Choix (“choose”)

Une chose très commune est de choisir un item aléatoirement dans une liste d’items connus. Par exemple, je peux vouloir jouer une note parmi les suivantes : 60, 65 ou 72. Je peux y arriver avec choose qui me choisit un item dans une liste. En premier, je dois mettre mes nombres dans une liste, ce qui est réalisé en les encadrant entre crochets et en les séparant avec des virgules : [60, 65, 72]. Ensuite, j’ai juste besoin de leur passer choose :

choose([60, 65, 72])

Écoutons comment cela sonne :

loop do
  play choose([60, 65, 72])
  sleep 1
end

rrand

Nous avons déja vu rrand, mais examinons-le encore. Il retourne un nombre aléatoire entre 2 valeurs exclues. Cela signifie qu’il ne retournera jamais soit la borne basse, soit la borne haute - toujours quelque chose entre les deux. Le nombre sera toujours un nombre flottant - ce qui signifie que ce n’est pas un nombre entier, mais une fraction de nombre. Exemple de flottants retournés par rrand(20, 110):

rrand_i

Occasionnellement, vous désirez un nombre entier aléatoire, pas un flottant. C’est là que rrand_i arrive à la rescousse. Il fonctionne de façon similaire à rrand sauf qu’il peut retourner potentiellement les valeurs minimales et maximales comme valeurs aléatoires (ce qui signifie que c’est inclusif plutôt qu’exclusif des bornes). Exemple de nombres retournés par rrand_i(20, 110) :

rand

Cette fonction va retourner un flottant aléatoire entre 0 (inclus) et la valeur maximale que vous spécifiez (exclue). Par défaut, elle retourne une valeur entre 0 et 1. C’est par conséquent utile pour choisir une valeur de amp: aléatoire :

loop do
  play 60, amp: rand
  sleep 0.25
end

rand_i

Similaire à la relation entre rrand_i et rrand, rand_i retournera un nombre entier compris entre 0 et la valeur maximale que vous spécifierez.

dice (dé)

Quelquefois, vous souhaitez émuler un jet de dés - c’est un cas particulier de rrand_i où la valeur minimale est toujours 1. Un appel à dice nécessite que vous spécifiez le nombre de faces du dé. Un dé standard a 6 faces, donc dice(6) agira de manière très similaire - retournant l’une des valeurs 1, 2, 3, 4, 5, ou 6. Cependant, juste comme dans des jeux de rôle fantaisistes, vous pourriez trouver des dés à 4 faces, ou à 12 faces, peut-être même à 120 faces !

one_in

Finalement, vous pouvez souhaiter simuler la chance que vous avez de tomber sur le nombre le plus élevé d’un dé, soit 6 pour un dé standard. Ainsi one_in retourne vrai (“true”) avec une probabilité de 1 sur le nombre de faces du dé. Par conséquent one_in(6) retournera vrai avec une probabilité de 1 sur 6 ou faux (“false”) autrement. Les valeurs True et False sont très utiles pour les ordres if que nous couvrirons dans une section suivante de ce tutoriel.

Maintenant allez et introduisez de l’aléatoire dans votre code !


5 - Structures de Programmation

Maintenant que vous avez appris les bases de la création des sons avec play et sample et la création de mélodies simples et de rythmes avec sleep entre les sons, vous pourriez être en train de vous demander ce que le monde du code peut vous offrir en plus…

Eh bien, vous y êtes et pour un voyage passionnant ! Il ressort que les structures de programmation de base telles les boucles, les conditionnels, les fonctions, les fils (“threads”) vont vous procurer des outils puissants et étonnants pour exprimer vos idées musicales.

Plongeons dans les bases…


5.1 - Blocs

Une structure que vous verrez souvant dans Sonic Pi est le bloc. Les blocs vous permettent de faire des choses utiles avec de grands morceaux de code. Par exemple, avec les paramètres des synthés et des échantillons, nous sommes capables de changer sur une seule ligne quelque chose qui s’est passé. Cependant, nous souhaitons quelquefois faire quelque chose de significatif sur un certain nombre de lignes de code. Par exemple, nous souhaiterions les faire boucler, leur ajouter de la réverbération, les exécuter seulement une fois sur 5, etc. Considérez le code suivant :

play 50
sleep 0.5
sample :elec_plip
sleep 0.5
play 62

Pour faire quelque chose avec un morceau de code, nous devons dire à Sonic Pi où commence le bloc et où il finit. Nous utilisons do pour le début et end pour la fin. Par exemple :

do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Toutefois, ce n’est pas encore complet et ne fonctionnera pas (essayez-le et vous obtiendrez une erreur) puique nous n’avons pas dit à Sonic Pi ce que nous voulions faire avec ce bloc do/end. On le dit à Sonic Pi en écrivant du code spécial avant le do. Nous verrons un certain nombre de ces bouts de code spéciaux plus tard dans ce tutoriel. Pour l’instant, il est important de savoir que d’encadrer votre code entre do et end dit à Sonic Pi que vous voulez faire quelque chose de spécial avec ce morceau de code.


5.2 - Itérations et Boucles

Jusqu’à maintenant nous avons passé beaucoup de temps à rechercher les différents sons que vous pouvez faire avec des blocs de play et de sample. Nous avons aussi appris comment déclencher ces sons dans le temps en utilisant sleep.

Comme vous vous en êtes probablement rendu compte, il y a beaucoup de plaisir à avoir avec la construction de ces blocs de base. Toutefois, une dimension totalement nouvelle de plaisir se découvre quand vous commencez à utiliser la puissance du code pour structurer votre musique et vos compositions. Dans les quelques sections suivantes, nous allons explorer quelques uns de ces nouveaux outils puissants. En premier, découvrons l’itération et les boucles.

Répétition

Avez-vous écrit du code que vous aimeriez répéter quelques fois ? Par exemple, vous pourriez avoir quelque chose comme ceci :

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

Que faire si nous voulions répéter ceci 3 fois ? Eh bien, nous pourrions faire simple et juste le copier et le coller trois fois : ~~~~ play 50 sleep 0.5 sample :elec_blup sleep 0.5 play 62 sleep 0.25

play 50 sleep 0.5 sample :elec_blup sleep 0.5 play 62 sleep 0.25

play 50 sleep 0.5 sample :elec_blup sleep 0.5 play 62 sleep 0.25 ~~~~

Maintenant, c’est beaucoup de code ! Que se passe-t-il si nous voulions changer l’échantillon en :elec_plip ? Vous aller devoir trouver tous les endroits avec l’original :elec_blup et les modifier un par un. De façon plus importante, que faire si vous voulez répéter le bout de code original 50 fois ou 1000 fois ? Ça ferait alors beaucoup de code, et beaucoup de lignes de code à modifier si vous vouliez faire un changement.

Itération

En fait, répéter le code devrait être aussi facile que de dire fais ceci trois fois. Eh bien, c’est presque cela. Souvenez-vous de notre vieil ami le bloc de code. Nous pouvons l’utiliser pour marquer le début et la fin du code que nous aimerions répéter trois fois. Nous utilisons alors le code spécial 3.times. Ainsi, à la place d’écrire fais cela trois fois, nous écrivons 3.times do - Ce n’est pas trop dur. Rappelez-vous juste d’écrire end à la fin du code que vous devez répéter :

3.times do
  play 50
  sleep 0.5
  sample :elec_blup
  sleep 0.5
  play 62
  sleep 0.25
end

Alors, est-ce que ce n’est pas plus propre que de copier-coller ! Nous pouvons l’utiliser pour créér beaucoup de chouettes structures répétitives.

4.times do
  play 50
  sleep 0.5
end

8.times do
  play 55, release: 0.2
  sleep 0.25
end

4.times do
  play 50
  sleep 0.5
end

Imbrication d’itérations

Nous pouvons mettre des itérations à l’intérieur d’autres itérations pour créér des motifs intéressants. Par exemple :

4.times do
  sample :drum_heavy_kick
  2.times do
    sample :elec_blip2, rate: 2
    sleep 0.25
  end
  sample :elec_snare
  4.times do
    sample :drum_tom_mid_soft
    sleep 0.125
  end
end

Bouclage

Si vous voulez répéter quelque chose un grand nombre de fois, vous pourriez vous trouvez en situation d’utiliser des nombres vraiment grands comme 1000.times do. Dans ce cas, vous feriez probablement mieux de demander à Sonic Pi de répéter à jamais (au moins jusqu’à ce que vous pressiez le bouton stop !). Bouclons l’échantillon amen à jamais :

loop do
  sample :loop_amen
  sleep sample_duration :loop_amen
end

La chose importante à savoir à propos des boucles est qu’elles se comportent comme des trous noirs pour le code. Une fois que le code est entré dans une boucle, il ne peut pas en sortir tant que vous n’avez pas pressé stop - il va juste tourner en rond dans la boucle à jamais. Ce qui signifie que si vous avez du code après la boucle, vous ne l’entendrez jamais. Par exemple, la cymbale suivant cette boucle ne sera jamais jouée :

loop do
  play 50
  sleep 1
end

sample :drum_cymbal_open

Maintenant, structurez votre code avec des itérations et des boucles !


5.3 - Conditionnels

Une situation commune dans laquelle vous vous trouverez probablement est de non seulement jouer une note aléatoire (voir la précédente section sur l’aléatoire) mais de prendre une décision aléatoire basée sur le résultat de l’exécution d’un code ou de tel autre code. Par exemple, vous pourriez vouloir jouer aléatoirement un tambour ou une cymbale. Nous pouvons y parvenir avec un ordre if (si).

Pile ou Face

Ainsi, faisons sauter une pièce : si c’est pile, joue un tambour, si c’est face, joue une cymbale. Facile. Nous pouvons émuler le saut d’une pièce avec notre fonction one_in (introduite dans la section traitant de l’aléatoire) en spécifiant une probabilité de 1 sur 2 : one_in(2). Nous pouvons alors en utiliser le résultat pour décider entre deux bouts de code, le code pour jouer le tambour et le code pour jouer la cymbale :

loop do

  if one_in(2)
    sample :drum_heavy_kick
  else
    sample :drum_cymbal_closed
  end
  
  sleep 0.5
  
end

Notez que les ordres if ont trois parties :

Typiquement, dans les langages de programmation, la notion de oui est représenté par le terme true (vrai) et la notion de non par le terme false (faux). Nous avons donc besoin de trouver une question qui nous donnera une réponse vraie ("true") ou fausse ("false"), ce qui est exactement ce que fait one_in.

Notez comment le premier choix est encadré entre le if et le else, et le second choix est encadré entre le else et le end. Juste comme pour les blocs do/end, vous pouvez mettre plusieurs lignes dans chacun de ces endroits. Par exemple :

loop do

  if one_in(2)
    sample :drum_heavy_kick
    sleep 0.5
  else
    sample :drum_cymbal_closed
    sleep 0.25
  end
  
end

Cette fois nous “dormons” pour une durée différente et dépendante du choix qui est fait.

If simple

Quelquefois, nous voulons optionnellement exécuter seulement une ligne de code. C’est possible en plaçant if à la fin et la question à la suite. Par exemple :

use_synth :dsaw

loop do
  play 50, amp: 0.3, release: 2
  play 53, amp: 0.3, release: 2 if one_in(2)
  play 57, amp: 0.3, release: 2 if one_in(3)
  play 60, amp: 0.3, release: 2 if one_in(4)
  sleep 1.5
end

Ceci va jouer des accords de différents nombres avec la chance pour chaque note d’être jouée avec une probabilité différente.


5.4 - Threads

(“thread” = terme technique intraduisible et dont la traduction la plus proche est “fil”)

Ainsi vous avez fait votre géniale ligne de basse et un super motif de batterie. Comment les jouez-vous en même temps ? Une solution est de les intercaler manuellement - joue quelques basses, puis quelques sons de batterie, puis encore des basses… Cependant, la synchronisation devient rapidement dure à concevoir, en particulier quand vous commencez à intercaler plus d’éléments.

Et si Sonic Pi pouvait vous synchroniser les choses automatiquement… Eh bien, il le peut, et vous le faites avec une chose spéciale appelée thread.

Boucles infinies

Pour garder cet exemple simple, vous devez imaginer que ceci est un super motif de batterie et une géniale ligne de basse :

loop do
  sample :drum_heavy_kick
  sleep 1
end

loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

Comme nous en avons parlé précédemment, les boucles sont comme des trous noirs pour un programme. Dès que vous êtes entré dans une boucle, vous ne pouvez jamais en sortir à moins de presser stop. Comment pouvons-nous jouer les deux boucles en même temps ? Nous devons dire à Sonic Pi que nous voulons démarrer quelque chose en même temps que le reste du code. C’est là que les threads arrivent à la rescousse.

Threads à la rescousse

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end

loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

En encadrant la première boucle dans un bloc in_thread do/end, nous disons à Sonic Pi d’exécuter le contenu du bloc do/end exactement en même temps que l’ordre suivant le bloc do/end (qui se trouve être la seconde boucle). Essayez-le et vous entendrez à la fois la batterie et la ligne de basse synchronisées !

Maintenant, que faire si nous voulons ajouter un synthé par-dessus. quelque chose comme :

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end

loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

loop do
  use_synth :zawa
  play 52, release: 2.5, phase: 2, amp: 0.5
  sleep 2
end

Maintenant, nous avons le même problème qu’avant. La première boucle est jouée en même temps que la seconde grâce au in_thread. Toutefois, la troisième boucle n’est jamais atteinte. Nous avons donc besoin d’un nouveau thread :

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end

in_thread do
  loop do
    use_synth :fm
    play 40, release: 0.2
    sleep 0.5
  end
end

loop do
  use_synth :zawa
  play 52, release: 2.5, phase: 2, amp: 0.5
  sleep 2
end

Runs en tant que threads

Ce qui peut vous surprendre est que quand vous pressez le bouton Run, vous êtes réellement en train de créér un nouveau thread pour l’exécution du code. C’est pour cela qu’en le pressant de multiples fois, vous superposerez des couches de sons les unes sur les autres. Comme les “runs” sont eux-même des threads, ils intercaleront les sons automatiquement pour vous.

Portée

Etudiant comment maîtriser Sonic Pi, vous apprendrez que les threads sont les composants les plus importants de votre musique. L’une des responsabilités importantes qu’ils ont est d’isoler la notion de paramètres courants vis à vis des autres threads. Qu’est-ce que cela signifie ? Eh bien, quand vous commutez les synthés avec use_synth, vous ne commutez réellement que le synthé dans le thread courant - aucun autre thread n’aura son synthé commuté. Voyons cela en action :

play 50
sleep 1

in_thread do
  use_synth :tb303
  play 50
end

sleep 1
play 50

Notez comme que le son du milieu était différent des autres. L’ordre use_synth affecte uniquement le thread dans lequel il était et pas le thread principal et extérieur du run.

Héritage

Quand vous créez un nouveau thread avec in_thread, le nouveau thread hérite automatiquement de tous les paramètres courants du thread courant. Voyons cela :

use_synth :tb303
play 50
sleep 1

in_thread do
  play 55
end

Notez que la seconde note est jouée avec le synthé :tb303 bien qu’elle soit jouée depuis un thread distinct. L’un quelconque des paramètres modifiés avec les différentes fonctions use_* se comportera exactement de la même manière.

Quand les threads sont créés, ils héritent de tous les paramètres de leur parent mais dès lors, ils ne partagent plus aucun changement.

Nommage des Threads

Finalement, nous pouvons donner des noms à nos threads :

in_thread(name: :bass) do
  loop do
    use_synth :prophet
    play chord(:e2, :m7).choose, release: 0.6
    sleep 0.5
  end
end

in_thread(name: :drums) do
  loop do
    sample :elec_snare
    sleep 1
  end
end

Regardez le panneau “trace” quand vous exécutez ce code. Regardez comment le “trace” rapporte le nom du thread avec le message.

[Run 36, Time 4.0, Thread :bass]
 |- synth :prophet, {release: 0.6, note: 47}

Seulement un thread autorisé par nom

Une dernière chose à savoir au sujet des threads nommés est que seul un thread d’un nom donné peut être en cours d’exécution au même moment. Explorons ceci. Considérez le code suivant :

in_thread do
  loop do
    sample :loop_amen
    sleep sample_duration :loop_amen
  end
end

Allez de l’avant et collez cela dans un buffer et pressez le bouton “run”. Pressez-le encore quelquefois. Ecoutez la cacaphonie des échantillons amen bouclant de façon désynchronisée. Ok, vous pouvez maintenant presser “stop”.

C’est le comportement que nous avons vu encore et encore - si vous pressez le bouton “run”, le son s’étend au dessus de tout son existant. Donc, si vous avez une boucle et que vous pressez le bouton “run” trois fois, vous aurez trois couches de boucles jouant simultanément.

Cependant, avec les threads nommés, c’est différent :

in_thread(name: :amen) do
  loop do
    sample :loop_amen
    sleep sample_duration :loop_amen
  end
end

Essayez de presser le bouton “run” plusieurs fois avec ce code. Vous entendrez seulement une boucle de l’échantillon amen. Vous allez aussi voir ceci dans la trace :

==> Skipping thread creation: thread with name :amen already exists.
   (sautant la création d'un thread : le thread avec le nom :amen existe déjà.)

Sonic Pi vous dit qu’un thread avec le nom :amen est déjà en train d’être joué, donc il ne va pas en créer un autre.

Ce comportement peut ne pas vous sembler utile immédiatement - mais il sera très pratique quand nous commencerons à coder en “live”…


5.5 - Fonctions

Une fois que vous commencez à écrire beaucoup de code, vous pouvez souhaiter trouver le moyen d’organiser et de structurer les choses pour les rendre plus ordonnées et faciles à comprendre. Les fonctions sont un moyen très puissant pour le faire. Elles vous donnent la capacité de donner un nom à un morceau de code. Jetons-y un œil.

Definition des fonctions

define :foo do
  play 50
  sleep 1
  play 55
  sleep 2
end

Ici, nous avons défini une nouvelle fonction appelée foo. Nous faisons cela avec notre vieil ami, le bloc do/end et le mot magique define suivi par le nom que nous voulons donner à notre fonction. Nous ne sommes pas tenus de l’appeler foo, nous aurions pu l’appeler avec n’importe quel nom que nous voulions, comme bar, baz ou idéalement quelque chose de significatif pour vous comme section_principale ou lead_riff.

Rappelez-vous d’ajouter un deux-points : devant le nom de votre fonction quand vous la définissez.

Appel des fonctions

Une fois que nous avons défini notre fonction, nous pouvons l’appeler simplement en écrivant son nom :

define :foo do
  play 50
  sleep 1
  play 55
  sleep 0.5
end

foo

sleep 1

2.times do
  foo
end

Nous pouvons même utiliser foo à l’intérieur de blocs d’itération ou n’importe où nous aurions pu écrire play ou sample. Ceci nous donne un super moyen de nous exprimer et de créér de nouveaux mots significatifs à utiliser dans nos compositions.

Les fonctions sont mémorisées à travers des runs

Pour le moment, chaque fois que nous avons pressé le bouton Run, Sonic Pi a démarré d’un état complètement vierge. Il ne savait rien à part ce qui était dans le buffer. Vous ne pouviez pas référencer du code d’un autre buffer ou d’un autre thread. Toutefois, les fonctions changent cela. Quand vous définissez une fonction, Sonic Pi s’en rappelle. Essayons-le. Effacez tout le code dans votre buffer et remplacez-le par :

foo

Pressez le bouton Run et écoutez votre fonction qui est jouée. Où le code est-il allé ? Comment Sonic Pi sait-il quoi jouer ? Sonic Pi s’est simplement souvenu de votre fonction - ainsi, même après l’avoir effacée de votre buffer, il se rappelle de ce que vous avez tapé. Ce comportement fonctionne uniquement avec les fonctions créées en utilisant define (et defonce).

Fonctions paramétrées

Vous pourriez être intéressé à savoir que juste comme vous pouvez passer les valeurs min et max à rrand, vous pouvez apprendre à vos fonctions à accepter des arguments. Jetons-y un œil.

define :my_player do |n|
  play n
end

my_player 80
sleep 0.5
my_player 90

Ce n’est pas très excitant, mais ça illustre le point. Nous avons créé notre propre version de play appelée my_player et qui est paramétrée.

Les paramètres doivent être placés après le do du bloc do/end de define, entourés par des barres verticales | et séparés par des virgules ,. Vous pouvez utiliser tout mot que vous souhaitez pour les noms de paramètres.

La magie se passe à l’intérieur du bloc do/end de define. Vous pouvez utiliser les noms de paramètres comme si c’étaient des valeurs réelles. Dans cet exemple, je joue la note n. Vous pouvez considérer les paramètres comme une sorte de promesse qui fait que, lorsque le code s’exécute, ils sont remplacés par des valeurs réelles. Vous faites ceci en passant un argument à la fonction quand vous l’appelez. Je le fais avec my_player 80 pour jouer la note 80. À l’intérieur de la définition de la fonction, n est alors remplacé par 80, donc play n est changé en play 80. Quand je l’appelle une nouvelle fois avec my_player 90, n est alors remplacé par 90, donc play n est changé en play 90.

Voyons un exemple plus intéressant :

define :chord_player do |root, repeats| 
  repeats.times do
    play chord(root, :minor), release: 0.3
    sleep 0.5
  end
end

chord_player :e3, 2
sleep 0.5
chord_player :a3, 3
chord_player :g3, 4
sleep 0.5
chord_player :e3, 3

Ici j’ai utilisé repeats comme si c’était un nombre dans la ligne repeats.times do. J’ai aussi utilisé root comme si c’était un nom de note dans mon appel à play.

Voyez comme nous sommes capables d’écrire quelque chose de très expressif et facile à lire en déplaçant beaucoup de notre logique à l’intérieur d’une fonction !


5.6 - Variables

Une chose utile à faire dans votre code est d’attribuer des noms aux choses. Sonic Pi rend cela très facile, vous écrivez le nom que vous voulez utiliser, un signe égal (=), puis la chose dont vous voulez vous rappeler :

sample_name = :loop_amen

Ici, nous nous sommes ‘rappelés’ du symbole :loop_amen dans la variable sample_name. Nous pouvons maintenant utiliser sample_name partout où nous aurions utilisé :loop_amen. Par exemple :

sample_name = :loop_amen
sample sample_name

Il y a trois raisons principales pour utiliser des variables dans Sonic Pi : communication de la signification, gestion de la répétition et capture des résultats des choses.

Communication de la signification

Quand vous écrivez du code, c’est facile de ne penser qu’à dire à l’ordinateur comment faire le boulot - tant que l’ordinateur comprend, c’est OK. Toutefois, il est important de se rappeler qu’il n’y a pas que l’ordinateur qui lit le code. D’autres personnes peuvent aussi le lire et essayer de comprendre ce qu’il fait. En outre, il est probable que vous ayez à lire votre propre code dans le futur et à essayer de comprendre ce qui s’y passe. Bien que cela puisse vous sembler évident maintenant, ce pourrait ne pas être si évident pour les autres et pour vous-même dans le futur.

Un moyen d’aider les autres à comprendre ce que fait votre code est d’écrire des commentaires (comme nous l’avons vu dans une section précédente). Une autre façon est d’utiliser des noms de variables significatifs. Regardez ce code :

sleep 1.7533

Pourquoi utilise-t-il le nombre 1.7533 ? D’où est-il venu ? Qu’est-ce que cela signifie ? En revanche, regardez ce code :

loop_amen_duration = 1.7533
sleep loop_amen_duration

Maintenant,; il est beaucoup plus clair que 1.7533 signifie la durée de l’échantillon :loop_amen ! Bien sûr, vous pourriez dire pourquoi ne pas simplement écrire :

sleep sample_duration(:loop_amen)

Qui, bien entendu, est un moyen très sympathique de communiquer l’intention du code.

Gestion de la répétition

Vous voyez souvent beaucoup de répétitions dans votre code et quand vous voulez changer les choses, vous devez les changer à beaucoup d’endroits. Jetez un œil à ce code :

sample :loop_amen
sleep sample_duration(:loop_amen)
sample :loop_amen, rate: 0.5
sleep sample_duration(:loop_amen, rate: 0.5)
sample :loop_amen
sleep sample_duration(:loop_amen)

Nous sommes en train de faire beaucoup de choses avec :loop_amen ! Que faire si nous voulons écouter comment ça sonne avec un autre échantillon tel que :loop_garzul ? Nous aurons à trouver et remplacer tous les :loop_amen par :loop_garzul. Ce serait bien si vous disposiez de beaucoup de temps - mais que faire si vous œuvrez sur scène ? Quelquefois, vous n’aurez pas le luxe de temps disponible - en particulier si vous voulez que les gens continuent à danser.

Et si vous aviez écrit votre code comme ceci :

sample_name = :loop_amen
sample sample_name
sleep sample_duration(sample_name)
sample sample_name, rate: 0.5
sleep sample_duration(sample_name, rate: 0.5)
sample sample_name
sleep sample_duration(sample_name)

Maintenant, ça fait exactement la même chose qu’au dessus (essayez-le). Ça nous procure aussi la capacité de changer juste une ligne : sample_name = :loop_amen en sample_name = :loop_garzul et la magie des variables nous le change dans beaucoup d’endroits.

Capture des résultats

Finalement, une bonne motivation pour utiliser des variables est de capturer les résultats des choses. Par exemple, vous pouvez vouloir faire des choses avec la durée d’un échantillon :

sd = sample_duration(:loop_amen)

Nous pouvons maintenant utiliser sd partout où nous avons besoin de la durée de l’échantillon :loop_amen.

Plus important peut-être, une variable nous permet de capturer le résultat d’un appel à play ou sample :

s = play 50, release: 8

Maintenant, nous avons capturé et mémorisé s comme une variable, ce qui nous permet de contrôler le synthé pendant qu’il est actif :

s = play 50, release: 8
sleep 2
control s, note: 62

Nous verrons le contrôle des synthés en plus détaillé dans une prochaine section.


5.7 - Synchronisation des Threads

Une fois que vous êtes suffisamment avancés en codage “live” avec un certain nombre de fonctions et de threads en simultanéité, vous avez probablement remarqué que c’est plutôt facile de faire une faute dans l’un des threads et qui lui met fin. Ce n’est pas un gros problème car vous pouvez facilement redémarrer le thread en pressant Run. Toutefois, quand vous redémarrez le thread, il se trouve alors déphasé avec les threads d’origine.

Temps hérité

Comme nous en avons discuté auparavant, les nouveaux threads créés avec in_thread héritent de tous les paramètres du thread parent. Ceci inclut l’heure actuelle. Ce qui signifie que les threads sont toujours en phase entre eux quand ils sont démarrés simultanément.

Toutefois quand vous démarrez un thread tout seul, il démarre avec sa propre heure qui n’est probablement pas en phase avec l’un quelconque des autres threads en cours d’exécution.

Cue et Sync

Sonic Pi fourni une solution à ce problème avec les fonctions cue et sync.

cue nous permet d’envoyer nos messages de battement de coeur à tous les autres threads. Par défaut, les autres threads ne sont pas intéressés et ignorent ces messages de battement de coeur. Cependant, vous pouvez leur déclarer de l’intérêt avec la fonction sync.

La chose importante à laquelle il faut être attentif est similaire à sleep, en ce sens que cela arrête le thread courant en l’empêchant de faire quoi que ce soit pendant un moment. Toutefois, avec sleep, vous spécifiez combien de temps vous voulez attendre tandis qu’avec sync, vous ne savez pas combien de temps vous allez attendre - étant donné que sync attend le cue suivant d’un autre thread, ce qui peut être court ou long.

Explorons ceci en un peu plus de détail :

in_thread do
  loop do
    cue :tick
    sleep 1
  end
end

in_thread do
  loop do
    sync :tick
    sample :drum_heavy_kick
  end
end

Nous avons ici deux threads - l’un agissant comme un métronome, ne jouant aucun son mais envoyant des messages de battement de coeur tick à chaque temps. Le second thread se synchronise sur les messages tick et quand il en reçoit un, il hérite de l’heure du thread cue et continue de jouer.

Par conséquent, nous entendons l’échantillon :drum_heavy_kick
exactement quand l’autre thread envoie le message tick, même si les deux threads n’ont pas démarré leur exécution en même temps :

in_thread do
  loop do
    cue :tick
    sleep 1
  end
end

sleep(0.3)

in_thread do
  loop do
    sync :tick
    sample :drum_heavy_kick
  end
end

Ce vilain appel à sleep mettrait typiquement le second thread en déphasage avec le premier. Cependant, comme nous utilisons cue et sync, nous synchronisons automatiquement les threads en évitant un décalage de temps accidentel.

Noms des “Cue”

Vous êtes libre d’utiliser n’importe quel nom que vous aimeriez pour vos messages cue. Vous devez juste vous assurer que tout autre thread se synchronise sur le bon nom - autrement il attendrait à jamais (au moins jusqu’à ce que vous pressiez le bouton Stop).

Jouons avec quelques noms de cue :

in_thread do
  loop do 
    cue [:foo, :bar, :baz].choose
    sleep 0.5
  end
end

in_thread do
  loop do 
    sync :foo 
    sample :elec_beep
  end
end

in_thread do
  loop do
    sync :bar
    sample :elec_flip
  end
end

in_thread do
  loop do
    sync :baz
    sample :elec_blup
  end
end

Ici, nous avons une boucle principale cue qui envoie aléatoirement un des battements de coeur nommés :foo, :bar ou :baz. Nous avons aussi ensuite trois boucles en thread se synchronisant sur ces noms indépendamment et jouant un échantillon différent. Il est clair que nous entendons un son à chaque demi-temps puisque chacun des threads sync est aléatoirement synchronisé avec le thread cue et joue son échantillon.

Ceci, bien entendu, marche aussi si vous ordonnez les threads en sens inverse puisque les threads sync restent en attente du cue suivant.


6 - Studio FX (effets de studio)

Un des aspects les plus gratifiants et sympathiques de Sonic Pi est la capacité d’ajouter des effets de studio à vos sons. Par exemple, vous pouvez vouloir ajouter de la réverbération à des parties de votre œuvre, ou de l’écho et peut-être même de la distorsion ou du trémolo à vos lignes de basse.

Sonic Pi fournit un moyen très simple mais cependant puissant pour ajouter des effets (FX). Il vous autorise même à les chaîner (ainsi vous pouvez passer vos sons dans la distorsion, puis dans l’écho, puis dans la réverbération) et aussi à contrôler chaque unité FX individuellement avec des paramètres (d’une façon similaire à la spécification des paramètres pour les synthés et les échantillons). Vous pouvez même modifier les paramètres d’un FX pendant qu’il est encore en train d’agir. Ainsi, par exemple, vous pouvez augmenter la réverbération de vos basses tout au long de la piste…

Pédales de Guitare

Si tout ceci paraît un tantinet compliqué, ne vous inquiétez pas. Une fois que vous aurez joué un peu avec, tout deviendra complètement clair. Avant qu’il en soit ainsi, faisons une simple analogie avec des pédales FX de guitare. Il y a des tas de sortes de pédales FX que vous pouvez acheter. Quelques unes ajoutent de la réverbération, d’autres de la distorsion, etc. Un guitariste va brancher sa guitare à une pédale FX - de distorsion par exemple - puis prendre un autre câble pour lui connecter (chaîner) une pédale de réverbération. La sortie de la pédale de réverbération pourra alors être branchée à l’amplificateur :

Guitare -> Distorsion -> Réverbération -> Amplificateur

Cela s’appelle le chaînage des FX. Sonic Pi supporte exactement cela. De plus, chaque pédale a souvent des molettes et des curseurs pour vous permettre de contrôler le montant de la distorsion, de la réverbération, de l’écho, etc. à appliquer. Sonic Pi supporte aussi ce type de contrôle. Finalement, vous pouvez imaginer un guitariste jouant pendant que quelqu’un joue avec les contrôles FX même s’ils sont en train d’agir. Sonic Pi supporte aussi ceci - mais au lieu d’avoir besoin de quelqu’un d’autre pour contrôler les choses pour vous, c’est l’ordinateur qui intervient.

Explorons les FX !


6.1 - Ajout d’effets (FX)

Dans cette section, nous allons regarder un couple de FX : réverbération et écho. Nous allons voir comment les utiliser, comment contrôler leurs paramètres et comment les chaîner.

Le système des FX de Sonic Pi utilise les blocs. Donc, si vous n’avez pas lu la section 5.1, vous pourriez vouloir lui jeter un œil et puis revenir ici.

Réverbération

Si nous voulons utiliser la réverbération, nous écrivons with_fx :reverb en tant qu’entête particulière de notre bloc, comme ceci :

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Maintenant exécutez ce code et vous l’entendrez joué avec réverbération. Ça sonne bien, n’est-ce pas ! Toute chose sonne plutôt agréablement avec de la réverbération.

Maintenant, voyons ce qui se passe si nous avons du code en dehors du bloc do/end :

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

sleep 1
play 55

Remarquez que le dernier play 55 n’est pas joué avec de la réverbération. C’est parce qu’il est en dehors du bloc do/end, ainsi le FX de réverbération n’agit pas sur lui.

Similairement, si vous placez des sons avant le bloc do/end, ils ne seront pas non plus affectés :

play 55
sleep 1

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

sleep 1
play 55

Écho

Il y a beaucoup de FX au choix. Que dire au sujet de l’écho ?

with_fx :echo do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Un des puissants aspects des blocs FX de Sonic Pi est qu’on peut leur passer des paramètres de manière similaire aux paramètres que nous avons déjà vus avec play et sample. Par exemple, un paramètre sympa d’écho avec lequel jouer est phase:. Il représente la durée d’un écho en temps musicaux. Faisons l’écho plus lent :

with_fx :echo, phase: 0.5 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Faisons aussi l’écho plus rapide :

with_fx :echo, phase: 0.125 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Faisons décroître l’écho plus longuement en spécifiant la durée de decay: à 8 temps :

with_fx :echo, phase: 0.5, decay: 8 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Imbrication des FX

Un des aspects les plus puissants des blocs FX est que vous pouvez les imbriquer. Ce qui vous permet de chaîner facilement les FX entre eux. Par exemple, que faire si vous vouliez jouer du code avec de l’écho et ensuite de la réverbération ? Facile, mettez simplement l’un à l’intérieur de l’autre :

with_fx :reverb do
  with_fx :echo, phase: 0.5, decay: 8 do
    play 50
    sleep 0.5
    sample :elec_blup
    sleep 0.5
    play 62
  end
end

Pensez à du son provenant de l’intérieur et se propageant vers l’extérieur. Le son de tout le code situé dans le bloc intérieur dont play 50 est d’abord envoyé vers le FX écho et le son produit par le FX écho est à son tour envoyé vers le FX réverbération.

Nous pouvons utiliser des imbrications très profondes pour des résultats délirants. Toutefois, soyez averti, les FX peuvent utiliser beaucoup de ressources et quand vous les imbriquez, vous allez effectivement faire agir de multiples FX simultanément. Donc soyez économe avec l’utilisation des FX, en particulier sur des plateformes peu puissantes telles que le Raspberry Pi.

À la découverte des FX

Sonic Pi est livré avec un grand nombre de FX avec lesquels vous pouvez jouer. Pour trouver ceux qui sont disponibles, cliquez sur “FX” dans le menu horizontal du système d’aide et vous verrez une liste des options disponibles. Voici une liste de mes préférés :

Maintenant, défoulez-vous et ajoutez des effets partout pour obtenir d’étonnants sons nouveaux !


6.2 - FX en pratique

Bien qu’ils paraissent trompeusement simples extérieurement, les FX sont réellement des bêtes plutôt complexes à l’intérieur. Leur simplicité incite souvent les gens à en abuser dans leurs morceaux. Ce peut être sympathique si vous avez une machine puissante, mais si - comme moi - vous utilisez un Raspberry Pi pour improviser, vous devez prendre garde à la somme de travail que vous lui demandez de faire si vous voulez vous assurer que la cadence reste fluide.

Considérez ce code :

loop do
  with_fx :reverb do
    play 60, release: 0.1
    sleep 0.125
  end
end

Dans ce code, nous jouons la note 60 avec une durée d’extinction très courte, c’est donc une note courte. Nous voulons aussi de la réverbération, alors nous l’avons imbriqué dans un bloc de réverbération. Jusqu’à maintenant, tout est bon. Sauf que…

Regardons ce que fait le code. En premier lieu, nous avons une boucle (loop), ce qui signifie que tout ce qui est à l’intérieur est répété sans fin. Ensuite, nous avons un bloc with_fx. Ceci veut dire que nous allons créer un nouvel FX de réverbération chaque fois que nous bouclons. C’est comme si nous disposions d’une pédale de réverbération distincte à chaque fois que nous pincions une corde sur une guitare. C’est super de pouvoir faire ça, mais ce n’est pas toujours ce que vous voulez. Par exemple, ce code va avoir du mal à s’exécuter comme il faut sur un Raspberry Pi. Tout le travail de création de la réverbération puis d’attente jusqu’à ce qu’elle doive être stoppée et enlevée est complètement pris en charge par with_fx pour vous, mais ceci prend de la puissance du microprocesseur (CPU) qui peut être précieuse.

Comment le faire d’une manière plus proche d’une installation traditionnelle où notre guitariste n’a qu’une pédale de réverbération dans laquelle passent tous les sons ? Simple :

with_fx :reverb do
  loop do
    play 60, release: 0.1
    sleep 0.125
  end
end

Nous mettons notre boucle à l’intérieur du bloc with_fx. De cette façon, nous créons seulement une unique réverbération pour toutes les notes jouées dans notre boucle. Ce code est beaucoup plus efficace et fonctionnerait bien sur un Raspberry Pi.

Un compromis est d’utiliser with_fx sur une itération à l’intérieur d’une boucle :

loop do
  with_fx :reverb do
    16.times do
      play 60, release: 0.1
      sleep 0.125
    end
  end
end

De cette façon, nous avons remonté le with_fx en dehors de la partie la plus intérieure de la boucle, et nous créons maintenant une nouvelle réverbération toutes les 16 notes.

C’est quelque chose que l’on fait si souvent que with_fx supporte une option pour faire exactement cela sans devoir écrire le bloc 16.times :

loop do
  with_fx :reverb, reps: 16 do
    play 60, release: 0.1
    sleep 0.125
  end
end

Les deux exemples reps: 16 et 16.times do se comporteront de la même manière. L’exemple avec reps: 16 répète en fait le code dans le bloc do/end seize fois donc vous pouvez choisir l’un ou l’autre en fonction de vos préférences.

Rappelez-vous, il n’y a pas de fautes, juste des possibilités. Toutefois, certaines de ces approches donneront un son différent et auront des caractéristiques de performance différentes. Donc, jouez et utilisez l’approche qui sonne le mieux pour vous tout en restant dans les contraintes de performance de votre plateforme.


7 - Contrôle des sons en cours d’écoute

Pour l’instant, nous avons regardé comment déclencher des sons de synthé et des échantillons, et aussi comment changer leur paramètres par défaut comme amplitude, balance, paramètres d’enveloppe, et plus. Chaque son émis est essentiellement son propre son avec son propre ensemble de paramètres fixés pour la durée du son.

Ne serait-ce pas sympathique si nous pouvions changer les paramètres d’un son pendant qu’il est encore en train d’être joué, juste comme vous pourriez tendre une corde de guitare pendant qu’elle est en train de vibrer ?

Vous êtes chanceux - cette section va vous montrer précisément comment le faire.


7.1 - Contrôle des synthés en train de jouer

Pour l’instant, nous nous sommes seulement préoccupés de déclencher de nouveaux sons et effets (FX). Toutefois, Sonic Pi nous offre la capacité de manipuler et de contrôler les sons pendant qu’il sont joués. Nous le faisons en utilisant une variable pour mémoriser la référence à un synthé.

s = play 60, release: 5

Ici, nous avons une variable locale d’exécution s qui représente le synthé jouant la note 60. Notez que c’est local à l’exécution - vous ne pouvez pas y accéder depuis d’autres exécutions comme les fonctions.

Une fois que nous avons s, nous pouvons commencer à le contrôler via la fonction control :

s = play 60, release: 5
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

La chose à remarquer est que nous ne sommes pas en train de déclencher 4 synthés différents - Nous en déclenchons seulement un et puis nous changeons ensuite 3 fois la hauteur, pendant qu’il joue.

Nous pouvons passer n’importe quel paramètre standard à control, vous pouvez donc contrôler des choses telles que amp:, cutoff: ou pan.

Paramètres non contrôlables

Quelques paramètres ne peuvent pas être contrôlés une fois que le synthé joue. C’est le cas pour tous les paramètres d’enveloppe ADSR. Vous pouvez trouver quels paramètres sont contrôlables en regardant leur documentation dans le système d’aide. Si la documentation dit Can not be changed once set (ne peut être modifié une fois attribué), vous savez que ce n’est pas possible de contrôler le paramètre après que le synthé ait commencé à jouer.


7.2 - Contrôle des effets (FX)

Il est aussi possible de contrôler les FX, bien que ce soit accompli d’une manière légèrement différente :

with_fx :reverb do |r|
  play 50
  sleep 0.5
  control r, mix: 0.7
  play 55
  sleep 1
  control r, mix: 0.9
  sleep 1
  play 62
end

Au lieu d’utiliser une variable, nous utilisons le paramètre cible d’un bloc do/end. A l’intérieur des barres verticales |, nous devons attribuer un nom unique à notre FX en cours, nom que nous référençons alors depuis l’intérieur du bloc do/end.

Maintenant, allez et contrôlez des synthés et des FX !


7.3 - Paramètres glissants

Pendant l’exploration des arguments de pilotage des synthés et des FX, vous pourriez avoir remarqué qu’il y a un certain nombre de paramètres finissant par _slide. Vous avez peut-être même essayé de les appeler et n’avez constaté aucun effet. C’est parce que ce ne sont pas des paramètres normaux, ce sont des paramètres spéciaux qui n’agissent que quand vous contrôlez les synthés comme cela est décrit dans la section précédente.

Considérez l’exemple suivant :

s = play 60, release: 5
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Ici, vous pouvez entendre la hauteur du son changer instantanément après l’appel à control. Toutefois, nous pourrions souhaiter que la hauteur glisse entre les changements. Comme nous sommes en train de contrôler le paramètre note:, pour ajouter un glissement, nous devons fixer le paramètre note_slide du synthé :

s = play 60, release: 5, note_slide: 1
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Maintenant, nous entendons la hauteur des notes glisser entre les appels à control. Ça sonne agréablement, n’est-ce pas ? Vous pouvez accélérer le glissement en utilisant une durée plus courte comme note_slide: 0.2 ou le ralentir en utilisant une durée de glissement plus longue.

Chaque paramètre qui peut être contrôlé a un paramètre correspondant avec _slide à votre disposition.

Le glissement est rémanent

Une fois que vous avez fixé un paramètre _slide à un synthé en cours de jeu, il sera mémorisé et appliqué à chaque fois que le paramètre correspondant sera utilisé. Pour arrêter le glissement, vous devez fixer la valeur de _slide à 0 avant l’appel suivant à control.

Paramètres FX glissants

Il est aussi possible de faire glisser les paramètres FX :

with_fx :wobble, phase: 1, phase_slide: 5 do |e|
  use_synth :dsaw
  play 50, release: 5
  control e, phase: 0.025
end

Maintenant ayez du plaisir à faire glisser les choses pour obtenir des transitions douces et un contrôle fluide…


8 - Structures de données

Un outil très utile de la boîte à outil d’un programmeur est la structuration des données.

Quelquefois, vous souhaiteriez représenter et utiliser plus d’une seule chose à la fois, vous pourriez trouver utile de disposer d’une série de notes à jouer l’une après l’autre. Les langages de programmation offrent des structures de données pour autoriser précisément ceci.

Il y a beaucoup de structures de données passionnantes et exotiques à disposition des programmeurs - et on en invente toujours de nouvelles. Cependant, pour l’instant nous avons seulement et réellement besoin de nous intéresser à une structure de données très simple - la liste.

Regardons-la de manière plus détaillée. Nous allons décrire sa forme basique et ensuite montrer comment l’utiliser pour représenter des gammes et des accords.


8.1 - Listes

Dans cette section, nous allons voir une structure de données qui est très utile - la liste. Nous l’avons rencontrée brièvement auparavant dans la section sur la randomisation quand nous choisissions aléatoirement des notes à jouer dans une liste :

play choose([50, 55, 62])

Dans cette section, nous allons explorer l’utilisation des listes également pour représenter des accords et des gammes. En premier lieu, récapitulons comment nous jouerions un accord. Souvenez-vous que si nous n’utilisons pas sleep, les sons arrivent tous au même moment :

play 52
play 55
play 59

Regardons une autre façon d’écrire ce code.

Jeu d’une liste

Une option est de placer toutes les notes dans une liste : [52, 55, 59]. Notre sympathique fonction play est assez évoluée pour savoir comment jouer une liste de notes. Essayez-le :

play [52, 55, 59]

Ooh, c’est déjà plus agréable à lire. Jouer une liste de notes ne vous empêche pas d’utiliser n’importe quel paramètre des spécifications :

play [52, 55, 59], amp: 0.3

Bien sûr, vous pouvez aussi utiliser les noms traditionnels des notes (en notation anglaise) à la place des nombres de la norme MIDI :

play [:E3, :G3, :B3]

Maintenant, ceux qui sont assez chanceux pour avoir étudié quelques notions de solfège, pourraient reconnaître l’accord de Mi mineur joué à la 3ème octave.

Accès à une liste

Une autre caractéristique très utile d’une liste est d’en extraire de l’information. Ceci peut paraître étrange, mais ce n’est pas plus compliqué que de tourner les pages d’un livre jusqu’à la page 23. Avec une liste, vous diriez : quel est l’élément à l’index 23 ? La seule chose étrange est qu’en programmation, les index commencent généralement à 0 et non pas 1.

Avec les index de liste, nous ne comptons pas 1, 2, 3… mais 0, 1, 2…

Regardons ceci en un peu plus de détails. Jetez un œil sur cette liste :

[52, 55, 59]

Il n’y a rien là de particulièrement effrayant. Maintenant, quel est le second élément de la liste ? Oui, bien sûr, c’est 55. C’était facile. Regardons si nous pouvons obtenir la réponse de l’ordinateur :

puts [52, 55, 59][1]

OK, ça semble un peu bizarre si vous n’avez jamais vu quelque chose de la sorte auparavant. Faites-moi confiance toutefois, ce n’est pas trop dur. Il y a trois parties dans la ligne ci-dessus : le mot puts, notre liste 52, 55, 59 et notre index [1]. En premier, nous disons puts parce que nous voulons que Sonic Pi nous affiche la réponse dans le panneau “trace”. Ensuite, nous lui donnons notre liste, et enfin notre index qui demande le second élément. Nous devons encadrer notre index avec des crochets et parce que le compte commence à 0, l’index pour le second élément est 1. Regardez :

# index :  0   1   2
          [52, 55, 59]

Essayez d’exécuter le code puts [52, 55, 59][1] et vous verrez 55 apparaître dans le panneau “trace”. Changez l’index 1 par d’autres valeurs, essayez des listes plus longues et pensez à la façon dont vous pourriez utiliser une liste dans votre prochaine improvisation avec du code. Par exemple, quelles structures musicales pourraient être représentées par une série de nombres…


8.2 - Accords

Sonic Pi incorpore le support des noms d’accord, lequel retourne des listes. Essayez-le vous-même :

play chord(:E3, :minor)

Maintenant, nous avons vraiment progressé. Ça parait beaucoup plus joli que les listes brutes (et c’est plus facile à lire pour les autres). Alors quels autres accords Sonic Pi supporte-t-il ? Eh bien, un tas. Essayez quelques uns parmi ceux-ci :

Arpèges

Nous pouvons facilement changer les accords en arpèges avec la fonction play_pattern :

play_pattern chord(:E3, :m7)

OK, ce n’est pas si plaisant - ça le joue vraiment lentement. play_pattern va jouer chaque note de la liste en le séparant par un appel à sleep 1 entre chaque appel à play. Nous pouvons utiliser une autre fonction play_pattern_timed pour spécifier nos propres durées et accélérer les choses :

play_pattern_timed chord(:E3, :m7), 0.25

Nous pouvons même passer une liste de durées qui seront traitées de façon circulaire :

play_pattern_timed chord(:E3, :m13), [0.25, 0.5]

Ceci est équivalent à :

play 52
sleep 0.25
play 55
sleep 0.5
play 59
sleep 0.25
play 62
sleep 0.5
play 66
sleep 0.25
play 69
sleep 0.5
play 73

Que préférez-vous écrire ?


8.3 - Gammes

Sonic Pi supporte un large éventail de gammes. Comment faire pour jouer une gamme majeure de Do3 (C3) ?

play_pattern_timed scale(:c3, :major), 0.125, release: 0.1

Nous pouvons même demander plusieurs octaves :

play_pattern_timed scale(:c3, :major, num_octaves: 3), 0.125, release: 0.1

Comment obtenir toutes les notes d’une gamme pentatonique ?

play_pattern_timed scale(:c3, :major_pentatonic, num_octaves: 3), 0.125, release: 0.1

Notes aléatoires

Les accords et les gammes sont un grand moyen de contraindre un choix aléatoire à quelque chose de significatif. Jouez un instant avec cet exemple qui prend des notes aléatoirement dans l’accord mineur de Mi3 :

use_synth :tb303
loop do
  play choose(chord(:E3, :minor)), release: 0.3, cutoff: rrand(60, 120)
  sleep 0.25
end

Essayez de modifier cet exemple avec quelques noms d’accord différents et des plages de cutoff différentes.

Découverte des accords et des gammes

Pour trouver quelles gammes et quels accords sont supportés par Sonic
Pi, cliquez sur le bouton “Lang” du menu horizontal à gauche et au bas de la fenêtre, et choisissez soit “chord” (accord) ou “scale” (gamme) dans la liste du dessus. Dans le panneau d’information, faites défiler l’affichage vers le bas jusqu’à voir une longue liste d’accords ou de gammes (selon ce que vous êtes en train de chercher).

Faites-vous plaisir et rappelez-vous : il n’y a pas de fautes, que des opportunités.


8.4 - Anneaux

Un parcours circulaire intéressant sur les listes est fourni par les anneaux (“rings”). Si vous avez quelques connaissances en programmation, vous pourriez avoir eu affaire aux “ring buffers” ou aux “ring arrays”. Ici, nous allons juste voir les “rings” - c’est court et simple.

Dans la section précédente sur les listes, nous avons vu comment nous pouvions aller en chercher des éléments en utilisant le mécanisme d’indexage :

puts [52, 55, 59][1]

Maintenant, qu’arrive-t-il si vous voulez l’index 100 ? Eh bien, c’est clair qu’il n’y a pas d’élément à l’index 100 puisque la liste ne contient que trois éléments. Alors Sonic Pi retournera nil (qui veut dire “rien”).

Maintenant, imaginons que nous ayons un compteur tel que celui des temps musicaux et qui s’incrémente continuellement. Créons notre compteur et notre liste :

counter = 0
notes = [52, 55, 59]

Nous pouvons maintenant utiliser notre compteur pour accéder à une note de notre liste :

puts notes[counter]

Super, nous avons obtenu 52. Maintenant, incrémentons notre compteur et obtenons une autre note :

counter = (inc counter)
puts notes[counter]

Super, nous obtenons maintenant 55 et si nous le faisons une nouvelle fois, nous obtenons 59. Toutefois, si nous le faisons encore une nouvelle fois, nous allons nous trouver en dehors des nombres de notre liste et obtenir nil. Que faire si nous voulions juste boucler en revenant en arrière et recommencer au début de la liste ? C’est pour cela que les anneaux (“rings”) sont faits.

Création des anneaux

Nous pouvons créer des anneaux de deux façons. Ou bien nous utilisons la fonction ring avec les élements de l’anneau comme paramètres :

(ring 52, 55, 59)

Ou bien nous pouvons prendre une liste normale et la convertir en anneau en lui envoyant le message .ring :

[52, 55, 59].ring

Indexation des anneaux

Une fois que nous avons un anneau, nous pouvons l’utiliser de la même manière que nous utiliserions une liste normale avec l’exception que nous pouvons utiliser des index négatifs ou des index qui sont plus grands que la taille de l’anneau, et ils vont boucler tout autour jusqu’à pointer sur un des éléments de l’anneau :

(ring 52, 55, 59)[0] #=> 52
(ring 52, 55, 59)[1] #=> 55
(ring 52, 55, 59)[2] #=> 59
(ring 52, 55, 59)[3] #=> 52
(ring 52, 55, 59)[-1] #=> 59

Utilisation des anneaux

Mettons que nous utilisions une variable pour représenter le numéro de battement courant. Nous pouvons l’utiliser comme un index de notre anneau pour aller chercher les notes à jouer, ou les durées d’extinction ou n’importe quelle chose utile que nous avons mémorisée dans notre anneau sans se préoccuper de la valeur du numéro de battement en cours.

Les gammes et les accords sont des anneaux

Une chose utile à savoir est que les listes retournées par scale et chord sont aussi des anneaux et cela vous autorise à les accéder avec des valeurs d’index arbitraires.

Constructeurs d’anneaux

En sus de ring, il y a un certain nombre de fonctions qui vous construiront un anneau.

Jetez un œil à leur documentation respective pour plus d’information.


En plus des constructeurs comme range et spread, une autre façon de créer de nouveaux anneaux est de manipuler des anneaux existants.

Commandes de chaîne

Pour explorer ceci, prenons un anneau simple :

(ring 10, 20, 30, 40, 50)

Et si on voulait son inverse ? Eh bien on utiliserait la commande de chaîne .reverse pour prendre l’anneau et l’inverser :

(ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)

Et si on voulait les trois premières valeurs de l’anneau ?

(ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)

Enfin, et si on voulait mélanger l’anneau ?

(ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)

Chaînes multiples

C’est déjà une manière puissante de créer de nouveaux anneaux. Ceci dit la vraie puissance vient quand on enchaîne quelques unes de ces commandes à la suite.

Et si on mélangeait l’anneau, on lâchait un élément puis on en prenait les trois suivants ?

Regardons ceci par étapes :

  1. (ring 10, 20, 30, 40, 50) - notre anneau initial
  2. (ring 10, 20, 30, 40, 50).shuffle - mélange - (ring 40, 30, 10, 50, 20)
  3. (ring 10, 20, 30, 40, 50).shuffle.drop(1) - en lâche un - (ring 30, 10, 50, 20)
  4. (ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3) - en prend trois - (ring 30, 10, 50)

Vous voyez comme on peut créer une longue chaîne de ces méthodes juste en les collant à la suite. On peut les combiner dans l’ordre qu’on veut, ce qui crée une manière extrêmement riche et puissante de générer de nouveaux anneaux à partir d’anneaux existants.

Immutabilité

Ces anneaux ont une propriété puissante et importante. Ils sont immutables, ce qui veut dire qu’ils ne peuvent pas changer. Cela veut dire que les méthodes de chaîne décrites dans cette section ne changent pas les anneaux, elles créent plutôt de nouveaux anneaux. Cela veut dire que vous êtes libres de partager des anneaux entre fils et de les chaîner dans un fil en sachant que vous n’affecterez aucun autre fil qui utilise le même anneau.

Méthodes de chaîne disponibles

Voici une liste des méthodes de chaîne disponibles :

Evidemment, les méthodes de chaîne qui prennent des nombres peuvent prendre d’autres nombres aussi ! N’hésitez donc pas à appeler .drop(5) au lieu de .drop(3) si vous voulez lâcher les cinq premiers éléments.


9 - Codage en “live”

Un des aspects les plus passionnants de Sonic Pi est qu’il vous permet d’écrire et de modifier du code en “live” pour faire de la musique, juste comme vous le feriez avec une guitare. Un avantage de cette approche est qu’il vous procure plus de feedback pendant que vous composez (avoir une simple boucle en cours d’exécution et continuer à l’ajuster jusqu’à qu’elle sonne parfaitement). Cependant, le principal avantage est que vous pouvez amener Sonic Pi sur scène et donner un concert avec.

Dans cette section, nous allons couvrir les fondamentaux du changement de vos compositions en interprétations dynamiques avec du code statique.

Tenez-vous bien…


9.1 - Codage en “live”

Maintenant nous en avons suffisamment appris pour commencer réellement à prendre du plaisir. Dans cette section, nous allons mettre en pratique toutes les sections précédentes et vous montrer comment commencer à faire vos compositions musicales en “live” et les transformer en interprétations. Pour cela, nous aurons besoin de trois ingrédients principaux :

D’accord, allons-y. Codons en “live” nos premiers sons. En premier lieu, nous avons besoin d’une fonction contenant le code que nous voulons jouer. Commençons simple. Nous voulons aussi une boucle d’appels à cette fonction dans un thread :

define :my_loop do
  play 50
  sleep 1
end

in_thread(name: :looper) do
  loop do
    my_loop
  end
end

Si ça vous semble un petit peu trop compliqué, revenez en arrière et relisez les sections sur les fonctions et les threads. Ce n’est pas trop compliqué si vous avez déjà emmagasiné ces choses dans votre tête.

Ce que nous avons ici est une définition de fonction qui joue juste la note 50 et qui dort pendant un temps musical. Nous définissons ensuite un thread nommé :looper qui simplement boucle en appelant my_loop de manière répétitive.

Si vous exécutez ce code, vous entendrez la note 50 répétée encore et encore…

Modifions-le

Maintenant, c’est là que le plaisir commence. Pendant que le code est encore en cours d’exécution changez 50 en un autre nombre, disons 55, ensuite pressez le bouton “Run” une nouvelle fois. Woah ! C’est modifié ! En “live” !

Une nouvelle couche n’a pas été ajoutée parce que nous avons utilisé des threads nommés et que seul un thread est permis pour chaque nom. En outre, le son a changé parce que nous avons redéfini la fonction. Nous avons donné à :my_loop une nouvelle définition. Quand le thread :looper a rebouclé, il a simplement appelé la nouvelle définition.

Essayez de le modifier encore, changez la note, changer la durée de sleep. Comment faire pour ajouter un ordre use_synth ? Par exemple, changez-le en :

define :my_loop do
  use_synth :tb303
  play 50, release: 0.3
  sleep 0.25
end

Maintenant, ça sonne plutôt intéressant, mais on peut le pimenter un peu plus. Au lieu de jouer la même note encore et encore, essayez de jouer un accord :

define :my_loop do
  use_synth :tb303
  play chord(:e3, :minor), release: 0.3
  sleep 0.5
end

Comment faire pour jouer des notes de l’accord aléatoirement :

define :my_loop do
  use_synth :tb303
  play choose(chord(:e3, :minor)), release: 0.3
  sleep 0.25
end

Ou utiliser une valeur de cutoff aléatoire :

define :my_loop do
  use_synth :tb303
  play choose(chord(:e3, :minor)), release: 0.2, cutoff: rrand(60, 130)
  sleep 0.25
end

Finalement, ajoutons quelques notes de batterie :

define :my_loop do
  use_synth :tb303
  sample :drum_bass_hard, rate: rrand(0.5, 2)
  play choose(chord(:e3, :minor)), release: 0.2, cutoff: rrand(60, 130)
  sleep 0.25
end

Maintenant, les choses commencent à devenir passionnantes !

Toutefois, avant que vous bondissiez et que vous vous lanciez dans le codage en “live” avec des fonctions et des threads, arrêtez ce que vous êtes en train de faire et lisez la section suivante sur live_loop qui va vous changer à jamais votre façon de coder dans Sonic Pi…


9.2 - Boucles en “live”

Ok, ainsi cette section est la véritable perle. Si vous ne lisez qu’une section, ce devrait être celle-ci. Si vous avez lu la section précédente sur les fondamentaux du codage en “live”, live_loop est une manière simple de faire exactement la même chose mais sans avoir tant à écrire.

Si vous n’avez pas lu la section précédente, live_loop est la meilleure façon d’improviser avec Sonic Pi.

Jouons. Ecrivez le code suivant dans un buffer :

live_loop :foo do
  play 60
  sleep 1
end

Maintenant pressez le bouton “Run”. Vous entendez un beep basique à chaque temps. Rien de plaisant pour l’instant. Toutefois, ne pressez pas tout de suite le bouton “Stop”. Changez le 60 en 65 et pressez “Run” à nouveau.

Woah ! Ça a changé automatiquement sans manquer un temps. C’est du codage en “live”.

Pourquoi ne pas le modifier pour ressembler plus à une basse ? Modifiez juste votre code pendant que ça joue :

live_loop :foo do
  use_synth :prophet
  play :e1, release: 8
  sleep 8
end

Puis pressez “Run”.

Faisons bouger le cutoff aléatoirement :

live_loop :foo do
  use_synth :prophet
  play :e1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Puis pressez “Run” à nouveau.

Ajoutez de la batterie :

live_loop :foo do
  sample :loop_garzul
  use_synth :prophet
  play :e1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Changez la note de e1 en c1 :

live_loop :foo do
  sample :loop_garzul
  use_synth :prophet
  play :c1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Maintenant, arrêtez de me suivre et jouez vous-même ! Prenez du plaisir !


9.3 - Boucles multiples en “live”

Considérez la boucle en “live” suivante :

live_loop :foo do
  play 50
  sleep 1
end

Vous pouvez vous être demandé pourquoi elle avait besoin du nom :foo. Ce nom est important parce qu’il signifie que cette boucle est différente des autres boucles en “live”.

Il ne peut y avoir deux boucles en “live” en cours d’exécution avec le même nom

Ce qui signifie que si nous voulons de multiples boucles en “live” s’exécutant en simultané, nous devons simplement leur donner des noms différents :

live_loop :foo do
  use_synth :prophet
  play :c1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

live_loop :bar do
  sample :bd_haus
  sleep 0.5
end

Vous pouvez maintenant modifier et changer chaque boucle indépendamment et simplement tout fonctionne.

Synchronisation des boucles en “live”

Une chose que vous pourriez avoir déjà remarqué est que ces boucles en “live” fonctionnent automatiquement avec le mécanisme de thread que nous avons exploré précédemment. Chaque fois qu’une “live loop” boucle, elle génère un nouvel événement cue avec le même nom que la boucle. Par conséquent, nous pouvons nous sync sur ces cues pour garantir que ces boucles soient synchronisées sans avoir à arrêter quoi que ce soit.

Considérez ce code mal synchronisé :

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.4
end

live_loop :bar do
  sample :bd_haus
  sleep 1
end

Voyons si nous pouvons corriger le timing et synchroniser sans arrêter l’exécution. Corrigeons la boucle :foo pour l’aligner sur le facteur de sleep de 1 - quelque chose comme 0.5 fera l’affaire :

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.5
end

live_loop :bar do
  sample :bd_haus
  sleep 1
end

Cependant, nous n’avons pas encore tout à fait fini - vous remarquerez que les temps ne battent pas ensemble correctement. C’est parce que les boucles sont déphasées. Corrigeons cela en les synchronisant :

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.5
end

live_loop :bar do
  sync :foo
  sample :bd_haus
  sleep 1
end

Wow, tout est maintenant parfaitement en phase - tout cela sans arrêter.

Maintenant, allez de l’avant et codez en “live” avec des “live loops” !


9.4 - Avance automatique (“ticking”)

Il est probable que vous vous trouverez quelquefois en train d’en faire des tas quand votre codage en “live” consistera à boucler au travers d’anneaux. Vous mettrez des notes dans des anneaux (“rings”) pour les mélodies, des “sleeps” pour les rythmes, des progressions d’accords, des variations de timbre, etc. etc.

Parcours automatique des anneaux

Sonic Pi fournit un outil très pratique pour travailler avec des anneaux (“rings”) à l’intérieur des live_loops. Il s’agit du système d’avance automatique (“tick”). Dans la section sur les anneaux on parlait d’un compteur qui augmente constamment, comme un nombre courant de battement. “Tick” implémente justement cette idée. Il vous fournit la capacité de parcourir des anneaux. Regardons un exemple :

counter = 0
live_loop :arp do
  play (scale :e3, :minor_pentatonic)[counter], release: 0.1
  counter += 1
  sleep 0.125
end

C’est l’équivalent de :

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick, release: 0.1
  sleep 0.125
end

Ici, nous prenons simplement la gamme mineure pentatonique de Mi3 et nous la parcourons élement par élément. C’est réalisé en ajoutant .tick à la fin de la déclaration de la gamme. Ce “tick” est local à la boucle live, ainsi chaque boucle live a son propre “tick” indépendant :

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick, release: 0.1
  sleep 0.125
end

live_loop :arp2 do
  use_synth :dsaw
  play (scale :e2, :minor_pentatonic, num_octaves: 3).tick, release: 0.25
  sleep 0.25
end

Fonction Tick

Vous pouvez également appeler tick comme une fonction standard et utiliser sa valeur de retour comme un index :

live_loop :arp do
  idx = tick
  play (scale :e3, :minor_pentatonic)[idx], release: 0.1
  sleep 0.125
end

Cependant, c’est plus joli d’appeler .tick à la fin. La fonction .tick est faite pour les cas où vous voulez faire des fantaisies avec la valeur retournée ou utiliser les “ticks” pour autre chose que l’indexation des anneaux.

Fonction Look

La chose magique apportée par “tick” est que non seulement un nouvel index est retourné (ou la valeur de l’anneau à cet index) mais qu’il garantit que la fois suivante où vous l’appellerez, vous obtiendrez la valeur suivante. Jetez un œil sur les exemples de la documentation de .tick pour voir les différentes façons de l’employer. Toutefois, pour le moment, il est important de souligner que quelquefois, vous voulez juste obtenir la valeur courante de “tick” sans l’incrémenter. Ceci est disponible via la fonction look. Vous pouvez appeler look comme une fonction standard ou ajouter .look à la fin d’un anneau.

Nommage des Ticks

Finalement, vous avez quelquefois besoin de plus d’un “tick” par boucle live. C’est réalisé en donnant un nom à vos “ticks” :

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick(:foo), release: 0.1
  sleep (ring 0.125, 0.25).tick(:bar)
end

Ici, nous utilisons deux “ticks”, un pour la note à jouer et un autre pour la durée de “sleep”. Comme ils sont tous deux dans la même boucle, pour les maintenir indépendants, nous devons leur donner des noms uniques. C’est exactement le même genre de solution que dans le cas
du nommage des live_loops - nous passons simplement un symbole précédé d’un :. Dans l’exemple ci-dessus, nous avons appelé un “tick” :foo et l’autre :bar. Si nous voulons juste connaître leur valeur, nous devons aussi passer le nom du “tick” à look.

Ne faites pas de choses trop compliquées

La plupart de la puissance du système des “ticks” n’est pas utile quand vous débutez. N’essayez pas et n’apprenez pas tout de cette section. Concentrez-vous seulement sur le parcours d’un simple anneau. Cela vous procurera la plus grande part de la joie et de la simplicité du parcours des anneaux dans vos live_loops.

Jetez un œil sur la documentation des ticks où se trouvent de nombreux exemples utiles, et joyeux parcours automatiques !


10 - Connaissances essentielles

Cette section va couvrir des connaissances très utiles - en vérité essentielles - pour obtenir le meilleur de votre expérimentation de Sonic Pi.

Nous couvrirons comment prendre avantage des nombreux raccourcis clavier mis à votre disposition, comment partager votre travail et quelques trucs sur l’interprétation musicale avec Sonic Pi.


10.1 - Utilisation des raccourcis clavier

Sonic Pi est plus un instrument qu’un environnement de programmation. Les raccourcis peuvent cependant rendre votre jeu avec Sonic Pi plus efficace et naturel - particulièrement quand vous jouez en “live” devant un auditoire.

La plus grande part de Sonic Pi peut être contrôlée au moyen du clavier. Au fur et à mesure que vous deviendrez plus familier dans la pratique et l’interprétation avec Sonic Pi, vous commencerez probablement à utiliser de plus en plus de raccourcis. Personnellement, je tape sans regarder le clavier (je recommande que vous appreniez à le faire aussi) et je me sens frustré quand j’ai besoin d’attraper la souris parce que ça me retarde. J’utilise donc tous ces raccourcis très régulièrement.

Par conséquent, si vous apprenez les raccourcis, vous saurez utiliser efficacement votre clavier et vous coderez en “live” comme un pro.

Toutefois, n’essayez pas de les apprendre tous à la fois, essayez et souvenez-vous simplement de ceux que vous utilisez le plus et continuez à en ajouter en supplément à votre pratique.

Compatibilité entre plateformes

Imaginez que vous appreniez la clarinette. Vous vous attendriez à ce que toutes les clarinettes aient les mêmes contrôles et le même doigté. Si elles ne l’avaient pas, vous passeriez un moment pénible à basculer entre différentes clarinettes et vous seriez enclin à rester toujours avec la même.

Malheureusement, les trois systèmes d’exploitation principaux (Linux, Mac OS X et Windows) se présentent avec leurs propres standards par défaut pour des actions telles que copier/coller. Sonic Pi va essayer d’honorer ces standards. Toutefois la priorité est de favoriser la compatibilité entre plateformes avec Sonic Pi plutôt que de tenter de se conformer aux standards d’une plateforme donnée. Ceci signifie que quand vous apprenez les raccourcis de jeu avec Sonic Pi sur votre Raspberry Pi, vous pouvez passer au Mac ou au PC et vous retrouver en terre connue.

“Control” et “Meta”

Une part de la notion de compatibilité est l’appellation des raccourcis. Dans Sonic Pi, nous utilisons les termes Control et Meta pour se référer aux deux combinaisons de touches principales. Sur toutes les plateformes Control (Ctrl) est identique. Toutefois, sur Linux et Windows, Meta est en réalité la touche Alt alors que sur Mac, Meta est la touche Command (Cmd). Pour la compatibilité, nous utiliserons le terme Meta - rappelez-vous juste de le faire correspondre à la touche appropriée sur votre système d’exploitation.

Abréviations

Pour conserver les choses simples et lisibles, nous utiliserons les abréviations C- pour Control plus une autre touche et M- pour Meta plus une autre touche. Par exemple, si un raccourci consiste à maintenir enfoncées à la fois meta et r, nous l’écrirons M-r. Le - veut dire simplement “en même temps que”.

Voici ci-dessous les raccourcis que j’estime les plus utiles :

Arrêt et Départ

Au lieu de toujours attraper la souris pour exécuter votre code, vous pouvez simplement presser M-r. Similairement, pour stopper l’exécution de votre code, vous pouvez presser M-s.

Je suis vraiment perdu sans les raccourcis de navigation. Je recommande donc vivement que vous passiez du temps à les apprendre. Ces raccourcis fonctionnent aussi extrèmement bien quand vous apprenez à taper sans regarder le clavier parce qu’ils utilisent des lettres standards sans nécessiter de déplacer votre main jusqu’à la souris ou jusqu’aux touches flèches de votre clavier.

Vous pouvez vous déplacer au début de la ligne avec C-a, à la fin de la ligne avec C-e, à la ligne du dessus avec C-p, à la ligne du dessous avec C-n, avancer d’un caractère avec C-f, reculer d’un caractère avec C-b. Vous pouvez même effacer tous les caractères depuis le curseur jusqu’à la fin de la ligne avec C-k.

Code ordonné

Pour aligner et indenter automatiquement vos lignes de code, pressez M-m.

Système d’aide

Pour afficher/cacher le système d’aide vous pouvez presser M-i. Toutefois un raccourci plus utile à connaître est C-i. Il détecte le mot où se trouve le curseur et affiche la documentation le concernant s’il la trouve. Aide instantanée !

Pour une liste complète, jetez un œil à la section 10.2 - Antisèche des raccourcis.


10.2 - Antisèche des raccourcis

Ce qui suit est un récapitulatif des principaux raccourcis clavier disponibles avec Sonic Pi. Voyez S.V.P. la section 10.1 pour la motivation et le contexte.

Conventions

Dans cette liste, nous utilisons les conventions suivantes (où Meta est la touche Alt pour Windows/Linux et Cmd sur Mac) :

Manipulation de l’Application principale

Sélection/Copier/Coller

Manipulation du texte

Suppression

Fonctionnalités avancées de l’éditeur


10.3 - Partage

Sonic Pi a tout ce qu’il faut pour étudier et partager avec les autres.

Une fois que vous avez appris comment coder de la musique, partager vos compositions est aussi simple que d’envoyer un mail contenant votre code. S.V.P. partagez votre code avec les autres, ainsi ils pourront apprendre de votre travail et même en utiliser des parties dans un nouveau “mashup”.

Si vous n’êtes pas sûr de connaître le meilleur moyen de partager votre travail avec les autres, je vous recommande de mettre votre code sur GitHub et votre musique sur SoundCloud. De cette manière vous pourrez atteindre un grand auditoire.

Code -> GitHub

GitHub est un site pour partager et travailler avec du code. Il est utilisé aussi bien par des développeurs professionnels que par des artistes pour partager et collaborer avec du code. La manière la plus simple pour partager un morceau de code (ou même un morceau non terminé) est de créer un Gist. Un Gist est un moyen simple de déposer votre code afin que les autres y aient accès de manière simple : voir, copier, et partager.

Audio -> SoundCloud

Une autre façon importante de partager votre travail est d’enregistrer l’audio et de déposer l’enregistrement sur SoundCloud. Une fois que vous avez déposé votre morceau, les autres peuvent commenter et discuter votre travail. Je vous recommande aussi de placer un lien vers le Gist de votre code dans la description de la piste.

Pour enregistrer votre travail, pressez le bouton Rec de la barre d’outils, et l’enregistrement démarre immédiatement. Pressez Run pour lancer votre code s’il n’est pas encore démarré. Quand votre enregistrement devra être arrêté, pressez le bouton Rec clignotant à nouveau, et il vous sera demandé d’entrer un nom de fichier. L’enregistrement sera sauvegardé dans le format d’un fichier WAV, lequel peut être modifié et converti en MP3 par n’importe quel programme gratuit (essayez Audacity par exemple).

Espoir

Je vous encourage à partager votre travail et espère vraiment que nous allons tous nous apprendre de nouvelles astuces et progresser avec Sonic Pi. Je suis réellement enthousiaste de ce que vous allez avoir à me montrer.


10.4 - Se produire

Un des aspects les plus passionnants de Sonic Pi est qu’il vous permet d’utiliser le code comme un instrument de musique. Ce qui signifie qu’écrire du code en “live” peut maintenant être considéré comme une nouvelle manière d’interpréter de la musique.

Nous appelons ceci codage en “live”.

Montrez votre écran

Quand vous codez en “live”, je vous recommande de montrer votre écran à votre auditoire. Autrement, c’est comme jouer de la guitare, mais en cachant vos doigts et les cordes. Quand je pratique à la maison, j’utilise un Raspberry Pi et un mini projecteur sur le mur de mon salon. Vous pouvez utiliser votre TV ou une de vos lampes de bureau pour faire un “show”. Essayez-le, c’est beaucoup de plaisir.

Formez un orchestre

Ne jouez pas juste pour vous seul - formez un orchestre de codage en “live”. C’est beaucoup de plaisir que d’improviser avec d’autres. Une personne pourrait faire la rythmique, une autre faire le fond ambiant, etc. Recherchez les combinaisons de sons que vous pouvez avoir ensemble.

TOPLAP

Le codage en “live” n’est pas totalement nouveau - un petit nombre de personnes l’on pratiqué maintenant depuis quelques années, typiquement en utilisant des systèmes sur mesure qu’ils avaient élaborés eux-mêmes. Un super site à visiter pour trouver plus d’informations sur les codeurs en “live” et leurs systèmes est TOPLAP.

Algorave

Une autre super ressource pour explorer le monde du codage en “live” est Algorave. Vous trouverez là tout sur une branche spécifique du codage en “live” pour faire de la musique dans les boîtes de nuit.


11 - Minecraft Pi

Sonic Pi supporte maintenant une simple API (interface de programmation) pour interagir avec Minecraft Pi - l’édition spéciale de Minecraft qui est installée par défaut avec le système d’exploitation Raspbian Linux du Raspberry Pi.

Importation de bibliothèques non nécessaire

L’intégration avec Minecraft Pi a été conçue pour être extrêmement simple à utiliser. Tout ce dont vous avez besoin est de lancer Minecraft Pi et de créer un nouveau monde. Il vous est alors possible d’utiliser les fonctions mc_* juste comme vous pourriez utiliser play et synth. Il n’y a pas besoin d’importer quoi que ce soit ou d’installer des bibliothèques - c’est tout prêt à utiliser et à fonctionner sans autre procès.

Connection Automatique

L’API à Minecraft Pi se préoccupe de la gestion de votre connexion à l’application Minecraft Pi. Ce qui signifie que vous n’avez pas besoin de vous en inquiéter. Si vous essayez d’utiliser l’API à Minecraft Pi quand Minecraft Pi n’est pas démarré, Sonic Pi vous en avertira poliment. Similairement, si vous arrêtez Minecraft Pi quand vous êtes encore en train d’exécuter une live_loop qui utilise l’API, la boucle s’arrêtera et vous avertira poliment de l’impossibilité de se connecter. Pour vous reconnecter, relancer simplement Minecraft Pi, Sonic Pi le détectera automatiquement et recréera la connection pour vous.

Conçue pour être codée en “live”

L’API à Minecraft a été conçue pour fonctionner sans heurt à l’intérieur des live_loops. Ce qui signifie qu’il est possible de synchroniser des modifications de vos mondes de Minecraft Pi avec des modifications de vos sons de Sonic Pi. Des vidéos sur le vif avec musique basée sur Minecraft ! Notez cependant que Minecraft Pi est un logiciel en phase alpha et qu’il est connu pour être légèrement bogué. Si vous rencontrez un problème quelconque, relancez simplement Minecraft Pi et continuez comme avant. La fonctionnalité de connexion automatique de Sonic Pi prendra soin des choses pour vous.

Nécessite un Raspberry Pi 2.0

Il est vivement recommandé d’utiliser un Raspberry Pi 2 si vous voulez exécuter à la fois Sonic Pi et Minecraft en même temps
- particulièrement si vous voulez utiliser les capacités sonores de Sonic Pi.

Support de l’API

À cette étape, Sonic Pi supporte les manipulations basiques des joueurs et des blocs qui sont détaillées dans la section 11.1. Le support pour les callbacks d’évènements générés par les interactions des joueurs dans le monde est planifié pour une version future.


11.1 - Basique API à Minecraft Pi

Sonic Pi supporte actuellement les interactions basiques suivantes avec Minecraft Pi :

Voyons chacune d’elles tour à tour.

Affichage de messages de “chat”

Voyons juste comme c’est facile de contrôler Minecraft Pi depuis Sonic Pi. Assurez-vous d’abord que vous avez Minecraft Pi et Sonic Pi actifs en même temps et assurez-vous aussi que vous êtes entré dans un monde de Minecraft et que vous pouvez vous y déplacer.

Dans un buffer vierge de Sonic Pi, entrez le code suivant :

mc_message "Hello from Sonic Pi"

Quand vous pressez le bouton Run, vous verrez votre message clignoter dans la fenêtre de Minecraft. Félicitations, vous avez écrit votre premier code Minecraft ! C’était facile, n’était-ce pas ?

Fixation de la position de l’utilisateur

Maintenant, essayons un peu de magie. Téléportons-nous quelque-part ! Essayez le code suivant :

mc_teleport 50, 50, 50

Quand vous pressez le bouton Run - boum ! Vous avez été intantanément transporté à un nouvel endroit. Le plus probablement, c’était dans le ciel et vous êtes tombé soit sur la terre ferme, soit dans l’eau. Maintenant, quels sont ces nombres : 50, 50, 50 ? Ce sont les coordonnées de l’endroit où vous essayiez d’être téléporté. Prenons un bref moment pour explorer ce que sont ces coordonnées et comment elles fonctionnent parce qu’elles sont réellement, réellement importantes pour programmer Minecraft.

Coordonnées

Imaginez une carte de pirate avec un grand X marquant l’emplacement d’un trésor. L’emplacement exact du X peut être décrit avec deux nombres - à quelle distance du bord gauche de la carte en allant vers la droite et à quelle distance du bord inférieur de la carte en allant vers le haut il se trouve. Par exemple, 10cm en horizontal et 8cm en vertical. Ces deux nombres 10 et 8 sont des coordonnées. Vous pourriez imaginer aisément le description des endroits d’autres cachettes de trésor avec d’autres paires de nombres. Peut-être y-a-t-il un gros coffre d’or à 2 en horizontal et à 9 en vertical…

Maintenant, dans Minecraft, deux nombres ne sont pas tout à fait suffisants. Nous devons aussi savoir à quelle hauteur nous sommes. Nous avons donc besoin de trois nombres :

Trouver vos coordonnées courantes

Jouons avec les coordonnées. Naviguez vers un bel endroit de la carte de Minecraft et puis basculez sur Sonic Pi. Maintenant, entrez le code suivant :

puts mc_location

Quand vous pressez le bouton Run, vous voyez les coordonnées de votre position courante affichées dans le panneau “trace”. Prenez en note, puis déplacez-vous dans le monde et essayez à nouveau. Notez comme les coordonnées ont changé ! Maintenant, je vous recommande de passer quelque temps à refaire exactement cela - vous déplacer un peu dans le monde, regarder les coordonnées et recommencer. Faites cela jusqu’à ce que vous commenciez à être à l’aise sur la manière dont changent les coordonnées quand vous vous déplacez. Une fois que vous avez compris comment fonctionnent les coordonnées, programmer avec l’API à Minecraft sera du gâteau.

Construisons !

Maintenant que vous savez comment trouver la position courante et vous téléporter en utilisant les coordonnées, vous avez tous les outils dont vous avez besoin pour commencer à construire des choses dans Minecraft avec du code. Disons que vous voulez faire du bloc avec les coordonnées 40, 50, 60 un bloc “glass” (de verre). C’est super facile :

mc_set_block :glass, 40, 50, 60

Ha ha, c’était vraiment facile. Pour voir le résultat de votre travail pratique, téléportez-vous aux alentours et regardez :

mc_teleport 35, 50, 60

Maintenant, tourner autour de vous et vous devriez voir votre bloc de verre ! Essayez de le changer en diamant :

mc_set_block :diamond, 40, 50, 60

Si vous regardiez dans la bonne direction, vous auriez même pu voir le changement devant vos yeux ! C’est le début de quelquechose de passionnant…

Recherche du type de bloc

Regardons une dernière chose avant d’aller vers quelque chose d’un peu plus compliqué. Étant donné un jeu de coordonnées, nous pouvons demander à Minecraft quel est le type d’un bloc spécifique à cet endroit. Essayons-le avec le bloc de diamant que vous venez de créer :

puts mc_get_block 40, 50, 60

Ouais ! C’est :diamond. Essayez de le faire revenir au verre et demandez à nouveau - Dit-il vraiment :glass maintenant ? je suis certain que oui :-)

Types de bloc disponibles

Avant que vous alliez vers un déchaînement de codage de Minecraft Pi, vous pourriez trouver utile cette liste des types de blocs disponibles :

    :air
    :stone
    :grass
    :dirt
    :cobblestone
    :wood_plank
    :sapling
    :bedrock
    :water_flowing
    :water
    :water_stationary
    :lava_flowing
    :lava
    :lava_stationary
    :sand
    :gravel
    :gold_ore
    :iron_ore
    :coal_ore
    :wood
    :leaves
    :glass
    :lapis
    :lapis_lazuli_block
    :sandstone
    :bed
    :cobweb
    :grass_tall
    :flower_yellow
    :flower_cyan
    :mushroom_brown
    :mushroom_red
    :gold_block
    :gold
    :iron_block
    :iron
    :stone_slab_double
    :stone_slab
    :brick
    :brick_block
    :tnt
    :bookshelf
    :moss_stone
    :obsidian
    :torch
    :fire
    :stairs_wood
    :chest
    :diamond_ore
    :diamond_block
    :diamond
    :crafting_table
    :farmland
    :furnace_inactive
    :furnace_active
    :door_wood
    :ladder
    :stairs_cobblestone
    :door_iron
    :redstone_ore
    :snow
    :ice
    :snow_block
    :cactus
    :clay
    :sugar_cane
    :fence
    :glowstone_block
    :bedrock_invisible
    :stone_brick
    :glass_pane
    :melon
    :fence_gate
    :glowing_obsidian
    :nether_reactor_core

12 - Conclusions

Ceci conclut ce tutoriel d’introduction à Sonic Pi. Heureusement, vous avez appris quelque chose tout au long. Ne vous inquiétez pas si vous pensez ne pas avoir tout compris - jouez simplement et prenez du plaisir, vous vous approprierez les choses à votre rythme. N’hésitez pas à replonger en arrière quand vous avez une question qui pourrait être couverte par une des sections.

Si vous avez des questions qui n’ont pas été couvertes dans le tutoriel, alors allez S.V.P. sur Sonic Pi forums et poser vos questions ici. Vous trouverez quelqu’un qui désirera vous tendre amicalement la main.

Enfin, je vous invite aussi à regarder en profondeur le reste de la documentation de ce système d’aide. Il y a un nombre de fonctionnalités qui n’ont pas été couvertes dans ce tutoriel et qui sont en attente de votre découverte.

Donc, jouez, prenez du plaisir, partagez votre code, produisez-vous devant vos amis, montrez vos écrans et rappelez-vous :

Il n’y a pas de fautes, que des opportunités

Sam Aaron


- Articles MagPi

L’appendice A rassemble tous les articles Sonic Pi écrits pour le magazine MagPi.

Plongez vous dans les sujets

Ces articles ne sont pas destinés à être lus dans un ordre particulier et contiennent beaucoup de choses qui sont aussi dans le tutoriel. Plutôt que d’essayer de vous apprendre tout Sonic Pi, chacun se focalise plutôt sur un aspect particulier de Sonic Pi et le couvre d’une manière amusante et accessible.

Lisez MagPi

Vous les trouverez avec leur présentation très professionnelle dans les PDFs gratuits en téléchargement ici : https://www.raspberrypi.org/magpi/

Suggérez un sujet

Si vous ne trouvez pas de sujet qui vous intéresse parmi ceux couverts dans ces articles, pourquoi ne pas en suggérer un ? La manière la plus simple de faire cela est de tweeter votre suggestion à @Sonic_Pi. On ne sait jamais, votre suggestion sera peut-être le sujet du prochain article !


- Les cinq meilleurs conseils

1. Il n’y a pas d’erreur

La plus importante leçon à apprendre avec Sonic Pi c’est qu’il n’y a vraiment pas d’erreur. La meilleure façon d’apprendre c’est juste d’essayer, essayer, et essayer. Essayez beaucoup de choses différentes, ne vous inquiétez pas de savoir si votre code sonne bien ou pas et commencez par expérimenter avec le plus de synthés, notes, effets et options possibles. Vous découvrirez beaucoup de choses qui vous feront rire parce qu’elles ne sonnent pas bien du tout et aussi quelques joyaux qui sonnent magnifiquement bien. Débarrassez-vous ensuite de ce que vous n’aimez pas et gardez les choses qui vous plaisent. Plus vous vous permettrez de faire des erreurs et plus vous apprendrez et découvrirez votre son de code personnel.

2. Utilisez les effets

Disons que vous maîtrisez déjà les bases de Sonic Pi pour créer des sons avec sample et play. Qu’est-ce qui vient ensuite ? Savez-vous que Sonic Pi supporte plus de 27 effets studio pour changer le son de votre code ? Les effets sont comme des filtres pour images dans les programmes de dessin, mais à la place de rendre l’image floue ou noir et blanc, on peut ajouter de la reverb, de la distorsion ou de l’écho au son. On peut voir ça comme brancher le câble d’une guitare dans une pédale d’effet puis dans un ampli. Heureusement Sonic Pi rend l’utilisation d’effets très simple et n’a pas besoin de câble. Tout ce dont vous avez besoin c’est de choisir à quelle section de votre code ajouter l’effet puis de l’entourer avec le code de l’effet. Prenons un exemple. Disons que vous avez le code suivant :

sample :loop_garzul
 
16.times do
  sample :bd_haus
  sleep 0.5
end

Si vous voulez ajouter un effet au sample :loop_garzul, il suffit de le mettre dans un bloc with_fx comme ceci :

with_fx :flanger do
  sample :loop_garzul
end
 
16.times do
  sample :bd_haus
  sleep 0.5
end

Maintenant si voulez ajouter un effet au tambour basse, enveloppez-le aussi dans un with_fx :

with_fx :flanger do
  sample :loop_garzul
end
 
with_fx :echo do
  16.times do
    sample :bd_haus
    sleep 0.5
  end
end

Rappelez-vous, vous pouvez entourer n’importe quel code dans with_fx et tous les sons créés passeront dans cet effet.

3. Paramétrez vos synthés

Pour découvrir vraiment votre son de code vous voudrez savoir comment modifier et contrôler les synthés et effets. Par exemple, vous voudrez peut-être changer la durée d’une note, ajouter plus de reverb, ou changer la durée entre échos. Heureusement, Sonic Pi vous donne un niveau de contrôle incroyable pour faire cela avec des paramètres optionnels ou opts pour faire court. Regardons ça rapidement. Copiez ce code dans un buffer et exécutez-le :

sample :guit_em9

Oh, un joli son de guitare ! Commençons à jouer un peu avec. Et si on changeait sa fréquence ?

sample :guit_em9, rate: 0.5

Hé, qu’est-ce que ce rate: 0.5 que j’ai ajouté à la fin ? C’est ce qu’on appelle une opt. Tous les synthés et samples de Sonic Pi les supportent et il y en a beaucoup avec lesquels on peut jouer. Ils sont disponibles pour les effets aussi. Essayez ceci :

with_fx :flanger, feedback: 0.6 do
  sample :guit_em9
end

Maintenant essayez d’augmenter ce feedback à 1 pour entendre des sons fous ! Lisez la documentation pour des détails complets sur les nombreuses opts disponibles.

5. Coder de manière interactive

La meilleure manière d’expérimenter rapidement et d’explorer Sonic Pi est de coder de manière interactive. Cela vous permet de partir d’un peu de code et de le changer de manière continue pendant qu’il est en train de s’exécuter. Par exemple, si vous ne savez pas ce que le paramètre cutoff fait à un sample, jouez avec. Essayons ! Copiez ce code dans un de vos buffers Sonic Pi :

live_loop :experiment do
  sample :loop_amen, cutoff: 70
  sleep 1.75
end

Maintenant cliquez sur ‘Run’ et vous entendrez un rhythme de batterie un peu étouffé. Maintenant changez la valeur de cutoff: en 80 et cliquez à nouveau sur ‘Run’. Entendez-vous la différence ? Essayez 90, 100, 110

Quand vous aurez pris la main à utiliser des live_loop, vous ne pourrez plus vous en passer. Quand je donne un concert de live coding je m’appuie autant sur live_loop qu’un batteur sur ses baguettes. Pour plus d’informations à propos du live coding regardez la section 9 du tutoriel inclus dans Sonic Pi.

5. Surfez sur les suites aléatoires

Enfin, une chose que j’adore faire est de tricher en faisant que Sonic Pi compose des choses pour moi. Une manière géniale de faire ça est d’utiliser l’aléatoire. Cela peut paraître compliqué mais ça ne l’est pas du tout. Regardons. Copiez ceci dans un buffer :

live_loop :rand_surfer do
  use_synth :dsaw
  notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
  16.times do
    play notes.choose, release: 0.1, cutoff: rrand(70, 120)
    sleep 0.125
  end
end

Maintenant, quand vous jouez cela, vous entendrez une suite continue de notes aléatoires de la gamme :e2 :minor_pentatonic jouée avec le synthé :dsaw. “Attendez, attendez ! Ce n’est pas une mélodie”, vous entends-je crier ! Eh bien, voici la première partie du tour de magie. Chaque fois que l’on recommence le live_loop on peut dire à Sonic Pi de fixer la suite aléatoire à un point connu. C’est un peu comme voyager dans le temps. Essayons ceci : ajoutez la ligne use_random_seed 1 au live_loop :

live_loop :rand_surfer do
  use_random_seed 1
  use_synth :dsaw
  notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
  16.times do
    play notes.choose, release: 0.1, cutoff: rrand(70, 120)
    sleep 0.125
  end
end

Maintenant, chaque fois que la live_loop boucle, la suite aléatoire est réinitialisée. Cela veut dire qu’elle contient exactement les même 16 notes à chaque fois. Et voilà ! Une mélodie de composée. Et maintenant voici la partie excitante. Changez la valeur de 1 en un autre nombre. Par exemple 4923. Ouaou, une autre mélodie ! Donc, en changeant juste un nombre (la graine aléatoire), on peut explorer autant de combinaisons mélodiques qu’on peut imaginer ! C’est ça la magie du code.


- Live Coding

Les rayons lasers perçaient à travers les bouffées de fumée et les baffles transmettaient des basses profondes dans les corps de la foule. L’atmosphère était remplie d’un mélange de synthés et de danse. Il y avait pourtant quelque chose d’étrange dans cette boîte de nuit. Du texte futuriste était projeté au dessus de la cabine du DJ, bougeant, dansant, clignotant. Ce n’étaient pas de belles visualisations, c’était juste une projection de Sonic Pi tournant sur un Raspberry Pi. La personne dans la cabine de DJ n’était pas en train de tourner des disques, elle écrivait, éditait et évaluait du code. En direct. C’est ça le Live Coding.

Sam Aaron Live Coding

Cela peut sonner comme une histoire tirée par les cheveux dans une boîte de nuit futuriste mais coder de la musique comme cela est une tendance qui se développe et qu’on appelle souvent Live Coding (programmation interactive) (http://toplap.org). Une des directions récentes que cette approche de la musique a prise est l’Algorave (http://algorave.com) : des événements où des artistes comme moi codent de la musique pour que les gens dansent. Cependant vous n’avez pas besoin d’une boîte de nuit pour coder en live : avec Sonic Pi version 2.6 et plus vous pouvez le faire dans n’importe quel endroit où vous pouvez prendre votre Raspberry Pi et un casque ou des haut-parleurs. Quand vous aurez atteint la fin de cet article, vous saurez programmez vos rythmes et les modifier en direct. Où vous irez ensuite ne sera limité que par votre imagination.

Boucle interactive

La clef de la programmation interactive est la maîtrise de la live_loop. En voici une :

live_loop :beats do
  sample :bd_haus
  sleep 0.5
end

Il y a quatre ingrédients principaux dans une live_loop. La première est son nom. Notre live_loop s’appelle ici :beats. Vous pouvez donner le nom que vous voulez à votre live_loop. Défoulez-vous. Soyez créatifs. J’utilise souvent des noms qui communiquent à l’audience qu’est-ce que la musique va faire. Le deuxième ingrédient est le mot do qui marque où la live_loop commence. Le troisième est le mot end qui marque où la live_loop finit, et enfin il y a le corps de la live_loop qui décrit ce que la boucle va répéter : c’est la partie entre do et end. Dans ce cas on joue en boucle un sample de tambour basse et on attend un demi temps. Cela produit un beau rythme régulier de basse. Allez, copiez-le dans un buffer vide de Sonic Pi et cliquez sur ‘Run’. Boum, boum, boum !

Redéfinir à la volée

OK, qu’est-ce qu’elle a de si spécial, cette live_loop ? Jusqu’ici on dirait que c’est juste une boucle ! Eh bien, la beauté des live_loops c’est qu’on peut les redéfinir à la volée. Cela veut dire que pendant qu’elles sont en train de tourner, on peut changer ce qu’elles font. C’est le secret de la programmation interactive avec Sonic Pi. Essayons :

live_loop :choral_drone do
  sample :ambi_choir, rate: 0.4
  sleep 1
end

Maintenant cliquez le bouton ‘Run’ ou tapez ‘alt-r’. Vous entendez maintenant de beaux sons de chorale. Ensuite, alors qu’il est encore en train de jouer, changer la fréquence de 0.4 en 0.38. Cliquez à nouveau sur ‘Run’. Ouaou ! Vous avez entendu le choeur changer de note ? Ecrivez à nouveau 0.4 pour revenir comme avant. Puis 0.2, puis 0.19, puis à nouveau 0.4. Voyez-vous comment juste changer un paramètre à la volée vous donne un réel contrôle sur la musique ? Maintenant jouez vous-même avec la fréquence, choisissez vos propres valeurs. Essayez des nombres négatifs, de très petits nombres et de grands nombres. Amusez-vous !

Il est important de dormir

Une des leçons les plus importantes avec les live_loop c’est qu’elles ont besoin de se reposer. Prenons par exemple cette live_loop :

live_loop :infinite_impossibilities do
  sample :ambi_choir
end

Si vous essayez d’exécuter ce code, vous verrez immédiatement que Sonic Pi se plaint que la live_loop n’a pas dormi. C’est un mécanisme de sécurité qui se met en place. Prenons un moment pour penser à ce que ce code demande à l’ordinateur de faire. C’est cela, on demande à l’ordinateur de jouer un nombre infini de samples de chorale dans un temps nul. Sans le mécanisme de sécurité le pauvre ordinateur essaierait de faire ça et exploserait. Souvenez-vous en bien : vos live_loops doivent contenir un appel à sleep.

Combiner des sons

La musique est pleine de choses qui arrivent en même temps. La batterie en même temps que la basse, en même temps que du chant, en même temps que des guitares… En informatique on appelle ça la concurrence et Sonic Pi nous donne une manière étonnamment simple de jouer des choses en même temps. Il suffit d’utiliser plus qu’une live_loop !

live_loop :beats do
  sample :bd_tek
  with_fx :echo, phase: 0.125, mix: 0.4 do
    sample  :drum_cymbal_soft, sustain: 0, release: 0.1
    sleep 0.5
  end
end
  
live_loop :bass do
  use_synth :tb303
  synth :tb303, note: :e1, release: 4, cutoff: 120, cutoff_attack: 1
  sleep 4
end

Ici nous avons deux live_loops, une qui tourne rapidement pour faire un rythme et une qui boucle lentement pour faire un son fou de basse.

Une des choses intéressantes quand on utilise plusieurs live_loops c’est que chacune gère son propre temps. Cela veut dire qu’il est très facile de créer des structures polyrythmiques intéressantes et même de jouer avec la phase dans le style de Steve Reich. Par exemple :

# La phase piano de Steve Reich
  
notes = (ring :E4, :Fs4, :B4, :Cs5, :D5, :Fs4, :E4, :Cs5, :B4, :Fs4, :D5, :Cs5)
  
live_loop :slow do
  play notes.tick, release: 0.1
  sleep 0.3
end
  
live_loop :faster do
  play notes.tick, release: 0.1
  sleep 0.295
end

Rassemblons tout

Dans chacun de ces tutoriels, nous finirons avec un exemple qui montre un nouveau morceau de musique qui utilise toutes les idées introduites. Lisez ce code et essayez d’imaginer ce qu’il fait. Ensuite, copiez-le dans un buffer frais de Sonic Pi et cliquez ‘Run’ pour entendre comment il sonne. Enfin changez un des nombres ou commentez / décommentez des parties. Voyez si vous pouvez prendre ça comme point de départ d’une nouvelle performance, et surtout amusez-vous ! A la prochaine…

with_fx :reverb, room: 1 do
  live_loop :time do
    synth :prophet, release: 8, note: :e1, cutoff: 90, amp: 3
    sleep 8
  end
end
  
live_loop :machine do
  sample :loop_garzul, rate: 0.5, finish: 0.25
  sample :loop_industrial, beat_stretch: 4, amp: 1
  sleep 4
end
  
live_loop :kik do
  sample :bd_haus, amp: 2
  sleep 0.5
end
  
with_fx :echo do
  live_loop :vortex do
    # use_random_seed 800
    notes = (scale :e3, :minor_pentatonic, num_octaves: 3)
    16.times do
      play notes.choose, release: 0.1, amp: 1.5
      sleep 0.125
    end
  end
end

- Rythmes codés

Une des évolutions techniques les plus excitantes et disruptives dans la musique moderne a été l’invention des samplers. C’étaient des boîtes qui permettaient d’enregistrer n’importe quels sons dedans et de les manipuler et jouer de nombreuses manières intéressantes. Par exemple, on pouvait prendre un vieux disque, trouver un solo de batterie (ou un break), l’enregistrer dans le sampler et ensuite le jouer deux fois moins vite pour créer la fondation de vos derniers rythmes. C’est ainsi que la musique hip-hop est née et aujourd’hui il est presque impossible de trouver de la musique électronique qui n’incorpore pas de samples. Utiliser des samples est une très bonne manière d’introduire facilement des éléments nouveaux et intéressants dans vos performances de live coding.

Comment pouvez-vous vous procurer un sampler ? Eh bien, vous en avez déjà un : c’est votre Raspberry Pi ! L’application de live coding Sonic Pi comprend un sampler très puissant. Jouons avec !

Le break Amen

Un des samples de break de batterie les plus classiques et reconnaissables s’appelle le break Amen. Il a été joué pour la première fois en 1969 dans la chanson “Amen Brother” des Winstons dans un break de batterie. Cependant c’est quand il a été découvert par les premiers musiciens de hip-hop dans les années 80 et utilisé dans des samplers qu’il a commencé à être très utilisé dans des styles aussi variés que le drum and bass, le breakbeat, la techno hardcore et le breakcore.

Je suis sûr que vous êtes ravis d’entendre qu’il est aussi inclus dans Sonic Pi. Choisissez un buffer vide et copiez-y ce code :

sample :loop_amen

Cliquez sur Run et boum ! Vous ententez l’un des breaks de batterie les plus influents de l’histoire de la musique dance. Ceci dit, ce sample n’est pas célèbre pour être joué juste une fois, il est fait pour être joué en boucle.

Etirer des rythmes

Jouons le break Amen en boucle en utilisant notre vieille amie la live_loop, introduite dans le tutoriel du mois dernier :

live_loop :amen_break do
  sample :loop_amen
  sleep 2
end

OK, ça boucle, mais il y a une pause ennuyeuse à chaque fois. C’est parce qu’on a demandé d’attendre 2 temps et avec le nombre par défaut de 60 BPM (battements par minute), le sample :loop_amen ne dure que 1.753 temps. Nous avons donc un silence de 2 - 1.753 = 0.247 temps. Même s’il est court, c’est notable.

Pour corriger ce problème on peut utiliser l’option beat_stretch pour demander à Sonic Pi d’étirer (ou rétrécir) le sample pour correspondre au temps spécifié.

[Breakout box start] Les fonctions sample et synth de Sonic Pi vous donnent beaucoup de contrôle via des paramètres optionnels comme amp:, cutoff: et release:. Cela dit le terme paramètre optionnel est très long à dire donc on les appelle juste opts pour rester simple. [Breakout box end]

live_loop :amen_break do
  sample :loop_amen, beat_stretch: 2
  sleep 2
end  

Maintenant on peut danser ! Quoique, peut-être qu’on veut l’accélérer ou le ralentir en fonction de l’ambiance.

Jouer avec le temps

OK, et si on voulait changer de style pour faire du hip hop old school ou du breakcore ? Une manière simple de faire ça est de jouer avec le temps : ou en d’autres mots jouer avec le tempo. C’est très facile avec Sonic Pi : il suffit d’appeler use_bpm dans votre boucle interactive :

live_loop :amen_break do
  use_bpm 30
  sample :loop_amen, beat_stretch: 2
  sleep 2
end 

Pendant que vous rappez sur ces rythmes lents, remarquez que nous avons toujours un repos de 2 et que notre BPM vaut 30, mais tout est bien synchronisé. L’option beat_stretch marche avec le BPM courant pour s’assurer que tout fonctionne bien.

Maintenant voici la partie amusante. Alors que la boucle est en train de tourner, changez le 30 dans la ligne use_bpm 30 en 50. Oh, tout est devenu plus rapide, mais toujours synchro ! Essayez d’aller plus vite : jusque 80, jusque 120, ou même, soyons fous, 200 !

Filtrer

Maintenant qu’on peut jouer des samples en boucle de manière interactive, regardons les options les plus amusantes proposées par le synthé sample. La première est le cutoff: qui contrôle le filtre de coupure du sampler. Par défaut il est désactivé mais on peut facilement l’activer :

live_loop :amen_break do
  use_bpm 50
  sample :loop_amen, beat_stretch: 2, cutoff: 70
  sleep 2
end  

Allez-y, changez la valeur de l’option cutoff:. Par exemple montez-la à 100, cliquez sur Run et attendez la prochaine boucle pour entendre la différence dans le son. Remarquez que des valeurs basses comme 50 sonnent plus doux et bas et que des hautes valeurs comme 100 ou 120 sonnent plus plein et râpeux. C’est parce que l’option cutoff: va couper les parties haute-fréquence du son tout comme une tondeuse coupe le haut de la pelouse. L’option cutoff: est comme le réglage de la longueur : cela détermine combien il reste d’herbe.

Couper

Un autre super outil avec lequel on peut jouer est l’effet slicer. Il va couper le son en tranches. Entourez la ligne de sample avec le code de l’effet ainsi :

live_loop :amen_break do
  use_bpm 50
  with_fx :slicer, phase: 0.25, wave: 0, mix: 1 do
    sample :loop_amen, beat_stretch: 2, cutoff: 100
  end
  sleep 2
end

Remarquez comme le son bondit un peu plus de haut en bas. (Vous pouvez entendre le son original sans l’effet en changeant l’option mix: en 0.) Maintenant essayez de modifier la valeur de l’option phase:. C’est la fréquence (en battements) de l’effet de coupe. Une plus petite valeur comme 0.5 va couper plus rapidement et une plus grande valeur comme 0.5 va couper plus lentement. Remarquez que si on divise ou multiplie successivement par deux l’option phase: cela sonne généralement bien. Enfin, choisissez une valeur pour l’option wave: entre 0, 1 et 2 et écoutez comment le son change. Ce sont différentes formes d’onde. 0 est une onde scie (elle commence fort et finit en fondu), 1 est une onde carrée (commence et finit fort) et 2 est une onde en triangle (commence en fondu, finit en fondu).

Rassemblons tout

Enfin, revenons dans le temps et revisitons la jeune scène de drum and bass de Bristol avec l’exemple de ce mois. Ne vous inquiétez pas trop de tout ce que cela signifie, tapez le, cliquez sur Run, puis commencez à coder interactivement en changement les valeurs des options et voyez où cela vous amène. Partagez ce que vous créez ! A la prochaine…

use_bpm 100
  
live_loop :amen_break do
  p = [0.125, 0.25, 0.5].choose
  with_fx :slicer, phase: p, wave: 0, mix: rrand(0.7, 1) do
    r = [1, 1, 1, -1].choose
    sample :loop_amen, beat_stretch: 2, rate: r, amp: 2
  end
  sleep 2
end
  
live_loop :bass_drum do
  sample :bd_haus, cutoff: 70, amp: 1.5
  sleep 0.5
end
  
live_loop :landing do
  bass_line = (knit :e1, 3, [:c1, :c2].choose, 1)
  with_fx :slicer, phase: [0.25, 0.5].choose, invert_wave: 1, wave: 0 do
    s = synth :square, note: bass_line.tick, sustain: 4, cutoff: 60
    control s, cutoff_slide: 4, cutoff: 120
  end
  sleep 4
end

- Riffs de synthés

Que ce soit la dérive hantée d’oscillateurs grondants ou le coup de poing désaccordé des ondes scies perçant à travers le mix, le synthé principal joue un rôle essentiel dans chaque piste électronique. Dans l’édition du mois dernier de cette série de tutoriels nous avons couvert comment coder nos rythmes. Dans ce tutoriel nous verrons comment coder les trois composants principaux d’un riff de synthé : le timbre, la mélodie et le rythme.

OK, allumez votre Raspberry Pi, ouvrez Sonic Pi (version 2.6 ou plus) et faisons du bruit !

Les possibilités du timbre

Une partie essentielle de n’importe quel riff de synthé est de jouer avec le timbre des sons. On peut contrôler le timbre dans Sonic Pi de deux manières : en choisissant différents synthés pour un changement dramatique et en définissant les diverses options des synthés pour des modifications plus subtiles. On peut aussi utiliser des effets, mais ce sera pour un autre tutoriel…

Créons une boucle interactive simple où l’on modifiera en continu le synthé courant :

live_loop :timbre do
  use_synth (ring :tb303, :blade, :prophet, :saw, :beep, :tri).tick
  play :e2, attack: 0, release: 0.5, cutoff: 100
  sleep 0.5
end

Regardez ce code. On parcourt (avec tick) juste un anneau de noms de synthés (on boucle sur chacun d’eux à leur tour puis on répéte la liste encore et encore). On passe ce nom de synthé à la fonction (fn) use_synth, ce qui changera le synthé courant de la live_loop. On joue aussi la note :e2 (E (ou Mi) à la deuxième octave), avec un temps de relâche de 0.5 battement (une demi seconde au BPM par défaut de 60) et avec l’option :cutoff fixée à 100.

Vous entendez que les différents synthés ont des sons très différents même s’ils jouent tous la même note. Maintenant expérimentez et jouez. Changez le temps de relâche en lui donnant des valeurs plus grandes et plus petites. Par exemple, changez les options attack: et release: pour voir comme des temps différents de fondu d’entrée et de sortie ont un grand effet sur le son. Enfin changez l’option cutoff: pour voir comment différentes valeurs de coupure ont une influence massive sur le timbre (des valeurs entre 60 et 130 sont bonnes). Voyez combien de sons vous pouvez créer juste en changeant quelques valeurs. Une fois que vous maîtrisez cela, allez dans l’onglet Synthés dans le système d’aide pour voir la liste entière des synthés et des options que chacun d’eux supporte pour voir l’étendue du pouvoir que vous avez au bouts de vos doigts de codeur.

Timbre

Le timbre est juste un mot savant pour décrire comment sonne un son. Si vous jouez la même note avec différents instruments comme un violon, une guitare, ou un piano, la fréquence (si elle sonne haut ou bas) sera la même, mais la qualité du son sera différente. La qualité du son, ce qui fait qu’on peut différencier un piano et une guitare, c’est le timbre.

Composition mélodique

Un autre aspect important de notre synthé principal est le choix de notes que l’on veut jouer. Si vous avez déjà une bonne idée, alors vous pouvez juste créer un anneau avec vos notes et les parcourir :

live_loop :riff do
  use_synth :prophet
  riff = (ring :e3, :e3, :r, :g3, :r, :r, :r, :a3)
  play riff.tick, release: 0.5, cutoff: 80
  sleep 0.25
end

Ici nous avons défini une mélodie avec un anneau qui inclut des notes comme :e3 et des silences représentés par :r. On utilise ensuite .tick pour jouer chaque note à son tour, ce qui nous donne un riff qui se répète.

Mélodie automatique

Ce n’est pas toujours facile d’inventer un riff sympa. C’est souvent plus simple de demander à Sonic Pi une sélection de riffs aléatoires et de choisir celui que l’on préfère. Pour faire cela on doit combiner trois choses : des anneaux, de l’aléatoire et des graines aléatoires. Regardons un exemple :

live_loop :random_riff do
  use_synth :dsaw
  use_random_seed 3
  notes = (scale :e3, :minor_pentatonic).shuffle
  play notes.tick, release: 0.25, cutoff: 80
  sleep 0.25
end

Plusieurs choses se passent : regardons les une par une. On commence par spécifier la graine aléatoire 3. Qu’est-ce que cela signifie ? Eh bien, c’est utile parce que quand on définit la graine, on sait prédire quelle sera la prochaine valeur aléatoire : ce sera la même que la dernière fois qu’on a choisi la graine 3 ! Une autre chose utile à savoir est que mélanger un anneau de notes fonctionne de la même façon. Dans l’exemple ci-dessus c’est comme si on demandait le ‘troisième mélange’ dans la liste standard de mélanges : il sera le même chaque fois comme on définit toujours la graine aléatoire à la même valeur avant le mélange. Enfin on parcourt juste nos notes mélangées pour jouer le riff.

Maintenant, c’est ici qu’on commence à s’amuser. Si on change la valeur de la graine aléatoire, par exemple en 3000, on a un mélange entièrement différent des notes. Ainsi il est très facile d’explorer de nouvelles mélodies. Il suffit de choisir la liste de notes que l’on veut mélanger (les gammes sont un très bon endroit pour commencer) et ensuite de choisir la graine avec laquelle on veut les mélanger. Si on n’aime pas la mélodie, on peut juste changer une de ces deux choses et essayer à nouveau. Répétez jusqu’à ce que vous aimiez ce que vous entendez !

Pseudo aléatoire

L’aléatoire de Sonic Pi n’est pas vraiment aléatoire, on appelle ça du pseudo aléatoire. Imaginez que vous jetez un dé 100 fois et que vous écrivez le résultat de chaque jet sur une feuille de papier. Sonic Pi a l’équivalent de cette liste de résultats qu’il utilise quand on demande une valeur aléatoire. Au lieu de jeter un vrai dé, il prend juste la valeur suivante dans la liste. Définir la graine aléatoire revient à sauter à un endroit particulier de cette liste.

Trouver votre rythme

Un autre aspect important de notre riff est le rythme : quand jouer une note et quand ne pas le faire. Comme on a vu, on peut utiliser :r dans nos anneaux pour insérer des silences. Une autre manière puissante consiste à utiliser des ‘spreads’ que l’on couvrira dans un futur tutoriel. Aujourd’hui nous allons utiliser l’aléatoire pour nous aider à trouver notre rythme. Au lieu de jouer toutes les notes on peut utiliser une condition pour jouer une note avec une probabilité donnée. Voyons cela :

live_loop :random_riff do
  use_synth :dsaw
  use_random_seed 30
  notes = (scale :e3, :minor_pentatonic).shuffle
  16.times do
    play notes.tick, release: 0.2, cutoff: 90 if one_in(2)
    sleep 0.125
  end
end

Une fonction très utile à connaître est one_in qui nous donne une valeur true ou false (vrai ou faux) avec la probabilité spécifiée. Ici nous utilisons une valeur de 2 donc en moyenne un appel sur deux à one_in retournera true. En d’autres termes, elle retournera true 50% du temps. Si on choisit des valeurs plus grandes elle retournera false plus souvent ce qui mettra plus d’espace dans notre riff.

Remarquez qu’on a introduit un peu d’itération ici avec 16.times. C’est parce qu’on ne veut redéfinir notre valeur de graine aléatoire que toutes les 16 notes pour que notre rythme se répète toutes les 16 fois. Cela n’affecte pas le mélange comme il est toujours fait juste après avoir défini la graine. On peut utiliser la longueur d’itération pour modifier la longueur de notre riff. Essayez de changer le 16 en 8 ou même en 4 ou 3 et voyez comment cela affecte le rythme du riff.

Rassemblons tout

OK, combinons tout ce que nous avons appris dans un dernier exemple. A la prochaine !

live_loop :random_riff do
  #  uncomment to bring in:
  #  synth :blade, note: :e4, release: 4, cutoff: 100, amp: 1.5
  use_synth :dsaw
  use_random_seed 43
  notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle.take(8)
  8.times do
    play notes.tick, release: rand(0.5), cutoff: rrand(60, 130) if one_in(2)
    sleep 0.125
  end
end
 
live_loop :drums do
  use_random_seed 500
  16.times do
    sample :bd_haus, rate: 2, cutoff: 110 if rand < 0.35
    sleep 0.125
  end
end
 
live_loop :bd do
  sample :bd_haus, cutoff: 100, amp: 3
  sleep 0.5
end

- Basse acide

Il est impossible de regarder l’histoire de la musique de danse électronique sans voir l’énorme impact du petit synthétiseur Roland TB-303. C’est la sauce secrète derrière le son original de basse acide. On entend ces riffs de basse classiques crissants et pataugeants depuis la jeune scène de house de Chicago jusqu’à des artistes plus récents comme Plastikman, Squarepusher et Aphex Twin.

Il est intéressant de savoir que Roland n’avait pas l’intention que le TB-303 soit utilisé dans de la musique pour danser. Il a été créé à l’origine comme une aide de travail pour les guitaristes. Ils ont imaginé que les gens les programmeraient pour jouer des lignes de basse d’accompagnement. Malheureusement il y avait un certain nombre de problèmes : ils étaient un peu compliqués à programmer, ne sonnaient pas particulièrement bien comme remplacement de guitare basse et ils étaient assez chers. Décidant d’arrêter les frais, Roland a cessé d’en fabriquer après en avoir vendu 10’000 unités et après un certain nombres d’années à rester sur les étagères des guitaristes, ils se retrouvés dans les vitrines des magasins d’occasion. C’est pauvres TB-303 rejetés attendaient d’être découverts par une nouvelle génération d’expérimentateurs qui ont commencé à les utiliser dans des manières que Roland n’avait pas imaginées pour créer des sons fous. La house acide était née.

Même si se procurer un TB-303 original n’est pas si facile vous serez heureux d’apprendre que vous pouvez transformer votre Raspberry Pi en TB-303 en utilisant la puissance de Sonic Pi. Lancez Sonic Pi, copiez ce code dans un buffer vide et cliquez sur ‘Run’ :

use_synth :tb303
play :e1

Instant acid bass! Let’s play around…

- Presse cette basse

Commençons par construire un arpège interactif pour rendre les choses amusantes. Dans le dernier tutoriel nous avons vu comment des mélodies peuvent être juste un anneau de notes qu’on joue les unes après les autres, en répétant quand on arrive à la fin. Créons une boucle interactive qui fait cela :

use_synth :tb303
live_loop :squelch do
  n = (ring :e1, :e2, :e3).tick
  play n, release: 0.125, cutoff: 100, res: 0.8, wave: 0
  sleep 0.125
end

Regardons chaque ligne.

  1. A la première ligne choisit tb303 comme synthé par défaut avec la fonction use_synth.

  2. A la deuxième ligne on crée une boucle interactive du nom de :squelch qui va juste boucler encore et encore.

  3. A la troisième ligne on crée notre mélodie : un anneau de notes (E ou Mi aux octaves 1, 2 et 3) et on le parcourt simplement avec .tick. On définit n pour représenter la note courante de la mélodie. Le signe égal veut juste dire qu’on affecte la valeur à droite au nom à gauche. Cette valeur sera différente à chaque boucle. La première fois n aura la valeur :e1. La deuxième fois ce sera :e2, puis :e3, puis de nouveau :e1, en bouclant à l’infini.

  4. A la ligne quatre on joue notre synthé :tb303. On lui passe quelques options intéressantes : release:, cutoff:, res: et wave: que l’on décrira plus bas.

  5. La ligne cinq est notre sleep : on demande à la boucle interactive de boucler toutes les 0.125secondes ou 8 fois par seconde au BPM par défaut de 60

  6. La ligne six est la fin de la boucle interactive. Le mot end indique juste à Sonic Pi où se termine la boucle interactive.

Alors que vous êtes encore en train de vous familiariser avec ce qui se passe, tapez le code ci-dessous et cliquez sur le bouton ‘Run’. Vous devriez entendre le :tb303 entrer en action. C’est ici le coeur de l’action : commençons à programmer de manière interactive.

Pendant que la boucle tourne, changez l’option cutoff: en 110. Puis cliquez à nouveau sur le bouton ‘Run’. Vous devriez entendre le son devenir un peu plus dur et sec. Montez à 120 et cliquez sur ‘Run’. Puis 130. Ecoutez comme les valeurs hautes de coupure rendent le son plus perçant et intense. Enfin, descendez à 80 quand vous sentirez que vous voulez un peu de repos. Puis répétez ça autant que vous voulez. Pas d’inquiétude, je serai toujours là…

Une autre option qui vaut le coup d’être utilisée est res:. Elle contrôle le niveau de résonance du filtre. Une haute résonance est caractéristique des sons de basse acide. Nous avons pour le moment une res: de 0.8. Essayez de la monter à 0.85, puis 0.9, et enfin 0.95. Un cutoff de 110 ou plus peut permettre d’entendre plus facilement les différences. Enfin défoulez-vous et montez jusque 0.999 pour avoir des sons déments. Avec une res aussi haute vous entendez le filtre de coupure résonner tant qu’il commence à faire ses propres sons.

Enfin pour avoir un grand impact sur le timbre essayez de mettre l’option wave: à 1. C’est le choix de l’oscillateur source. La valeur par défaut est 0 qui est une onde en dents de scie.

Bien sûr, essayez différentes mélodies en changeant les notes dans l’anneau ou même en choisissant des notes de gammes ou d’accords. Amusez-vous bien avec votre premier synthé de basse acide.

- Déconstruisons le TB-303

Le design du TB-303 original était en fait assez simple. Comme vous pouvez le voir sur le diagramme suivant il n’y a que quatre parties principales.

TB-303 Design

En premier on a l’onde oscillatoire : les ingrédients de base du son. Dans ce cas nous avons une onde carrée. Ensuite on a l’enveloppe d’amplitude de l’oscillateur qui contrôle l’amplitude de l’onde carrée au cours du temps. On peut y accéder dans Sonic Pi avec les options attack:, decay:, sustain: et release: ainsi que leur niveau correspondant. Pour plus d’informations lisez la Section 2.4 ‘Durée avec enveloppes’ dans le tutoriel inclus dans Sonic Pi. On passe ensuite notre onde carrée enveloppée dans un filtre passe bas résonant. Cela coupe les hautes fréquences et a un bel effet de résonance. Et c’est ici que ça devient amusant. La valeur de coupure de ce filtre est aussi contrôlée par sa propre enveloppe ! Cela veut dire que nous avons un contrôle incroyable sur le timbre du son en jouant avec ces deux enveloppes. Jetons-y un oeil :

use_synth :tb303
with_fx :reverb, room: 1 do
  live_loop :space_scanner do
    play :e1, cutoff: 100, release: 7, attack: 1, cutoff_attack: 4, cutoff_release: 4
    sleep 8
  end
end

Pour chaque option standard d’enveloppe, il y a une option cutoff_ équivalente dans le synthé :tb303. Donc, pour changer le temps d’attaque de la coupure on peut utiliser l’option :cutoff_attack. Copiez le code ci-dessus dans un buffer vide et cliquez sur ‘Run’. Vous entendrez un son fou entrer et sortir. Maintenant essayez de jouer avec. Essayez de changer la durée de cutoff_attack: en 1 puis en 0.5. Puis essayez 8.

Remarquez que j’ai passé tout cela à travers un effet :reverb pour plus d’atmosphère : essayez d’autres effets pour voir ce qui marche !

Rassemblons tout

Enfin voici un morceau que j’ai composé en utilisant les idées de ce tutoriel. Copiez le dans un buffer vide, écoutez un peu, puis commencez à programmer interactivement vos changements. Voyez quels sons fous vous pouvez faire avec ! A la prochaine…

use_synth :tb303
use_debug false
 
with_fx :reverb, room: 0.8 do
  live_loop :space_scanner do
    with_fx :slicer, phase: 0.25, amp: 1.5 do
      co = (line 70, 130, steps: 8).tick
      play :e1, cutoff: co, release: 7, attack: 1, cutoff_attack: 4, cutoff_release: 4
      sleep 8
    end
  end
 
  live_loop :squelch do
    use_random_seed 3000
    16.times do
      n = (ring :e1, :e2, :e3).tick
      play n, release: 0.125, cutoff: rrand(70, 130), res: 0.9, wave: 1, amp: 0.8
      sleep 0.125
    end
  end
end

- Minecraft musical

Bonjour et bienvenue à nouveau ! Dans les tutoriels précédents nous nous somes concentrés exclusivement sur les possibilités mnusicales de Sonic Pi, en transformant votre Raspberry Pi en instrument de musique prêt à l’emploi. Jusqu’ici nous avons appris comment :

Il y a tellement plus à vous montrer, et nous l’explorerons dans de futures éditions. Cependant, ce mois-ci, nous allons regarder une chose que Sonic Pi sait faire et que vous n’avez probablement pas remarquée : contrôler Minecraft.

- Bonjour, monde de Minecraft

OK, commençons. Démarrez votre Raspberry Pi, lancez Minecraft Pi et créez un nouveau monde. Maintenant démarrez Sonic Pi et déplacez vos fenêtres de manière à pouvoir voir Sonic Pi et Minecraft Pi en même temps.

Dans un buffer disponible tapez ce qui suit :

mc_message "Hello Minecraft from Sonic Pi!"

Maintenant cliquez sur ‘Run’. Boum ! Votre message est apparu dans Minecraft ! C’était facile, non ? Maintenant arrêtez un moment de lire ceci et jouez un peu avec vos propres messages. Amusez-vous !

Screen 0

- Téléportation sonique

Explorons un peu. L’option standard est de saisir la souris et le clavier et de commencer à se promener. Ca marche, mais c’est assez lent et ennuyeux. Ce serait beaucoup mieux si on avait une sorte de machine de téléportation. Eh bien, grâce à Sonic Pi, on en a une. Essayez ceci :

mc_teleport 80, 40, 100

Oh ! On est monté bien haut. Si vous n’étiez pas en mode volant vous avez du retomber jusqu’au sol. Si vous double-tapez Espace pour entrer en mode volant et vous téléportez à nouveau, vous resterez en l’air à l’endroit où vous vous êtes déplacés.

Maintenant, qu’est-ce que ces nombres signifient ? Nous avons trois nombres qui décrivent les coordonnées de l’endroit du monde où vous voulez vous déplacer. On donne à chacun de ces nombres un nom : x, y et z.

En choisissant différentes valeurs pour x, y, et z, on peut se téléporter n’importe où dans notre monde. Essayez ! Choisissez différents nombres et regardez où vous vous retrouvez. Si l’écran devient noir c’est que vous vous êtes téléportés sous terre ou dans une montagne. Choisissez juste une valeur de y plus grande pour vous retrouver au-dessus de la terre. Continuez à explorer jusqu’à ce que vous trouviez un endroit qui vous plaise…

En utilisant les idées vues jusqu’ici, construisons un téléporteur sonique qui fera un son amusant de téléportation quand il nous fera voyager à travers le monde de Minecraft :

mc_message "Preparing to teleport...."
sample :ambi_lunar_land, rate: -1
sleep 1
mc_message "3"
sleep 1
mc_message "2"
sleep 1
mc_message "1"
sleep 1
mc_teleport 90, 20, 10
mc_message "Whoooosh!"

Screen 1

- Blocs magiques

Maintenant que vous avez trouvé un endroit sympathique, commençons à construire. Vous pourriez faire comme vous en avez l’habitude et commencer à cliquer furieusement la souris pour placer des blocs sous le curseur. Ou vous pourriez utiliser la magie de Sonic Pi. Essayez ceci :

x, y, z = mc_location
mc_set_block :melon, x, y + 5, z

Maintenant regardez vers le haut ! Il y a un melon dans le ciel ! Prenez un moment pour regarder le code. Qu’est-ce qu’on a fait ? Sur la première ligne on a attrapé l’emplacement actuel de Steve dans les variables x, y et z. Elles correspondent aux coordonnées décrites ci-dessus. Nous utilisons ces coordonnées dans la fonction mc_set_block qui va placer le bloc de votre choix aux coordonnées spécifiées. Pour placer quelque chose plus haut dans le ciel on doit juste augmenter la valeur de y, c’est pour ça qu’on lui ajoute 5. Faisons un chemin de melons :

live_loop :melon_trail do
  x, y, z = mc_location
  mc_set_block :melon, x, y-1, z
  sleep 0.125
end

Maintenant sautez dans Minecraft, assurez-vous d’être en mode volant (tapez deux fois sur Espace sinon) et volez autour du monde. Regardez derrière vous pour voir un beau chemin de blocs de melon ! Voyez quels dessins tordus vous pouvez faire dans le ciel.

- Programmer Minecraft de manière interactive

Ceux d’entre vous qui ont suivi ce tutoriel pendant les derniers mois doivent être bien étonnés. Le chemin de melons est assez cool, mais la partie la plus excitante de l’exemple précédent est qu’on peut utiliser la live_loop avec Minecraft ! Pour ceux qui ne savent pas, la live_loop est la faculté magique et spéciale de Sonic Pi qu’aucun autre langage de programmation ne possède. Elle vous permet d’exécuter des boucles multiples en même temps et vous permet de les modifier pendant qu’elles tournent. Elles sont incroyablement puissantes et amusantes. J’utilise les live_loops pour jouer de la musique dans des boîtes de nuit avec Sonic Pi : les DJs utilisent des disques et moi j’utilise des live_loops :-) Cependant aujourd’hui nous allons programmer de manière interactive de la musique et Minecraft.

Commençons. Exécutez le code ci-dessus et commencez à faire votre chemin de melons de nouveau. Maintenant, sans arrêter le code, changez simplement :melon en :brick et cliquez sur Run. Eh voilà, vous construisez maintenant un chemin de briques. C’était simple, non ? Un peu de musique pour accompagner ça ? Facile. Essayez ceci :

live_loop :bass_trail do
  tick
  x, y, z = mc_location
  b = (ring :melon, :brick, :glass).look
  mc_set_block b, x, y -1, z
  note = (ring :e1, :e2, :e3).look
  use_synth :tb303
  play note, release: 0.1, cutoff: 70
  sleep 0.125
end

Maintenant pendant que ça joue commencez à modifier le code. Changez les types de bloc : essayez :water, :grass ou votre type de bloc préféré. Aussi, essayez de changer la valeur de coupure de 70 à 80 puis jusque 100. N’est-ce pas amusant ?

Rassemblons tout

Screen 2

Rassemblons tout ce que nous avons vu jusqu’ici avec un peu de magie en plus. Combinons notre faculté de téléportation avec placement de blocs et la musique pour faire une vidéo de musique Minecraft. Ne vous inquiétez pas si vous ne comprenez pas tout, tapez juste le code et jouez ensuite à modifier quelques-unes des valeurs pendant qu’il s’exécute. Amusez-vous bien et à la prochaine…

live_loop :note_blocks do
  mc_message "This is Sonic Minecraft"
  with_fx :reverb do
    with_fx :echo, phase: 0.125, reps: 32 do
      tick
      x = (range 30, 90, step: 0.1).look
      y = 20
      z = -10
      mc_teleport x, y, z
      ns = (scale :e3, :minor_pentatonic)
      n = ns.shuffle.choose
      bs = (knit :glass, 3, :sand, 1)
      b = bs.look
      synth :beep, note: n, release: 0.1
      mc_set_block b, x+20, n-60+y, z+10
      mc_set_block b, x+20, n-60+y, z-10
      sleep 0.25
    end
  end
end

live_loop :beats do
  sample :bd_haus, cutoff: 100
  sleep 0.5
end

- Battements de Bizet

Après notre briève excursion dans le monde fantastique de la programmation Minecraft avec Sonic Pi le mois dernier, penchons nous sur la musique à nouveau. Aujourd’hui nous allons amener un morceau classique de danse d’opéra droit dans le 21e siècle en utilisant la puissance fantastique du code.

- Scandaleux et perturbateur

Sautons dans une machine à remonter le temps jusqu’en 1875. Un compositeur nommé Bizet avait juste terminé son dernier opéra : Carmen. Malheureusement comme beaucoup de nouveaux morceaux excitants et perturbateurs les gens ne l’aimaient pas du tout au début parce qu’il était trop scandaleux et différent. Malheureusement Bizet est mort dix ans avant que l’opéra ne connaisse un grand succès international et ne devienne un des opéras les plus connus et les plus fréquemment interprétés de tous les temps. Par sympathie pour cette tragédie nous allons prendre un des thèmes principaux de Carmen et nous allons le convertir dans un format moderne de musique qui est aussi trop scandaleux et différent pour la plupart des gens de notre époque : la musique codée interactive !

- La Habanera décryptée

Essayez de programmer un opéra entier de manière interactive serait un peu ambitieux pour ce tutoriel, concentrons nous sur une des ses plus célèbres parties : la ligne de basse de la Habanera :

Habanera Riff

Cela peut vous sembler complètement illisible si vous n’avez pas étudié la notation musicale. Cependant, en tant que programmeurs nous voyons la notation musicale comme juste une autre forme de code, elle représente juste des instructions pour un musicien au lieu d’un ordinateur.

- Notes

Les notes sont arrangées de gauche à droite comme les mots dans ce magasine mais elles ont aussi différentes hauteurs. La hauteur sur la partition représente la hauteur d’une note. Plus une note est haut sur la partition, plus sa hauteur est grande.

Dans Sonic Pi nous savons déjà comment changer la hauteur d’une note : on peut utiliser des grands ou petits nombres comme play 75 et play 80 ou on peut utiliser les noms des notes : play :E et play :F. Heureusement chacune des positions verticales sur la partition représente un nom de note en particulier. Jetez un oeil à cette table de correspondance bien pratique :

Notes

- Silences

Les partitions sont une sorte de code extrêmement riche et expressif capable de communiquer de nombreuses choses. Cela ne devrait donc pas nous surprendre que les partitions peuvent non seulement nous dire quelles notes jouer mais aussi quand ne pas jouer de note. En programmation c’est à peu près l’équivalent de l’idée de nil ou null : l’absence de valeur. En d’autres mots ne pas jouer une note c’est comme une absence de note.

Si vous regardez de près la partition vous verrez que c’est en fait une combinaison de ronds noirs avec des barres qui représentent les notes à jouer et des choses ondulées qui représentent les silences. Heureusement, Sonic Pi a une notation très pratique pour un silence : :r, donc si on exécute play :r il jouera en fait un silence ! On pourrait aussi écrire play :rest, play nil ou play false qui sont autant de manières équivalentes de représenter un silence.

- Rythme

Enfin il y a une dernière chose à apprendre à décoder dans la notation : la notion du temps. Dans la notation originale vous verrez que les notes sont liées par des traits épais. La deuxième note a deux de ces traits ce qui veut dire qu’elle dure un 16e de temps. Les autres notes ont un seul trait ce qui veut dire qu’elles durent un 8e de temps. Le silence a aussi deux traits ondulés ce qui veut dire qu’il représente aussi un 16e de temps.

Quand on essaie de décoder et d’explorer de nouvelles choses un truc très pratique est de rendre tout le plus semblable possible pour essayer de voir des relations ou modèles. Par exemple quand on réécrit notre notation uniquement en double-croches on peut voir que notre notation devient une séquence agréable de notes et de silences.

Habanera Riff 2

- Re-programmer la Habanera

Nous sommes maintenant prêts a traduire cette ligne de basse dans Sonic Pi. Encodons ces notes et silences dans un anneau :

(ring :d, :r, :r, :a, :f5, :r, :a, :r)

Voyons ce que ça donne. Jetons ça dans une boucle interactive et parcourons-là :

live_loop :habanera do
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
end

Fabuleux, cette mélodie qu’on reconnait immédiatement prend vie dans vos haut-parleurs. On a fait des efforts pour en arriver là, mais ça valait la peine, bravo !

- Synthés de mauvaise humeur

Maintenant qu’on a la ligne de basse, essayons de re-créer une partie de l’ambiance de la scène d’opéra. Un synthé à essayer est :blade qui est un synthé style années 80. Essayons le avec la note de départ :d passée dans un slicer et de la reverb :

live_loop :habanera do
  use_synth :fm
  use_transpose -12
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
end

with_fx :reverb do
  live_loop :space_light do
    with_fx :slicer, phase: 0.25 do
      synth :blade, note: :d, release: 8, cutoff: 100, amp: 2
    end
    sleep 8
  end
end

Maintenant essayez les autres notes de la ligne de basse : :a et :f5. Souvenez-vous que vous n’avez pas besoin de cliquer sur ‘Stop’, vous pouvez juste modifier le code pendant que la musique tourne et ensuite cliquer sur ‘Run’ à nouveau. Aussi essayez différentes valeurs pour l’option phase: du slicer comme 0.5, 0.75 et 1.

Rassemblons tout

Enfin, combinons toutes les idées vues jusqu’ici dans un nouveau remix de la Habanera. Vous remarquerez peut-être que j’ai inclus une autre partie de la ligne de basse en commentaire. Quand vous aurez tout tapé dans un buffer de libre cliquez sur ‘Run’ pour entendre la composition. Maintenant, sans cliquer sur ‘Stop’, décommentez la seconde ligne en enlevant le # et cliquez sur ‘Run’ à nouveau : c’est merveilleux, non ? Maintenant amusez-vous à le modifier vous-même.

use_debug false
bizet_bass = (ring :d, :r, :r, :a, :f5, :r, :a, :r)
#bizet_bass = (ring :d, :r, :r, :Bb, :g5, :r, :Bb, :r)
 
with_fx :reverb, room: 1, mix: 0.3 do
  live_loop :bizet do
    with_fx :slicer, phase: 0.125 do
      synth :blade, note: :d4, release: 8,
        cutoff: 100, amp: 1.5
    end
    16.times do
      tick
      play bizet_bass.look, release: 0.1
      play bizet_bass.look - 12, release: 0.3
      sleep 0.125
    end
  end
end
 
live_loop :ind do
  sample :loop_industrial, beat_stretch: 1,
    cutoff: 100, rate: 1
  sleep 1
end
 
live_loop :drums do
  sample :bd_haus, cutoff: 110
  synth :beep, note: 49, attack: 0,
    release: 0.1
  sleep 0.5
end

- Devenez un VJ Minecraft

Screen 0

Tout le monde a joué à Minecraft. Vous aurez tous construit des structures incroyables, conçu des pièges rusés et même créé des lignes de chariots raffinées contrôlées par des interrupteurs de pierre rouge. Mais qui parmi vous s’est produit avec Minecraft ? On parie que vous ne saviez pas que vous pouvez utiliser Minecraft pour créer des animations visuelles incroyables tout comme un VJ professionnel.

Si votre seule possibilité de modifier Minecraft était d’utiliser la souris, vous auriez du mal à changer les choses suffisamment vite. Heureusement pour vous votre Raspberry Pi a une version de Minecraft qui peut être contrôlée avec du code. Il contient aussi une application nommée Sonic Pi qui rend la programmation Minecraft non seulement facile mais aussi incroyablement amusante.

Dans l’article d’aujourd’hui nous allons vous montrer quelques trucs et astuces que nous avons utilisés pour créer des spectacles dans des boîtes de nuit et salles de concert autour du monde.

Commençons…

- Commencer

Commençons avec un simple exercice d’échauffement pour nous rappeler les bases. Commencez par allumer votre Raspberry Pi et lancer Minecraft et Sonic Pi. Dans Minecraft, créez un nouveau monde, et dans Sonic Pi choisissez un buffer de libre et écrivez-y ce code :

mc_message "Let's get started..."

Cliquez sur le bouton ‘Run’ et vous verrez le message dans la fenêtre Minecraft. OK, on est prêt à démarrer, on va s’amuser…

- Tempêtes de sable

Quand on utilise Minecraft pour créer des visuels on essaie de penser à des choses qui auront l’air intéressantes et qui seront aussi faciles à générer avec du code. Un truc sympa est de créer une tempête de sable en laissant tomber des bloc de sable du ciel. Pour cela on a juste besoin de quelques fonctions simples :

Si vous ne connaissez pas une des ces fonctions comme rrand, vous pouvez juste taper le mot dans votre buffer, cliquer dessus, puis taper Control-i sur le clavier pour ouvrir la documentation. Vous pouvez aussi aller dans l’onglet lang du système d’aide puis y chercher directement les fonctions et toutes sortes d’autres choses excitantes que vous pouvez faire.

Commençons par faire tomber un peu de pluie avant de laisser la tempête complète éclater. Récupérez votre emplacement courant et utilisez-la pour créer quelques blocs de sable dans le ciel pas loin :

x, y, z = mc_location
mc_set_block :sand, x, y + 20, z + 5
sleep 2
mc_set_block :sand, x, y + 20, z + 6
sleep 2
mc_set_block :sand, x, y + 20, z + 7
sleep 2
mc_set_block :sand, x, y + 20, z + 8

Après avoir cliqué sur ‘Run’, vous devrez peut-être un peu regarder autour de vous car les blocs peuvent commencer par tomber derrière vous, suivant dans quelle direction vous êtes pour le moment. N’ayez pas peur, si vous les avez raté, cliquez à nouveau sur ‘Run’ pour créer encore un peu de pluie de sable, assurez-vous juste de regarder dans la bonne direction.

Parcourons rapidement ce qui se passe ici. Sur la première ligne nous avons récupéré l’emplacement Steve en coordonnées avec la fonction mc_location et les avons placées dans les variables x, y et z. Puis sur les lignes suivantes nous avons utilisé la fonction mc_set_block pour placer un peu de sable aux mêmes coordonnées que Steve mais avec quelques modifications. On a utilisé la même coordonnée x, une coordonnée y 20 blocs plus haut et des coordonnées z successivement plus larges pour que le sable tombe dans une ligne en s’éloignant de Steve.

Et si vous preniez ce code et commenciez à jouer avec ? Essayez d’ajouter plus de lignes, de changer la durée d’attente, essayez de mélanger du :sand avec du :gravel et choisissez différentes coordonnées. Expérimentez et amusez-vous !

- Boucles interactives déchaînées

OK, il est l’heure de lancer la tempête en déchaînant la puissance complète de la live_loop : la capacité magique de Sonic Pi qui montre la puissance entière de la programmation interactive : changer le code à la volée pendant qu’il est en train de s’exécuter !

live_loop :sand_storm do
  x, y, z = mc_location
  xd = rrand(-10, 10)
  zd = rrand(-10, 10)
  co = rrand(70, 130)
  synth :cnoise, attack: 0, release: 0.125, cutoff: co
  mc_set_block :sand, x + xd, y+20, z+zd
  sleep 0.125
end

Qu’est-ce que c’est amusant ! On boucle assez vite (8 fois par seconde) et pendant chaque boucle on trouve l’emplacement de Steve comme avant mais on génère ensuite trois valeurs aléatoires :

On utilise ensuite ces valeurs aléatoires dans les fonctions synth et mc_set_block ce qui nous donne du sable qui tombe dans des endroits aléatoires autour de Steve ainsi qu’un son percussif semblable à de la pluie, joué le synthé :cnoise.

Pour ceux d’entre vous qui ne connaissaient pas les boucles interactives : c’est là qu’on commence vraiment à s’amuser avec Sonic Pi. Pendant que le code tourne et que le sable pleut, essayez de changer une des valeurs, peut-être la valeur d’attente à 0.25 ou le type de bloc :sand en :gravel. Ensuite cliquez sur ‘Run’ à nouveau. Et voilà ! Les choses changent sans que le code ne s’arrête. C’est votre passerelle pour vous produire comme un vrai VJ. Continuez à vous exercer à changer des choses. Jusqu’où arrivez-vous à modifier les visuels sans arrêter le code ?

- Des formes de blocs épiques

Screen 1

Enfin une autre super façon de générer des visuels intéressants est de générer des énormes murs de motifs vers lesquels voler. Pour cet effet nous allons devoir passer d’un placement aléatoire de blocs à un placement de manière ordonnée. On peut faire cela en imbriquant deux itérations (cliquez sur le bouton ‘Aide’ et allez dans la section 5.2 du tutoriel “Itération et boucles” pour plus d’informations sur l’itération). L’étrange |xd| après le do veut dire que xd prendra une valeur à chaque boucle de l’itération. La première fois il vaudra 0, puis 1, puis 2, etc. En imbriquant deux itérations comme cela on peut générer toutes les coordonnées d’un carré. On peut ensuite choisir aléatoirement des types de blocs d’un anneau de blocs pour obtenir un effet intéressant :

x, y, z = mc_location
bs = (ring :gold, :diamond, :glass)
10.times do |xd|
  10.times do |yd|
    mc_set_block bs.choose, x + xd, y + yd, z
  end
end

Pas mal. Pendant qu’on s’amuse ici, essayez de changer bs.choose en bs.tick pour passer d’un motif aléatoire à un motif plus régulier. Essayez de changer les types de blocs et les plus aventureux parmi vous voudrons peut-être mettre ce code dans une live_loop pour que les modifs continuent à changer automatiquement.

Enfin, pour la fin du set du VJ, changez les deux 10.times en 100.times et cliquez sur ‘Run’. Boum ! Un énorme mur géant de briques aléatoires. Imaginez combien de temps ça vous aurait pris de construire ça avec votre souris ! Double-tapez la touche Espace pour entrer en mode volant et commencez à planer pour obtenir de super effets visuels. Ne vous arrêtez pas là, utilisez votre imagination pour trouver des idées sympa et utilisez ensuite la puissance de programmation de Sonic Pi pour le réaliser. Quand vous vous serez suffisamment exercés, baissez la lumière et donnez un spectacle de VJ pour vos amis !


- Surfer sur des flux aléatoires

Dans le quatrième épisode de cette série de tutoriels nous avons jeté un oeil brièvement à l’aléatoire en codant des riffs grésillants de synthé. Vu comme l’aléatoire est une partie très importante de mes performances de live coding j’ai pensé qu’il serait utile d’en couvrir les bases plus en détail. Mettez votre casquette et surfons sur des flux aléatoires !

- Il n’y a pas d’aléatoire

La première chose à apprendre qui pourrait vraiment vous surprendre en jouant avec les fonctions aléatoires de Sonic Pi c’est qu’elles ne sont en fait pas vraiment aléatoires. Qu’est-ce que cela signifie ? Eh bien, faisons quelques essais. Commencez par imaginer un nombre dans votre tête entre 0 et 1. Gardez-le en tête et ne me le dites pas. Maintenant, laissez-moi deviner… est-ce que c’était 0.321567 ? Non ? Bah, je ne suis clairement pas bon à ce jeu. Essayons encore une fois, mais demandons à Sonic Pi de choisir un nombre cette fois. Lancez Sonic Pi version 2.7 ou plus et demandez lui un nombre aléatoire mais de nouveau ne me dites pas le résultat.

print rand

Et maintenant pour le truc… est-ce que c’était 0.75006103515625 ? Oui ! Ha, je vois que vous êtes un peu sceptique. C’était peut-être juste de la chance. Essayons encore. Cliquez sur ‘Run’ à nouveau et regardons ce qu’on obtient… Quoi ? Encore 0.75006103515625 ? Ca ne peut clairement pas être aléatoire ! Vous avez raison, ça ne l’est pas.

Qu’est-ce qui se passe ici ? Le mot savant d’informatique pour ceci est le déterminisme. Cela veut juste dire que rien n’a lieu par hasard et que tout a sa destinée. Votre version de Sonic Pi a le destin de toujours retourner 0.75006103515625 dans le programme ci-dessus. Cela peut sembler assez inutile, mais laissez moi vous assurer que c’est une des parties les plus puissantes de Sonic Pi. Si vous persévérez vous apprendrez comment compter sur la nature déterministique de l’aléatoire dans Sonic Pi comme un bloc de construction fondamental pour vos compositions et performances de live coding.

- Une mélodie aléatoire

Quand Sonic Pi démarre il charge en fait en mémoire une séquence de 441 000 valeurs aléatoires pré-générées. Quand vous appelez une fonction aléatoire comme rand ou rrand, ce flux aléatoire est utilisé pour générer votre résultat. Chaque appel à une fonction aléatoire consomme une valeur de ce flux. Ainsi le dixième appel à une fonction aléatoire utilisera la dixième valeur du flux. Aussi, chaque fois que vous cliquez sur le bouton ‘Run’, le flux est réinitialisé pour cette exécution. C’est pour cela que j’ai pu prédire le résultat de rand et pourquoi la mélodie ‘aléatoire’ était la même à chaque fois. La version de Sonic Pi de chacun utilise exactement le même flux aléatoire ce qui est très important quand on commence à partager nos morceaux.

Utilisons cette connaissance pour générer une mélodie aléatoire répétable :

8.times do
 play rrand_i(50, 95)
 sleep 0.125
end

Tapez ceci dans un buffer de libre et cliquez sur ‘Run’. Vous entendrez une mélodie de notes aléatoires entre 50 et 95. Quand elle aura fini, cliquez sur ‘Run’ à nouveau pour entendre exactement la même mélodie à nouveau.

start breakout box ## Des fonctions aléatoires pratiques

Sonic Pi contient un certain nombre de fonctions utiles pour travailler avec le flux aléatoire. Voici une liste des plus utiles :

Regardez leur documentation dans le système d’aide pour des informations détaillées et des exemples.

end breakout box

- Réinitialiser le flux

Même si la capacité de répéter une séquence de notes choisies est essentielle pour vous permettre de rejouer une mélodie sur la piste de danse, ça pourrait ne pas être exactement la mélodie que vous souhaitez. Ne serait-ce pas génial si on pouvait essayez différentes mélodies et choisir celle qu’on préfère ? C’est ici que la vraie magie commence.

On peut régler le flux manuellement avec la fonction use_random_seed. En informatique, une graine aléatoire est le point de départ à partir duquel un nouveau flux de valeurs aléatoires peut fleurir. Essayons-le :

use_random_seed 0
3.times do
  play rrand_i(50, 95)
  sleep 0.125
end

Super, on récupère les trois premières notes de notre mélodie aléatoire ci-dessus : 84, 83 et 71. Cependant on peut maintenant changer la graine. Par exemple :

use_random_seed 1
3.times do
  play rrand_i(50, 95)
  sleep 0.125
end

Intéressant, on obtient 83, 71 et 61. Vous avez peut-être remarqué que les deux premiers nombres ici sont les mêmes que les deux derniers nombres d’avant : ce n’est pas une coïncidence.

Rappelez-vous que le flux aléatoire est juste une liste géante de valeurs pré-choisies. Choisir une graine aléatoire nous déplace juste en un point de la liste. Une autre manière de voir ça est d’imaginer un énorme jeu de cartes pré-mélangées. Utiliser une graine aléatoire, c’est couper le jeu en un point particulier. Ce qui est fabuleux avec ça c’est qu’on peut se déplacer dans le flux aléatoire, ce qui nous donne un énorme pouvoir quand on fait de la musique.

Revisitons notre mélodie aléatoire de huit notes avec cette nouvelle capacité de réinitialiser le flux, et mettons là dans une boucle interactive pour pouvoir expérimenter pendant qu’elle joue :

live_loop :random_riff do    
  use_random_seed 0
  8.times do
    play rrand_i(50, 95), release: 0.1
    sleep 0.125
  end
end

Maintenant, pendant qu’elle est en train de jouer, changez la valeur de la graine de 0 en quelque chose d’autre. Essayez 100, ou pourquoi pas 999. Essayez vos propres valeurs, expérimentez et amusez-vous : voyez quelle graine génère la mélodie que vous préférez.

- Rassemblons tout

Le tutoriel de ce mois a été un plongeon bien technique dans les entrailles de la fonctionnalité aléatoire de Sonic Pi. J’espère que cela vous a montré un peu comment elle marche et comment vous pouvez commencer à utiliser de l’aléatoire de manière fiable pour créer des motifs reproductibles dans votre musique. Il est important de souligner qu’on peut utiliser de l’aléatoire reproductible on veut. Par exemple, on peut rendre aléatoire l’amplitude des notes, le mix d’un effet, etc. Dans l’avenir nous regarderons de plus près certaines de ces applications, mais pour le moment je vais vous laisser avec un exemple court.

Tapez le code suivant dans un buffer disponible, cliquez sur ‘Run’ et commencez à modifier les graines, cliquez sur ‘Run’ de nouveau (pendant que le code tourne) et explorez les différents sons, rythmes et mélodies que vous pouvez créer. Quand vous en trouvez une qui sonne bien, notez la graine pour pouvoir y revenir plus tard. Enfin, quand vous aurez trouvé quelques graines qui vous plaisent, donnez un concert de live coding à vos amis en changeant simplement entre vos graines préférées pour créer un morceau entier.

live_loop :random_riff do use_random_seed 10300 use_synth :prophet s = [0.125, 0.25, 0.5].choose 8.times do r = [0.125, 0.25, 1, 2].choose n = (scale :e3, :minor).choose co = rrand(30, 100) play n, release: r, cutoff: co sleep s end end

live_loop :drums do use_random_seed 2001 16.times do r = rrand(0.5, 10) sample :drum_bass_hard, rate: r, amp: rand sleep 0.125 end end


- Contrôler votre son

Jusqu’ici dans cette série nous nous sommes concentrés sur le déclenchement de sons. Nous avons découvert qu’on pouvait déclencher les nombreux synthés présents dans Sonic Pi avec play ou synth et comment déclencher des samples pré-enregistrés avec sample. Nous avons aussi vu comment on pouvait entourer ces sons dans des effets studio tels que la reverb et la distorsion en utilisant la commande with_fx. En combinant cela avec le système de chronométrage incroyablement précis de Sonic Pi on peut produire un vaste ensemble de sons, rythmes et mélodies. Cependant, une fois qu’on a soigneusement sélectionné les options d’un son en particulier et qu’on l’a déclenché, on ne peut plus le modifier pendant qu’il est joué, c’est ça ? Non ! Aujourd’hui vous allez apprendre quelque chose de très puissant : comment contrôler des synthés qui sont en train d’être joués.

Un son de base

Créons un simple son agréable. Lancez Sonic Pi et tapez le code suivant dans un buffer disponible :

synth :prophet, note: :e1, release: 8, cutoff: 100

Maintenant cliquez sur le bouton ‘Run’ en haut à gauche pour entendre un beau son de synthé grondant. Allez-y, cliquez à nouveau dessus quelques fois pour vous habituer. OK, fini? Commençons à le contrôler !

Noeuds de synthé

Une fonctionnalité peu connue de Sonic Pi est que les fonctions play, synth et sample retournent ce qu’on appelle un SynthNode qui représente un son en train d’être joué. Vous pouvez capturer un de ces SynthNodes en utilisant une variable standard et le contrôler ensuite dans le futur. Par exemple, changeons la valeur de l’option cutoff: après un battement :

sn = synth :prophet, note: :e1, release: 8, cutoff: 100
sleep 1
control sn, cutoff: 130

Regardons chaque ligne une par une :

On commence par déclencher le synthé :prophet en utilisant la fonction synth habituelle. Cependant on capture aussi le résultat dans une variable nommée sn. On aurait pu appeler cette variable complètement différemment comme par exemple synth_node ou jane : le nom n’a pas d’importance. Enfin il est important de choisir un nom qui a du sens pour vous pour vos performances et pour les gens qui lisent votre code. J’ai choisi sn parce que c’est un bon petit moyen mnémotechnique pour ‘synth node’.

A la ligne 2 on a une commande sleep standard. Ca ne fait rien de spécial : ça demande juste à l’ordinateur d’attendre un battement avant d’avancer à la ligne suivante.

C’est à la ligne 3 qu’on commence à s’amuser. Ici on utilise la fonction control pour dire à notre SynthNode courant de changer la valeur de coupure en 130. Si vous cliquez sur le bouton ‘Run’, vous entendrez le synthé :prophet commencer à jouer comme avant, mais après un battement il changera et sonnera beaucoup plus clair.

** Breakout Box Start ** Options modulables

La plupart des options des synthés et effets de Sonic Pi peuvent être modifiées après avoir été déclenchées. Cependant, ce n’est pas le cas pour toutes. Par exemple, les options d’enveloppe attack:, decay:, sustain: et release: ne peuvent être définies que quand on déclenche le synthé. Pour savoir quelles options peuvent être modifiées ou non, c’est simple : allez voir la documentation d’un synthé ou effet et regardez la documentation des options individuelles et cherchez les phrases “May be changed whilst playing” (Peut être modifiée en jouant) ou “Can not be changed once set” (ne peut pas être modifiée une fois définie). Par exemple, la documentation de l’option attack: du synthé :beep indique clairement qu’on ne peut pas la modifier ultérieurement :

Modifications multiples

Pendant qu’un synthé est joué vous n’êtes pas limités à ne le changer qu’une fois : vous êtes libres de le modifier autant que vous le souhaitez. Par exemple, on peut transformer notre :prophet en petit arpégiateur avec le code suivant :

notes = (scale :e3, :minor_pentatonic)
sn = synth :prophet, note: :e1, release: 8, cutoff: 100
sleep 1
16.times do
  control sn, note: notes.tick
  sleep 0.125
end

Dans cet extrait de code nous avons juste introduit quelques choses en plus. On commence par définir une nouvelle variable appelée notes qui contient les notes qu’on aimerait parcourir en boucle (un arpégiateur est juste un mot savant pour quelque chose qui parcourt en boucle une liste de notes dans un ordre donné). Ensuite on déplace notre appel à control dans une itération en l’appelant 16 fois. A chaque appel à control on parcourt notre anneau de notes qui va se répéter automatiquement quand on arrivera à sa fin (grâce à la puissance fabuleuse des anneaux de Sonic Pi). Pour un peu de variété essayez de remplacer .tick par .choose et tentez d’entendre la différence.

Notez qu’on peut modifier plusieurs options en même temps. Essayez de changer la ligne de contrôle en la suivante et écoutez la différence :

control sn, note: notes.tick, cutoff: rrand(70, 130)

Transitions

Quand on contrôle un SynthNode, il répond exactement à ce moment-là et change immédiatement la valeur de l’option comme si vous aviez pressé un bouton ou actionné un interrupteur pour demander la modification. Cela peut sonner rythmique et percussif, notamment si l’option contrôle un aspect du timbre comme cutoff:. Cependant, on n’a pas toujours envie que la modification arrive immédiatement. On a parfois envie de se déplacer en douceur de la valeur courante à la nouvelle, comme si on avait déplacé un curseur. Bien sûr, Sonic Pi sait aussi faire cela en utilisant les options _slide:

Chaque option qui peut être modifiée a aussi une option spéciale correspondante _slide: qui vous permet de définir un temps de transition. Par exemple, amp: a amp_slide: et cutoff: a cutoff_slide:. Ces options de transition marchent un peu différemment de toutes les autres options parce qu’elles disent à la note de synthé comment se comporter la prochaine fois qu’elle seront contrôlées. Voyons ça :

sn = synth :prophet, note: :e1, release: 8, cutoff: 70, cutoff_slide: 2
sleep 1
control sn, cutoff: 130

Remarquez que cet exemple est exactement le même qu’avant sauf qu’on a ajouté cutoff_slide:. Ceci indique que la prochaine fois que l’option cutoff: de ce synthé sera contrôlée, il mettra deux battements pour passer de sa valeur courante à la nouvelle valeur. Par conséquent, quand on utilise control vous pouvez entendre la coupure changer graduellement de 70 à 130. Cela crée une sensation dynamique intéressante pour le son. Maintenant essayez de changer la durée de cutoff_slide: en une valeur plus courte comme 0.5 ou une valeur plus longue comme 4 pour voir comment ça change le son. Souvenez-vous que vous pouvez transitionner chacune des options modifiables de cette même manière, et chaque valeur de _slide: peut être complètement différente donc vous pouvez avoir une transition lente de la coupure, une transition rapide de l’amplitude, et une transition de la stéréo un peu entre les deux si c’est ce que vous avez envie de créer.

Rassemblons tout

Regardons un court exemple qui montre la puissance du contrôle des synthés après leur déclenchement. Remarquez que vous pouvez aussi transitionner les effets comme les synthés, mais avec une syntaxe légèrement différente. Regardez la section 7.2 du tutoriel inclus dans Sonic Pi pour plus d’information sur le contrôle des effets.

Copiez le code dans un buffer de libre et écoutez. Ne vous arrêtez pas là : jouez à modifier le code. Changez les durées de transition, changez les notes, le synthé, l’effet et les durées d’attente et voyez si vous pouvez le transformer en quelque chose de complètement différent !

live_loop :moon_rise do
  with_fx :echo, mix: 0, mix_slide: 8 do |fx|
    control fx, mix: 1
    notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle
    sn = synth :prophet , sustain: 8, note: :e1, cutoff: 70, cutoff_slide: 8
    control sn, cutoff: 130
    sleep 2
    32.times do
      control sn, note: notes.tick, pan: rrand(-1, 1)
      sleep 0.125
    end
  end
end

- Suivre le rythme

Le mois dernier dans cette série nous avons regardé en détail comment fonctionne le système de gestion de l’aléatoire de Sonic Pi. On a exploré comment on peut l’utiliser de manière déterministe pour avoir de nouveaux niveaux de contrôle dynamique sur notre code. Ce mois-ci nous allons continuer notre exploration technique et regarder le système unique de ‘tick’ de Sonic Pi. D’ici la fin de cet article vous parcourrez des rythmes et mélodies sur votre chemin pour devenir un DJ de programmation interactive.

- Compter les temps

Quand on fait de la musique on a souvent envie de faire quelque chose de différent en fonction du temps sur lequel on est. Sonic Pi a un système spécial pour compter les temps appelé tick pour vous donner un contrôle précis sur quand est-ce qu’un battement arrive réellement et il supporte même des battements multiples avec leur propre tempo.

Amusons-nous : pour avancer le temps on a juste besoin d’appeler tick. Ouvrez un buffer libre, tapez le code suivant et cliquez sur le bouton ‘Run’ :

puts tick #=> 0

Cela retournera le battement courant : 0. Remarquez que même si vous cliquez plusieurs fois sur le bouton ‘Run’, il retournera toujours 0. Cela parce que chaque exécution commence avec un compteur qui part de 0. Cependant, pendant que le programme tourne, on peut avancer le compteur autant qu’on veut :

puts tick #=> 0
puts tick #=> 1
puts tick #=> 2
Quand vous voyez le symbole `#=>` à la fin d'une ligne de code cela veut dire que cette ligne va noter ce texte dans la partie de droite de Sonic Pi. Par exemple, `puts foo #=> 0` veut dire que le code `puts foo` affiche `0` dans le log à cet endroit du programme.

- Vérifier le compteur

On a vu que tick fait deux choses. Il incrémente (ajoute un) et retourne le compteur courant. Parfois on veut juste regarder le battement courant sans devoir l’incrémenter et on peut faire cela via look.

puts tick #=> 0
puts tick #=> 1
puts look #=> 1
puts look #=> 1

Dans ce code on incrémente le compteur deux fois puis on appelle look deux fois. On verra les valeurs suivantes dans le log : 0, 1, 1, 1. Les deux premiers ticks ont retourné 0 et 1, comme attendu, puis les deux looks ont juste retourné la dernière valeur du compteur deux fois, donc 1.

- Anneaux

On peut donc avancer le compteur avec tick et en connaître la valeur avec look. Qu’est-ce qui vient suite ? On a besoin de quelque chose à parcourir. Sonic Pi utilise les anneaux pour représenter les mélodies et rythmes et le système de tick a été conçu spécialement pour fonctionner avec eux. En fait, les anneaux ont leur propre version de tick qui fait deux choses. D’un côté elle agit comme un tick normal et incrémente le compteur. D’un autre, elle donne une valeur de l’anneau en utilisant le compteur comme index. Voyons cela :

puts (ring :a, :b, :c).tick #=> :a

.tick est une version spéciale avec un point de tick qui nous retourne la première valeur de l’anneau: : :a. On peut attraper chacune des notes de l’anneau en appelant :tick plusieurs fois :

puts (ring :a, :b, :c).tick #=> :a
puts (ring :a, :b, :c).tick #=> :b
puts (ring :a, :b, :c).tick #=> :c
puts (ring :a, :b, :c).tick #=> :a
puts look                   #=> 3

Regardez le log et vous verrez :a, :b, :c et puis de nouveau :a. Remarquez que look retourne 3. Les appels à .tick se comportent comme les appels à tick : ils incrémentent le compteur local.

- Un arpégiateur dans une boucle interactive

La véritable puissance vient quand on mélange tick avec des anneaux et des live_loops. En les combinant on a tous les outils dont on a besoin pour construire et comprendre un arpégiateur simple. On a juste besoin de quatre choses :

  1. Un anneau qui contient les notes sur lesquelles on va boucler
  2. Une manière d’incrémenter et de lire le compteur
  3. La capacité de jouer une note en se basant sur le compteur courant
  4. Une structure de boucle qui répète l’arpégiateur en continu

Ces concepts se retrouvent tous dans le code suivant :

notes = (ring 57, 62, 55, 59, 64)

live_loop :arp do
  use_synth :dpulse
  play notes.tick, release: 0.2
  sleep 0.125
end

Regardons chacune de ces lignes. On commence par définir notre anneau de notes que nous allons jouer en continu. On crée ensuite une live_loop nommée :arp qui va boucler pour nous. A chaque itération de la live_loop on choisit un synthé :dpulse et on joue ensuite la note suivante de notre anneau en utilisant .tick. Souvenez-vous que cela va incrémenter notre compteur de temps et en utiliser la valeur comme index dans notre anneau de notes. Enfin on attend un huitième de temps avant de recommencer la boucle.

- Battements multiples simultanés

Une chose très importante à savoir est que les ticks sont liés à la live_loop. Cela veut dire que chaque live_loop a son propre compteur indépendant. C’est beaucoup plus puissant que d’avoir un métronome et battement global. Regardons ce que cela donne :

notes = (ring 57, 62, 55, 59, 64)

with_fx :reverb do live_loop :arp do use_synth :dpulse play notes.tick + 12, release: 0.1 sleep 0.125 end end

live_loop :arp2 do use_synth :dsaw play notes.tick - 12, release: 0.2 sleep 0.75 end

- Collisions de battements

Une grande source de confusion dans le système de tick de Sonic Pi est quand on veut parcourir plusieurs anneaux dans le même live_loop.

use_bpm 300 use_synth :blade live_loop :foo do play (ring :e1, :e2, :e3).tick play (scale :e3, :minor_pentatonic).tick sleep 1 end

Même si chaque live_loop a son compteur indépendant, ici on appelle .tick deux fois dans la même live_loop. Cela veut dire que le compteur sera incrémenté deux fois à chaque boucle. Cela peut produire des polyrythmes intéressants mais ce n’est souvent pas ce que l’on souhaite. Il y a deux solutions à ce problème. Une option est d’appeler tick manuellement au début de la live_loop puis d’utiliser look pour chercher la valeur courante du compteur dans chaque live_loop. La seconde solution est de passer un nom unique à chaque appel à .tick, comme par exemple .tick(:foo). Sonic Pi créera alors un compteur séparé pour chaque tick nommé que vous utiliserez. Ainsi on peut travailler avec autant de compteurs que nécessaire ! Lisez le section 9.4 sur les ticks nommés dans le tutoriel inclus dans Sonic Pi pour plus d’informations.

- Rassemblons tout

Combinons nos connaissances sur les ticks, rings (anneaux) et live_loops pour un dernier exemple amusant. Comme d’habitude, ne traitez pas ceci comme un morceau terminé. Commencez à changer des choses et amusez-vous avec et voyez en quoi vous pouvez le transformer. A la prochaine…

use_bpm 240 notes = (scale :e3, :minor_pentatonic).shuffle

live_loop :foo do use_synth :blade with_fx :reverb, reps: 8, room: 1 do tick co = (line 70, 130, steps: 32).tick(:cutoff) play (octs :e3, 3).look, cutoff: co, amp: 2 play notes.look, amp: 4 sleep 1 end end

live_loop :bar do tick sample :bd_ada if (spread 1, 4).look use_synth :tb303 co = (line 70, 130, steps: 16).look r = (line 0.1, 0.5, steps: 64).mirror.look play notes.look, release: r, cutoff: co sleep 0.5 end