|
Pagina 3 di 6
2.3 Opcode e operatori relativi alla partitura
Nuovi opcode di partitura
{ } - abilita i loop con possibilità di annidamento
F - tabelle dello score
Macro annidabili
La nuova sintassi permette di annidare le macro (ossia di avere macro che ne
contengono altre)
L’annidamento consente di avere più di un loop, uno dentro l’altro. Per esempio, se
abbiamo quattro sezioni compositive chiamate A,B,C,D, e vogliamo ripetere 4 volte la
prima sezione, 3 la seconda, 2 la terza, mentre la quarta non ha ripetizioni, avremo una
sequenza del seguente tipo:
A-A-A-A-B-B-B-C-C-D.
Le prime quattro ripetizioni del blocco A possono essere generate da un loop di 4
iterazioni; idem per le 3 ripetizioni di B e le 2 di C. Supponiamo di voler ripetere l’intero
costrutto per 4 volte, avremo la sequenza seguente:
A-A-A-A-B-B-B-C-C-D-A-A-A-A-B-B-B-C-C-D-A-A-A-A-B-B-B-C-C-D-A-A-A-A-B-B-B-C-C-D.
Questa sequenza può essere facilmente generata da un loop esterno di 4 iterazioni, che
contiene i 3 loop interni. Può darsi che non convenga usare un loop nidificato per una
ripetizione testuale, per via delle difficoltà di apprendimento da parte dell’utente della
tecnica dei loop. Comunque si possono presentare esigenze compositive secondo cui i
parametri di ciascuna iterazione devono essere variati in accordo ad un algoritmo
definito dall’utente stesso. In questo caso i parametri devono essere diversi per ogni
iterazione, e calcolare ciascun parametro a mano risulterebbe complesso e noioso,
specialmente quando si a che fare con migliaia di eventi. In questo caso è molto più
conveniente usare i loop annidati, perché, tra l’altro, permettono di mantenere della
partitura più sintetica e leggibile.
Nuovi operatori di macro della partitura
T - restituisce un elemento di una tabella di partitura, fornendo il rispettivo indice.
R - restituisce un numero casuale
^ - eleva a potenza
% - effettua l’operazione di modulo
3. USIAMO DIRECTCSOUND IN TEMPO REALE
In questa sezione saranno analizzati alcuni esempi di orchestre controllate via MIDI.
Per usare DirectCsound in tempo reale, è necessario avviarlo con alcuni flag particolari,
non presenti nella versione canonica. DirectCsound è in grado di gestire sia l’ingresso che
l’uscita MIDI. Per quanto riguarda l’audio, è possibile usare sia i vecchi driver MME che
i driver DirectX a bassa latenza. Comunque, i rispettivi flag non possono essere usati
contemporaneamente (ossia, o si usa l’MME o il DirectX). Il buffer audio del DirectX è
unico, mentre è possibile abilitare più buffer quando si usano i driver MME. Notare che
i flag non standard hanno il prefisso ‘-+’ mentre quelli standard hanno soltanto ‘-’.
L’utente deve usare i seguenti flag per avviare gli esempi:
-b imposta la lunghezza del buffer (flag standard)
-+p < numero > imposta il numero di buffer del driver MME (da NON usare insieme a
-+X o a -+S)
-+X attiva il buffer primario del DirectX (da NON usare insieme a -+q o a -+S)
-+S attiva un buffer secondario del DirectX (da NON usare insieme a -+q
o a -+X)
-+C attiva il driver DirectX per l’ingresso audio (da NON usare insieme a -i)
-+q attiva il driver MME per l’uscita audio (da NON usare insieme a -+X
o a -+S)
-+i attiva il driver MME per l’ingresso audio (da NON usare insieme a -i)
-+K attiva la porta MIDI IN
-+Q attiva la porta MIDI OUT
Nel caso siano disponibili diverse porte audio o MIDI, DirectCsound mostrerà una
lista contenente i nomi delle porte installate, chiedendo all’utente di selezionarne una.
Nei seguenti esempi viene data per scontata una conoscenza di base del protocollo
MIDI da parte dell’utente.
3.1 Un semplice esempio: sine.orc
Questo è il più semplice esempio che possa essere scritto. Consiste in un
oscillatore la cui frequenza viene controllata dal numero di nota MIDI inviato da una
master-keyboard MIDI.
| ; sine.orc |
|
|
|
|
sr |
= |
44100 |
|
kr |
= |
441 |
|
ksmps |
= |
100 |
|
nchnls |
= |
1 |
| gi1 |
ftgen |
|
1, 0, 1024, 10, 1 |
|
instr |
1 |
|
| ifreq |
cpsmidi |
|
|
| iamp |
ampmidi |
|
10000 |
| a1 |
oscili |
iamp |
ifreq, 1 |
|
out |
a1 |
|
|
endin |
|
|
questa è la partitura
; sine.sco
f0 3600
Questo esempio deve essere avviato con la seguente linea di comando, se l’utente ha
i drivers DirectX già installati nel suo computer:
csound.exe -+X -+K -b200 sine.orc sine.sco
...altrimenti deve usare i vecchi driver MME con la seguente linea di comando:
csound.exe -+q -b500 -+p8 -+K sine.orc sine.sco
DirectCsound partirà chiedendo all’utente di digitare il numero di porta audio e
quello della porta MIDI che vuole attivare in una finestra di dialogo.
Dopo che l’utente ha digitato questi dati, è possibile suonare delle note in una
master-keyboard connessa alla porta MIDI IN che è stata scelta precedentemente,
e ascoltare le sinusoidi prodotte, che avranno una frequenza corrispondente al
tasto premuto. Il timbro non sarà certo eclatante, ma questa orchestra risulterà utile
per verificare che tutto stia a posto. Se ci sono interruzioni del flusso sonoro, sarà
necessario aumentare la lunghezza del buffer, cambiando il numero abbinato al
flag -b.
In questo caso gli opcode che gestiscono il MIDI sono quelli standard: cpsmidi che
restituisce la frequenza ampmidi, che restituisce l’ampiezza.
Notare che la partitura contiene solo la linea f0 3600, che permette di suonare Csound
in tempo reale per 3600 secondi (ossia un’ora). In effetti, in questo caso la tabella audio
contenente la sinusoide viene generata direttamente all’interno dell’orchestra, con
l’opcode ftgen. E’ possibile terminare la sessione in tempo reale in qualunque momento,
premendo CONTROL-C nel caso della versione CONSOLE di DirectCsound, o
cliccando sul bottone STOP per quella con la GUI integrata.
3.2 Aggiungiamo un inviluppo di ampiezza a sine.orc
Ora modificheremo lo strumento 1 della precedente orchestra come segue:
|
instr |
1 |
| ifreq |
cpsmidi |
|
| iamp |
ampmidi |
10000 |
| kenv |
linsegr |
0, .1, 1, .3, .5, .2, 0 |
| a1 |
oscili |
iamp, ifreq, 1 |
|
out |
1*kenv |
|
endin |
|
Come si può notare, viene usato l’opcode linsegr. Questo opcode permette di gestire
lo stadio di rilascio quando la nota corrente riceve un messaggio MIDI di note-off.
L’effetto risultante sarà quello di estendere la durata normale della nota per il tempo che
l’utente ha assegnato al parametro corrispondente (cioè il penultimo argomento della
linea contenente linsegr; l’ultimo argomento contiene il livello che la nota avrà al
termine della fase di rilascio, che normalmente deve essere posto a zero).
linsegr estende automaticamente la durata della nota e la fase di rilascio consiste
soltanto di un segmento. Notare che linsegr deve essere usato soltanto negli strumenti
attivati dal MIDI, altrimenti non produrrà l’effetto desiderato.
Che cosa occorre fare quando serve un inviluppo complesso nella fase di rilascio,
formata da più segmenti (per esempio un crescendo seguito da un diminuendo)?
Il prossimo esempio mostrerà come ottenere ciò usando due nuovi opcode: xtratim e
release.
3.3 Estendiamo la vita di una nota attivata dal MIDI: xtratim e release
In questo esempio supponiamo che l’utente voglia un inviluppo più complesso nella
fase di rilascio di una nota attivata dal MIDI.
A questo punto è necessario fare una distinzione tra due tipi diversi di strumenti: quelli
che vengono attivati dalla partitura e quella che vengono attivati da un messaggio MIDI di note-on. Il motivo di questa distinzione è che ci sono alcuni opcode che operano
correttamente solo con uno strumento attivato dal MIDI, sebbene la maggioranza degli
opcode funzionano altrettanto bene sia col MIDI che con la partitura.
In effetti, estendere una nota di uno strumento attivato dallo score è molto facile:
siccome la sua durata viene definita dal parametro p3 dell’opcode i dello score, per
estenderlo è sufficiente assegnare alla variabile p3 la somma tra il suo valore attuale ed
il valore relativo all’estensione della durata stessa, espressa in secondi:
p3 = p3+1 ;aggiunge 1 secondo alla durata della nota corrente
Questo è vero per gli strumenti attivati dallo score.
Negli strumenti attivati dal MIDI, p3 è privo di significato, perché la nota
corrispondente rimane in realtà attiva fino a che un messaggio MIDI di note-off non
viene ricevuto.
I soli modi di estendere la durata di questo tipo di note sono:
• usando un opcode relativo all’inviluppo delle note MIDI (quelli che terminano con
la “r”, linenr, linsegr, expsegr, la “r” sta per “release”), o
• usando due opcode, progettati specificamente per questo scopo: xtratim e release.
Osserviamo il seguente esempio:
|
instr |
1 |
| inum |
notnum |
|
| icps |
cpsmidi |
|
| iamp |
ampmidi |
4000 |
;############## inviluppo MIDI complesso #################
|
xtratim |
1 |
; tempo extra, cioè la durata del rilascio |
| krel |
init |
0 |
|
| krel |
release |
|
; restituisce il flag relativo allo stato di rilascio (0 o 1) |
| if |
(krel > .5) |
(krel > .5)kgoto rel |
; se si è nella fase di rilascio salta alla sezione relativa |
;************ sezione attack e sustain ***********
| kmp1 |
linseg |
0, .03, 1, .05, 1, .07, 0, .08, .5, 1, .2, 50, .2 |
| kmp |
= |
kmp1*iamp |
| kgoto |
done |
|
;************ sezione di rilascio **********************
| rel: |
|
|
| kmp2 |
linseg |
1, .05, 4, .7, 0 |
| kmp |
= |
kmp1*kmp2*iamp |
| done: |
|
|
;###################################################
| a1 |
oscili |
kmp, icps, 1 |
| out |
a1 |
|
| endin |
|
|
Anche se questo strumento può apparire complesso, in realtà non lo è. Lo scopo
dell’opcode xtratim è di aggiungere una durata addizionale allo strumento 1. La quantità
di tempo extra viene definita dall’argomento di ingresso (che nell’esempio è di un
secondo). Notare che xtratim non ha output. Lo scopo dell’opcode release è quello di
informare lo strumento su quando la nota corrispondente si trova nello stadio normale e
quando invece passa allo stadio di rilascio. In questo caso ci sono due inviluppi, eseguiti
in successione. Da notare un importante dettaglio: nella maggior parte dei casi
l’inviluppo di sustain non viene eseguito completamente perché è impossibile prevedere
in anticipo per quanto tempo l’esecutore lascia premuto il tasto, così l’ultimo valore della
variabile kmp1 potrebbe non essere uguale al valore iniziale di kmp2. Per evitare
discontinuità nel suono prodotto (che disturberebbero l’ascolto con dei click), è
necessario moltiplicare l’ultimo valore di kmp1 per kmp2 (kmp2 deve essere posto ad 1
all’inizio, per lasciare il valore iniziale dell’uscita di linseg inalterato). In questo caso,
l’inviluppo della fase di rilascio funziona da moltiplicatore per l’ultimo valore che è stato
raggiunto dall’inviluppo nello stadio precedente. Nell’esempio, inizialmente abbiamo un
rilascio in crescendo, che successivamente discende a zero.
|