Boucles

Répéter, répéter, etc…

Nous venons d’utiliser notre première boucle. Cette structure de contrôle est de loin la plus populaire et la plus répandue dans le domaine du live-coding. Vous êtes libres de ne pas en utiliser, mais dès lors qu’il s’agit d’improviser, la boucle offre une structure intéressante et unificatrice. Nous chercherons la plupart du temps, dans la majorité des styles musicaux, à gêrer plusieurs sections instrumentales simultanément : percussions, échantillons sonores, accords, fragments mélodiques, etc.. Il faudra dans notre cas y adjoindre une série de contrôles pour les synthétiseurs, le tempo, le réseau, etc.. Une série de boucles synchronisées peuvent facilement remplir ce rôle. Voici une structure d’improvisation typique que l’on rencontre fréquemment lors des performances de live-coding :

 

De nombreuses raisons, tant esthétiques que pratiques ou techniques l’expliquent. Beaucoup ne seront pas gênés par ce type de structure. Pour ceux qui auraient à coeur de composer une musique composée de sections de durée variable, sans répétition spécifique, ou dans une proportion limitée, les différentes structures de contrôle du flux vous permettront un très grand contrôle sur le résultat que vous cherchez à obtenir.

Voici mes raisons pour introduire les boucles avant tout autre élément du langage :

  • vous pourrez modifier dynamiquement le code qu’elles contiennent pour en étudier l’effet.
  • elles permettent très rapidement d’obtenir des résultats musicaux intéressants et peuvent se synchroniser entre elles.

Loop do / Live_loop

Il existe dans la syntaxe de Sonic-Pi un type de boucle extrêmement rudimentaire :


loop do end

Je ne lui trouve honnêtement aucun autre mérite que celui d’exister. Il est assez rarement employé. Je pense qu’il constitue un vestige et une curiosité historique d’une version antérieure de Sonic-Pi, bien que je n’en ait pas la confirmation.

Remarquons que loop do bloque l’exécution du code situé en aval :


loop do play :c4 sleep 0.5 end loop do play :fs6 sleep 0.5 end

Le premier loop sera joué mais le second restera mutique. Les boucles suspendent l’exécution du code situé en aval. Le code est pris dans une répétition sans fin. Ce type de boucle correspond au comportement standard que l’on attends d’une boucle dans un langage de programmation standard. Aucune condition de sortie n’a été définie, il est donc logiquement impossible d’en sortir.

Il est presque toujours préférable d’utiliser live_loop. Cette structure de contrôle est la plus intéressante, et vous aurez besoin de l’écrire très souvent [0]. Veillez donc à connaître le raccourci qui lui est dédié.


live_loop :ode do end


Un live_loop possède un nom, ici :ode. Il constitue pour Sonic-Pi une entité indépendante à laquelle il est possible de référer. Le code défini à l’intérieur d’un live_loop reste local, il n’est valable que pour la portion de votre code définie entre live_loop et end. Pour les lecteurs qui possèdent quelques notions d’informatique, c’est un exemple de code qui tourne dans un scope ou — en français — avec une certaine portée. Le nom de notre live_loop est toujours précédé par un : car il s’agit pour Ruby d’une variable d’instance — et honnêtement, ceci n’est pas important pour vous —.

Essayons de le simplifier à l’extrême pour comprendre son fonctionnement :


live_loop :on_repeat do play :c4 sleep 0.5 end


Modifiez :c4 pour changer de note (notation anglaise, le chiffre indiquant l’octave sur un piano). Modifiez 0.5 pour changer l’intervalle de temps séparant deux notes. Allez-y, c’est le moment d’essayer 0.00001 [1] ou 45, :c9 ou :d1.

Chaque fois que notre boucle arrive à son terme, elle revient à son commencement et poursuit cette routine ad aeternam. Au risque de me répéter :  il n’est pas possible de sortir de cette structure de contrôle en utilisant un opérateur conditionnel. Oubliez immédiatement cette idée. Un live_loop est un îlot de son indépendant et clos.

On pourrait croire, dès lors, qu’il est impossible de lire simultanément deux live_loop. L’exemple suivant est paradoxalement tout à fait valide, et vous entendrez deux notes :

live_loop :on_repeat do play :c4 sleep 0.5 end live_loop :on_repeat_too do play :fs4 sleep 0.25 end


Pour notre confort, ce type de boucle contredit le fonctionnement traditionnel d’un langage de programmation. Il nous est possible d’utiliser plusieurs boucles simultanées, d’empiler sons sur sons, synthétiseurs sur synthétiseurs. Sonic-Pi utilise la syntaxe du Ruby, la déforme, la tourne à son avantage, et cherche en premier lieu à donner au musicien le plus de latitude possible.

Jouez un peu avec cet exemple, modifiez les notes, et pressez Ctrl + R pour écouter les changements. Vous le remarquerez vite, vos live_loop ne sont pas synchronisés, et il devient plus que difficile de rétablir un semblant de synchronie. C’est pour cela que l’on nomme les live_loop : pour qu’ils puissent se coordonner, s’attendre l’un l’autre et se fixer sur un tempo défini. Voici par exemple ce qu’il advient si je modifie la valeur de sommeil de ma boucle et que j’y reviens suite à quelques changements :

Observez le changement mineur dans la syntaxe de l’exemple suivant :


live_loop :on_repeat do play :c4 sleep 0.5 end live_loop :on_repeat_too, sync: :on_repeat do play :fs4 sleep 0.25 end


Vous devriez entendre une itération solitaire de votre première boucle, suivie par l’entrée de la seconde boucle pour le prochain cycle. Notre deuxième live_loop a attendu un signal de synchronisation pour se caler sur le cycle défini par le premier. Ce n’est pas trop mal pour un début : vous savez déjà synchroniser des boucles de durée variable, et vous devriez avoir compris comment produire un certain nombre de polyrythmies complexes. Vous avez déjà, en théorie, bien que le son ne soit pas encore intéressant, tout pour organiser une performance rythmiquement intéressante.

Pour les enthousiastes des musiques de phase, voici déjà un exemple de phasing/dephasing :


live_loop :ding do play :c4 sleep 0.25 end live_loop :dong do play :g4 sleep 0.26 end


Notez la présence dans les exemples de Sonic-Pi d’une version [2] de Piano Phase (1967 – Steve Reich), dont vous trouverez une interprétation et partition sur YouTube : lien.

Héritage et parenté

Les live_loop sont exécutés dans des threads séparés. Un thread est une instance d’exécution particulière du code. Nommer un thread revient à indiquer à Sonic-Pi qu’il n’a pas à créer une instance anonyme, et que nous comptons modifier celle-ci dans le futur. Il nous permettra donc d’accéder à son emplacement et d’y toucher. Sonic-Pi est bâti sur l’utilisation intensive de threads à tout les niveaux :

– chaque exécution Ctrl + R démarre un thread, d’où les horribles superpositions causées par les boucles non nommées ou non synchronisées. Si elles sont nommées, Sonic-Pi les modifie à la prochaine exécution.
– chaque live_loop est un thread séparé.
– Le bloc de code suivant existe, et nous en parlerons ultérieurement :
in_thread(name: :one) do loop do play :c4 sleep 0.5 end end in_thread(name: :two) do loop do play :c2 sleep 1 end end

Mon objectif est toutefois de vous rendre opérationnel le plus rapidement possible. Continuons, et nous reviendrons plus tard aux détails, lorsque ceux-ci poseront un problème créatif intéressant.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[0] Snippets : Certaines instructions sont si fréquemment employées qu’il est possible d’utiliser des raccourcis pour les employer. ll + tabulation aura pour effet de créer un live_loop vide et sans nom. Nous verrons comment ajouter vos propres raccourcis textuels.

 

 

 

 

 

 

 

 

 

 

 

[1] Gestion du temps : Sonic-Pi vous permet de faire beaucoup de choses mais il n’aime pas quand vous essayez de contredire les lois de la physique. Ce nombre aura pour effet de générer l’erreur suivante : “thread got too far behind time”. Vous verrez également qu’une erreur est prévue pour ceux d’entre vous qui essayeront de voyager dans le temps.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[2] Pédagogie : Sonic-Pi est particulièrement utile pour expliquer et examiner certaines techniques musicales contemporaines et expérimentales.