opcode — Commence un bloc d'opcode défini par l'utilisateur.
Les instructions opcode et endop permettent de définir un nouvel opcode qui peut être utilisé de la même façon qu'un opcode original de Csound. Ces blocs d'opcode ressemblent beaucoup aux instruments (et sont, en fait, implémentés comme des instruments spéciaux), mais on ne peut pas les appeler comme des intruments normaux, par exemple avec des instructions i.
Un bloc d'opcode défini par l'utilisateur doit précéder l'instrument (ou l'opcode) depuis lequel on l'utilise. Mais un opcode peut aussi s'appeler lui-même. Cela permet une récursivité dont la profondeur n'est limitée que par la mémoire disponible. De plus, on peut, à titre expérimental, exécuter l'opcode défini à un taux de contrôle plus élevé que la valeur de kr spécifiée dans l'en-tête de l'orchestre.
Comme pour les intruments, les variables et les étiquettes d'un bloc d'opcode défini par l'utilisateur sont locales et ne sont pas visible depuis l'instrument appelant (de même que l'opcode n'a pas accès aux variables de l'instrument qui l'a appelé).
Cependant, certains paramètres sont copiés automatiquement à l'initialisation :
tous les p-champs jusqu'à celui de numéro le plus élevé inclus, référencés dans l'instrument appelant
le temps supplémentaire (voir aussi xtratim, linsegr, et les opcodes correspondants). Ceci peut affecter le fonctionnement de linsegr/expsegr/linenr/envlpxr dans le bloc d'opcode défini par l'utilisateur.
les paramètres MIDI, s'il y en a.
Le drapeau de release (voir l'opcode release) est également copié durant l'exécution.
La modification de la durée de la note dans la définition de l'opcode en assignant une valeur à p3, ou l'utilisation de ihold, turnoff, xtratim, linsegr, ou d'autres opcodes similaires affecteront aussi l'instrument appelant. Les changements sur des contrôleurs MIDI (par exemple avec ctrlinit) s'appliqueront aussi à l'instrument qui a appelé l'opcode.
Utilisez l'opcode setksmps pour fixer la valeur locale de ksmps.
Les opcodes xin et xout copient les variables vers et depuis la définition de l'opcode, permettant la communication avec l'instrument appelant.
Les types des variables d'entrée et de sortie sont définis par les paramètres intypes et outtypes.
Astuce | |
---|---|
On peut créer des UDOs sans entrée ou sans sortie en remplaçant la chaîne de caractères correspondante par 0. |
Notes | |
---|---|
|
nom -- nom de l'opcode. Il est constitué de n'importe quelle combinaison de lettres, chiffres et traits de soulignement mais il ne doit pas commencer par un chiffre. Si un opcode du même nom existe déjà, il est redéfini (un avertissement est affiché dans ce cas). Certains mots réservés (comme instr et endin) ne peuvent pas être redéfinis.
intypes -- liste des types en entrée, toute combinaison des caractères a, f, k, O, P, V, K, i, o, p et j. Un caractère 0 unique peut être utilisé s'il n'y a pas d'argument en entrée. Il n'y a pas besoin d'apostrophes doubles et de délimiteurs (comme la virgule).
La signification des différent intypes est montrée dans le tableau suivant :
Type | Description | Types de Variable Autorisés | Mise à jour |
---|---|---|---|
a | variable de taux-a | taux-a | taux-a |
f | variable sig-f | sig-f | taux-k |
i | variable de taux-i | taux-i | initialisation |
j | facultatif de taux-i, -1 par défaut | taux-i, constante | initialisation |
k | variable de taux-k | taux-k et -i, constante | taux-k |
O | variable facultative de taux-k, valant 0 par défaut | taux-k et -i, constante | taux-k |
P | variable facultative de taux-k, valant 1 par défaut | taux-k et -i, constante | taux-k |
V | variable facultative de taux-k, valant 0.5 par défaut | taux-k et -i, constante | taux-k |
J | variable facultative de taux-k, valant -1 par défaut | taux-k et -i, constante | taux-k |
K | taux-k avec initialisation | taux-k et -i, constante | taux-i et taux-k |
o | facultatif à l'initialisation, 0 par défaut | taux-i, constante | initialisation |
p | facultatif à l'initialisation, 1 par défaut | taux-i, constante | initialisation |
S | variable chaîne de caractères | chaîne de caractères de taux-k et -i, constante | taux-i et taux-k |
Le nombre maximum d'arguments en entrée autorisé est 256.
outtypes -- liste des types en sortie. Le format est le même que celui utilisé pour intypes.
Voici les outtypes disponibles :
Type | Description | Types de Variable Autorisés | Mise à jour |
---|---|---|---|
a | variable de taux-a | taux-a | taux-a |
f | variable sig-f | sig-f | taux-k |
i | variable de taux-i | taux-i | initialisation |
k | variable de taux-k | taux-k | taux-k |
K | taux-k avec initialisation | taux-k | taux-i et taux-k |
S | variable chaîne de caractères | chaîne de caractères de taux-k et -i, constante | taux-i et taux-k |
Le nombre maximum d'arguments en sortie autorisé est 256.
iksmps (facultatif, 0 par défaut) -- fixe la valeur locale de ksmps. Doit être un nombre entier positif, et le ksmps de l'instrument appelant doit être un multiple entier de cette valeur. Par exemple, si ksmps vaut 10 dans l'instrument depuis lequel l'opcode a été appelé, les valeurs permises pour iksmps sont 1, 2, 5, et 10.
Si iksmps vaut zéro, le ksmps de l'instrument ou de l'opcode appelant est utilisé (c'est le comportement par défaut).
Note | |
---|---|
Le ksmps local est implémenté en divisant une période de contrôle en sous-périodes-k plus petites et en modifiant temporairement les variables globales internes de Csound. Ceci nécessite aussi la conversion du taux des arguments d'entrée et de sortie de taux-k (les variables d'entrée reçoivent la même valeur dans tous les sous-périodes-k, tandis que les valeurs de sortie ne sont écrites que pendant la dernière). |
Avertissement au sujet du ksmps local | |
---|---|
Lorsque le ksmps local est différent du ksmps de l'orchestre (celui spécifié dans l'en-tête de l'orchestre), il ne faut pas utiliser d'opération globale de taux-a dans le bloc d'opcode défini par l'utilisateur. Ceci comprend :
En général, il faut utiliser le ksmps local avec précaution car c'est une fonctionnalité expérimentale, bien qu'elle fonctionne correctement dans la plupart des cas. |
L'instruction setksmps peut être utilisée pour fixer la valeur du ksmps local du bloc d'opcode défini par l'utilisateur. Elle a un paramètre de taux-i spécifiant la nouvelle valeur de ksmps (qui reste inchangée si l'on utilise zéro, voir aussi les notes au sujet de iksmps ci-dessus). setksmps doit être utilisé avant tout autre opcode (mais il est autorisé après xin), autrement des résultats imprévisibles peuvent se produire.
On peut lire les paramètres d'entrée avec l'opcode xin, et la sortie est écrite par l'opcode xout. On ne doit utiliser qu'une seule instance de ces unités, car xout écrase la sortie sans accumuler les valeurs. Le nombre et le type des arguments pour xin et xout doit être le même que dans la déclaration du bloc d'opcode défini par l'utilisateur (voir les tableaux ci-dessus).
Les arguments d'entrée et de sortie doivent se conformer à la définition à la fois en nombre (sauf si des entrées de taux-i facultatives sont utilisées) et en genre. Un paramètre d'entrée facultatif de taux-i (iksmps) est automatiquement ajouté à la liste des intypes et (comme pour setksmps) fixe la valeur du ksmps local.
La syntaxe d'un bloc d'opcode défini par l'utilisateur est la suivante :
opcode nom, outtypes, intypes xinarg1 [, xinarg2] [, xinarg3] ... [xinargN] xin [setksmps iksmps] ... the rest of the instrument's code. xout xoutarg1 [, xoutarg2] [, xoutarg3] ... [xoutargN] endop
Le nouvel opcode peut ensuite être utilisé avec la syntaxe usuelle :
[xoutarg1] [, xoutarg2] ... [xoutargN] nom [xinarg1] [, xinarg2] ... [xinargN] [, iksmps]
Note | |
---|---|
L'opcode est toujours appelé à la fois durant l'initialisation et durant l'exécution, même s'il n'y a pas d'arguments de taux-k ou -a. Si l'on sait que plusieurs opcodes définis par l'utilisateur n'ont pas d'effet durant l'exécution (taux-k) dans un instrument, on peut épargner du temps CPU en sautant ces groupes d'opcodes avec kgoto. |
Voici un exemple d'opcode défini par l'utilisateur. Il utilise le fichier opcode.csd.
Exemple 678. Exemple d'opcode défini par l'utilisateur.
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 realtime audio input is needed too ; For Non-realtime ouput leave only the line below: ; -o opcode_example.wav -W ;;; for file output any platform </CsOptions> <CsInstruments> sr = 44100 ksmps = 32 nchnls = 2 0dbfs = 1 /* example opcode 1: simple oscillator */ opcode Oscillator, a, kk kamp, kcps xin ; read input parameters a1 vco2 kamp, kcps ; sawtooth oscillator xout a1 ; write output endop /* example opcode 2: lowpass filter with local ksmps */ opcode Lowpass, a, akk setksmps 1 ; need sr=kr ain, ka1, ka2 xin ; read input parameters aout init 0 ; initialize output aout = ain*ka1 + aout*ka2 ; simple tone-like filter xout aout ; write output endop /* example opcode 3: recursive call */ opcode RecursiveLowpass, a, akkpp ain, ka1, ka2, idep, icnt xin ; read input parameters if (icnt >= idep) goto skip1 ; check if max depth reached ain RecursiveLowpass ain, ka1, ka2, idep, icnt + 1 skip1: aout Lowpass ain, ka1, ka2 ; call filter xout aout ; write output endop /* example opcode 4: de-click envelope */ opcode DeClick, a, a ain xin aenv linseg 0, 0.02, 1, p3 - 0.05, 1, 0.02, 0, 0.01, 0 xout ain * aenv ; apply envelope and write output endop /* instr 1 uses the example opcodes */ instr 1 kamp = .7 ; amplitude kcps expon 50, p3, 500 ; pitch a1 Oscillator kamp, kcps ; call oscillator kflt linseg 0.4, 1.5, 0.4, 1, 0.8, 1.5, 0.8 ; filter envelope a1 RecursiveLowpass a1, kflt, 1 - kflt, 10 ; 10th order lowpass a1 DeClick a1 outs a1, a1 endin </CsInstruments> <CsScore> i 1 0 4 e5 ;extra second before quitting </CsScore> </CsoundSynthesizer>