Vrac

Liste de paramètres Tidal

Cette page est une liste presque exhaustive des paramètres de contrôle disponibles dans Tidal Cycles. J’ai fait le choix de conserver les paramètres les plus courants et d’éliminer les paramètres les plus obscurs ou utilisés seulement pour des fonctions très facultatives ou aujourd’hui obsolètes. Cette page est constituée à partir des informations glânées sur la documentation officielle. Elle peut servir à se faire une idée de ce que Tidal offre avec une installation normale de SuperDirt (+ sc3plugins).

Général

Nom de la fonction Type de l’argument Valeur type Description
sound String “jvbass” Dossier de sample ou nom du synthétiseur SuperDirt
s String “jvbass” Dossier de sample ou nom du synthétiseur SuperDirt.
n Double 0-x Numéro de la sample dans le dossier.
begin Double 0-1 Début du sample ou 0 est le début du fichier et 1 la fin.
end Double 0-1 Fin du sample ou 0 est le début du fichier et 1 la fin.
loop Double 0 ou 1 Nombre d’itérations sur la sample en un cycle.
offset Double 0-x Forme de décalage temporel (décalage vers le futur)
cut Int 0 ou 1 Couper la sample lorsque l’enveloppe se réamorçe. 0 ou 1.
gain Float 0-x Volume. 0 : silence. 1: normal. >1 : de plus en plus fort.
pan Float 0-1 Position stéréo. 0 : gauche, 1 : droite.
orbit Int 0-9 Choix du canal d’effets (par défaut, 9 orbits sont disponibles).
speed Float -x-x Vitesse de lecture de la sample.
accelerate Float -x-x Effet de rampe sur la vitesse de lecture du sample.
cps Float 0-x Change la vitesse de lecture de tout les patterns. Le tempo est exprimé en cycles par seconde (cps).
nudge Float 0-x Change le timing des samples. Moduler ce paramètre permet d’humaniser le jeu des patterns. Valeurs basses: swing, valeurs hautes : plus étrange.

Envelopes

Nom de la fonction Type de l’argument Valeur type Description
attack Float 0-x Durée de l’attaque (durée avant amplitude maximale).
att Float 0-x Paramètre utilisé pour l’enveloppe ASR.
decay Float 0-x Durée de la chute de l’amplitude jusqu’à zone d’entretien.
sustain Float 0-x Durée de la zone d’entretien, niveau d’amplitude stable.
sus Float 0-x Durée de la zone d’entretien, niveau d’amplitude stable.
release Float 0-x Durée de l’extinction de la note.

Filtres

Nom de la fonction Type de l’argument Valeur type Description
cutoff Double 0-20000 Fréquence de coupure du filtre passe bas.
lpf Float 0-20000 Fréquence de coupure du filtre passe bas.
lpq Float 0-1 Fréquence de résonance du filtre passe bas.
resonance Float 0-1 Fréquence de résonance du filtre passe bas.
bandf Float 0-20000 Fréquence de coupure du filtre passe bande.
bpf Float 0-20000 Fréquence de coupure du filtre passe bande.
bandq Float 0-1 Fréquence de résonance du filtre passe bande.
bpq Float 0-1 Fréquence de résonance du filtre passe bande.
hcutoff Float 0-20000 Fréquence de coupure du filtre passe haut.
hpf Float 0-20000 Fréquence de coupure du filtre passe haut.
hpq Float 0-1 Fréquence de résonance du filtre passe haut.
hresonance Float 0-1 Fréquence de résonance du filtre passe haut.

Notes et fréquences

Nom de la fonction Type de l’argument Valeur type Description
freq Float 0-20000 Fréquence du synthétiseur ou de la sample.
midinote Float 0-127 Hauteur de la note MIDI.
note Float 0-127 Hauteur de la note MIDI (?).
octave Int 0-10 (?) Octave de la note.
legato Float 0-x Taux de superposition entre deux samples ou notes.

MIDI

Nom de la fonction Type de l’argument Valeur type Description
cc String 0-x Spécifier un ccn et un ccv sous la forme ccn:ccv. Quasi-obsolète.
ccn Float 0-x Control Number (MIDI)
ccv Float 0-127 Control Value (MIDI)
midichan Int 0-15 Sélection du canal MIDI.
modWheel Float 0-127 Valeur de la roue de modulation MIDI.
portamento Float 0-127 Valeur du portamento.
progNum Int 0-127 Program Number ?
dur Float 0-x Durée de la note.
expression Float/Int (?) 0-127 Pédale d’expression (volume).
sustainpedal Float/Int (?) 0-127 Pédale de soutien.
mtranspose Int 0-127 Transposition MIDI ?
midicmd String “noteon” “noteon” transforme le pattern en valeurs note on. Autres valeurs : “touch”, “polytouch”, “bend”…

Delay

Nom de la fonction Type de l’argument Valeur type Description
delay Float 0-1 wet/dry pour du délai.
delayfeedback Float 0-1 Valeur de retour du délai, entre 0 et 1.
delayfb Float 0-1 Valeur de retour du délai, entre 0 et 1.
delaytime Float 0-1 Intervalle du délai.
delayt Float 0-1 Intervalle du délai.
lock Int 0 ou 1 Permet de verrouiller le valeur du délai sur la longueur du cycle.

Distortion et dégradation du signal

Nom de la fonction Type de l’argument Valeur type Description
coarse Int 0-x Divise la fréquence d’échantillonage. 1 : normal. 2 : divisé par deux. etc…
crush Float 0-16 Effet de bit-crushing: 1 : drastique. 16 : presque normal.
distort Float 0-x Une distortion très sèche avec beaucoup d’harmoniques.
triode Float 0-x Une distortion triode.
krush Float 0-x Distortion “krush” importée de Sonic-Pi.
kcutoff Float 0-20000 Cutoff du “krush”.
shape Float 0-x Un type d’amplification particulier.
squiz Int 0,2-x Filtre, modulateur en anneau et pitch-shifter. Dégrade le signal. Passer un multiple de deux comme argument.

Reverb

Nom de la fonction Type de l’argument Valeur type Description
room Float 0-1 Taille de la pièce.
size Float 0-1 Métaphore de la “profondeur”, entre 0 et 1.
dry Float 0-1 Paramètre wet/dry entre 0 (wet) et 1 (dry).

Octaviation

Nom de la fonction Type de l’argument Valeur type Description
octer Float ? Harmoniques à l’octave.
octersub Float ? Harmoniques à l’octave / 2.
octersubsub Float ? Harmoniques à l’octave / 4.

Phaser

Nom de la fonction Type de l’argument Valeur type Description
phaserrate Float 0-x Vitesse du phaser.
phasr Float 0-x Vitesse du phaser.
phaserdepth Float 0-x Profondeur du phaser.
phasdp Float 0-x Profondeur du phaser.

Tremolo

Nom de la fonction Type de l’argument Valeur type Description
tremolodepth Float 0-x Profondeur de l’effet de trémolo.
tremdp Float 0-x Profondeur de l’effet de trémolo.
tremolorate Float 0-x Vitesse du trémolo.
tremr Float 0-x Vitesse du trémolo.

Leslie

Nom de la fonction Type de l’argument Valeur type Description
leslie Float 0-x Dry/Wet de l’effet de cabine leslie.
lrate Float 0-x Vitesse de rotation de la cabine.
lsize Float 0-x Taille (change l’effet doppler)

Autres effets et divers

Nom de la fonction Type de l’argument Valeur type Description
vowel String “a” Filtre formant. Au choix parmi : “aeiou”. “~” pour aucun effet.
legato Float 0-1 Taux de superposition entre deux sons.
waveloss Int 0-100 Divise un flux audio en petits segments. Ne conserve qu’une fraction d’entre eux.
xsdelay Float ? Délai spectral (???)
tsdelay Float ? Délai spectral (???)
freeze Int 0 ou 1 Gèle l’audio et tente de maintenir le même spectre.
comb Float 0-x Le nombre de dents et la profondeur du filtre sont contrôlés par un seul nombre à virgule.
scram Float 0-x Randomise l’ordre des bits dans le signal audio.
smear Float 0-x Effet de “smearing”.
binshift Float 0-x Stretching et shifting des bits. Tout est contrôlé par un seul nombre à virgule. Peut s’utiliser comme un pitch-shifter.
hbrick Float 0-? Un filtre passe-haut de type spectral.
lbrick Float 0-? Un filtre passe-bas de type spectral.
real Float ? ???
imag Float ? ???
enhance Float ? ???
djf Float 0-1 Un filtre DJ. Passe-bas pour la première moitié, passe-haut pour le reste.

Exemplier Tidal Cycles

Cette page recense quelques exemples de patterns simples réalisés à l’aide des samples et des instruments par défaut de Tidal Cycles. Il est donc possible de copier/coller les exemples afin d’expérimenter en les modifiant. Chacune des sections cherche à illustrer l’un des aspects de la syntaxe du langage, tout en limitant le niveau de complexité. Il est recommandé de jouer avec chacun des exemples afin d’acquérir une plus grande familiarité avec le code et sa manipulation en temps réel.

Gymnastique

-- Tempo = CPS (Cycles per second).
setcps 0.8

-- Quelques patterns très simples.

d1 $ s "bd*4"

d2 $ s "~ ~ ~ sd"

d3 $ s "hh cp hh cp"

-- Tidal est un langage très expressif. Il existe beaucoup de manières
-- permettant d'exprimer une même idée. En voici trois :

d1 $ s "[[bd*4],[~ ~ ~ sd],[hh cp hh cp]]"

d1 $ stack [s "bd*4",
            s "~ ~ ~ sd",
            s "[hh cp]*2"]

d1 $ s "[bd(4,4), sd(1,4), [hh,cp](2,4)]"

d1 $ silence
-- ou bien
hush 

Choisir un échantillon sonore ou un synthétiseur

-- Sur la piste 1, je veux jouer "numbers".
d1 $ s "numbers"

-- Sur la piste 1, je veux jouer le premier son du dossier "numbers".
d1 $ n 0 # s "numbers"

-- Ibid avec notation interne au pattern.
d1 $ s "numbers:0"

-- ibid, en alternant entre "0, 1, 2 et 3".
d1 $ n "<0 1 2 3>" # s "numbers"

-- ibid, en jouant deux dossiers de samples en même temps.
d1
  $ fast 2 $ n "<0 1 2 3>" # s "[numbers, jazz]"
  
-- choix pseudo-aléatoire de la sample.
d1 $ fast 8 $ s "808" # n (irand 20)

-- on parcourt alternativement deux dossiers
d1 $ fast 2 $ n (run 4) # cat [s "808", s "jazz"]

-- plusieurs dossiers de sample dans un même pattern
d1 $ s "bass3 jvbass:2"
 

La représentation du temps privilégie par Tidal est cyclique et non linéaire. Cette idée possède des implications profondes pour la manipulation des patterns et des contenus musicaux.

Représentation cyclique du temps.
Représentation linéaire d’un pattern.

Tout est un pattern

-- Tidal introduit un nouveau type : les patterns.
-- Les patterns remplaçent les chaînes de caractères. 

-- La syntaxe des patterns est assez complexe. Essayons d'en avoir une 
-- compréhension intuitive avant de l'expliquer plus en détail.

-- un son de grosse caisse.

d1 $ s "bd"

-- Deux sons de grosse caisse répartis sur un cycle.
-- Tidal adopte une représentation cyclique du temps.

d1 $ s "bd bd"
d1 $ s "bd*2"
d2 $ s "hh*4"

-- Deux sons de grosse caisse et charlestons fermées à la noire..
-- Les crochets expriment l'idée de groupe.
-- La virgule l'idée de simultanéité / superposition.

d1 $ s "[bd*2, hh*4]"
d1 $ s "[[bd*2, hh*4], [jvbass]]" -- les groupes peuvent être enchåssés.

-- Il existe une petite arithmétique relative aux répétitions / divisions.

d1 $ s "hh*2"
d2 $ s "hh*4"
d1 $ s "hh/2"
d1 $ s "hh*<2 4 8 16>" -- par "accident", l'arithmétique se patterne...

-- L'exemple donné est ici celui des samples. Tout fonctionne également
-- avec des notes !

d1 $ s "c4*2 ds4/2 g4*2 bf4/4" -- peu lisible mais tout à fait possible.

-- Les patterns permettent une forme élégante de combinatoire : 

d1 $ s "<bd hh sn hh>" -- Un seul élément par cycle, en alternance.
d1 $ s "[bd|hh|sn|hh]" -- Choix aléatoire entre quatre samples.
d1 $ s "jvbass? bd"    -- 50% de chances de ne pas jouer la note.
d1 $ s "bd(5,4)"       -- séquence euclidienne.

-- Il existe d'autres opérateurs plus complexes.
-- Nous les aborderons ultérieurement.

-- Exemple : il existe toute une catégorie d'opérateurs permettant une 
-- arithmétique entre patterns (|+ +|, |- -|, |* *|, etc...) 

Patterner sons, notes et paramètres

	

-- Beaucoup de choses peuvent être exprimées en tant que patterns.

-- Dessin manuel d'une enveloppe de volume cyclique. 
d1 $ s "hh*8" # amp "0.2 0.4 0.8 0.9 0.5 0.2 0.1"

-- Vitesse de lecture de l'échantillon.
d1 $ s "jvbass*8" # speed "0.2 0.4 0.8 0.9 0.5 0.2 0.1"

-- Exemple complexe : modulations paramétriques multiples
-- 0 et 0.5 peuvent être patternés également !
d2
  $ s "[jvbass|amencutup]*8" # speed (range 0 0.5 $ run "<8 5 16>")
  # lpf "<400 800 1200 2000 4000 8000>"

-- Exemple complexe : basse "acide" et grosse caisse.
-- Modulation du filtre et de la séquence de note.
d1
  $ fast 2
  $ note "<c3 f2 g2>*4" |+ note "0 12"
  # s "supersaw" # cut 1 # release 0.2
  # lpf "<400 500 1000 2000 4000 5000>" # lpq "0.2 0.4 0.5 0.1"
  
d2
  $ s "808bd*2" # amp 2

-- Exemple complexe : courte pièce générative pour cordes pincées
-- avec un message...
do
  setcps 0.5
  d1
    $ slow 2
    $ rarely (superimpose ((|+ note "[0,12,-12]") . (# release 4) . (# room 0.8)))
    $ superimpose ((fast "<0 1 0 1 0 [1|2]>") . (off "<0.75 0.25 0.5>" (id)))
    $ note "c a f e   b a b a   d a d a   g e g e " |+ note 12 # s "pluck"
    # release 2 # room 0.5 # dry 0.6 # size 0.7

-- Exemple : nappe de bruits complexe. Beaucoup de variations paramétriques.
d1
  $ rarely (slow 4)
  $ sometimes (superimpose (# speed 0.0125) . (# amp 1.5))
  $ rarely ((fast 4) . (|+ speed (run 8)))
  $ s "[hand|gretsch]*8" # n (irand 20) # cut 0 # speed (range 0.8 1 $ rand)
  # lpf "<4000 2000 3000 6000 100 400>" # room 0.6 # size 0.6 # dry 0.4
  # hpf "[1000|2000|4000|1250|1500]"
  # pan (range 0 1 $ rand)

    
 

Composition de fonction

-- Chaque pattern constitue une seule et même expression. Tidal procède
-- par composition de fonctions. Il existe, par conséquent, un très grand
-- nombre de fonctions aux effets variés. Voici un inventaire de quelques 
-- fonctions courantes : 

-- accélérer le pattern
d1 $ fast 2 $ s "jvbass"

-- accélérer le pattern et la vitesse de lecture
d1 $ hurry 2 $ s "jvbass"

-- ralentir le pattern
d2 $ slow 2 $ s "jvbass"

-- renverser le pattern
d1 $ rev 4 $ n "0 1 2 3" # s "numbers"

-- chop | striate | bite | chew pour le découpage des samples.
d1 $ fast 2 $ chop "<2 4 8 16 32 64 128 256 512>" $ s "tabla:4 tabla:2"

-- Il est possible de d´éfinir une probabilité d'application
-- de fonction avec certaines fonctions

-- sometimes | rarely | often | always
d1
  $ sometimes (fast 8)
  $ s "jvbass*2"
  
-- Pour une liste plus complète des fonctions, reportez vous à l'une 
-- des pages de ce même site. 

SuperDirt

-- Tidal Cycles est d'ordinaire couplé à SuperDirt, une extension de 
-- SuperCollider pensée pour Tidal. SuperDirt expose de très nombreux
-- paramètres de synthèse accessibles par défaut dans un pattern.

-- appliquer un filtre passe-bas/passe-haut/passe-bande
d1 $ fast 2 $ s "jvbass" # lpf 500 # lpq 0.1
d1 $ fast 2 $ s "jvbass" # hpf 500 # hpq 0.1
d1 $ fast 2 $ s "jvbass" # bpf 500 # bpq 0.1

-- ajouter de la réverbération
d1 $ hurry 2 $ s "jvbass" # room 0.5 # size 0.5 # dry 0.5

-- ajouter du délai
d2 $ fast 2 $ s "jvbass" # delay 0.5 # delaytime 0.5 # delayfeedback 0.6

-- Il est possible de donner une dimension probabiliste 
-- à l'application d'un effet.

d2
  $ sometimes ((# speed 4) . (# room 0.8))
  $ s "hh*8" 

Combiner paramètres et fonctions / Apprendre Tidal Cycles

Les exemples précédents illustrent trois caractéristiques essentielles de la syntaxe :

  • Tidal permet de travailler à l’échelle du son/timbre (outil pour la synthèse / le contrôle paramétrique).
  • Tidal permet de créer dynamiquement des patterns et de les combiner (outil d’interprétation / instrument).
  • Par combinaison de fonctions, Tidal organise et structure le jeu musical (outil de composition).

Cette page ne se destine qu’à introduire à la syntaxe de Tidal et omet volontairement un grand nombre de possibilités et de fonctionnalités (mini-notation des accords, des polymètres, arithmétique des patterns, composition de nouvelles fonctions, interface MIDI et I/O en général). Le langage dans son ensemble doit être pensé comme une interface permettant d’organiser des évènements dans le temps. Tidal ne se préoccupe presque pas de la nature des objets séquencés (hormis interface SuperDirt). Il s’agit d’un outil permettant de mettre en forme rapidement (en temps réel ?) une pensée musicale algorithmique. L’apprentissage de Tidal, comme celui d’un instrument, requiert de la patience et de la pratique (au-delà même du seul aspect digital et de la manipulation du texte). La flexibilité de la syntaxe et la possibilité de composer des fonctions / de combiner rapidement plusieurs paramètres en fait un outil particulièrement puissant avec de fortes propriétés d’émergence. 

Belly

Apprendre à programmer un DSL de live-coding


Je travaille en parallèle de ma thèse sur un environnement de live-coding musical nommé Belly. Ayant appris la programmation sur le tard et en autodidacte, la tâche s’avère lente et fastidieuse [1]. Il s’agit d’un client pour SuperDirt en Python. C’est un bon exercice pour comprendre les enjeux de la conception d’un tel système : scheduling temps-réel, manipulation de la syntaxe, couplage avec le moteur audio et avec Emacs. Je posterais le programme et sa documentation lorsque celui-ci atteindra la maturité et la stabilité suffisante pour être utilisé quotidiennement sans trop de heurts. Le but est de se rapprocher, autant que possible, des langages les plus utilisés par la communauté TOPLAP (Tidal Cycles, FoxDot, etc…). Le but est également d’expérimenter avec plusieurs modalités de représentation algorithmique de la notation musicale et de réfléchir sur de potentielles nouvelles notations pour les musiques électroniques et informatiques. J’espère à terme que ces expérimentations mèneront vers un environnement stable que je pourrais utiliser pour enseigner et pratiquer cette approche particulière du jeu et de l’improvisation musicale.

Belly n’est qu’une surcouche logicielle pour SuperCollider et SuperDirt (échantillonnage, synthèse sonore, sorties audios). Le logiciel n’émet donc aucun son : Belly se charge d’organiser la performance en émettant des messages temporels très précis renseignant les différents paramètres et les différents signaux qui composent le jeu musical. Cette architecture est assez commune pour ce type de langages/DSL, ainsi qu’en témoignent Sonic Pi ou Tidal Cycles dont Belly s’inspire très largement. Du fait de la relative jeunesse du programme, je n’ai pas encore précisément décidé du paradigme de programmation attendu de la part de l’utilisateur/musicien : fonctionnel ou impératif. Il s’agit encore d’établir une interface de haut-niveau pour la notation musicale ou pour la manipulation et la description du temps musical. L’idéal serait de programmer entièrement Belly, une seconde fois, dans un langage fonctionnel ou multi-paradigmatique (Common Lisp ?). L’absence de librairies permettant de faciliter la tâche me retient encore de m’y consacrer plus pleinement.

Le programme repose sur un mécanisme très incomplet et approximatif de « récursion temporelle », notion illustrée et largement développée/commentée par Andrew Sorensen [2]. Ce mécanisme ne peut être identique à celui proposé par Sorensen pour au moins une raison. De manière notoire, Python ne supporte pas l’optimisation des fonctions tail recursive qui sont à la base même de ce type particulier de récursion, courant dans des langages tels que Scheme. Racket ou CL. Je souhaite pourtant m’inspirer, autant que possible, des langages fonctionnels ou des langages de type LISP. La sur-représentation du LISP ou des dérivés de SmallTalk dans le milieu de l’informatique musicale ne m’apparaît pas comme une simple coïncidence. Sans doute s’agit-t-il d’une indication du fait que ces langages s’adaptent mieux à certaines contraintes propres au domaine musical : prototypage rapide, hot-reloading, concision et souplesse de la syntaxe, adaptation de cette dernière au domaine (expression musicale, synthèse, composition). La plupart de ces langages proposent une approche in media res de la programmation musicale, permettant la manipulation du programme dans le temps et dans l’action. De manière tout simplement personnelle, j’ai également une préférence esthétique pour l’élégance de ces langages.

Python possède l’une des syntaxes les plus rigides et l’un des interpréteurs les plus contraignants qui soit : espaces signifiants, absence de macros, AST peu déchiffrable, impossibilité de recharger un module, de mettre à jour les instances d’une classe lors d’une redéfinition de l’objet, etc… Pour ces raisons au moins, Belly me semble handicapé par rapport à ce qui peut déjà se faire dans le domaine du live-coding, au travers de langages tels que Clojure ou Haskell. C’est un handicap que j’accepte volontiers, dans la mesure ou je manque encore de pratique et de métier; la programmation n’étant pas mon activité principale ni ma spécialité. Le fait que FoxDot existe reste toutefois la preuve que Python supporte ce type d’applications musicales.

Du point de vue technique

Belly est capable, au travers de SuperDirt, de gérer les entrées et sorties MIDI ou OSC. Cela lui permet de communiquer assez facilement avec l’essentiel des STAN ou des moteurs audios existants. La précision temporelle est tout à fait acceptable, ce qui fait déjà de ce programme un séquenceur efficace pour prototyper et tester plusieurs dispositifs ou instruments simples. De manière détournée, ces deux dernières caractéristiques font de Belly un outil qui peut être employé en dehors de son domaine pour piloter sons, lumières, animations et autres.

L’output du programme est pensé pour être interprété par SuperDirt, le moteur audio par défaut de Tidal Cycles. Tout ce qui est exprimable dans Tidal l’est donc potentiellement avec Belly (manipulation de samples, paramètres de synthèse). Belly est pourtant très loin de permettre la même expressivité que le langage développé par Alex McLean. Pour le moment, Belly reste un DSL très verbeux, peu élégant et peu capable pour ce qui s’agit de représenter la musique et le temps. Il est difficile de faire émerger un sens de la structure, une idée mélodique complexe, ou d’être réellement expressif. J’espère trouver un moyen d’arranger cela au cours des prochains mois. J’ai bon espoir, car le système d’objets de Python est assez flexible, et supporte bien des bizarreries. Les quelques vidéos en annexe de ce post donnent une bonne idée de la syntaxe actuelle, à quelques différences mineures près.

Notes

Médias