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…
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.
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…
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 :
sleep
de 0.5
à quelque chose plus élevé comme 1
Run
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 :
rate:
pour entendre changer
le son de l’échantillon.sleep
et découvrez que les 2 boucles
peuvent tourner à différentes cadences.#
) et apprécier
le son de la guitare joué en fond.mix:
avec des nombres
entre 0
(pas dans le mixage) et 1
(entièrement dans le mixage).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…
Sonic Pi a une interface très simple pour coder de la musique. Passons
un peu de temps à l’explorer.
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.
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.
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 (F) et le bouton Prefs active la fenêtre des préférences qui vous permet de contrôler quelques paramètres systèmes basiques.
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.
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).
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.
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.
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.
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é.
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 !
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…
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…
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.
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 play
s, 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.
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.
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.
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.
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:
.
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.
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
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 !
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.
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.
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
.
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 :
:prophet
:dsaw
:fm
:tb303
:pulse
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.
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 :
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.
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.
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 :
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.
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 :
Bien entendu, vous pouvez inverser les choses. Essayez une attaque longue et une exctinction rapide :
play 60, attack: 4, release: 0.7
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
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
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.
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
Ainsi pour résumer, les enveloppes de Sonic Pi ont les phases suivantes :
attack_level
,attack_level
jusqu’au niveau sustain_level
,sustain_level
,sustain_level
au niveau 0Il 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.
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…
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.
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 :
:ambi_
:bass_
:elec_
:perc_
:guit_
:drum_
:misc_
:bd_
Maintenant commencez à introduire des échantillons dans vos compositions !
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:
.
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
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
.
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.
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.
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.
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.
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.
(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 :
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.
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.
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
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.
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.
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.
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.
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.
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 ?
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
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
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 !
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
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.
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.
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.
Alors comment jouez-vous n’importe quel fichier WAV ou AIFF 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
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.
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.
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
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
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.
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
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)
:
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)
:
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
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.
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 !
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 !
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…
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.
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.
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.
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
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
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 !
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).
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.
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.
(“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.
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.
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
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.
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.
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.
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}
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”…
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.
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.
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.
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
).
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 !
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.
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.
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.
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.
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.
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.
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.
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.
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…
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 !
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.
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
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
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.
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 !
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.
Rappelez-vous, il n’y a pas de fautes, juste des possibilités. Toutefois, chacune de ces approches donnera un son différent et aura 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.
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.
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
.
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.
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 !
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.
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
.
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…
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.
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.
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.
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…
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 :
chord(:E3, :m7)
chord(:E3, :minor)
chord(:E3, :dim7)
chord(:E3, :dom7)
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 ?
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
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.
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.
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.
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
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
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.
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.
En sus de ring
, il y a un certain nombre de fonctions qui vous
construiront un anneau.
range
vous invite à spécifier un point de départ, un point de
fin, et la taille du pas.bools
vous permet d’utiliser des 1
s et 0
s pour représenter les
booléens de manière condensée.knit
vous permet de créer une séquence de valeurs dupliquées.spread
crée un anneau de booléens avec une distribution euclidienne.Jetez un œil à leur documentation respective pour plus d’information.
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…
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…
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…
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 !
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.
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” !
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.
Sonic Pi fournit un outil très pratique pour travailler avec des anneaux
(“rings”) à l’intérieur des live_loop
s. Il s’agit du système d’avance
automatique (“tick”). Il vous fournit la capacité de parcourir des anneaux.
Regardons un exemple :
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
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.
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.
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_loop
s - 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
.
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_loop
s.
Jetez un œil sur la documentation des tick
s où se trouvent de nombreux
exemples utiles, et joyeux parcours automatiques !
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.
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.
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.
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.
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 :
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
.
Pour aligner et indenter automatiquement vos lignes de code, pressez M-m
.
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.
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.
Dans cette liste, nous utilisons les conventions suivantes (où Meta est la touche Alt pour Windows/Linux et Cmd sur Mac) :
C-a
signifie maintenir la touche Control enfoncée puis presser la touche a, puis relacher les deux en même temps.M-r
signifie maintenir la touche Meta enfoncée puis presser la touche r, puis relacher les deux en même temps.S-M-z
signifie maintenir les touches Majuscule et Meta enfoncées puis presser la touche z, puis les relacher toutes en même temps.C-M-f
signifie maintenir les touches Control et Meta enfoncées puis presser la touche f, puis les relacher toutes en même temps.M-r
- Exécute le codeM-s
- Arrête le codeM-i
- Affiche/cache le système d’aideM-p
- Affiche/cache les préférencesM-<
- Bascule sur le buffer de gaucheS-M-<
- Bascule sur le buffer de droiteM-+
- Augmente la taille du texte du buffer courantM--
- Diminue la taille du texte du buffer courantM-a
- Sélectionne toutM-c
- Copie la sélection dans le presse-papierM-x
- Coupe la sélection et la copie dans le presse-papierC-k
- Coupe jusqu’à la fin de la ligne et le copie dans le presse-papierM-v
- Colle depuis le presse-papierC-y
- Colle depuis le presse-papierC-SPACE
- Pose une marque. La navigation surligne et sélectionne la région depuis la marque.
Utilisez C-g
pour sortir.M-m
- aligne et indente tout le texteTab
- aligne et indente la ligne courante ou la sélection (ou la liste complète)C-t
- Intervertit les caractères sélectionnésM-u
- Convertit le mot suivant (ou la sélection) en majuscule.M-l
- Convertit le mot suivant (ou la sélection) en minuscule.C-a
- Déplace au début de la ligneC-e
- Déplace à la fin de la ligneC-p
- Déplace à la ligne précédenteC-n
- Déplace à la ligne suivanteC-f
- Avance d’un caractèreC-b
- Recule d’un caractèreM-f
- Avance d’un motM-b
- Recule d’un motC-M-n
- Déplace la ligne ou la sélection vers le basC-M-p
- Déplace la ligne ou la sélection vers le hautS-M-u
- Déplace 10 lignes vers le hautS-M-d
- Déplace 10 lignes vers le basC-h
- Supprime le caractère précédentC-d
- Supprime le caractère suivantC-i
- Affiche la documentation du mot où se trouve le curseurM-z
- DéfaitS-M-z
- RefaitC-g
- SortS-M-f
- Bascule en mode plein écranS-M-b
- Affiche/cache les boutonsS-M-l
- Affiche/cache le panneau “trace”S-M-m
- Bascule entre l’affichage clair et sombreSonic 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.
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.
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).
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.
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”.
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.
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.
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.
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.
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.
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.
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.
L’API à Minecraft a été conçue pour fonctionner sans heurt à l’intérieur
des live_loop
s. 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.
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.
À 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.
Sonic Pi supporte actuellement les interactions basiques suivantes avec Minecraft Pi :
Voyons chacune d’elles tour à tour.
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 ?
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.
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 :
x
z
y
Une chose en plus - nous décrivons habituellement ces trois
coordonnées dans l’ordre x
, y
, z
.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.
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…
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 :-)
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
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