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 
Décompte, itération sur deux dossiers de samples
Choix de la sample et choix des sons
-- 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"
 
Tidal Cycles conçoit le temps de manière cyclique (ce qui explique le nom du langage).
Représentation imagée d'un pattern de batterie.
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. 
Paramètres de synthèse
-- 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" 

Pour une liste plus complète des paramètres de synthèse disponibles, consultez la page dédiée qui recense la quasi-totalité des paramètres disponibles ainsi que des conseils d’utilisation : lien interne.

Pour une liste  des fonctions, consultez cette page : lien interne.

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. 

Lil Data : Reconstruction du morceau “Avril 14th” à l’aide de Tidal Cycles et d’un piano virtuel.

Exemples supplémentaires

d1 $ s "jazz*8" # n (irand 20)                                                -- Génération de rythme sur samples aléatoires

d2
  $ sometimesBy 0.3 (# amp 0)                                                 -- 30% du temps, on souhaite baisser le volume de sortie au minimum.
  $ rarely (superimpose ((|+ speed "<1 2 3 4 5 6 7 8>") . (ply "[2|4|1|1]"))) -- Transformations complexes : superposition de pattern avec vitesse de lecture comprise entre 1 et 8 et répétition d'éléments
  $ s "jazz*8" # n (irand 20) # speed (rand)                                  -- Vitesse de lecture aléatoire

d3 $ s "808bd*4" # amp 2                                                      -- On joue un kick.
 
-- Rythme basique :
d1
  $ stack [                       -- superposition de sons
    s "808bd:7(4,4)" # amp 1.5,   -- une grosse caisse sur tout les temps (4/4)
    s "sd:2(2,4)",                -- une caisse claire tout les deux temps (2/4)
    s "hh(8,4)"]                  -- une charleston fermee tout les demi-temps.


-- Rythme basique avec basse :
d1
  $ stack [
    s "808bd:7(4,4)" # amp 1.5,
    s "sd:2(2,4)",
    fast 2 $ cat[note "0 3 7 10 4 _ _ _ ",                           -- on alterne entre deux patterns.
                 note "0 3 7 10 12 _ _ _ "] # s "jvbass" # speed 1,  -- on applique ce pattern à un sample.
    s "hh(8,4)"] 
    # delay 0 # delayfeedback 0 # delaytime 0 # lock 0

-- Rythme basique, basse et percussions supplémentaires : 
d1
  $ stack [
    s "808bd:7(4,4)" # amp 1.5,
    s "sd:2(2,4)",
    fast 2 $ cat[note "0 3 7 10 4 _ _ _ ",
                 note "0 3 7 10 12 _ _ _ "] # s "jvbass" # speed 1,
  sometimesBy 0.1 (ply 2) $ fast 2 $ n "0 1 2 3" # s "jazz" # speed 0.75 -- Application de fonction probabiliste (10% de chances)
  # lpf (slow 2 $ range 200 20000 $ sine) # lock 1 # delay 0.25 # delaytime "<0.25 0.5>" # delayfeedback 0.5, -- modification des paramètres de synthèse
  s "hh(8,4)"]