{"id":745,"date":"2020-03-30T17:54:18","date_gmt":"2020-03-30T15:54:18","guid":{"rendered":"https:\/\/unprojetparjour.fr\/?p=745"},"modified":"2020-03-31T11:24:53","modified_gmt":"2020-03-31T09:24:53","slug":"clapping-music-codage-sur-sonic-pi","status":"publish","type":"post","link":"https:\/\/unprojetparjour.fr\/?p=745","title":{"rendered":"Clapping Music &#8211; Codage sur Sonic Pi"},"content":{"rendered":"<h1>La base<\/h1>\n<p>N\u2019\u00e9tant pas un habitu\u00e9 de Sonic Pi lequel j\u2019ai trouv\u00e9 en faisant l\u2019ann\u00e9e derni\u00e8re des recherches internet sur la codage musical et les algorithmes de m\u00eame ordre. J\u2019ai abandonn\u00e9 cette piste relativement rapidement du fait d\u2019autres pr\u00e9occupations.<\/p>\n<p>Je reprend cette ann\u00e9e mes recherches et j\u2019esp\u00e8re aller un peu plus \u00e0 fond dans ces principes.<\/p>\n<p>Sonic Pi est \u00e0 la fois simple, ludique, musical mais aussi alli\u00e9 \u00e0 de puissants outils utilis\u00e9s mondialement depuis au moins 2 sinon 3 g\u00e9n\u00e9rations.<!--more--><\/p>\n<p>Du cot\u00e9 musical et multim\u00e9dia on a le protocole Midi, cr\u00e9\u00e9 sp\u00e9cialement pour la communication entre instruments de musique \u00e9lectronique. Un autre protocole OSC (Open sound Control) est venu quelques ann\u00e9es plus tard, s\u2019adjoindre au midi pour am\u00e9liorer les possibilit\u00e9s et les vitesses de transferts des informations. Le protocole midi s\u2019apparente plus \u00e0 une simple liaison RS232 avec les limites en terme d\u2019envoi et de r\u00e9ception de flux d\u2019informations \u00e0 la fois dans la quantit\u00e9 \u2014 ceci d\u00fb \u00e0 la vitesse tr\u00e8s limit\u00e9e de 31,25 kbits\/sec (moins qu\u2019un modem \u00e0 56 kb dans la valeur de chaque information envoy\u00e9 (0 to 127). De m\u00eame c\u2019est un protocole symetrique unidirectionnel n\u00e9cessitant 2 c\u00e2bles pour envoyer et recevoir les informations. Il a tendance \u00e0 saturer les instruments et chaque musicien l\u2019utilisant a eu au moins une fois la peur de sa vie devant le comportement \u00e9trange d\u2019un synth\u00e9 qui se met \u00e0 vomir des sons sans plus aucune volont\u00e9 de sa part. Panique. Le format de transmission OSC permet lui un transfert sur des r\u00e9seaux car il est soutenu par les protocoles UDP et TCP qui sont la base d\u2019ethernet. Il n\u2019est donc quasiment pas limit\u00e9 par la vitesse et permet des interactions en temps r\u00e9el. Il a \u00e9t\u00e9 con\u00e7u au d\u00e9part pour des interfaces gestuelles permettant de faire de la musique et maintenant il permet la transmission d\u2019ordre sur des r\u00e9seaux m\u00e9lant instruments de musique \u00e9lectronique, informatique, mat\u00e9riel d\u2019\u00e9clairage, interfaces temps r\u00e9el diverses. Je vous mets en fin d\u2019articles quelques liens si votre curiosit\u00e9 vous am\u00e8ne \u00e0 vouloir en savoir plus.<\/p>\n<p>Du cot\u00e9 programmation, si Sonic Pi est clairement dirig\u00e9 vers l\u2019apprentissage de la musique et du codage de celle-ci, il s\u2019appuie sur le langage Ruby qui est un langage open-source moderne s\u2019apparentant peut-\u00eatre \u00e0 notre vieux basic des ann\u00e9es 80-90 mais aussi au langage Lisp qui depuis sa cr\u00e9ation dans les ann\u00e9es 50 par John McCarthy est le langage de l\u2019intelligence artificielle et de ce fait de l\u2019algorithmique. La syntaxe de Ruby est simple et facile \u00e0 retenir et malgr\u00e9 cela, comporte les m\u00eames fonctionnalit\u00e9s que des langages objets plus complexes que lui. C\u2019est donc un langage en plein d\u00e9veloppement qui permet de multiples projets dont Sonic Pi. Sonic Pi s\u2019appuie aussi sur un moteur de synth\u00e8se audio en temps r\u00e9el qui s\u2019appelle super-collider. et qui permet le live coding donc la possibilit\u00e9 de faire \u00e9voluer une musique en temps r\u00e9el.<\/p>\n<p>L\u2019int\u00e9r\u00eat de ces outils : Sonic Pi, Super-Collider, Ruby sont qu\u2019ils sont tous en open-source et donc accessibles et modifiables \u00e0 volont\u00e9 ce qui permet une grande diversit\u00e9 des cibles et un d\u00e9veloppement constant dans le temps du fait d\u2019une large base d\u2019utilisateur. Le fait par exemple d\u2019initier aux enfants la musique par l\u2019interm\u00e9diaire de Sonic Pi les fait entrer dans le monde de la programmation de plein pied \u00e0 un \u00e2ge auquel le cerveau int\u00e8gre beaucoup plus facilement la nouveaut\u00e9 qu\u2019\u00e0 un vieux comme moi. D\u2019ailleurs la base d\u2019utilisateur en constante augmentation et la pr\u00e9sence sur le web d\u2019une communaut\u00e9 importante autour de Sonic Pi permettent un apprentissage simplifi\u00e9 ne serait ce que par rapport \u00e0 des langages comme Java ou le C.<\/p>\n<h1>Passons au programme<\/h1>\n<p>En cherchant sur le web des exemples de programmes en Sonic Pi, je suis tomb\u00e9 sur le compte de G. Martin Butz et sur son s\u00e9quenceur en Sonic Pi. Qui dit s\u00e9quenceur dit stockage des informations et envoie de celle-ci suivant son ordre dans une s\u00e9rie de tableau ou une matrice de stockage. Je cherchais comment stocker et envoyer des informations en midi. Son petit programme m\u2019en a donn\u00e9 la solution. et n\u2019\u00e9tant pas familiaris\u00e9 particuli\u00e8rement avec le Ruby cela m\u2019a fait gagner un temps pr\u00e9cieux.<\/p>\n<p>J\u2019ai pris l\u2019\u0153uvre de Steve Reich, Clapping Music pour faire mes tests.<br \/>\n1. parce que j\u2019aime bien la musique minimaliste am\u00e9ricaine des ann\u00e9es 60-70 qui nous a certainement fait \u00e9voluer \u00e9norm\u00e9ment en mati\u00e8re de musique \u00e9lectronique.<br \/>\n2. parce que ce morceau est d\u2019une simplicit\u00e9 d\u00e9concertante (pour faire un jeu de mot facile. Ceux qui n\u2019ont pas compris l\u00e8ve la main) et qu\u2019il ne demande pas de ce fait un nombre de ligne de code insurmontable \u00e0 mon apprentissage<\/p>\n<p>En gros le programme ne n\u00e9cessite que 2 tableaux de 12 notes puisque le rythme de base de Clapping Music est constitu\u00e9 de 7 notes et de 5 espaces, quelques variables et tableaux permettant le stockage temporaire d\u2019information, quelques boucles, quelques fonctions.<\/p>\n<p>Nous les appelerons<\/p>\n<ol>\n<li>Les tableaux (ou pattern pour parler musik)\n<ul>\n<li><strong>base_pattern_clap<\/strong> (tableau du pattern de base, s\u2019ex\u00e9cutant tout du long du morceau)<\/li>\n<li><strong>base_mob_pattern_clap<\/strong> (tableau en rotation constante le long du morceau)<\/li>\n<li><strong>tmp_pattern<\/strong> (tableau de stockage temporaire dans la fonction bouge_element, non utilis\u00e9 dans la version actuelle du programme)<\/li>\n<\/ul>\n<\/li>\n<li>Les fil d\u2019ex\u00e9cution (threads)\n<ul>\n<li><strong>base_jeu<\/strong> (la boucle, fonction jouant le pattern base_pattern_clap)<\/li>\n<li><strong>mobile_jeu<\/strong> (la boucle, fonction jouant le pattern base_mob_pattern_clap<\/li>\n<\/ul>\n<\/li>\n<li>Les fonctions\n<ul>\n<li><strong>play_rythm_bar<\/strong> (la fonction lan\u00e7ant le jeu d\u2019un pattern)<\/li>\n<li><strong>bouge_element<\/strong> (la fonction permettant de translater le pattern)<\/li>\n<li><strong>get_bmp_val<\/strong> (la fonction permettant de connaitre la dur\u00e9e d&rsquo;une note ou d&rsquo;un silence<\/li>\n<\/ul>\n<\/li>\n<li>Les variables\n<ul>\n<li><strong>d<\/strong> ( la valeur en temps d\u2019un silence)<\/li>\n<li><strong>s<\/strong> (sens de rotation du pattern)<\/li>\n<li><strong>clap<\/strong>, <strong>clap2<\/strong> (variable contenant le chemin d&rsquo;acc\u00e8s aux samples)<\/li>\n<li><strong>el__a_bouger<\/strong> (l\u2019\u00e9lement du tableau <strong>base_mob_pattern_clap<\/strong> \u00e0 passer du d\u00e9but \u00e0 la fin de celui-ci ou inversement)<\/li>\n<li>d&rsquo;autres variables temporaires utilis\u00e9es dans les param\u00e8tres de fonctions<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>On va commencer par les variables fixes ou fonctions de param\u00e9trage du programme<\/p>\n<p><strong>use_debug<\/strong><\/p>\n<p>ce premier \u00e9l\u00e9ment permet d&rsquo;indiquer dans la fen\u00eatre journal de Sonic Pi certains r\u00e9sultats de fonctions. Il permet dans notre cas de v\u00e9rifier le bon chargement des samples (voir plus loin) et leur bonne ex\u00e9cution dans le programme. Ses param\u00e8tres sont true ou false. le param\u00e8tre par d\u00e9faut \u00e9tant true il n&rsquo;est pas utile d&rsquo;utiliser la fonction dans le cas ou vous voulez en avoir l&rsquo;usage. En revanche, pour limiter les sorties dans le journal, indiquez<\/p>\n<pre lang=\"ruby\">use_debug false<\/pre>\n<p>en d\u00e9but de votre programme.<\/p>\n<p>Maintenant nous indiquons<\/p>\n<pre lang=\"ruby\">set_volume! 1<\/pre>\n<p>Pour indiquer le niveau de sortie du son. Ici aussi, nous utilisons la valeur par d\u00e9faut; le param\u00e8trage pouvant se faire de 0 \u00e0 5 et accepte les fractions.<\/p>\n<pre lang=\"ruby\">use_bpm 170<\/pre>\n<p><strong>use_bpm<\/strong> correspond au tempo du morceau. Dans les \u0153uvres de Steve Reich, le tempo est souvent modulable ainsi que le nombre de r\u00e9p\u00e9titions de chaque motif. Pour Clapping Music, on a un tempo de 160 \u00e0 210 environ et un nombre de r\u00e9p\u00e9titions de 4 \u00e0 8 fois le motif de base. Dans notre cas et pour d\u00e9marrer, nous allons utiliser un tempo de 60 ou de 90. \u00e0 votre convenance. Vous pouvez tester le temps mis par une boucle en entrant le code suivant :<\/p>\n<pre lang=\"ruby\">use_debug true\r\nset_volume! 1\r\nuse_bpm 60\r\n\r\nlive_loop :test do\r\n  sleep 1\r\n  puts \"j'ai fait un tour\"\r\nend\r\n<\/pre>\n<p>J&rsquo;explique ce petit bout de code<\/p>\n<p>Nous avons cr\u00e9e un boucle (<strong>live_loop<\/strong>) appel\u00e9e test (<strong>:test<\/strong>) qui fait (<strong>do<\/strong>)<br \/>\n<strong>sleep 1<\/strong> (pause de une mesure)<br \/>\n<strong>puts<\/strong> (placer, imprimer \u00e0 l&rsquo;\u00e9cran) <strong>\u00ab\u00a0j&rsquo;ai fait un tour\u00a0\u00bb<\/strong> (texte affich\u00e9 dans le journal)<br \/>\n<strong>end<\/strong> (fin de la boucle)<br \/>\non recommence \u00e0 <strong>sleep 1<\/strong><\/p>\n<p>En changeant la valeur de <strong>use_bpm<\/strong>et en relan\u00e7ant le programme, on s&rsquo;aper\u00e7oit dans le journal que notre boucle est plus ou moins rapide en fonction de la nouvelle valeur mise.<\/p>\n<p><strong>d<\/strong> est d\u00e9pendant de la longueur du motif de base (ici <strong>base_pattern_clap<\/strong>). On le calcule donc par rapport \u00e0 celui-ci avec la fonction <strong>get_bpm_val<\/strong>.<br \/>\nLa fonction <strong>bouge_element<\/strong> est on ne peut plus simple. Elle est appel\u00e9e avec une variable <strong>s<\/strong> qui est le sens de rotation du pattern et le pattern qu\u2019on doit modifier suivant ce sens, on met dans <strong>el_a_bouger<\/strong>, l\u2019\u00e9l\u00e9ment qu\u2019on doit reporter de l\u2019autre cot\u00e9 du pattern<br \/>\non enl\u00e8ve du tableau l\u2019\u00e9l\u00e9ment qu\u2019on vient de stocker dans <strong>el_a_bouger<\/strong><br \/>\net on ajoute <strong>el_a_bouger<\/strong> en fin ou en d\u00e9but de tableau<\/p>\n<p>ce qui donne :<\/p>\n<pre lang=\"ruby\">define :bouge_element do |s, tab|\r\n  if s == 1\r\n    el_a_bouger = base_mob_pattern_clap[11]\r\n    base_mob_pattern_clap.delete_at (11)\r\n    base_mob_pattern_clap = [el_a_bouger] + base_mob_pattern_clap\r\n  elsif s == -1\r\n    el_a_bouger = base_mob_pattern_clap[0]\r\n    base_mob_pattern_clap.delete_at (0)\r\n    base_mob_pattern_clap = base_mob_pattern_clap + [el_a_bouger]\r\n  end\r\nend\r\n<\/pre>\n<p>La fonction <strong>play_rythm_bar<\/strong> (traduction litt\u00e9rale jouer le rythm de la mesure) est appel\u00e9e elle aussi avec deux arguments : l\u2019instrument qui va \u00eatre utilis\u00e9 pour la premi\u00e8re mesure et le pattern \u00e0 jouer.<\/p>\n<pre lang=\"ruby\">define :play_rhythm_bar do |instr, instr_pattern|\r\n  instr_pattern.each do |i|\r\n    if i != 0\r\n      instr.call\r\n    end\r\n    sleep d\r\n  end\r\nend\r\n<\/pre>\n<p>Vous aurez observ\u00e9 l\u2019appel des m\u00e9thode <strong>each<\/strong> et <strong>call<\/strong> que je vous explique.<\/p>\n<pre lang=\"ruby\">inst_pattern.each do |i|\r\n<\/pre>\n<p><strong>inst_pattern.each<\/strong> est une m\u00e9thode simplifi\u00e9 pour une boucle de type <strong>for<\/strong> ou <strong>while<\/strong> et se traduirait pour chaque \u00e9l\u00e9ment du tableau.<br \/>\n<strong>do |i|<\/strong> : pour chaque <strong>inst_pattern[i]<\/strong> faire\u2026 la suite.<br \/>\nVous remarquerez qu\u2019une fonction, une boucle, enfin quoi que ce soit qui s\u2019ex\u00e9cute ou qui se d\u00e9finit utilisent les termes <strong>do<\/strong> au d\u00e9part et <strong>end<\/strong> \u00e0 la fin.<br \/>\nLa m\u00e9thode <strong>call<\/strong> est utilis\u00e9 de la m\u00eame fa\u00e7on pour lancer un objet d\u00e9finit pr\u00e9c\u00e9demment.<\/p>\n<p>Dans notre cas, on va cr\u00e9er une fonction permettant de jouer un son enregistr\u00e9 pr\u00e9c\u00e9demment (sample). Pour cela, il nous faut ce son qu\u2019on va appeler <strong>clap<\/strong>.<\/p>\n<pre lang=\"ruby\">clap = \"~\/Music\/SonicPi\/Samples\/Base Drums\/Clap_1_VideoStar.wav\"\r\n<\/pre>\n<p>On va appeler ce son par la m\u00e9thode <strong>load_sample<\/strong><\/p>\n<pre lang=\"ruby\">load_sample clap\r\n<\/pre>\n<p>On cr\u00e9e une m\u00e9thode <strong>lambda<\/strong> qu\u2019on appelle <strong>base<\/strong><\/p>\n<pre lang=\"ruby\">base = lambda do\r\n  sample clap, amp: 4, pan: 0.5\r\nend\r\n<\/pre>\n<p>il ne suffit plus qu\u2019\u00e0 lancer cette m\u00e9thode<\/p>\n<pre lang=\"ruby\">base.call\r\n<\/pre>\n<p>Et voil\u00e0 notre son est jou\u00e9.<\/p>\n<p>On recommence avec un deuxi\u00e8me son pour notre deuxi\u00e8me instrument<\/p>\n<pre lang=\"ruby\">clap2 = \"~\/Music\/SonicPi\/Samples\/Base Drums\/Clap_2_VideoStar.wav\"\r\n\r\nload_sample clap\r\n\r\nmobile = lambda do\r\n  sample clap2, amp: 4, pan: 0.5\r\nend\r\n\r\nmobile.call\r\n<\/pre>\n<p>vous pouvez lancer le programme avec les deux claps. Vous n\u2019entendez qu\u2019un son ? C\u2019est normal. Pour entendre les deux sons, on va utiliser une pause entre le premier et le deuxi\u00e8me <strong>call<\/strong>. O\u00f9 vous voulez\u2026 sauf \u00e0 l\u2019int\u00e9rieur de la m\u00e9thode <strong>lambda<\/strong>.<\/p>\n<pre lang=\"ruby\">sleep 1\r\n<\/pre>\n<p>Soit une pause de 1 mesure.<\/p>\n<p>Voil\u00e0 nous avons pos\u00e9 les bases de fonctionnement de notre programme<\/p>\n<p>Si vous avez bien observ\u00e9, on a utilis\u00e9 <strong>sleep<\/strong> dans le fonction <strong>play_rythm_bar<\/strong> avec l\u2019argument <strong>d<\/strong>. Cette variable n\u2019a pour l\u2019instant pas \u00e9t\u00e9 d\u00e9finie.<\/p>\n<p>J\u2019ai donc utilis\u00e9 et am\u00e9lior\u00e9 la fonction de G. Martin Butz pour d\u00e9finir cette valeur <strong>d<\/strong>. qui correspond \u00e0 la valeur d\u2019un silence identique aux notes de notre pattern.<\/p>\n<p>Consid\u00e9rons une mesure; Au plus il y a de notes dans la mesure, c\u2019est \u00e0 priori parce que le temps allou\u00e9 \u00e0 chaque note est plus petit.<br \/>\nPar exemple en 4\/4, on peut mettre au choix 1 ronde, 2 blanches, 4 noires, 8 croches, 16 doubles-croches, 32 triples-croches, 64 quadruples-croches, 128 quintuples-croches.<\/p>\n<p>Donc, au plus notre tableau (pattern) contient de notes au plus petites elle sont. Nous en d\u00e9duisons donc la valeur de <strong>d<\/strong> de cette fa\u00e7on. On prend bien entendu l\u2019hypoth\u00e8se qu\u2019un pattern correspond \u00e0 une mesure.<\/p>\n<p>Voici notre fonction <strong>get_bmp_val<\/strong> que j&rsquo;ai limit\u00e9 de la noire \u00e0 la double croche en incluant les rythmes \u00e0 trois temps.<\/p>\n<pre lang=\"ruby\">define :get_bmp_val do |a|\r\n  if a.count == 4 || a.count == 6\r\n    d = 1\r\n  elsif a.count == 8 || a.count == 12\r\n    d = 0.5\r\n  elsif a.count == 16 || a.count == 24\r\n    d = 0.25\r\n  else\r\n    puts \"NOTE: Aucune id\u00e9e du rythme de votre morceau !\"\r\n  end\r\n  return d\r\nend\r\n<\/pre>\n<p><strong>a<\/strong> \u00e9tant bien entendu notre pattern et la m\u00e9thode <strong>count<\/strong> permettant le calcul du nombre d\u2019\u00e9l\u00e9ments de celui-ci.<\/p>\n<p>On peut mettre indiff\u00e9remment notre appel \u00e0 cette fonction \u00e0 l\u2019int\u00e9rieur d\u2019une autre fonction ou de fa\u00e7on ind\u00e9pendante pour d\u00e9finir une fois, pour toute la dur\u00e9e du programme la valeur d. L\u2019int\u00e9r\u00eat de la mettre \u00e0 l\u2019int\u00e9rieur d\u2019une fonction est que si 2 patterns sont d\u2019un nombre de notes diff\u00e9rentes alors les deux patterns peuvent s\u2019enchev\u00eatrer pendant le jeu. Ce qui bien s\u00fbr en musique arrive r\u00e9guli\u00e8rement. Je vous laisserai le soin de l\u2019imaginer et de modifier le mode de calcul de <strong>d<\/strong>. Sur un synth\u00e9tiseur muni d\u2019un s\u00e9quenceur l\u2019appel est souvent en multiples de 4 (4, 8, 16, 32) et il est rare de pouvoir faire des mesures tronqu\u00e9es par rapport \u00e0 ces mesures, de m\u00eame que de faire des mesures sur 3 ou 5 temps. La possibilit\u00e9 de le faire avec Sonic Pi peut dans ce cas \u00eatre un plus et sortir nos musiciens de gal\u00e8res qui quelquefois r\u00e9duisent leurs superbes imaginations.<\/p>\n<p>C\u2019est bien mais avec tout \u00e7a on n\u2019a pas encore d\u00e9fini le contenu de notre pattern.<\/p>\n<p>Le motif de base de Clapping musique est<\/p>\n<p>,tac,tac,tac, ,tac,tac, ,tac, ,tac,tac, ,<\/p>\n<p>soit transform\u00e9 par le miracle de l\u2019intelligence (non artificielle de l\u2019\u00eatre humain) en <strong>[ 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0 ]<\/strong>.<\/p>\n<p>On a donc d\u00e9fini nos deux tableaux qui sont pour l\u2019instant identique.<\/p>\n<pre lang=\"ruby\">pattern_clap      =  [ 1,  1,  1,  0,  1,  1,  0,  1,  0,  1,  1,  0  ]\r\nbase_mob_pattern_clap  =  [ 1,  1,  1,  0,  1,  1,  0,  1,  0,  1,  1,  0  ]\r\n<\/pre>\n<p>Maintenant il ne nous reste plus qu\u2019\u00e0 appeler nos fonctions avec des threads. Les threads dont la traduction est fil (ici plus pr\u00e9cis\u00e9ment fil d\u2019ex\u00e9cution) est en fait le d\u00e9roulement d\u2019une partie d\u2019un programme. un peu comme un instrumentiste qui jouerait uniquement sa partie en solo.<\/p>\n<p>Comme il y a deux instruments sur Clapping Music, on va cr\u00e9er 2 threads dans lesquels on va jouer nos patterns.<\/p>\n<pre lang=\"ruby\"> in_thread(name:  :base_jeu) do\r\nend\r\n\r\nin_thread(name:  :mobile_jeu) do\r\nend\r\n<\/pre>\n<p>Comme le morceau de Steve Reich fait 104 mesures, on va voir combien de fois chaque mesure est jou\u00e9.<\/p>\n<p>Pour l\u2019instrument 1, c\u2019est facile le motif \u00e9tant jou\u00e9 ad vitam aeternam, enfin jusqu\u2019\u00e0 la fin du morceau donc 104 mesures.<\/p>\n<p>On cr\u00e9e donc une boucle que l\u2019on va reproduire 104 fois. C\u2019est bien facile puisqu\u2019une instruction est faite pour cela. l\u2019instruction <strong>times<\/strong> que l\u2019on fait pr\u00e9c\u00e9der du nombre de fois o\u00f9 elle doit \u00eatre jou\u00e9 et d\u2019un point de s\u00e9paration comme <strong>call<\/strong>, <strong>each<\/strong>, <strong>count<\/strong>, etc. Comme chaque instruction de ce type, on la fait suivre par <strong>do<\/strong> et finir par <strong>end<\/strong> (voir pr\u00e9c\u00e9demment).<\/p>\n<p>On ins\u00e8re dans cette boucle notre fonction <strong>play_rhythm_bar<\/strong> avec ses arguments : le son \u00e0 jouer et le pattern correspondant. Chez vous, faites un test sur une mesure ou si cela n\u2019est pas le rendu esp\u00e9r\u00e9, pensez aux raccourcis pour arr\u00eater votre programme.<\/p>\n<pre lang=\"ruby\">in_thread(name:  :base_jeu) do\r\n  104.times do\r\n    play_rhythm_bar base, base_pattern_clap\r\n  end\r\nend\r\n<\/pre>\n<p>Pour le deuxi\u00e8me instrument, on a le m\u00eame nombre de mesures total mais on joue chaque pattern huit fois avant de faire une rotation dans le tableau. Le nombre de rotations total pour revenir au motif de base est de la longueur du pattern, soit 12 rotations plus le motif de base qui multipli\u00e9es par nos 8 r\u00e9p\u00e9titions donnent bien 104.<\/p>\n<p>On a donc deux boucles imbriqu\u00e9es de cette fa\u00e7on.<\/p>\n<pre lang=\"ruby\">in_thread(name:  :mobile_jeu) do\r\n  13.times do\r\n    8.times do |count|\r\n      play_rhythm_bar base, base_mob_pattern_clap\r\n    end\r\n  end\r\nend\r\n<\/pre>\n<p>Il ne suffit plus qu\u2019\u00e0 rajouter notre fonction de rotation de pattern pour faire \u00e9voluer comme il se doit le morceau.<\/p>\n<pre lang=\"ruby\">in_thread(name:  :mobile_jeu) do\r\n  13.times do\r\n    8.times do |count|\r\n      play_rhythm_bar base, base_mob_pattern_clap\r\n    end\r\n    bouge_element -1, base_mob_pattern_clap\r\n  end\r\nend\r\n<\/pre>\n<p>Si vous avez bien suivi, votre programme sous Sonic Pi devrait fonctionner. Si vous rencontrez des probl\u00e8mes, n\u2019h\u00e9sitez pas \u00e0 utiliser l\u2019instruction <strong>puts<\/strong>, l\u2019\u00e9quivalent de notre print du basic du commodore 64 et de l\u2019employer pour suivre la valeur de vos variables, l\u2019aspect de vos tableaux ou encore les valeurs de retour de vos fonctions.<\/p>\n<p>En dernier et j\u2019en ai parl\u00e9 au d\u00e9but, l\u2019un des buts de Sonic Pi n\u2019est pas de faire de la musique seul dans son coin m\u00eame si \u00e0 priori il le fait bien mais gr\u00e2ce au protocole midi et OSC \u00e0 envoyer des informations \u00e0 d\u2019autres p\u00e9riph\u00e9riques.<\/p>\n<p>Je vous donne donc les rudiments pour y arriver.<\/p>\n<p>Pour un simple envoi d\u2019une note sur le synth\u00e9 midi de votre choix utilisez la fonction <strong>midi_note_on<\/strong> suivi au minumum de la valeur de la note comme cela :<\/p>\n<pre lang=\"ruby\">midi_note_on 60\r\n<\/pre>\n<p>qui joue un do et qui pourrait s&rsquo;\u00e9crire aussi :c4 en notation anglaise. Vous pouvez ensuite ajouter \u00e0 cela la v\u00e9locit\u00e9 de la note jou\u00e9e :<\/p>\n<pre lang=\"ruby\">midi_note_on 60, 90\r\n<\/pre>\n<p>sur une valeur de 0 \u00e0 127,<\/p>\n<p>puis l\u2019instrument sur lequel vous voulez jouer avec le param\u00e8tre <strong>port:<\/strong>. Par exemple :<\/p>\n<pre lang=\"ruby\">midi_note_on :c4, 90, port: [\u201dmon_synth\u00e9_rien_qu\u00e0_moi\u201d]\r\n<\/pre>\n<p>et enfin le canal midi correspondant \u00e0 vos r\u00e9glages sur le synth\u00e9.<\/p>\n<pre lang=\"ruby\">midi_note_on :c4, 90, port: [\u201dmon_synth\u00e9_rien_qu\u00e0_moi\u201d], channel: 1\r\n<\/pre>\n<p>Vous rajouter \u00e0 cela un <strong>sleep<\/strong> correspondant \u00e0 la longueur de la note jou\u00e9e et vous finissez par \u00e9teindre la note avec l\u2019instruction midi <strong>midi_note_off<\/strong> avec le port et le canal correspondant<\/p>\n<p>ce qui pourrait donner dans votre programme une portion de code similaire \u00e0 celle ci :<\/p>\n<pre lang=\"ruby\">midi_note_on note, velocity, port: \"gestionnaire_iac_bus_1\", channel: 10\r\nsleep d\r\nmidi_note_off note, port: \"gestionnaire_iac_bus_1\"\r\n<\/pre>\n<p>Je vous renvoie sur mon pr\u00e9c\u00e9dent article sur Clapping Music sur lequel vous trouverez un enregistrement complet de celui-ci disponible sur Youtube.<\/p>\n<p>https:\/\/unprojetparjour.fr\/2020\/03\/28\/steve-reich-clapping-music-realisation-avec-sonic-pi-logic-pro-x-et-drumlab\/<\/p>\n<p>N\u2019h\u00e9sitez pas \u00e0 vous mettre \u00e0 Sonic Pi et \u00e0 en faire profiter vos enfants par exemple car c\u2019est ludique et cela peut vous faire cr\u00e9er de belles choses. En cette p\u00e9riode de confinement, c\u2019est un atout pour ne pas s\u2019ennuyer (les enfants) ou ne pas stresser (les parents).<\/p>\n<p>Sonic Pi existe sur les diff\u00e9rentes plateformes informatique, Mac, Windows, et Unix et il a \u00e9t\u00e9 d\u00e9velopp\u00e9 au d\u00e9part pour Raspberry Pi sur lequel il fonctionne toujours.<\/p>\n<p>Bonne programmation.<\/p>\n<h1>Liens divers<\/h1>\n<p><a href=\"https:\/\/fr.wikipedia.org\/wiki\/Musical_Instrument_Digital_Interface\">https:\/\/fr.wikipedia.org\/wiki\/Musical_Instrument_Digital_Interface<\/a><br \/>\n<a href=\"https:\/\/fr.wikipedia.org\/wiki\/Open_Sound_Control\">https:\/\/fr.wikipedia.org\/wiki\/Open_Sound_Control<\/a><br \/>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Sonic_Pi\">https:\/\/en.wikipedia.org\/wiki\/Sonic_Pi<\/a><br \/>\n<a href=\"https:\/\/fr.wikipedia.org\/wiki\/Ruby\">https:\/\/fr.wikipedia.org\/wiki\/Ruby<\/a><br \/>\n<a href=\"https:\/\/fr.wikipedia.org\/wiki\/SuperCollider\">https:\/\/fr.wikipedia.org\/wiki\/SuperCollider<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>La base N\u2019\u00e9tant pas un habitu\u00e9 de Sonic Pi lequel j\u2019ai trouv\u00e9 en faisant l\u2019ann\u00e9e derni\u00e8re des recherches internet sur la codage musical et les algorithmes de m\u00eame ordre. J\u2019ai abandonn\u00e9 cette piste relativement rapidement du fait d\u2019autres pr\u00e9occupations. Je &hellip; <a href=\"https:\/\/unprojetparjour.fr\/?p=745\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,52],"tags":[],"class_list":["post-745","post","type-post","status-publish","format-standard","hentry","category-informatique","category-musique"],"_links":{"self":[{"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=\/wp\/v2\/posts\/745"}],"collection":[{"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=745"}],"version-history":[{"count":8,"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=\/wp\/v2\/posts\/745\/revisions"}],"predecessor-version":[{"id":753,"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=\/wp\/v2\/posts\/745\/revisions\/753"}],"wp:attachment":[{"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unprojetparjour.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}