timedseq — Séquenceur à variation temporelle.
Un séquenceur d'évènements dans lequel le temps peut être contrôlé par un pointeur. Les données de la séquence sont stockées dans une table.
ktri -- signal de déclenchement en sortie.
ktimpnt -- pointeur de temps dans le fichier de la séquence, en secondes.
kp1,...,kpN -- p-champs des notes retournés en sortie. kp2 est la date relative et kp3 est la durée des notes en secondes.
timedseq est un séquenceur qui permet de programmer des notes venant d'une séquence de l'utilisateur et dépendant d'une base de temps externe donnée par un pointeur de temps (l'argument ktimpnt). L'utilisateur doit remplir la table ifn avec une liste de notes, qui peuvent provenir d'un fichier texte externe lu par GEN23, ou en les tapant directement dans le fichier d'orchestre (ou de partition) avec GEN02. Le format du fichier texte contenant la séquence comprend simplement des lignes qui contiennent plusieurs nombres séparés par des espaces (comme dans une partition normale de Csound). La première valeur de chaque ligne doit être une valeur positive ou nulle, sauf dans un cas spécial qui sera expliqué ci-dessous. Cette première valeur sert normalement à définir le numéro d'instrument correspondant à cette note particulière (comme dans une partition normale). La seconde valeur de chaque ligne doit contenir la date de la note correspondante et la troisième valeur sa durée. Voici un exemple :
0 0 0.25 1 93 0 0.25 0.25 2 63 0 0.5 0.25 3 91 0 0.75 0.25 4 70 0 1 0.25 5 83 0 1.25 0.25 6 75 0 1.5 0.25 7 78 0 1.75 0.25 8 78 0 2 0.25 9 83 0 2.25 0.25 10 70 0 2.5 0.25 11 54 0 2.75 0.25 12 80 -1 3 -1 -1 -1 ;; dernière ligne de la séquence
Dans cet exemple, la première valeur de chaque ligne est toujours zéro (c'est une valeur sans signification, mais ce p-champ peut servir, par exemple, pour donner un canal MIDI ou un numéro d'instrument), sauf dans la dernière ligne qui commence par -1. Cette valeur (-1) est une valeur spéciale qui indique la fin de la séquence. Elle a elle-même une date car les séquences peuvent être lues en boucle. Ainsi la séquence précédente a une durée par défaut de 3 secondes, 3 étant la dernière date de la séquence.
Il est important que TOUTES les lignes contiennent le même nombre de valeurs (dans l'exemple, toutes les lignes contiennent exactement 5 valeurs). Le nombre de valeurs contenues dans chaque ligne DOIT être égal au nombre d'arguments kpXX de sortie (noter que même si kp1, kp2, etc. sont placés à la droite de l'opcode, ce sont des arguments de sortie, pas des arguments d'entrée).
L'argument ktimpnt fournit la temporisation réelle de la séquence. Actuellement, le déroulement du temps dans la séquence est spécifié par ktimpnt lui-même, qui représente le temps en secondes. ktimpnt doit toujours être positif, mais il ne peut pas avancer ou reculer dans le temps, être stationnaire ou discontinu, comme un pointeur dans un fichier séquentiel à la manière de pvoc ou de lpread. Lorsque ktimpnt atteint la date d'une note, un signal de déclenchement est envoyé sur l'argument de sortie ktrig, et les arguments kp1, kp2, ..., kpN sont mis à jour avec les valeurs de chaque note. Cette information peut ensuite être utilisée par schedkwhen pour activer des évènements de note. Noter que les données kp1, ..., kpn peuvent être traitées (par exemple retardées avec delayk, transposées, etc.) avant d'être passées à schedkwhen.
ktimpnt peut être contrôlé par un signal linéaire, par exemple :
ktimpnt line 0, p3, 3 ; la durée originale de la séquence était de 3 sec ktrig timedseq ktimpnt, 1, kp1, kp2, kp3, kp4, kp5 schedkwhen ktrig, 105, 2, 0, kp3, kp4, kp5
Dans ce cas la séquence complète (avec sa durée originale de 3 secondes) sera jouée en p3 secondes.
On peut faire boucler une séquence en la contrôlant avec un phaseur :
kphs phasor 1/3 ktimpnt = kphs * 3 ktrig timedseq ktimpnt ,1 ,kp1, kp2, kp3, kp4, kp5 schedkwhen ktrig, 105, 2, 0, kp3, kp4, kp5
Il est évident que l'on peut ne jouer qu'un fragment de la séquence, la lire à l'envers, et avoir un accès non-linéaire à ses données de la même manière que les opcodes pvoc et lpread.
Avec l'opcode timedseq, on peut faire presque tout ce que l'on fait dans une partition normale, excepté les limitations suivantes :
On ne peut pas avoir deux notes commençant exactement à la même date ; actuellement deux notes doivent être séparées d'au moins un k-cycle (sinon le mécanisme de schedkwhen en escamote une des deux).
Toutes les notes de la séquence doivent avoir le même nombre de p-champs (même si elles activent différents instruments).
On peut remédier à ces limitations en complétant avec des valeurs sans signification les notes des instruments qui ont moins de p-champs que les autres.
Voici un exemple complet de l'opcode timedseq. Il utilise le fichier timedseq.csd.
Exemple 1097. Exemple de l'opcode timedseq.
Voir les sections Audio en Temps Réel et Options de la Ligne de Commande pour plus d'information sur l'utilisation des options de la ligne de commande.
<CsoundSynthesizer> <CsOptions> ; Select audio/midi flags here according to platform -odac ;;;realtime audio out ;-iadc ;;;uncomment -iadc if RT audio input is needed too ; For Non-realtime ouput leave only the line below: ; -o timedseq.wav -W ;;; for file output any platform </CsOptions> <CsInstruments> sr = 44100 ksmps = 32 nchnls = 2 0dbfs = 1 giseq ftgen 0,0,128,-2, 2, 0, 0.5, 8.00,\ ;first note 2, 1, 0.5, 8.02,\ ;second note 2, 2, 0.5, 8.04,\ ;third 2, 3, 0.5, 8.05,\ ;fourth 2, 4, 0.5, 8.07,\ ;fifth 2, 5, 0.5, 8.09,\ ;sixth 2, 6, 0.5, 8.11,\ ;seventh 2, 7, 0.5, 9.00,\ ;eight note 2, 8, 0.5, 8.00,\ ;due to a quirk in the opcode, it needs an extra note - a copy of the first note -1, 8, -1, -1 ;last line is a dummy event that indicates to timedseq when to loop back to the beginning instr 1 ibeats = 8 ;lengths of sequence in beats itempo = p4 ;tempo iBPS = itempo/60 ;beats per second kphase phasor iBPS/ibeats ;phasor to move through table kpointer = kphase*ibeats ;multiply phase (range 0 - 1) by the number of beats contained within the sequence kp1 init 0 kp2 init 0 kp3 init 0 kp4 init 0 ktrigger timedseq kpointer, giseq, kp1, kp2,kp3, kp4 schedkwhen ktrigger, 0, 0, 2, 0, kp3/abs(iBPS), kp4 ;p3 values have been scaled according to tempo so that they maesure beats rather than seconds endin ;abs(iBPS)(absolute value) is used because the tempo provided by the fourth note of the score is negative. ;Durations here should be positive, because negative values for duration would indicate a held note. instr 2 aenv linseg 0,0.01,1,p3-0.01,0 ;amplitude envelope asig vco2 0.4, cpspch(p4), 4, 0.5 outs asig*aenv, asig*aenv endin </CsInstruments> <CsScore> i 1 0 4 120 i 1 + . 240 i 1 + . 480 i 1 + . -480 ;when negative it plays backwards e </CsScore> </CsoundSynthesizer>