Lezione 14 Inviluppi d’ampiezza Programmazione timbrica - Prof. Luca A. Ludovico Estrazione di inviluppi da file: opcode follow • L’opcode follow estrae l’inviluppo da un segnale in ingresso (per poi applicarlo ad un altro suono). • Sintassi: ares follow asig, idt ove asig è il segnale in ingresso, idt è il periodo (espresso in secondi) nel quale viene misurata l’ampiezza media dell’ingresso e ares è il segnale di uscita, che contiene i valori dell’inviluppo di asig. • Osservazioni: – se la frequenza di asig è bassa, allora idt deve essere grande (più della metà del periodo di asig); – Per evitare il rumore prodotto dalle discontinuità nell’inseguimento di un inviluppo complesso, è possibile utilizzare un filtro passabasso che ammorbidisce e arrotonda il segnale in uscita risultante. Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Estrazione di inviluppi da file: opcode follow • Come applicare i risultati di follow? – Utilizzando la variabile audio di uscita come argomento dell’opcode balance. Perché non utilizzare direttamente rms + gain o balance? Perché non danno controllo sull’inseguimento dell’inviluppo. Esempio: → 14_01_follow.csd – Sfruttando i risultati di follow come valori di ampiezza istantanei per un opcode generatore di suono, ad esempio oscil. Esempio: → 14_02_follow.csd Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Opcode limit • L’opcode limit fissa i valori massimi e minimi per il segnale di ingresso. Questo opcode viene spesso utilizzato con i suoni campionati, ed è particolarmente utile per limitare gli indici di lettura da tabella e per evitare il clipping dei segnali. • Sintassi: ares limit asig, klow, khigh ires limit isig, ilow, ihigh kres limit ksig, klow, khigh ove il primo parametro rappresenta il segnale in ingresso, il secondo il valore minimo e il terzo il valore massimo consentito (variabili nel tempo a frequenza di controllo, tranne nel caso di valori a init-time). Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Opcode limit • Sintassi: ares ires kres limit asig, klow, khigh limit isig, ilow, ihigh limit ksig, klow, khigh • Osservazioni: – se xhigh è inferiore a xlow, allora l’output sarà la media dei due valori, indipendentemente dai valori assunti da xsig (da notare che in generale possono variareo nel tempo); – questo opcode introduce una distorsione armonica del segnale in ingresso, aggiungendo armoniche dispari (come ad esempio facevano i distorsori per chitarra elettrica instrodotti negli anni ‘60). Tanto più bassa è la soglia, tanto più distorto è il suono. • Esempio di distorsione: → 14_03_limit.csd Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Segnali di controllo per gli inviluppi • Il tipico inviluppo di ampiezza per un suono è caratterizzato da 4 fasi: Attack (Attacco), Decay (Decadimento), Sustain (Sostegno), Release (Rilascio). Inviluppo ADSR, o ADSR envelope Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Modellazione di inviluppi: opcode envlpx • In Csound è possibile costruire un inviluppo di ampiezza parametrico, il cui attacco ha una forma complessa a piacimento, attraverso l’opcode envlpx. L’inviluppo viene depositato in una var. d’uscita. • Sintassi: ares envlpx xamp, irise, idur, idec, ifn, iatss, iatdec [, ixmod] kres envlpx kamp, irise, idur, idec, ifn, iatss, iatdec [, ixmod] – irise – tempo di attacco in secondi. Se ≤ 0, non c’è modifica di attacco; – idur – durata totale dell’inviluppo in secondi, tipicamente p3; – idec – tempo di decadimento in secondi, al più nullo. Se idec > idur, il decadimento risulta troncato dallo spegnimento della nota; – ifn – numero di tabella-funzione contenente la forma dell’attacco. Tale tabella deve avere extended guard point, ossia un numero di punti potenza di 2 + 1 (1025, 4097, …), e l’ultimo valore deve essere 1 per evitare discontinuità. Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Modellazione di inviluppi: opcode envlpx • Sintassi: ares envlpx xamp, irise, idur, idec, ifn, iatss, iatdec [, ixmod] kres envlpx kamp, irise, idur, idec, ifn, iatss, iatdec [, ixmod] – iatss – fattore di attenuazione dell’eventuale fase di sustain, per il quale viene modificato l’ultimo valore dell’attacco durante la fase pseudostazionaria: 1 significa semplice sustain, >1 crescita esponenziale, <1 diminuzione esponenziale, 0 non è ammesso. Contrariamente a quanto avviene in uno strumento quale il pianoforte, tale attenuazione non avviene in modo fisso ma dipende dalla durata della nota. Si ricordi che la durata di questa fase è idur – (idec + irise). – iatdec – fattore di attenuazione per il decay, necessariamente positivo e normalmente dell’ordine di 0.01. – ixmod (opzionale, default = 0, di solito intorno a +/-0.9) – modificatore della curva esponenziale per la fase stazionaria. Valori < 0 causeranno una crescita o un decadimento accelerato, > 0 un ritardo nella crescita/decadimento. Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Segmenti di retta in tabella: routine GEN07 • La routine GEN07, appartenente alla famiglia dei generatori di segmenti, compila una tabella funzione con segmenti di retta. • Sintassi: f # ove time size 7 a n1 b n2 c ... – a, b, c, ecc. (p-field dispari p5, p7, p9, …) sono i valori da interpolare – n1, n2, ecc. (p-field pari p6, p8, …) sono le lunghezza dei segmenti in punti • Le lunghezze non possono essere negative, ma valori nulli sono ammessi per creare punti di discontinuità. • In situazioni normali, la somma n1 + n2 + ... coinciderà con la lunghezza della tabella. In altro caso, la valorizzazione sarà o troncata (lunghezza minore di somma) o la tabella sarà riempita con zeri, senza proseguire l’interpolazione (lunghezza maggiore di somma). Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Altre routine di generazione di segmenti • La routine GEN05 compila una tabella funzione con segmenti di esponenziale. La sintassi è uguale a GEN07, ma i valori interpolati non possono essere nulli e devono avere tutti lo stesso segno. • La routine GEN16 crea un’interpolazione tra un valore iniziale e uno finale pemettendo di specificare un andamento. Sintassi: f # time size 16 beg dur type end • Esempi: • forma d’onda a dente di sega tramite GEN07 → 14_04_sawtooth.csd • forma d’onda con andamento impulsivo tramite GEN 05 → 14_05_impulsive_envelope.csd Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Modellazione di inviluppi: envlpx e GEN • Poiché l’opcode envlpx richiede di leggere informazioni sull’inviluppo da tabella, tornano utili in questo contesto alcune routine GEN già viste, e in particolare: – Le routine di accesso ai file, quali GEN01 (in modo da conferire a un inviluppo i dati estratti da un file) – Le routine di generazione di spezzate di retta e di esponenziale, quali GEN05, GEN07, GEN16, ecc. (in modo da generare manualmente i valori di inviluppo) • Esempio: → 14_06_envlpx_gen01_07.csd In questo esempio si usa come inviluppo il file custom_attack.wav. E’ possibile generarne uno a piacimento, ad esempio creando in Audacity un file nuovo, producendo silenzio per 65, o 129, o altro campioni e disegnando con lo strumento matita una funzione. Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Scrittura diretta di valori in tabella: GEN02 • Anziché caricare i valori da un file o calcolarli tramite funzioni trigonometriche e aritmetiche, è possibile scrivere valori direttamente all’interno di una tabella sotto forma di un elenco di pfield: in tal caso si utilizza la routine GEN02. • Sintassi: f # time size 2 v1 v2 v3 ... ove la dimensione al solito è una potenza di due (al limite +1), ma il numero massimo di p-field è attualmente fissato a 1000. Ulteriori punti disponibili in tabella saranno valorizzati a 0. • Si ricorda che, in assenza del segno – davanti all’identificativo di GEN (in questo caso -2), i valori vengono normalizzati, il che in questo caso solitamente non è l’effetto desiderato! • Esempio: → 14_07_square_gen02_07.csd Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza Lettura di valori da tabella: opcode table • L’opcode table accede ai valori scritti in una tabella per indice. • Sintassi: – – – – – ares table andx, ifn [, ixmode] [, ixoff] [, iwrap] ires table indx, ifn [, ixmode] [, ixoff] [, iwrap] kres table kndx, ifn [, ixmode] [, ixoff] [, iwrap] il primo argomento indica il valore dell’indice da cui leggere, e normalmente varia nel tempo (può essere normalizzato o meno); ifn è il numero di tabella funzione da cui estrarre i valori; ixmode (opzionale, default = 0) è il modo di interpretare l’indice: 0 significa indice grezzo (raw), 1 indice normalizzato; ixoff (optional, default = 0) è la quantità dell’offset da aggiungere all’indice. Ad esempio, per una lettura dal centro, si usa tablesize/2 (raw) o .5 (normalizzato); iwrap (opzionale, default = 0) è il flag che indica se leggere la tabella in modo ciclico (iwrap = 1) o meno, fermandosi agli estremi inferiore e superiore se index < 0 (trattato come index = 0) o index > tablesize (trattato come index = tablesize) • Esempio: → 14_08_table.csd Programmazione timbrica - Prof. Luca A. Ludovico Inviluppi d'ampiezza