{"id":1099,"date":"2015-10-30T17:27:46","date_gmt":"2015-10-30T16:27:46","guid":{"rendered":"http:\/\/www.zylannprods.fr\/fr\/?p=1099"},"modified":"2015-10-30T17:45:22","modified_gmt":"2015-10-30T16:45:22","slug":"reaper-creer-des-effets-avec-jsfx","status":"publish","type":"post","link":"https:\/\/www.zylannprods.fr\/fr\/reaper-creer-des-effets-avec-jsfx\/","title":{"rendered":"REAPER &#8211; Cr\u00e9er des effets avec JSFX"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p><a href=\"http:\/\/www.reaper.fm\/\">Reaper<\/a> est un logiciel de production audio supportant plusieurs types de plugins: VST, DX, et JSFX (JS).<br \/>\nContrairement aux premiers, les effets JSFX sont en r\u00e9alit\u00e9 de simples scripts, qu&rsquo;il est possible de modifier en temps r\u00e9el via leur bouton \u00ab\u00a0Edit\u00a0\u00bb.<br \/>\n<img alt=\"Screenshot bouton editer\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/edit_button.png\" \/><\/p>\n<p>Au premier abord, ce code peut para\u00eetre \u00e9trange, m\u00eame quand on a l&rsquo;exp\u00e9rience de langages comme Javascript ou C++. Les ressources officielles sur JSFX sont disponibles en anglais sur le site de Cockos: <a href=\"http:\/\/www.reaper.fm\/sdk\/js\/js.php\">http:\/\/www.reaper.fm\/sdk\/js\/js.php<\/a><\/p>\n<p>Pour ceux qui connaissent ShaderToy ou Processing, JSFX est un \u00e9quivalent audio, utilisable directement dans Reaper \ud83d\ude42<br \/>\nJe m&rsquo;y suis tout de m\u00eame int\u00e9ress\u00e9 de plus pr\u00e8s, et autant faire d&rsquo;une pierre deux coups: j&rsquo;ai d\u00e9cid\u00e9 d&rsquo;\u00e9crire<br \/>\nun article en fran\u00e7ais sur ce que j&rsquo;apprend de cet outil \ud83d\ude42<\/p>\n<p>Note: je passe volontairement certaines parties pr\u00e9sent\u00e9es par la documentation officielle pour rester simple, j&rsquo;aborderai ces d\u00e9tails peut-\u00eatre plus tard.<\/p>\n<h2>Cr\u00e9er un effet<\/h2>\n<p>Pour cr\u00e9er un nouvel effet, ouvrez la fen\u00eatre \u00ab\u00a0Add FX\u00a0\u00bb, \u00ab\u00a0File -&gt; Create new JS FX&#8230;\u00a0\u00bb<br \/>\n<img alt=\"Screenshot create new JS effect\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/create_new_js_fx.png\" \/><\/p>\n<p>Choisissez le nom de votre effet:<br \/>\n<img alt=\"Screenshot effect name\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/js_effect_name.png\" \/><\/p>\n<p>Reaper va cr\u00e9er votre effet avec quelques sliders de base, histoire de pas partir de rien.<br \/>\n<img alt=\"Screenshot effect UI\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/effect_ui_01.png\" \/><\/p>\n<p>Si vous le testez, \u00e9videmment, il ne fait rien de sp\u00e9cial. Pour \u00e7a, il va falloir mettre les mains dans le cambouis \ud83d\ude00<br \/>\nCliquez sur Edit&#8230;<br \/>\n<img alt=\"Screenshot default code\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/default_code.png\" \/><\/p>\n<p>D\u00e9cortiquons le code qui nous est fourni comme point de d\u00e9part \ud83d\ude42<\/p>\n<h2>Description<\/h2>\n<p>Chaque effet JS doit commencer par cette ligne:<\/p>\n<div class=\"zcustom-codeblock\"><code>desc:new effect<\/code><\/div>\n<p>C&rsquo;est une courte description qui sera utilis\u00e9e comme nom dans la liste des effets.<br \/>\nAussi, comme Reaper sauvegarde l&rsquo;effet sans extension, c&rsquo;est ce qui lui permet de savoir que le fichier est un effet JSFX.<\/p>\n<h2>Sliders<\/h2>\n<div class=\"zcustom-codeblock\"><code>slider1:0&lt;0,100,1&gt;parameter1<br \/>\nslider2:0&lt;0,100,1&gt;parameter2<br \/>\nslider3:0&lt;0,100,1&gt;parameter3<br \/>\nslider4:0&lt;0,100,1&gt;parameter4<br \/>\nslider5:0&lt;0,100,1&gt;parameter5<\/code><\/div>\n<p>S&rsquo;ensuit une liste des sliders, qui d\u00e9finissent les param\u00e8tres que l&rsquo;on peut changer en temps r\u00e9el depuis l&rsquo;interface ou automatiser.<br \/>\nEn JS, ces param\u00e8tres portent forc\u00e9ment le nom \u00ab\u00a0slider\u00a0\u00bb suivi de leur num\u00e9ro, m\u00eame si leur valeur ne change qu&rsquo;entre deux ou trois nombres.<\/p>\n<p>La syntaxe d&rsquo;un slider est la suivante:<\/p>\n<div class=\"zcustom-codeblock\"><code>slider[num\u00e9ro]:[valeur par d\u00e9faut]&lt;[minimum], [maximum], [pas]&gt;titre<\/code><\/div>\n<p>Tous les sliders (et toutes les variables) sont des nombres flottants (\u00e0 virgule).<\/p>\n<h2>Les sections de code<\/h2>\n<p>Une fois que l&rsquo;on a d\u00e9fini une description et des param\u00e8tres, on peut impl\u00e9menter des sections, ou des m\u00e9thodes virtuelles pour ceux qui sont habitu\u00e9s \u00e0 la programmation orient\u00e9 objet \ud83d\ude42<\/p>\n<div class=\"zcustom-codeblock\"><code><span class=\"zcustom-jsfx-block\">@init<\/span><br \/>\nbpos=0;<br \/>\n<span class=\"zcustom-jsfx-block\">@slider<\/span><br \/>\nsomething=slider1*srate;<\/p>\n<p><span class=\"zcustom-jsfx-block\">@block<\/span><br \/>\nblah+=samplesblock;<\/p>\n<p><span class=\"zcustom-jsfx-block\">@sample<\/span><br \/>\nspl0=spl0;<br \/>\nspl1=spl1;<\/code><\/div>\n<p>Ces sections sont appel\u00e9es \u00e0 des moments diff\u00e9rents pour ex\u00e9cuter diff\u00e9rentes t\u00e2ches:<\/p>\n<ul>\n<li><code>@init<\/code>: appel\u00e9 \u00e0 chaque fois que l&rsquo;on lance la lecture ou que l&rsquo;on appuie sur CTRL+S dans l&rsquo;\u00e9diteur de code<\/li>\n<li><code>@slider<\/code>: appel\u00e9 apr\u00e8s <code>@init<\/code> ou \u00e0 chaque fois que l&rsquo;utilisateur modifie un slider<\/li>\n<li><code>@block<\/code>: appel\u00e9 pendant la lecture \u00e0 chaque bloc de samples. Un bloc aura une taille diff\u00e9rente en fonction de vos options, entre 128 et 2048.<\/li>\n<li><code>@sample<\/code>: appel\u00e9 \u00e0 chaque \u00e9chantillon sonore (sample en anglais), le plus souvent 44100 fois par seconde. C&rsquo;est le bloc le plus int\u00e9ressant, car c&rsquo;est ici que l&rsquo;on peut modifier le son avec les variables <code>spl0<\/code>..<code>spl63<\/code>.<\/li>\n<\/ul>\n<p>D&rsquo;autres sections existent dans la doc, j&rsquo;y reviendrai \u00e0 l&rsquo;occasion \ud83d\ude42<\/p>\n<h2>Jouer avec le bloc @sample<\/h2>\n<p>Un moyen simple de commencer \u00e0 modifier le son consiste \u00e0 jouer un peu avec le bloc <code>@sample<\/code>.<br \/>\nComme dit plus haut, dans ce bloc nous avons acc\u00e8s aux variables <code>spl0<\/code> et <code>spl1<\/code> (autant que de canaux, ici on s&rsquo;int\u00e9ressera seulement \u00e0 la st\u00e9r\u00e9o).<br \/>\nCes variables contiennent la valeur des \u00e9chantillons sonores que re\u00e7oit notre effet.<\/p>\n<p>L&rsquo;impl\u00e9mentation de base est la suivante:<\/p>\n<div class=\"zcustom-codeblock\"><code>spl0 = spl0;<br \/>\nspl1 = spl1;<\/code><\/div>\n<p>Qui, vous l&rsquo;aurez devin\u00e9, ne fait qu&rsquo;envoyer en sortie ce qu&rsquo;on re\u00e7oit en entr\u00e9e.<br \/>\nIl est possible de faire des op\u00e9rations sur ces variables comme dans tout langage de programmation:<\/p>\n<div class=\"zcustom-codeblock\"><code><span class=\"zcustom-codecomment\">\/\/ On inverse la st\u00e9r\u00e9o, amplifie le canal gauche et att\u00e9nue le droit<\/span><br \/>\nspl0 = spl1*2.0;<br \/>\nspl1 = spl0\/0.5;<\/code><\/div>\n<p>Note: on peut \u00e9videmment ajouter des commentaires avec <code>\/\/<\/code> ou <code>\/* *\/<\/code> comme en Javascript.<\/p>\n<p>On peut aussi cr\u00e9er des variables.<br \/>\nEn JSFX, les variables sont d\u00e9clar\u00e9es comme en Python: elles existent \u00e0 partir du moment o\u00f9 on leur donne une valeur.<\/p>\n<div class=\"zcustom-codeblock\"><code>volume = 0.5;<br \/>\nspl0 = spl0 * volume;<br \/>\nspl1 = spl1 * volume;<\/code><\/div>\n<p>Pour rendre \u00e7a plus interactif, on peut aussi utiliser nos sliders. Par exemple, un effet qui contr\u00f4le juste le volume peut s&rsquo;\u00e9crire ainsi:<\/p>\n<div class=\"zcustom-codeblock\">\n<p><code>slider1:100&lt;0,100,1&gt;Volume<\/p>\n<p><span class=\"zcustom-jsfx-block\">@sample<\/span><br \/>\nk = slider1 \/ 100.0;<br \/>\n<span class=\"zcustom-codecomment\">\/\/ On pourrait directement utiliser un slider entre 0 et 1, mais ce serait moins \u00e9vident pour la plupart des utilisateurs.<\/span><br \/>\nspl0 = spl0 * k;<br \/>\nspl1 = spl1 * k;<\/p>\n<p><\/code><\/div>\n<p>Jusqu&rsquo;\u00e0 maintenant, on n&rsquo;a d\u00e9fini de variables que dans <code>@sample<\/code>. Mais on peut aussi utiliser <code>@init<\/code> pour cr\u00e9er un compteur par exemple:<\/p>\n<div class=\"zcustom-codeblock\"><code><span class=\"zcustom-jsfx-block\">@init<\/span><br \/>\ncompteur = 0;<\/p>\n<p><span class=\"zcustom-jsfx-block\">@sample<\/span><br \/>\ncompteur += 1; <span class=\"zcustom-codecomment\">\/\/ On incr\u00e9mente le compteur \u00e0 chaque sample<\/span><br \/>\n<span class=\"zcustom-codecomment\">\/\/ Et ici on se sert du compteur pour faire varier le volume par va-et-vient<\/span><br \/>\nk = 1 + 0.5 * sin(compteur \/ srate) <span class=\"zcustom-codecomment\">\/\/ Coefficient entre 0 et 1<\/span><br \/>\nspl0 = spl0 * k;<br \/>\nspl1 = spl1 * k;<\/p>\n<p><\/code><\/div>\n<p>Vous remarquerez la pr\u00e9sence d&rsquo;une variable sp\u00e9ciale, <code>srate<\/code>. Elle est surlign\u00e9e et visible dans le panneau lat\u00e9ral de l&rsquo;\u00e9diteur (si, si, en scrollant en bas).<br \/>\n<img alt=\"Screenshot srate\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/srate.png\"\/><\/p>\n<p><code>srate<\/code> contient la fr\u00e9quence d&rsquo;\u00e9chantillonage (sample rate en anglais). Si l&rsquo;on revient au code d&rsquo;exemple pr\u00e9c\u00e9dent, cela veut donc dire que <code>compteur \/ srate<\/code> sera \u00e9quivalent au temps \u00e9coul\u00e9 depuis le dernier appel \u00e0 <code>@init<\/code>, en secondes \ud83d\ude42<\/p>\n<p>Vous pouvez aussi voir la valeur de <code>compteur<\/code>, plus haut:<br \/>\n<img alt=\"Screenshot compteur\" src=\"http:\/\/zylannprods.fr\/tutorials\/jsfx\/compteur.png\" \/><\/p>\n<p>J&rsquo;ai aussi utilis\u00e9 la fonction <code>sin<\/code>, qui fait partie d&rsquo;une longue liste de fonctions math\u00e9matiques de base que vous pouvez \u00e9galement utiliser ici.<br \/>\nVous pouvez les retrouver dans la doc: <a href=\"http:\/\/www.reaper.fm\/sdk\/js\/basiccode.php#js_basicfunc\">http:\/\/www.reaper.fm\/sdk\/js\/basiccode.php#js_basicfunc<\/a><\/p>\n<h2>Conditions<\/h2>\n<p>Nous avons vu comment modifier le son avec des formules simples, or il est aussi possible de r\u00e9aliser des conditions, des <code>if<\/code> comme on fait dans pratiquement tous les langages.<br \/>\nOr, en JSFX, c&rsquo;est un peu diff\u00e9rent:<\/p>\n<div class=\"zcustom-codeblock\"><code>valeur &gt; 50 ? truc = 5 : truc = 0;<\/code><\/div>\n<p>D\u00e9routant?<br \/>\nEn JSFX, les conditions sont exprim\u00e9es comme des ternaires.<br \/>\nOn \u00e9crit une expression suivie d&rsquo;un <code>?<\/code>. Si l&rsquo;expression ne retourne pas 0, l&rsquo;instruction suivant le <code>?<\/code> sera ex\u00e9cut\u00e9e. Sinon, l&rsquo;instruction suivant le <code>:<\/code> sera ex\u00e9cut\u00e9e. Si on a rien \u00e0 faire dans le second cas, on peut se passer du <code>:<\/code>, c&rsquo;est optionnel.<\/p>\n<p>Il est possible de grouper des instructions avec les parenth\u00e8ses, ce qui donne une syntaxe peut-\u00eatre plus famili\u00e8re:<\/p>\n<div class=\"zcustom-codeblock\"><code>valeur &gt; 50 ? (<br \/>\n&nbsp;&nbsp;<span class=\"zcustom-codecomment\">\/\/ Si vrai<\/span><br \/>\n&nbsp;&nbsp;truc = 5;<br \/>\n&nbsp;&nbsp;k += 1;<br \/>\n) : (<br \/>\n&nbsp;&nbsp;<span class=\"zcustom-codecomment\">\/\/ Sinon<\/span><br \/>\n&nbsp;&nbsp;truc = 0;<br \/>\n)<\/code><\/div>\n<h2>Tableaux<\/h2>\n<p>Tout langage de programmation permet d&rsquo;utiliser des listes, arrays, vectors (appelez-\u00e7a comme vous voulez :p).<br \/>\nEn JSFX, une nouvelle fois, la syntaxe est diff\u00e9rente.<\/p>\n<p>La doc nous dit ceci \u00e0 propos des arrays:<\/p>\n<blockquote><p>A virtual local address space of about 8 million words, which can be accessed via brackets \u00ab\u00a0[\u00a0\u00bb and \u00ab\u00a0]\u00a0\u00bb.<\/p><\/blockquote>\n<p>Concr\u00e8tement, cela signifie que l&rsquo;on peut utiliser n&rsquo;importe quelle variable comme une addresse dans un ensemble de valeurs que JSFX a cr\u00e9\u00e9 pour nous (\u00e7a devrait parler aux adeptes du C\/C++!).<\/p>\n<div class=\"zcustom-codeblock\"><code>compteur = 0;<br \/>\n<span class=\"zcustom-codecomment\">\/\/ Si j'\u00e9cris compteur[0], j'acc\u00e8derai \u00e0 la case 0.<\/span><br \/>\ncompteur += 1<br \/>\n<span class=\"zcustom-codecomment\">\/\/ Si j'\u00e9cris compteur[0], j'acc\u00e8derai \u00e0 la case 1. compteur[-1] sera la valeur pr\u00e9c\u00e9dente, et compteur[1] celle d'apr\u00e8s.<\/span><\/code><\/div>\n<p>Voyons un exemple pratique sur ce syst\u00e8me. Si on a besoin de m\u00e9moriser les derniers \u00e9chantillons lus par l&rsquo;effet et les restituer avec un retard, pour faire un \u00e9cho par exemple, \u00e7a donnerait quelque chose comme \u00e7a:<\/p>\n<div class=\"zcustom-codeblock\"><code><span class=\"zcustom-jsfx-block\">@init<\/span><br \/>\ncompteur = 0; <span class=\"zcustom-codecomment\">\/\/ Compteur de samples<\/span><br \/>\ntaille = srate ; <span class=\"zcustom-codecomment\">\/\/ Taille de notre tableau, correspondant \u00e0 1 seconde d'audio (44100 \u00e9chantillons)<\/span><\/p>\n<p><span class=\"zcustom-jsfx-block\">@sample<\/span><br \/>\ncompteur += 1; <span class=\"zcustom-codecomment\">\/\/ On incr\u00e9mente le compteur \u00e0 chaque sample<\/span><\/p>\n<p><span class=\"zcustom-codecomment\">\/\/ Si on arrive au bout du tableau, on recommence \u00e0 z\u00e9ro (notre tableau est cyclique).<\/span><br \/>\ncompteur == taille ? compteur = 0;<\/p>\n<p><span class=\"zcustom-codecomment\">\/\/ tableau contient en fait l'addresse \u00e0 laquelle on se place, comme en C\/C++.<br \/>\n\/\/ x2 car on est en st\u00e9r\u00e9o (ce qui signifie qu'en fait on a 44100 couples de valeurs, donc un tableau de 88200 nombres)<\/span><br \/>\ntableau = compteur * 2;<\/p>\n<p><span class=\"zcustom-codecomment\">\/\/ On ajoute le son m\u00e9moris\u00e9 (l'\u00e9cho), qui vaudra 0 au d\u00e9but tant que le tableau n'aura pas compl\u00e9t\u00e9 son premier cycle.<br \/>\n\/\/ Pour rester simple, on fait juste la moyenne des deux.<\/span><br \/>\nspl0 = (spl0 + tableau[0])\/2 ;<br \/>\nspl1 = (spl1 + tableau[1])\/2;<\/p>\n<p><span class=\"zcustom-codecomment\">\/\/ on m\u00e9morise l'\u00e9chantillon courant, qui sera restitu\u00e9 en tant qu'\u00e9cho 44100 \u00e9chantillons plus tard.<br \/>\n\/\/ Note: JSFX ajuste automatiquement la taille du tableau en fonction des acc\u00e8s.<\/span><br \/>\ntableau[0] = spl0;<br \/>\ntableau[1] = spl1;<\/p>\n<p><\/code><\/div>\n<h2>To be continued<\/h2>\n<p>\u00c7a commen\u00e7ait tout juste \u00e0 devenir marrant, mais c&rsquo;est maintenant que je vous laisse \ud83d\ude42<br \/>\nJ&rsquo;ai encore \u00e0 apprendre moi-m\u00eame sur JSFX, j&rsquo;esp\u00e8re que cet article vous a plu \/ aid\u00e9 \u00e0 rentrer dans le d\u00e9lire de cette fonctionnalit\u00e9 m\u00e9connue de Reaper.<br \/>\nJ&rsquo;\u00e9crirai une suite \u00e0 l&rsquo;occasion, je suis certain qu&rsquo;il y a beaucoup d&rsquo;autres sujets \u00e0 aborder.<br \/>\nBon bidouillage!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Reaper est un logiciel de production audio supportant plusieurs types de plugins: VST, DX, et JSFX (JS). Contrairement aux<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,102,5],"tags":[],"_links":{"self":[{"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/posts\/1099"}],"collection":[{"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/comments?post=1099"}],"version-history":[{"count":47,"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/posts\/1099\/revisions"}],"predecessor-version":[{"id":1142,"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/posts\/1099\/revisions\/1142"}],"wp:attachment":[{"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/media?parent=1099"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/categories?post=1099"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zylannprods.fr\/fr\/wp-json\/wp\/v2\/tags?post=1099"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}