| Home | Contact | Il Suono Virtuale | Virtual Sound |


Indice articolo
DirectCSound
Pagina 2
Pagina 3
Pagina 4
Pagina 5
Pagina 6


3.4 Controllers continui: variamo l’ampiezza
e la frequenza del vibrato mentre suoniamo le note.


;vibrato.orc
instr 1
ifreq cpsmidi
iamp ampmidi 10000
kfrqvib midic7 1, 0, 1
kampvib midic7 2, 0, 1
kvib oscili kampvib, kfrqvib, 1
kenv linsegr 0, .1, 1, .3, .5, .2, 0
a1 oscili iamp, ifreq*powoftwo(kvib), 1
out a1*kenv
endin


Questo esempio permette di suonare una nota sulla master-keyboard variando sia la frequenza che l’ampiezza del vibrato allo stesso tempo. Il vibrato è generato da un ulteriore oscillatore (operante a k-rate), che genera un segnale di controllo che viene moltiplicato per la frequenza base dell’oscillatore audio. La frequenza e l’ampiezza dell’oscillatore che genera il vibrato possono essere variate in modo continuo per mezzo di messaggi MIDI di control-change.
Gli argomenti di ingresso di midic7 sono tre (più uno opzionale) cioè: il numero di controller MIDI (per esempio, 1 corrisponde alla modulation-wheel, 2 al breath-control ecc.) e i valori di minimo e massimo, usati per riscalare l’uscita.
Notare l’uso della funzione powoftwo( ) che restituisce un moltiplicatore che varia esponenzialmente anziché linearmente: se avessimo usato direttamente una somma tra il segnale di vibrato e la frequenza base della nota, il vibrato avrebbe prodotto grandi variazioni frequenziali nella gamma grave e piccole variazioni nella gamma acuta. Nel nostro caso, moltiplicare la frequenza base per una potenza permette di esprimere la variazione in ottave anziché in Hertz. Sebbene la trattazione matematica di questo concetto non sia eccessivamente complicata, va comunque oltre gli scopi di questa lettura. Diamo semplicemente per scontato che l’intervallo della seconda istanza dell’opcode midic7 (che controlla l’ampiezza del vibrato) viene espressa in ottave e che varia tra 0 e 1.

3.5 Un vibrato più complesso, con delay e tremolo controllabili in tempo reale

L’esempio precedente non è stato ottimizzato per la velocità: se l’esecutore suonasse più di una nota contemporaneamente, verrebbero attivate istanze differenti dell’opcode midic7 che generano lo stesso identico segnale: questo sarebbe un inutile spreco di tempo di calcolo da parte del processore. Per spiegare come risolvere questo inconveniente, è necessario riflettere un po’ sul funzionamento degli strumenti e degli opcode di Csound.
Uno strumento è un modello (un template in inglese) usato come schema di base da Csound quando deve attivare la nota corrispondente. Quando questo accade, viene creata una istanza di quello strumento, insieme con i suoi dati.
Gli strumenti di Csound sono polifonici, così è possibile attivare allo stesso tempo più di una nota dello stesso strumento con parametri differenti. Ognuna di queste note è in effetti una istanza dello strumento a cui si riferisce.
In maniera simile, diverse istanze dello stesso opcode possono essere contenute nello stesso strumento (in effetti ciò accadeva nel precedente esempio con l’opcode midic7). Così abbiamo una gerarchia di istanze: note diverse dello stesso strumento attivano istanze diverse di quello strumento, ognuna delle può contenere più istanze dello stesso opcode. Le variabili di Csound rappresentano segnali, che possono essere segnali di controllo, segnali audio o parametri di inizializzazione (questi ultimi rimangono costanti per tutta la durata della nota corrispondente).
E’ importante notare che le variabili contenute in uno strumento sono in genere locali, questo significa che variabili con lo stesso nome, situate in strumenti diversi sono variabili differenti in tutti i sensi. In più, anche considerando lo stesso strumento, variabili con lo stesso nome sono differenti in ciascuna nota (o istanza) dello strumento stesso, e contengono valori differenti e indipendenti, in accordo ai parametri con cui la nota corrispondente viene attivata.
Ritornando all’esempio precedente, quando l’esecutore attiva un accordo consistente di 3 note, le 2 istanze di midic7 contenute nello strumento 1 sono in effetti moltiplicate per 3, per un totale di 6 istanze contemporanee di midic7, che sono un’inutile spreco di tempo di calcolo perché producono tutte gli stessi identici valori. E’ meglio usare midic7 in uno strumento separato che viene attivato una sola volta, e che rimane attivo per tutta la durata della sessione corrente. Questo strumento verrà attivato dallo score, invece che dal MIDI.
Per permettere che il segnale prodotto da tale strumento sia visibile dall’esterno (e in particolare dallo strumento attivato dal MIDI che necessita di accedere ai valori generati dai controller), è necessario usare le variabili globali.
Le variabili globali hanno visibilità a livello di orchestra, non di strumento; questo significa che esse sono condivise e visibili da tutti gli strumenti dell’orchestra. In più, a differenza dalle variabili locali, esse sono uniche e comuni a tutte le istanze di tutti gli strumenti correntemente attive.
Diamo un’occhiata allo strumento seguente:

;orchestra
sr = 44100
kr = 441
ksmps = 100
nchnls = 1
gi1 ftgen 1, 0, 1024, 10, 1, .2, 0, 0, .1, 0, 0, .05 ; tabella audio
gi1 ftgen 2, 0, 129, 7, 0, 4, -1, 64, -1, 4, 0, 56, 0 ; tabella del tremolo
;## tabelle del vibrato
gi1 ftgen 50, 0, 513, 10, 1 ; sine
gi1 ftgen 51, 0, 513, 7, 1, 511, -1 ; dente di sega discendente
gi1 ftgen 52, 0, 513, 7, -1, 511, 1 ; dente di sega ascendente
gi1 ftgen 53, 0, 513, 7, 0, 128, 1, 256, -1, 128, 0 ; triangolare
gi1 ftgen 54, 0, 513, 7, 1, 256, -1, 255, 0 ; square
gi1 ftgen 55, 0, 513, 7, 0, 170, 0, 0, 1, 170, 1, 0, -1, 170, -1, 0, 0 ; a 3 gradini
gi1 ftgen 56, 0, 513, 7, 0, 128, 0, 0, 1, 128, 1, 0, 0, 128, 0, 0, -1, 128, -1, 0, 0 ;4 ; 4 gradini
gi1 ftgen 57, 0, 513, 7, 1, 128, 1, 0, 0, 128, 0, 0, -1, 128, -1, 0, 0, 128, 0 ;4 ; 4 gradini 2
gi1 ftgen 58, 0, 513, 7, -1, 128, -1, 0, 0, 128, 0, 0, 1, 128, 1, 0, 0, 128, 0 ;4 ; 4 gradini 3
; quarta, quinta e ottava
gi1 ftgen 59, 0, 513, 7, 0, 128, 0, 0, 5, 128, 5, 0, 7, 128, 7, 0, 12, 128, 12
; ottava, quarta, quinta ed unisono
gi1 ftgen 60, 0, 513, 7, 12, 128, 12, 0, 5, 128, 5, 0, 7, 128, 7, 0, 0, 128, 0
;4 glissando
gi1 ftgen 61, 0, 513, 7, -1, 90, -1, 38, 0, 90, 0, 38, 1, 90, 1, 38, 0, 90, 0, 38, -1
gi1 ftgen 100, 0, 8193, 5, .001, 8193, 1 ; curva esponenziale per il mapping dello slider
gk1 init 0
gk2 init 0
gk3 init 0
gk4 init 0
gk5 init 0
gk6 init 0
gk7 init 0
gk8 init 0
gaout init 0
;////////////////////////////
instr 1
;////////////////////////////
kvib oscili gk1, gk2, i(gk3)+.5
atrem oscili gk4, gk5, 2
ifreq cpsmidi
iamp ampmidi 10000
aenv linsegr 0, .05, 1, .2, .2, 10, .2, .2, 0
a1 oscili aenv*iamp*(1+atrem), ifreq*powoftwo(kvib),1
vincr gaout a1
endin
;////////////////////////////
instr 100
;////////////////////////////
initc7 1, 3, (50-50)/(61.5-50)
gk1 ctrl7 1, 1, 0, 1 ; ampiezza del vibrato
gk2 ctrl7 1, 2, .5, 20, 101, 2, .5, 20, 100 ; frequenza del vibrato
gk3 ctrl7 1, 3, 50, 61.5 ; tabella del vibrato
gk4 ctrl7 1, 4, 0, 1 ; ; profondità del tremolo
gk5 ctrl7 1, 5, 2, 20, 100 ; frequenza del tremolo
gk6 ctrl7 1, 6, 0, 1 ; rapporto wet/dry
gk7 ctrl7 1, 7, 0, 1 ; feedback del delay
gk8 ctrl7 1, 8, 1, 1000 ; tempo di delay
gk8 tonek gk8,2
a8 interp gk8
a1 init 0
a1 vdelay gaout+a1*gk7,a8,1000
out a1*gk6+gaout*(1-gk6)
clear gaout
endin
;score
i100 0 3600


Come potete vedere, lo score non necessita dell’opcode f0, perché la durata della sessione in tempo reale viene già portata a 3600 secondi dall’unica nota che attiva lo strumento “globale” 100. Vedremo lo scopo dello strumento 100 più avanti.
Lo strumento 1 ha tre oscillatori. Il primo e il secondo oscillatore generano il vibrato e il tremolo, mentre il terzo genera il segnale audio. Seguono alcune osservazioni circa lo strumento 1:
1.   l’ampiezza del vibrato viene definita esternamente dallo strumento 1, così come la frequenza del vibrato, il numero di tabella del vibrato, la profondità del tremolo e la frequenza del tremolo. Questi parametri vengono forniti agli oscillatori dalle variabili globali gk1, gk2, gk3, gk4 e gk5. Più avanti vedremo il punto in cui tali variabili vengono riempite.
2.  l’opcode out non è presente all’interno dello strumento 1, invece l’uscita viene assegnata alla variabile globale gaout. Il motivo per cui si usa la variabile globale, invece di mandare il segnale audio direttamente all’opcode out, è che questo segnale deve essere riutilizzato da un altro strumento, per aggiungere un effetto (un delay in questo caso) e occorre bilanciare il rapporto wet/dry (bagnato/secco ossia con o senza effetto) prima di assegnarlo all’opcode out.
Per abbinare un segnale alla variabile globale gaout una semplice assegnazione non è sufficiente, perché tale variabile è in comune con tutte le istanze dello strumento 1, quindi se tale strumento venisse usato polifonicamente e la sua uscita fosse semplicemente assegnata a gaout, il segnale generato da altre istanze concorrenti dello strumento 1 sarebbe semplicemente rimpiazzato da quella relativa all’istanza presente.
In questo caso, quando gaout venisse connessa all’opcode out dello strumento 100, il segnale sarebbe monofonico e non polifonico, perché conterrebbe soltanto l’uscita dell’ultima istanza dello strumento 1 (ossia l’ultima voce suonata della polifonia). Per evitare questo inconveniente, dobbiamo missare l’uscita dello strumento 1 con il contenuto precedente di gaout, invece che assegnare direttamente il valore. Nel nostro caso questa operazione viene fatta con l’opcode vincr, che fa la stessa cosa della linea seguente:
   gaout = gaout + a1
...ma è più veloce. E’ un accumulatore, progettato specificamente per sommare un segnale ad una linea di missaggio. Dopo aver connesso gaout all’opcode out (situato nello strumento 100), è necessario azzerare la variabile gaout, altrimenti potrebbe ‘esplodere’ perché i valori continuerebbero ad accumularsi indefinitamente.
Per porre la variabile gaout a zero, sarebbe sufficiente la seguente linea:
   gaout = 0
...ma viene usato l’opcode clear, perché è stato progettato apposta per svolgere questo compito in maniera più veloce (in questo caso particolare l’incremento di velocità non è così evidente, ma quando ci sono diverse variabili a dover essere azzerate nella stessa linea, lo diventa. Vedere il manuale).

Lo strumento 100 viene attivato dallo score solo una volta per ogni sessione in tempo reale. Questo strumento si occupa di tre cose:
1.   gestisce i messaggi MIDI di control-change, riempiendo le variabili globali, che hanno il seguente scopo:

gk1 - ampiezza del vibrato
gk2 - frequenza del vibrato
gk3 - numero di tabella del vibrato
gk4 - profondità del tremolo
gk5 - frequenza del tremolo
gk6 - rapporto wet/dry del delay
gk7 - feedback del delay (per supportare l’eco)
gk8 - tempo del delay

2.   genera l’effetto di delay (che è unico per tutte le note di tutti gli strumenti)

3.   gestisce l’uscita master.

Osserviamo questo strumento. Sicuramente avrete notato che non c’è nessuna istanza di midic7 nello strumento 1, infatti in questo caso i messaggi MIDI di control-change sono gestiti da diverse istanze di ctrl7, che è un opcode simile a midic7, ma che permette di definire il canale MIDI. Di conseguenza ctrl7 può essere usato anche negli strumenti attivati dallo score, mentre se si assegna midic7 ad uno strumento attivato dallo score, Csound si bloccherà, dal momento che in midic7 il canale MIDI è implicitamente lo stesso dello strumento con cui viene attivato.
Notare che le variabili globali devono essere inizializzate prima di ogni strumento, nella sezione dello header dell’orchestra, altrimenti verrebbero prodotti degli errori dovuti all’uso di variabili senza inizializzazione.
Lo scopo di initc7 è quello di inizializzare il primo valore in uscita del corrispettivo opcode che gestisce i messaggi MIDI di control-change (funziona sia con midic7 che con ctrl7, vedi il manuale).



 
English Version
Home
- - - - - - - - - - - -
Il Suono Virtuale
- - - - - - - - - - - -
Articoli
- - - - - - - - - - - -
Tutorial
- - - - - - - - - - - -
Corsi Online
- - - - - - - - - - - -
Software
- - - - - - - - - - - -
Forum
- - - - - - - - - - - -
Search
- - - - - - - - - - - -
Contact
- - - - - - - - - - - -