PROTOTIPO PER LA SINTESI DEL SUONO CON WEB AUDIO … · Capitolo 2 Stato dell’arte In questo...

61
UNIVERSITÀ DEGLI STUDI DI MILANO FACOLTÀ DI SCIENZE E TECNOLOGIE Corso di Laurea in Informatica Musicale PROTOTIPO PER LA SINTESI DEL SUONO CON WEB AUDIO API Relatore: Prof. Luca Andrea LUDOVICO Tesi di laurea di: Sebastian MARTINI Matricola n. 857196 Anno Accademico 2017/2018

Transcript of PROTOTIPO PER LA SINTESI DEL SUONO CON WEB AUDIO … · Capitolo 2 Stato dell’arte In questo...

UNIVERSITÀ DEGLI STUDI DI MILANOFACOLTÀ DI SCIENZE E TECNOLOGIE

Corso di Laurea in Informatica Musicale

PROTOTIPO PER LA SINTESI DEL SUONO CON WEB AUDIO API

Relatore: Prof. Luca Andrea LUDOVICO

Tesi di laurea di: Sebastian MARTINI

Matricola n. 857196

Anno Accademico 2017/2018

Ringraziamenti:

Ringrazio tutte le persone che mi sono state accanto in questo percorso. Per tutto il sostegno e

l’affetto ringrazio i miei genitori Barbara e Pino, le mie sorelle Dada e Vera e ringrazio Ele.

Ringrazio Gabri, Gre, Ste, Beppe, Gil, Gio, Vale, Freddi, Andy, Fra, Mike, Mari, Ele, Sam, Marta,

Gaia e Lollo con cui vivo la vita ogni giorno e che porto dentro di me in ogni momento. Ringrazio

tutti i compagni dell’università con cui ho condiviso questa esperienza universitaria e i miei compagni e amici che dal liceo vengono avanti accanto me.

Ringrazio tutti i ragazzi di Manipastaciòn Marci, Charis, Chryssa, Elektra, Maqui, Ale, Cami,

Miguel, Ale e tutte le altre persone che ho conosciuto in Spagna, rendendo quell’esperienza

eccezionale. Ringrazio tutta la famiglia e in particolare la zia Liliana, la più anziana tra noi.

Un ringraziamento speciale va a Gi per il suo amore e il sostegno vitale, sempre presente nella mia vita. La ringrazio anche per i consigli e le correzioni che sono stati estremamente utili per scrivere

questo elaborato.

Indice

Ringraziamenti

1. Introduzione 1

2. Stato dell’arte 4 2.1. Applicativi per la sintesi del suono online . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2. Applicativi con Web Audio API e Web MIDI API . . . . . . . . . . . . . . . . . . . . . . 5

3. Tecnologie utilizzate 8 3.1. Internet e il World Wide Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2. Web Programming: HTML e Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.3. La tecnologia MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.4. Audio digitale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4. Applicazione Web sviluppata 17 4.1. Descrizione del Prototipo per la sintesi del suono con Web Audio API . . . . . . 17 4.2. Funzionalità, utilizzi e scelte progettuali. . . . . . . . . . . . . . . . . . . . . . . . . . . . .19 4.3. Web Audio API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21

4.3.1. Il Web e l’audio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.3.2. L’Audio Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224.3.3. Le sorgenti audio e la riproduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244.3.4. AudioNode e AudioParam utilizzati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254.3.5. Compatibilità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.4. Modelli di sintesi del suono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284.4.1. La sintesi additiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284.4.2. Modulazione di Frequenza (FM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.4.3. Modulazione di Ampiezza (AM) e Modulazione ad Anello (RM) . . . . . 364.4.4. La sintesi sottrattiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404.4.5. La sintesi per modelli fisici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

INDICE

4.5. Web MIDI API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474.5.1. L’accesso: requestMIDIAccess() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474.5.2. Mapping di input e output MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484.5.3. Lettura dei dati: MIDIMessageEventHandler() . . . . . . . . . . . . . . . . . . . 494.5.4. Compatibilità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

4.6. Responsive Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5. Conclusioni e sviluppi futuri 53 5.1. Conclusioni e problemi riscontrati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 5.2. Sviluppi futuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

Bibliografia 55

Sitografia 56

Capitolo 1Introduzione

Questo progetto è stato sviluppato nel contesto del tirocinio svolto durante il corso di

studi in Informatica Musicale, tra ottobre 2017 e gennaio 2018. L’attività è stata svolta

presso il Laboratorio di Informatica Musicale (LIM) dell’Università degli Studi di Milano,

sotto la supervisione del professore relatore Luca A. Ludovico. Il tirocinio si è protratto per 14 settimane comprendendo attività di studio e analisi degli

argomenti di interesse, attività di sviluppo e di test dell’applicativo e attività di confronto

con il prof. relatore.

Il LIM è uno dei principali laboratori del Dipartimento di Informatica

dell’Università. Attivo dal 1985 sotto la direzione di Goffredo Haus, ha svolto numerosissime attività di ricerca nell’ambito dell’informatica e della tecnologia audio,

nell’ambito dell’informatica applicata alla musica e nell’ambito della multimedialità [XIII].

Negli anni si è affermata la sua importanza internazionale e sono state svolte importanti

attività di ricerca nel campo dell’informatica musicale. Tra queste ci sono ricerche sulla

rappresentazione multilivello dell’informazione musicale (cioè lo standard IEEE 1599), sulle Reti di Petri per la rappresentazione formale dell’informazione musicale, ricerche

sulla trascrizione automatica delle partiture musicali ed altre ancora: ricerche sull’analisi e

la sintesi del suono, sviluppo di applicazioni e software per l’elaborazione del suono ed

altre legate all’ambito dei beni culturali e della formazione musicale [XIII].

!1

CAPITOLO 1. INTRODUZIONE

In questo contesto si inserisce il Prototipo per la sintesi del suono con Web Audio API (che

chiameremo anche Prototipo), progetto che si trova nell’ambito multidisciplinare in cui interagiscono informatica e musica, cosa che avviene nelle ricerche del LIM. L’obiettivo

primario dell’attività è stato quello di realizzare una applicazione Web che implementasse

le principali tecniche di sintesi del suono attraverso la Web Audio API di JavaScript, che

potesse interagire con dispositivi esterni secondo lo standard MIDI e che avesse una

impostazione responsive. Dunque lo scopo era quello di creare una pagina attiva che sfruttasse la programmazione ‘lato client’ nel Web e che fosse adattiva, cose che invece

mancavano nell’applicazione precedentemente realizzata dal LIM.

Infatti il Prototipo si ispira all’applicativo realizzato per il MeetMeTonight2017 che era

pensato per la divulgazione e la spiegazione della sintesi del suono e del funzionamento

delle principali tecniche di sintesi, fornendo una dimostrazione pratica durante l’evento. Si è dunque conservata l’impostazione didascalica, mantenendo l’idea di creare un sito che

oltre che suonare, potesse spiegare ad un utente le singole tecniche di sintesi fornendogli

chiarezza attraverso un’esperienza sonora concreta, attraverso testi esplicativi e la

visualizzazione dei modelli o delle forme d’onda.

Così è stato sviluppato il Prototipo e si è cercato di portare a termine tutti gli obiettivi che erano stati stabiliti. La prima fase è stata quella di studio delle API in modo

da poterne capire i concetti che ne stanno alla base per un corretto funzionamento, ed è

stato anche necessario l’approfondimento di alcuni aspetti rilevanti dei linguaggi HTML,

CSS e JavaScript. Sempre in questa fase sono state studiate le tecniche di sintesi che era di

interesse sviluppare, analizzandone le formule matematiche, i modelli e i concetti di base per poterle implementare.

La fase di sviluppo è avvenuta implementando volta per volta una tecnica di sintesi,

usando gli strumenti JavaScript (Web Audio API e Web MIDI API), HTML e CSS nel modo

opportuno perché l’applicativo potesse funzionare al meglio. Alcune delle principali scelte

progettuali saranno discusse approfonditamente nei prossimi capitoli. È stato sviluppato in questo modo un applicativo Web basato sull’esecuzione di

script lato client, in cui è possibile selezionare e far suonare sintetizzatori basati sulle

principali tecniche del suono che sono state sviluppate negli anni.

!2

CAPITOLO 1. INTRODUZIONE

In questo elaborato verrà dunque discusso qual è il livello di conoscenza e di

sviluppo nel campo della sintesi del suono online e delle API che ne stanno alla base, verrano introdotte le varie tecnologie utilizzate per lo sviluppo dell’applicativo e si entrerà

nel merito del codice approfondendo gli aspetti legati alla sua progettazione e

implementazione (Web Audio API, Web MIDI API, i modelli matematici alla base delle

tecniche di sintesi e qualche commento sull’approccio responsive legato al design della

pagina).

!3

Capitolo 2Stato dell’arte

In questo capitolo si discuterà di quello che è lo stato attuale delle conoscenze in materia di

sintesi del suono online e delle API che sono state utilizzate. Sarà rilevante parlare di

applicativi Web con obiettivi e funzionalità simili a quello del Prototipo per la sintesi del

suono con Web Audio API e in generale di applicativi che utilizzano Web MIDI API e soprattutto Web Audio API per l’implementazione delle loro funzionalità.

2.1 Applicativi per la sintesi del suono online

È necessario iniziare a parlare dell’applicativo sviluppato e proposto dal LIM per

l’edizione del 2017 del MeetMeTonight, dal quale prende le sue origini il Prototipo per la

sintesi del suono con Web Audio API. Con il titolo “Scolpire” i suoni con l’informatica, l’evento aveva come obiettivo quello di fare delle dimostrazioni sulla sintesi del suono e veniva

utilizzato a questo scopo l’applicativo Web realizzato dal LIM. Le funzionalità sono molto

simili a quelle del Prototipo ma esistono delle consistenti differenze che fanno sì che i due

progetti risultino diversi sia da un punto di vista progettuale che tecnologico.

Nel prototipo del MeetMeTonight i pitch vengono letti da controller MIDI e i parametri dei sintetizzatori sono modificabili attraverso interfaccia grafica. Le diverse tecniche di sintesi

vengono scelte attraverso QR-code letti con la webcam, ma la generazione del suono

!4

CAPITOLO 2. STATO DELL’ARTE

avviene in modo totalmente diverso dal Prototipo. Infatti viene utilizzata una

programmazione ‘lato server’ anziché ‘lato client’, poiché la generazione dei segnali audio digitali viene affidata al programma Csound che si occupa della sintesi digitale diretta del

suono, in esecuzione sul server. Questa è la più grande differenza con il Prototipo: la

generazione di suoni non richiede l’esecuzione di altre applicazioni ma avviene

direttamente sul browser dell’utente grazie alla Web Audio API di JavaScript, nelle

modalità che verranno discusse in seguito. Un altro esempio di applicativo di cui è interessante parlare si chiama WebSynths (a

cui si accede attraverso l’URL www.websynths.com), in via di sviluppo per mano di Mitch

Wells. È molto interessante poiché oltre che avere come scopo la creazione di sintetizzatori

online, utilizza sia le Web Audio API sia le Web MIDI API. Ovviamente non vi è lo scopo

didattico del Prototipo e i sintetizzatori non sono divisi in base al modello di sintesi che ne sta alla base. L’obiettivo di WebSynths è quello di creare un sintetizzatore modulare in

grado di comportarsi come un VSTi o un plugin AU [IX], che sono diventati molto comuni

nell’ambito della musica elettronica. A questo scopo vengono usati tre oscillatori (ognuno

dei quali modificabile nella forma d’onda, nel panning, nell’inviluppo di ampiezza e nello

spettro con un equalizzatore parametrico), vi sono due filtri con otto modi ciascuno, il controllo di BPM, la possibilità di creare e salvare patch e altre funzionalità ancora.

Di applicazioni di questo tipo, che sviluppano sintetizzatori modulari online, ce ne

sono molte in Internet anche se con funzionalità e funzionamento differenti. Molte

richiamano i sintetizzatori modulari analogici dove i moduli venivano connessi via cavo

(come WebModular), altre usano interfacce molto più semplici invocando lo storico Commodore 64 (WebSID), altre ancora ricreano delle drum machine (OneMotion o

QwertyBeats).

2.1 Applicativi con Web Audio API e Web MIDI API

È molto importante citare il sito Web Audio Weekly tenuto da Chris Lowis, ricercatore presso BBC R&D, che ha partecipato all’Audio Working Group della W3C (World Wide

Web Consortium), gruppo creato per la definizione delle specifiche audio nel Web. Nel sito

ha accumulato fin dal 2013 novità, demo e storie relative alle Web Audio API e Web MIDI

!5

CAPITOLO 2. STATO DELL’ARTE

API [XII]. Molte delle applicazioni che vedremo in seguito e che porteremo da esempio per

mostrare lo stato dell’arte nell’ambito di Web Audio API e Web MIDI API, sono contenute nella lista di Chris Lowis. Questa è estremamente estesa ed è ricca di applicativi Web

sviluppati con Web Audio API o con Web MIDI API, tutti molto diversi tra loro e con

finalità di ogni tipo.

Inoltre Lowis si occupa di aggiornare settimanalmente il sito inserendo oltre agli applicativi,

anche le più importanti proposte, cambiamenti o aggiornamenti che vengono fatti nel mondo dell’audio Web. All’interno ci sono centinaia di nomi, cosa che dimostra che il

mondo delle Web Audio API e delle MIDI API continua ad essere in espansione, e

l’approccio sperimentale che ha avuto finora dimostra che queste due tecnologie possono

portare alla creazione di applicativi Web estremamente avanzati, complessi e performanti.

Nella seguente lista estratta dal sito webaudio.github.it, vengono riportate alcune demo che utilizzano Web Audio API e Web MIDI API (molte delle quali si trovano anche

sul sito Web Audio Weekly di Lowis). Si tratta di applicativi Web che citeremo per capire il

livello e le molteplici funzionalità che queste librerie (in particolare Web Audio API)

possono apportare nel mondo Web. Di primario interesse sono le applicazioni che possono

essere utili in tempo reale ad un musicista. Vediamo infatti che si possono creare accordatori come Pitch Detector oppure generare effetti per chitarra e per voce, come ad 1

esempio pedals.io e Vocoder . Si trova l’applicativo MixBolt , pensato per i dj per mixare 2 3 4

le canzoni, o anche l’applicativo SoundSlice , pensato per la visualizzazione di spartiti e 5

tablature sincronizzati con file multimediali, per uno scorrimento temporizzato

dell’indicatore e l’accensione delle note. Interessante notare che questo applicativo sviluppa il concetto di rappresentazione multilivello della musica, richiamando dunque

anche lo standard IEEE 1599.

https://webaudiodemos.appspot.com/pitchdetect/index.html1

https://pedals.io2

https://webaudiodemos.appspot.com/Vocoder/index.html3

http://mixbolt.com4

https://www.soundslice.com/slices/XCycc5

!6

CAPITOLO 2. STATO DELL’ARTE

Un applicativo interessante è WebAudioComposer : richiama infatti l’ambiente di 6

sviluppo grafico MAX consentendo di visualizzare graficamente il grafo audio della Web Audio API e di inserire e modificare i nodi e i parametri.

Se si vuole comprendere il grado di interattività della Web Audio API un buon esempio è

l’applicativo Plink del Dinahmoe Lab. Di fatto funziona come un videogioco multi player, 7

in cui i vari gamer sentono un canzone riprodotta in sottofondo ma possono posizionarsi

su una delle bande all’interno dell’ambiente di gioco e suonare a loro volta cliccando con il mouse, partecipando ad una jam session insieme a persone distribuite geograficamente in

tutto il mondo.

Si analizzerà ora un esempio di utilizzo di Web Audio API che si distacca dall’ambito

propriamente musicale. È il caso dell’applicazione Call Codes per mobile sviluppata

dall’agenzia Innate Agency, che ha l’obiettivo di fornire agli utenti i codici telefonici nazionali per aiutarli nelle chiamate internazionali [XI]. L’applicazione dà la possibilità di

inserire i numeri attraverso due metodi di inserimento ereditati dai vecchi apparati

telefonici: sia il disco combinatorio dei telefoni fissi analogici che le tastiere dei primi

cellulari. Viene utilizzata Web Audio API per fare in modo che quando i numeri vengono

inseriti venga riprodotto il suono reale della tastiera o del disco combinatorio. Questo mostra come la API JavaScript possa aumentare il potenziale degli applicativi Web, come

si legge nel titolo dell’articolo [XI].

Sempre nella lista di demo proposta da [X], si trovano due applicativi che usano

entrambi Web MIDI API per la comunicazione con dispositivi MIDI al fine di leggere

l’input di un controller MIDI. Uno dei due è una drum machine chiamata Shiny Happy MIDI Drum Machine , l’altra invece è pensata per la riproduzione di file standard MIDI e 8

si chiama Standard MIDI File Player .9

https://tai2.net/docs/webaudiocomposer6

http://labs.dinahmoe.com/plink7

http://webaudiodemos.appspot.com/MIDIDrums/index.html8

https://ryoyakawai.github.io/smfplayer/9

!7

CAPITOLO 2. STATO DELL’ARTE

In questo capitolo si è data una visione generale del contesto tecnologico di ricerca e di

sviluppo in cui si inserisce il Prototipo per la sintesi del suono con Web Audio API. Nei prossimi capitoli si entrerà nel merito del progetto, osservando le varie tecnologie

coinvolte, le scelte progettuali che ne stanno alla base e saranno approfondite la Web

Audio API e la Web MIDI API, utilizzate per lo sviluppo dell’applicativo.

!8

Capitolo 3Tecnologie utilizzate

3.1. Internet e il World Wide Web

Internet e in particolare il World Wide Web sono i primi concetti che necessitano di un approfondimento per comprendere in che modo funziona un sito Web, a prescindere dalle

sue funzionalità e dagli utilizzi per il quale viene creato.

Internet (con la “i” maiuscola) deve essere inteso come un sistema che interconnette

miliardi di computer in tutto il globo, attraverso delle reti, cablate o wireless che siano.

Non si deve immaginare come una singola ed enorme rete, ma come una connessione di tanti reti più piccole che connettono dispositivi ad un livello locale [1].

Internet dunque è una rete di reti, una internetwork, dinamica ed espandibile che consente

a dispositivi anche molto distanti tra loro di entrare in comunicazione e scambiarsi delle

informazioni. Ogni computer connesso è in grado di inviare dei dati ad un altro, così come

è in grado di riceverli ed elaborarli. Il contenuto di questi dati e le modalità con le quali avviene la comunicazione sono molteplici a seconda delle differenti esigenze comunicative

che possono esserci in rete. Esistono quindi diversi paradigmi per connettere i dispositivi

attraverso Internet, in funzione dei quali sono stati definiti i diversi protocolli che regolano

la comunicazione e il trasferimento delle informazioni in rete.

In questo contesto venne creato il World Wide Web, più comunemente conosciuto come WWW o semplicemente Web. L’idea che ne sta alla base venne proposta nel 1989 da

Tim Berners-Lee al CERN. Egli proponeva un sistema che consentisse a vari ricercatori in

!9

CAPITOLO 3. TECNOLOGIE UTILIZZATE

tutto il mondo di accedere, rapidamente e dal luogo in cui si trovavano, alle pubblicazioni

scientifiche. Il Web è diventato così un’enorme collezione di documenti, le pagine Web, collegate tra loro [1].

Il tipo di comunicazione che viene utilizzato nel World Wide Web, è basato sul paradigma

client/server, in cui i servizi sono tutti forniti da computer chiamati server, mentre i client ne

usufruiscono attraverso programmi chiamati browser. I server sono dei sistemi sempre in

esecuzione, in attesa che un client gli faccia una richiesta. Un client ha quindi la possibilità in ogni momento di fare la richiesta per ricevere una pagina Web e visualizzarla attraverso

il suo browser.

È importante sapere che i documenti Web possono essere raggruppati in tre

categorie: statici, dinamici e attivi.

I documenti statici hanno un contenuto predeterminato, creato e caricato su un server da uno sviluppatore. Un client sarà in grado solo di ricevere una copia di tale documento e

visualizzarla così come è stata creata. Questi documenti vengono creati utilizzando

linguaggi di programmazione per il Web quali HTML (HyperText Markup Language), XSL

(Extensible Style Language) e XHTML (Extensible HyperText Markup Language).

I documenti dinamici sono invece delle pagine il cui contenuto viene creato dinamicamente (in tutto o in parte) dal server nel momento in cui riceve una richiesta da

parte del client. Per fare questo sul server vengono eseguiti dei programmi o degli script in

base alla richiesta inviata dal client, dunque il contenuto della pagina può essere diverso in

funzione dell’esecuzione di questi programmi. Un linguaggio utilizzato a questo scopo è

PHP. Infine ci sono i documenti attivi, molto importanti all’interno di questa discussione in

quanto sono parte centrale del progetto sviluppato. Questi consentono a un utente di

Internet, oltre che di ricevere delle pagine con un contenuto fisso, di eseguire programmi o

script in esse incorporati, direttamente sul suo computer. Parte del contenuto viene quindi

generato “lato client”, ossia direttamente sul browser che esegue i programmi e gli script che gli sono stati inviati dal server attraverso la pagina Web. Le tecnologie più utilizzate a

questo scopo sono le applet Java e il linguaggio di scripting JavaScript [1].

!10

CAPITOLO 3. TECNOLOGIE UTILIZZATE

3.2. Web Programming: HTML e JavaScript

Per pubblicare un documento all’interno del sistema del World Wide Web, al CERN è stato

ideato nei primi anni ’90 il linguaggio conosciuto come HTML (HyperText Markup Language). Non è un linguaggio di programmazione, bensì di pubblicazione, che contiene

delle informazioni che possono essere lette ed interpretate attraverso un browser [2]. È un

linguaggio di markup, in cui gli elementi vengono definiti e strutturati attraverso dei tag,

racchiusi tra parentesi angolari. Attraverso questi tag viene dunque definita la struttura di

un documento, cioè si definiscono gli elementi che dovranno apparire sullo schermo e come essi debbano essere disposti [I]. Una pagina HTML è generalmente composta da tre

elementi principali che contengono tutti gli altri: il primo è <!doctype> che definisce la

versione dell’HTML utilizzata; l’elemento <head> contiene invece informazioni che non

sono direttamente visualizzate ma che sono fondamentali per il corretto funzionamento

della pagina (ad esempio il titolo della pagina, i metadati relativi alla codifica o il riferimento ai fogli di stile per la modifica dell’aspetto grafico); infine l’elemento <body>

contiene tutto il resto dei tag HTML che saranno effettivamente visualizzati su schermo.

HTML è quindi un linguaggio statico, usato per creare pagine Web che contengano

degli elementi (grafici, testuali, ipertestuali o multimediali che siano) e che possano essere

interpretate e visualizzate sul maggior numero possibile di browser. È molto importante considerare che nel tempo HTML si è evoluto consentendo di realizzare applicativi Web

molto complessi e con numerose funzionalità. Questo è possibile perché HTML viene

integrato con tecnologie che apportano funzionalità differenti e dinamiche che ne

estendono la potenzialità e garantiscono una suddivisione dei compiti. Ad esempio CSS

(Cascading Style Sheet), definisce una serie di regole che permettono di definire l’aspetto (lo stile) che devono assumere gli elementi della pagina. Dimensioni, colori, animazioni,

ogni caratteristica visuale può essere manipolata [I].

Ancor più importante all’interno del Prototipo per la sintesi del suono con Web Audio API,

risulta essere JavaScript, che ha avuto un ruolo focale nello sviluppo dell’applicativo.

JavaScript è un linguaggio di programmazione (o scripting), orientato agli oggetti e agli eventi, per l’esecuzione lato client di script inseriti nelle pagine HTML o file di

estensione .js ad esse associati. Consente di manipolare tutti gli aspetti di una pagina: lo

stile, i contenuti, ma soprattutto l’interazione con l’utente. Consente di creare la logica

!11

CAPITOLO 3. TECNOLOGIE UTILIZZATE

dell’interfaccia utente e di sfruttare le API messe a disposizione dal browser: dalla gestione

del mouse alla manipolazione delle immagini, dalle richieste di dati dinamiche (in modalità Ajax) alla gestione di dati in locale (grazie ai LocalStorage) [I]. È un linguaggio di

alto livello, caratterizzato da un alto grado di astrazione che lo rende facilmente

comprensibile, ma il browser deve possedere un interprete per poterlo eseguire [3].

Nonostante questo ha consentito l’introduzione, nel mondo del Web, di applicazioni

estremamente dinamiche e interattive, che hanno reso la fruizione dei siti un’esperienza attiva per gli utenti.

Grazie alle numerose API messe a disposizione dai browser, JavaScript risulta essere un

linguaggio estremamente performante. Nel nostro caso di studio, le due API

maggiormente utilizzate sono state Web Audio API (per la gestione dell’audio sul browser;

per la creazione, manipolazione e riproduzione di suoni; per la lettura e la decodifica di file audio inseriti dall’utente) e Web MIDI API (per la gestione dell’input e dell’output

MIDI del browser e per la comunicazione con un dispositivo MIDI). La combinazione

delle due API consente ad un utente che si connette al sito di suonare in tempo reale un

sintetizzatore digitale connettendo al computer una tastiera o un controller MIDI.

3.3. La tecnologia MIDI

Lo standard MIDI è un aspetto estremamente importante quando si parla di musica

elettronica, sintetizzatori e di rappresentazione dell’informazione musicale digitale in

generale. È una tecnologia che è stata importantissima perché ha rivoluzionato tutta

l’industria musicale, cambiando sia i processi di produzione che il modo di suonare di molti musicisti. Ha avuto un impatto che può essere paragonato a quello che ebbe

l’elettrificazione delle chitarre qualche decennio prima [II].

Questa tecnologia nacque come prototipo nel 1980, col nome di USI (Universal Synthesizer

Interface), grazie al lavoro di Dave Smith e Chet Wood, che avevano l’obiettivo di creare

una tecnologia che potesse standardizzare i segnali di controllo tra diversi strumenti elettronici. I due progettisti sottoposero il prototipo al giudizio della AES (Audio

Engineering Society) nel 1981 e venne approvato col nome MIDI (Musical Instrument

!12

CAPITOLO 3. TECNOLOGIE UTILIZZATE

Digital Interface) nel 1983, con la partecipazione dei maggiori produttori di strumenti

musicali elettronici del mondo, divenendo uno standard a tutti gli effetti [4].Lo standard MIDI può essere definito come un insieme di specifiche hardware e

software che rende possibile lo scambio di informazioni (note, modifiche di

configurazione, controllo dell’espressione, ecc.) tra strumenti musicali elettronici o altri

dispositivi come computer, sequencer, centraline di controllo luci, mixer, ecc.

In tal senso non va inteso come un linguaggio musicale e non bisogna pensare che l’informazione trasmessa sia informazione audio: il protocollo MIDI veicola l’informazione

relativa alla performance, alla esecuzione, di un musicista su una tastiera o qualsiasi

controller MIDI. Si può fare un paragone con la differenza che c’è tra una registrazione

(che cattura la musica stessa) ed uno spartito: il secondo non ha un valore musicale di per

sé, solo stabilisce che cosa e come un musicista deve suonare per creare la musica da esso rappresentata. Il MIDI si comporta allo stesso modo, rappresentando gli step elettronici

necessari per produrre un suono [4].

Questo protocollo definisce delle specifiche in due aree distinte: l’hardware e il

software. Per ciò che riguarda l’hardware, stabilisce quali sono e che caratteristiche devono

avere le porte dei dispositivi per la connessione MIDI, e in che modo devono essere fatti i cavi; per ciò che riguarda il software definisce quale deve essere il formato dei dati

trasmessi e come vanno codificati i messaggi MIDI.

Le porte MIDI sono di tre tipi diversi, tutte costituite da un jack femmina per ricevere i

cinque pin del cavo MIDI. Si occupano di convertire l’informazione digitale in segnale che

rappresenta il cambio di voltaggio, o viceversa. Una porta di tipo OUT converte i messaggi MIDI in segnali elettrici per trasmetterli ad un altro dispositivo che deve dunque

possedere una porta di tipo IN, che invece riceve segnale e lo trasforma in dati MIDI

digitali. Il terzo tipo è la porta THRU che copia qualsiasi segnale in ingresso e lo

ritrasmette istantaneamente attraverso il jack THRU.

Per ciò che riguarda il software, il protocollo MIDI definisce quelli che vengono chiamati messaggi MIDI. Questi sono delle sequenze numeriche che servono per descrivere tutti gli

eventi che possono verificarsi nel panorama MIDI: dall’accensione di una nota al

movimento di un pedale, dal cambiamento delle impostazioni del controller alla velocity

di un tasto. Ogni dispositivo deve contenere dunque un microprocessore che sia in grado

di interpretare e attuare queste stringhe binarie [4].

!13

CAPITOLO 3. TECNOLOGIE UTILIZZATE

I messaggi MIDI fondamentali sono quelli di Note On e Note Off, che identificano gli

eventi di inizio e fine di un suono con una determinata frequenza. Questi contengono in sé l’informazione di pitch e di volume, ma possono essere aggiunti dei messaggi separati che

descrivano elementi dell’espressività musicale umana, come il vibrato o il pitch bend.

Di fatto tutti i messaggi MIDI sono divisi in due grandi tipologie: la prima contiene quelli

che sono chiamati Channel Message (poiché sono destinati ad uno dei sedici canali MIDI),

che a loro volta sono divisi in Channel Voice Message (che controllano le voci dello strumento, ovvero che cosa deve essere suonato) e Channel Mode Message (che

controllano il modo in cui lo strumento deve interpretare i Channel Voice Message); la

seconda tipologia è quella dei System Message usati per la gestione dei dispositivi, ad

esempio per la loro sincronizzazione.

Tutti questi messaggi possono essere immagazzinati e riprodotti in sequenza da un dispositivo chiamato sequencer, che si occupa anche della sincronizzazione dei messaggi

nel tempo.

Per una questione di completezza rispetto a ciò che riguarda il mondo dei

sintetizzatori, si è scelto di integrare il Prototipo per la sintesi del suono con Web Audio API

con la Web MIDI API, affinché fosse possibile ricevere l’input da un controller MIDI. L’intenzione primaria è stata quella di leggere il pitch dei suoni da generare attraverso il

controller, dunque gli unici eventi MIDI che vengono interpretati e gestiti sono quelli di

NoteOn e NoteOff, ma il progetto potrebbe essere espanso per gestire in modo completo

diversi tipi di eventi, nei limiti della API.

3.4. Audio digitale

Questo paragrafo è stato inserito per dare uno sguardo generale sul mondo dell’audio

digitale, dato che l’oggetto centrale del progetto è quello della sintesi del suono e in

particolare della sintesi digitale. Abbiamo già visto una tecnologia (quella MIDI) basata

sulla codifica digitale delle informazioni, dunque risulta fondamentale approfondire

questo argomento. L’audio digitale ha segnato un profondo cambiamento nell’ambito musicale sotto ogni

aspetto ed è diventato predominante rispetto alle tecnologie analogiche che sono state

utilizzate per diversi decenni nel corso del ‘900.

!14

CAPITOLO 3. TECNOLOGIE UTILIZZATE

Nel mondo analogico l’informazione viene rappresentata attraverso un segnale continuo

che rappresenta il continuo cambiamento nel tempo di una grandezza fisica. Ad esempio la variazione di pressione dell’aria che determina il suono, può essere convertita in una

variazione di tensione elettrica, generando così un segnale elettrico del tutto analogo

all’onda sonora [5]. Nell’audio digitale, invece, un suono non risulta essere continuo né nel

tempo né nell’ampiezza, ma viene approssimato in una sequenza di numeri finiti che

rappresentano le ampiezze istantanee dell’onda rilevate ad intervalli regolari di tempo. Quanto più sono piccoli questi intervalli e quanti più numeri possono essere assegnati alle

ampiezze istantanee dell’onda, quanto più sarà fedele il segnale digitale all’analogico [4].

I due procedimenti che rendono possibile il passaggio da analogico a digitale sono,

consecutivamente, il campionamento e la quantizzazione, che stanno alla base del sistema

ADC (Analog to Digital Converter). Il campionamento effettua la discretizzazione del segnale nel tempo, rilevando ad

intervalli di tempo regolari i campioni, il cui valore è uguale al valore dell’onda in

quell’istante. La durata dell’intervallo di tempo a cui si campiona, viene chiamata intervallo

di campionamento e il suo inverso è la frequenza di campionamento (o sample rate) che indica il

numero di campioni per secondo [5]. Il risultato del campionamento genera un segnale con una forma d’onda a gradini che può

essere assimilata a quella nella seguente figura.

Fig. 3.4-1. Onda sinusoidale e onda a gradini generata dal suo campionamento

In funzione della frequenza di campionamento è stato definito il Teorema di Nyquist, che

stabilisce le regole per cui si può fare un campionamento senza introdurre distorsione o

!15

CAPITOLO 3. TECNOLOGIE UTILIZZATE

perdere informazione. Il teorema asserisce che la frequenza di campionamento deve essere

maggiore o uguale al doppio della frequenza massima del segnale da campionare [4]. Se non si rispetta questa regola si introduce un effetto di aliasing che modifica lo spettro del

segnale, creando distorsione con la comparsa di frequenze gravi che prima non esistevano.

Vediamo infatti che i sistemi digitali che lavorano con formati audio PCM (Pulse-Code

Modulation), come il Wav, adottano un sample rate uguale a 44.1 kHz, 48 kHz, 96 kHz o

altri, maggiori della massima frequenza percepibile dall’apparato uditivo umano (intorno ai 20 kHz).

La quantizzazione è invece un procedimento di discretizzazione dell’ampiezza. I

segnali analogici, in questo caso consideriamo quelli a banda d’ampiezza limitata (per

esempio un segnale sinusoidale), hanno ampiezza continua, ossia rappresentabile

attraverso numeri reali. Per un computer risulta impossibile rappresentare valori reali, è dunque necessario convertirli in numeri interi.

L’intera banda d’ampiezza viene divisa in intervalli (la cui ampiezza può variare a seconda

del tipo di quantizzatore che si utilizza, nel caso del quantizzatore lineare uniforme sono

tutti uguali). Ad ogni intervallo viene fatto corrispondere un numero binario, che

rappresenta il valore centrale dell’intervallo. A questo punto, tutti i valori reali di un onda che si trovano all’interno di un intervallo, vengono quantizzati con lo stesso numero

binario finito che corrisponde a tale intervallo. In generale più questa stringa binaria è

lunga, più accurata sarà la codifica dell’ampiezza, poiché consente di rappresentare più

valori di ampiezza riducendo l’errore di quantizzazione (dovuto all’approssimazione che

si fa passando da un numero reale ad uno intero) e aumentando il range dinamico rappresentabile [5]. Il rapporto segnale/rumore sarà quindi maggiore quanto più è lunga la

parola di quantizzazione, aumentando la qualità del segnale prodotto.

In generale si è visto che si ottengono risultati soddisfacenti con numeri binari di almeno

16 bit [5] (che ammettono 65536 valori compresi tra -32768 e +32767) ma si può

quantizzare anche a 24 bit, 32 bit o 96 bit, cosa che però porta ad un incremento molto significativo del bitrate.

Il procedimento inverso della conversione analogico-digitale è la conversione

digitale-analogico resa possibile dal sistema DAC (Digital to Analog Converter). Questa

conversione risulta fondamentale perché consente di poter ascoltare un segnale sonoro

digitale. Tuttavia quando un segnale si trova in formato digitale, può essere memorizzato

!16

CAPITOLO 3. TECNOLOGIE UTILIZZATE

ed elaborato attraverso i computer in una maniera che risulta essere molto più agevole

rispetto a quando si lavora in analogico.Si può quindi parlare di sintesi digitale del suono. Un computer è in grado di

generare dei segnali digitali direttamente all’interno del suo processore, basandosi sui

calcoli matematici che stanno alla base della sintesi del suono e sfruttando i principi del

campionamento e della quantizzazione visti sopra. Un processore può creare onde

sinusoidali in formato digitale, sommarle, cambiarne la frequenza attraverso l’eliminazione o l’interpolazione di campioni, modificarne l’ampiezza o la fase, gestirne la

stereofonia, può creare filtri digitali con cui modificarle e molto altro.

Il suono può dunque essere creato all’interno di una macchina e poi convertito in

analogico ed essere riprodotto e ascoltato. Questo è il principio della sintesi digitale del

suono su cui si basa il Prototipo per la sintesi del suono con Web Audio API.

!17

Capitolo 4Applicazione Web sviluppata

4.1. Descrizione del Prototipo per la sintesi del suono con Web Audio API

Il Prototipo per la sintesi del suono con Web Audio API è un applicativo Web che ha come

obiettivo quello di supportare diverse tecniche di sintesi del suono. Oltre all’aspetto

meramente tecnico ed informatico che riguarda l’audio (e dunque la sua implementazione

attraverso la Web Audio API di JavaScript) si è data importanza al come far suonare i vari

tipi di sintesi e come gestirne i diversi parametri, visualizzando graficamente una tastiera di pianoforte e degli slider di controllo, implementando la lettura da tastiera del computer

e più in particolare quella da un controller MIDI. Non meno rilevante è stato l’aspetto

grafico che, come in ogni applicativo Web, ne determina la chiarezza rendendo accessibili

le diverse funzionalità dell’applicazione.

Le tecniche di sintesi del suono sviluppate sono state la sintesi additiva, la sintesi per modulazione di ampiezza (AM), la sintesi ad anello (RM), la sintesi per modulazione

di frequenza (FM), la sintesi sottrattiva e la sintesi per modelli fisici della corda pizzicata,

secondo l’algoritmo di Karplus & Strong. Questi modelli di sintesi del suono e

l’applicativo Web in generale, sono stati sviluppati utilizzando il linguaggio di

programmazione lato client JavaScript e la relativa Web Audio API, il linguaggio di markup HTML e il linguaggio CSS per la formattazione. Stiamo dunque parlando di un

sito attivo, dove lo script JavaScript che si occupa della sintesi del suono e la gestione degli

eventi è integrato nel documento HTML e viene eseguito “lato client”. È interessante

notare che tutti i suoni prodotti non sono generati e inviati dal server, ma sono generati

!18

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

direttamente sul computer dell’utente, conferendo al sito una dinamicità e interattività

molto elevata. Come si è visto, l’attenzione è stata posta sullo sviluppo della sintesi sonora che,

nonostante JavaScript risulti essere un linguaggio di alto livello abbastanza intuitivo, ha

richiesto molto tempo sia in fase di analisi e studio delle API che in fase di sviluppo. Oltre

a questo, però, è stato necessario sviluppare numerosi altri aspetti perché il sintetizzatore

potesse funzionare. Tra questi c’è la lettura di eventi del mouse (tra i quali On Click, On Mouse Down, On Mouse Over e On Mouse Out) che consentono di passare da un modello

di sintesi ad un altro attraverso una barra di navigazione, di modificare i vari parametri

utili al modello di sintesi corrente attraverso degli slider o altri pulsanti, cliccare le note

della tastiera di pianoforte inserita come elemento grafico della pagina per far suonare il

sintetizzatore. Un altro aspetto è anche la gestione dei key event, ossia eventi relativi alla tastiera del computer, che è stata sviluppata per avere un modo di leggere i pitch

alternativo a quello del click con il mouse.

Uno degli obiettivi era quello di sviluppare l’applicativo con approccio Web

Responsive. Questo significa far sì che gli elementi grafici della pagina (o i contenuti stessi)

si adattino e cambino in funzione delle dimensioni dello schermo del dispositivo su cui sono caricate. In questo senso nel Prototipo per la sintesi del suono con Web Audio API si è

lavorato in due direzioni principali: la prima è quella di fissare la grandezza di molti

elementi della pagina utilizzando delle percentuali (la view width per la larghezza e la view

heigth per l’altezza) calcolate direttamente sulle dimensioni dello schermo grazie al

linguaggio CSS (tenendo in considerazione anche alcuni aspetti della tecnica di grid per la disposizione degli elementi); la seconda direzione, sicuramente più efficace, è stata quella

di utilizzare le media query. Grazie a queste è possibile determinare a prescindere la

formattazione specifica per vari tipi di dispositivi. Se un device soddisfa dunque le

condizioni poste da una media query, visualizzerà la pagina con la formattazione che è stata

stabilita ad hoc per quel particolare tipo di dispositivo. In questo modo il sito si adatta a schermi piccoli come quelli di uno Smart Phone, a schermi medio grandi come quelli di

laptop tra i 13 e i 15 pollici o agli schermi dei Tablet, gestendone sia il posizionamento

verticale che quello orizzontale.

Per una questione di completezza rispetto a ciò che riguarda il mondo dei

sintetizzatori, si è scelto di integrare il progetto con la Web MIDI API affinché fosse

!19

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

possibile ricevere l’input da un controller MIDI. L’intenzione primaria è stata quella di

leggere il pitch dei suoni da generare attraverso il controller, dunque gli unici eventi MIDI che vengono interpretati e gestiti sono quelli di NoteOn e NoteOff, ma il progetto potrebbe

essere espanso per gestire in modo completo diversi eventi MIDI, nei limiti della API.

Nonostante in questo momento la Web MIDI API sia supportata solo dal browser Google

Chrome, ha apportato al prototipo un valore aggiunto, che lo ha spostato dall’essere un

applicativo meramente esplicativo sulla sintesi digitale del suono, all’essere un applicativo che si comporta come un vero sintetizzatore: non solo genera il suono attraverso diverse

tecniche di sintesi sonora, ma può essere suonato in tempo reale da un qualsiasi utente che

connetta una tastiera o un controller MIDI al suo dispositivo.

4.2. Funzionalità, utilizzi e scelte progettuali

È importante vedere ora le principali scelte progettuali. Lo sviluppo del progetto infatti è

avvenuto sviluppando una per volta le diverse sintesi del suono viste nel paragrafo

precedente. Per ognuna è stata necessaria l’implementazione del modello di sintesi

attraverso la Web Audio API di JavaScript, per cui è stato creato un file di estensione .js ad

hoc, incorporato nel codice HTML utilizzando gli elementi <script>. Di volta in volta sono stati aggiunti al file HTML gli elementi che risultavano essere utili per il tipo di sintesi in

questione e sono state aggiunte le funzioni JavaScript necessarie perché tale tipo di sintesi

venisse inizializzato correttamente.

Per passare da un tipo di sintesi ad un altro si è scelto di utilizzare una barra di

navigazione. Quando uno degli elementi della barra viene cliccato, viene eseguita la funzione changeSynth(type) contenuta nel file applicazione.js. Questo file infatti si occupa di

passare da un tipo di sintesi ad un altro, modificando l’aspetto grafico della pagina

(cambiando il contenuto di alcuni elementi o modificando la visibilità di altri) e

inizializzando il nuovo contesto audio relativo alla sintesi sonora selezionata.

function changeSynth(type){ switch (type) { case 'additiva': impostaSintesiAdditiva(); break;

!20

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

case 'fm': impostaSintesiFM(); break; case 'am': impostaSintesiAM(); break; case 'rm': impostaSintesiAM(); break; case 'sottrattiva': impostaSintesiSottrattiva(); break; case 'string': impostaSintesiKarplusStrong(); break; }; };

Questa funzione è di fatto uno Switch che consente di selezionare le varie funzioni di

inizializzazione relative ai vari type di sintesi, contenute anch’esse nel file applicazione.js.

La visualizzazione del sito sullo schermo cambia in funzione della tecnica di sintesi

sonora seleziona, ma esiste comunque un design di base per cui la pagina è divisa in tre blocchi fissi la cui posizione non cambia mai, che dona omogeneità ai contenuti e ai vari

sintetizzatori. Questi tre blocchi sono un header (e la barra di navigazione), un corpo centrale

e un footer.

In alto vi è sempre l’header contenente il titolo della sintesi corrente, seguito dalla barra di

navigazione; si trova poi il corpo centrale diviso in tre bande: sulla sinistra viene mostrato un testo che spiega il tipo di sintesi del suono corrente, al centro vi è una banda che in

generale contiene i controller per modificare i parametri dei sintetizzatori e sulla destra un

rettangolo per la visualizzazione grafica di forme d’onda o diagrammi; in fondo alla

pagina vi è il footer in cui ci sono alcuni elementi che richiamano la composizione di una

tastiera elettronica: c’è sempre il controllo del volume master di uscita, viene visualizzata la frequenza fondamentale o della portante, si trova il pulsante Panic! per eliminare

drasticamente tutto il contesto audio in caso di emergenza e infine vi è la tastiera di

pianoforte che è possibile cliccare per far suonare il sintetizzatore. La tastiera (che viene

eliminata nel caso della sintesi sottrattiva in quanto smette di essere rilevante) è composta

da due ottave ma è possibile cambiarne l’ottava grazie ai due pulsanti Up e Down posti alla sua destra.

!21

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Si entrerà nel merito dello sviluppo dell’applicativo nei prossimi paragrafi, spiegando nel

dettaglio le API utilizzate e i modelli matematici che stanno alla base delle varie tecniche di sintesi del suono. Per fare questo verranno inseriti e spiegati frammenti del codice

sorgente del Prototipo per la sintesi del suono con Web Audio API.

4.3. Web Audio API

4.3.1. Il Web e l’audio

Sono stati fatti diversi tentativi per inserire e gestire l’audio nel Web. Uno fu quello di

utilizzare il tag <bgsound> HTML per riprodurre in background dei suoni su una pagina,

un’altro quello di utilizzare il tag <embed> implementato da Netscape, ma nessuno dei due venne mai standardizzato ed erano utilizzabili su pochissimi browser. Si provò anche ad

usare un plug-in prodotto da Flash per il playback, ma anche questo tentativo non risultò

essere funzionale per gli utenti.

Si è raggiunto un buon risultato con l’introduzione dell’elemento <audio> di HTML5,

riconosciuto e supportato da tutti i moderni browser. Se l’elemento <audio> può essere molto utile poiché non necessita di plug-in, presenta comunque molte limitazioni

soprattutto riguardo all’implementazione di applicativi interattivi [6].

Per superare questi limiti il primo tentativo fu quello della Audio Data API, progettata da

Mozilla Firefox, che partiva dall’elemento <audio> ma ne estendeva la API JavaScript con

funzionalità aggiuntive. Anche Audio Data API, però, non fu più adottata dopo la sua prima implementazione ed ora è deprecata in Firefox in favore della Web Audio API.

Web Audio API è un modello totalmente nuovo di interfaccia che si separa del tutto

dall’elemento <audio> di HTML5. È una API JavaScript di alto livello pensata per

processare e sintetizzare suoni negli applicativi Web. Sono state assimilate funzionalità del

moderno videogaming online e strumenti per processare, mixare o filtrare il suono, presi dalle applicazioni desktop per la produzione audio [III]. Il punto di forza della Web Audio

API è stato quello di introdurre nel Web l’audio interattivo, adatto anche alle applicazioni

dal comportamento non prevedibile, come i videogiochi, dove i suoni possono interagire

!22

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

con l’ambiente ed essere mixati in modo complesso, gestendo effetti attraverso i filtri e

gestendo il posizionamento dei suoni nello spazio.

4.3.2. L’Audio Context

La Web Audio API si basa sul concetto di audio context. L’audio context è un grafo orientato

di nodi audio che definisce in che modo si sviluppa il flusso audio, dalla sorgente al nodo destinazione [6]. Ogni nodo, che viene creato dal contesto, può avere degli input o degli

output e processa il segnale che gli viene dato in ingresso per poi ritrasmetterlo in uscita

(si noti che il SourceNode non ha input in quanto costituisce la sorgente sonora, mentre il

DestinationNode non ha output in quanto è l’ultimo nodo del grafo che può essere

immaginato, in modo astratto, come gli altoparlanti del computer) [III]. Ogni nodo è caratterizzato da una serie di parametri AudioParam che ne controllano il comportamento.

L’audio context si basa dunque sul modular routing: ogni nodo può essere connesso

arbitrariamente ad altri nodi di tipo diverso e/o, più in particolare, può essere connesso ai

parametri AudioParam che controllano il comportamento di altri differenti AudioNode [III].

Si possono quindi creare grafi anche molto complessi in cui diversi moduli, in sequenza o in parallelo, collaborano per la gestione e la manipolazione dell’intero aspetto audio di

un’applicazione. Nella seguente figura possiamo osservare un contesto audio complesso,

un grafo dove i blocchi costituiscono i nodi e le frecce la loro connessione: si può notare

che ogni nodo può avere multiple connessioni in input e/o in output [III].

!23

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Fig. 4.3 - 1. Esempio di audio context complesso basato su modular routing.

Le prime cose da fare per lavorare con la Web Audio API, sono la creazione e

l’inizializzazione del contesto audio. Nel seguente codice vediamo che il costruttore va

definito anche con il prefisso webkit affinché possa lavorare sui browser Chrome, Opera e Safari [IV]:

var context = new (window.AudioContext || window.webkitAudioContext)();

Dal momento che il contesto audio supporta grafi molto complessi, è sempre meglio

utilizzare un solo contesto audio per applicativo [6]. In questo progetto si è scelto di

chiudere e reinizializzare l’audio context quando si passa da un tipo di sintesi sonora ad un

altro, per una questione di chiarezza e per evitare di creare un grafo eccessivamente

grande. Vediamo la funzione JavaScript che inizializza il contesto audio per la sintesi additiva:

function avviaAddSynth(){ context.close(); context = new(window.AudioContext || window.webkitAudioContext)(); sound = []; sound.push(new Sound(context)); sound[0].initialize(); };

!24

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Una volta inizializzato il contesto si procede alla creazione dei nodi AudioNode, alla

definizione dei loro parametri AudioParam e alla loro connessione per creare il grafo. Per la creazione dei nodi esistono moltissimi metodi per ciascun tipo di nodo audio. Vediamo un

esempio di codice che esemplifica i tre passaggi citati sopra: initializeAM(pitch){

this.masterGain=this.context.createGain(); this.gainNodeMod=this.context.createGain(); this.gainNodeCar=this.context.createGain(); this.carrier=this.context.createOscillator(); this.modulante=this.context.createOscillator();

this.carrier.type=‘sawtooth’; this.modulante.frequency.value=document.getElementById('sliderV2').value; this.carrier.frequency.value=document.getElementById('sliderF').value; this.modulante.connect(this.gainNodeMod); this.gainNodeMod.connect(this.gainNodeCar.gain); this.carrier.connect(this.gainNodeCar); this.gainNodeCar.connect(this.masterGain); this.masterGain.connect(this.context.destination); };

Nell’esempio viene creato il sintetizzatore per la modulazione di ampiezza. Si osserva che

vengono creati tre nodi di tipo Gain (tra cui quello chiamato masterGain che viene connesso alla destinazione) e due Oscillator (portante e modulante). Per l’oscillatore this.carrier viene

impostato il parametro type che ne definisce la forma d’onda (dente di sega), mentre per

entrambi gli oscillatori si definisce la frequenza leggendo da due <input type=“slider”>

HTML. Entrambi gli oscillatori vengono connessi con il metodo connect() ai due nodi gain

(this.gainNodeMod e this.gainNodeCar relativi a modulante e portante). Il gain della portante viene connesso al masterGain e dunque al nodo destinazione, ma il gain della modulante

viene connesso al parametro gain del GainNode della portante, generando di fatto la

modulazione:

this.gainNodeMod.connect(this.gainNodeCar.gain);

4.3.3 Le sorgenti audio e la riproduzione

Una volta visto come inizializzare il contesto e come creare il grafo audio necessario per

l’applicativo che si desidera realizzare, per generare il suono si procede “azionando” i nodi sorgente che sono stati creati. Proseguendo con l’esempio appena fatto:

!25

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

playSynthAM(){ this.modulante.start(); this.carrier.start(); };

stopSynthAM(){ this.gainNodeMod.gain.value=0; this.modulante.stop(this.context.currentTime+0.01); this.carrier.stop(this.context.currentTime+0.01); }

Con i metodi start() e stop() siamo in grado di riprodurre e fermare qualsiasi nodo

sorgente. In questo caso abbiamo usato come sorgente un AudioNode di tipo oscillatore ma i nodi sorgente possono essere di tipo differente. Ad esempio si può utilizzare il nodo di

tipo BufferSource che è stato pensato per la creazione di buffer riproducibili. Questo buffer

può essere caricato con file provenienti da diverse sorgenti: o file che vengono dal server

richiesti con XMLhttpRequest o file inseriti dal client attraverso il tag <input> di tipo file,

come nel nostro caso:

function leggiAudioFIle(input){ var audioFile=input; if(audioFile){ var reader=new FileReader();

reader.onload = function(){

var arrayBuffer = reader.result; context.decodeAudioData(arrayBuffer, function decodedDone(decoded) { song = decoded; console.log("typedArray:"); console.log(song); },

function(e){ alert("Errore nel decodificare il file.\n SELEZIONA UN FILE AUDIO") }); }; reader.readAsArrayBuffer(audioFile); };

Web Audio API dà inoltre la possibilità di impostare come sorgenti audio elementi audio o

video HTML usando l’interfaccia MediaElementAudioSourceNode, un microfono direttamente connesso al computer o un dispositivo line-in con

MediaStreamAudioSourceNode.

!26

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Gli audio node di Web Audio API sono molteplici e con funzioni molto diverse tra

loro. Abbiamo visto più nello specifico i nodi che costituiscono sorgente audio e che cos’è l’audio destination, ma sono molti (e con differenti funzionalità) i nodi intermedi per

processare il suono all’interno del grafo. È quindi funzionale citare alcuni di questi nodi

che sono stati fondamentali per la realizzazione dell’applicativo Prototipo per la sintesi del

suono con Web Audio API.

4.3.4 AudioNode e AudioParam utilizzati

Il primo nodo di cui parleremo è il GainNode, che ha un ruolo fondamentale nella

creazione dei mixer [III]. Serve per determinare l’ampiezza di un suono e per modificarla dinamicamente. Di fatto è un moltiplicatore scalare dell’ampiezza del suono. Il suo valore

di default è 1 (non vi è cambiamento d’ampiezza), il minimo valore è 0 ma si possono

utilizzare valori negativi per invertire la fase. Sono ammessi anche valori maggiori di 1

per aumentare l’ampiezza dell’onda. Il valore può essere cambiato

immediatamente attraverso il parametro GainNode.gain.value oppure utilizzando delle funzioni che hanno comportamenti specifici e di cui può essere gestito il timing (e che

dunque possono essere usate come primo strumento per la creazione dell’inviluppo).

Infatti nel contesto audio si può far sempre riferimento al concetto astratto di currentTime,

ossia il momento 0, inteso come il momento presente in cui sta avvenendo l’esecuzione. Si

può far riferimento ad un momento futuro sommando al currentTime un valore positivo che indica i secondi. Questa è una peculiarità della Web Audio API che consente una

gestione precisa del timing all’interno del contesto audio [6].

Tra queste funzioni ci sono: setValueAtTime(value, time) che imposta immediatamente il

valore al tempo indicato, come indicato dagli argomenti; linearRampToValueAtTime(value,

time) che raggiunge il valore indicato al tempo indicato, con un andamento lineare; exponentialRampToValueAtTime(value, time) che funziona come il metodo precedente ma ha

un andamento esponenziale.

Un altro nodo audio utilizzato nell’applicativo è stato il BiquadFilterNode che

implementa comuni filtri di basso ordine [III]. I filtri possono essere combinati per ottenere

filtri più complessi e di ordine superiore. I parametri che identificano questi filtri sono il type (con cui si possono definire filtri low-pass, high-pass, band-pass, high-shelf, low-shelf,

!27

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

notch, peaking e allpass) [III], il parametro frequency, il gain e il Q, che però assumono

significato diverso a seconda del tipo di filtro. Ad esempio in un BiquadFilterNode di tipo low-pass il parametro gain non viene utilizzato, il parametro frequency indica la frequenza

di taglio e il parametro Q indica la pendenza della risposta del filtro alla frequenza di

taglio [III].

Un altro nodo audio utilizzato è stato il DelayNode che implementa una linea di

ritardo del valore indicato attraverso il suo parametro DelayTime. Di fatto il segnale in input viene ritardato del tempo DelayTime e ritrasmesso in output.

I nodi visti finora sono solo una piccola parte di tutti quelli implementati nella Web

Audio API. Esistono infatti nodi per gestire la spazializzazione del suono, per fare

compressione dinamica, per analizzare il suono, per fare merging o splitting dei canali, per

introdurre filtri IIR o distorsioni, creare oscillatori e definirne la forma d’onda o molti altri ancora per processare il suono. Tutto ciò rende la Web Audio API uno strumento

performante in grado di costruire applicativi Web avanzati.

4.3.5. Compatibilità

Nella figura si osserva che la Web Audio API è supportata da tutti i maggiori browser

esclusi Internet Explorer 11 ed Opera Mini:

Fig. 4.3 - 2 Compatibilità della Web Audio API.

!28

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

In questo paragrafo si è cercato di spiegare quali sono i principi e gli elementi

fondamentali perché un applicativo possa funzionare con Web Audio API. Sono stati portati degli esempi di codice estratti dal Prototipo per la sintesi del suono con Web Audio API.

In questo capitolo si continuerà su questa linea e si approfondiranno nello specifico alcuni

aspetti fondamentali per la realizzazione del progetto, riportando e commentando il

codice sorgente. Il prossimo paragrafo mostra nel dettaglio quali sono state le sintesi del

suono sviluppate, quali sono i concetti matematici che ne stanno alla base e come sono state effettivamente implementate le varie tecniche di sintesi attraverso Web Audio API.

4.4. Modelli di sintesi del suono

L’obiettivo del Prototipo per la sintesi del suono con Web Audio API è stato quello di

sviluppare un applicativo che implementasse i principali metodi per sintetizzare il suono. Sono infatti state implementate con Web Audio API la sintesi additiva, la sintesi per

modulazione di frequenza (FM), la sintesi per modulazione d’ampiezza (AM), la sintesi ad

anello (RM), la sintesi sottrattiva e la sintesi per modelli fisici della corda pizzicata (basata

sull’algoritmo di Karplus e Strong).

Come si legge in [7], la possibilità che ha dato lo sviluppo della computer music è quella di creare dei segnali digitali di dati campionati, che una volta convertiti in segnali

analogici e riprodotti su impianti audio di alta qualità, producono il suono che si desidera

creare. Questo procedimento si chiama sintesi del suono e viene sviluppato secondo diverse

tecniche, ciascuna delle quali possiede la sua formula con cui determinare quali siano i

campioni da creare[7]. Le formule sono delle espressioni che rappresentano il modello matematico della forma d’onda che si vuole generare.

4.4.1 La sintesi additiva

La sintesi additiva è una tecnica di sintesi che rappresenta la forma d’onda come una

somma di segnali sinusoidali. L’espressione a cui si fa riferimento per la sintesi additiva è

la seguente:

!29

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Si osservi che il segnale in uscita ! è una somma si componenti sinusoidali con

frequenza multipla di ! (chiamata frequenza fondamentale), cioè sono in rapporto armonico

tra loro, ciascuna delle quali è controllata da una funzione di inviluppo ! che ne

descrive il comportamento dell’ampiezza nel tempo e ciascuna delle quali possiede la sua fase 𝜙! . Il segnale in uscita è dunque un suono complesso composto dalla somma di altre

sinusoidi: il fatto che siano in rapporto armonico risulta rilevante da un punto di vista

musicale, poiché generalmente gli strumenti musicali producono suoni con spettri

composti da sinusoidi chiamate appunto armoniche, ma potrebbero anche non esserlo. Ora si osservi il diagramma che rappresenta il modello e procediamo a discutere in che modo

questa sintesi è stata sviluppata:

Fig. 4.4-1 Schema del modello della sintesi additiva[5].

Per sviluppare la sintesi additiva sono necessari oscillatori che generino le sinusoidi una

per una e che si possano controllare in ampiezza e in frequenza (in taluni casi è opportuna

anche la fase). Le sinusoidi generate verranno sommate producendo il segnale digitale di

uscita, di fatto facendo una media pesata campione per campione di ogni sinusoide.

Nel Prototipo per la sintesi del suono con Web Audio API sono stati usati dieci oscillatori in rapporto armonico tra loro, cioè le frequenze sono pari a n* ! con 1 < n < 10 (sono multiple

della fondamentale ! ).

y(t)f0

rk(t)

k

f0f0

!30

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

var x=10; for (var i=0; i<x; i++){

if(gainSum==0) gainIN=0; else gainIN=document.getElementById("sliderV"+ (i+1)).valueAsNumber/gainSum;

var freq=document.getElementById('sliderF').value;

if((i+1)*freq<=20000){ this.oscillators[i]=this.context.createOscillator(); this.gainNode[i]=this.context.createGain(); this.gainNode[i].gain.value=gainIN; this.oscillators[i].frequency.value=freq*(i+1); this.oscillators[i].connect(this.gainNode[i]); this.gainNode[i].connect(this.pb[i]); this.pb[i].connect(this.masterGain);

} else document.getElementById(‘singleF'+(i+1)).innerHTML='NO'; }

In questo frammento (estratto dal file addSynth.js che implementa questa sintesi) si vede

che vengono creati dieci oscillatori connessi a dieci nodi di tipo gain, il cui valore viene

letto da elementi HTML <input> di tipo slider. La frequenza degli oscillatori è calcolata in

funzione della frequenza fondamentale che viene letta da uno slider (ma di fatto

controllata o dal controller MIDI o dai tasti della tastiera del computer o cliccando col mouse sulla tastiera di pianoforte visualizzata sullo schermo). Viene fatto un controllo in

modo che non vengano creati oscillatori la cui frequenza superi i 20 kHz.

Per evitare che il segnale somma vada in overload, il gain (gainIN) assegnato ad ogni

oscillatore viene diviso per la somma (gainSum) di tutti i valori letti dagli slider, in modo

che la somma finale risulti sempre uguale a 1. Tutti i GainNode, relativi a ciascun oscillatore, vengono connessi ad un unico masterGain che consente di gestire il volume di

uscita del sintetizzatore.

In ogni momento, dunque, l’utente può personalizzare a suo piacimento il suono

modificando uno ad uno gli slider relativi alle singole armoniche. Inoltre c’è la possibilità

!31

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

di scegliere dei preset per far sì che il sintetizzatore produca onde triangolari, a dente di sega,

sinusoidi o onde quadre. Queste forme d’onda si distinguono per il loro assetto spettrale. Un’onda sinusoidale è composta dalla sola frequenza fondamentale di ampiezza 1, un’onda

quadra ha solo le armoniche dispari con ampiezza uguale a 1/n, l’onda a dente di sega

possiede tutte le armoniche con ampiezza 1/n e l’onda triangolare ha solo le armoniche dispari con ampiezza 1/ ! ma la 3° e la 7° hanno un’inversione di fase. Vediamo come

viene creata l’onda triangolare nel Prototipo:

var count=0; for(var i=0; i<sound.length; i++){ for(var j=0; j<sound[i].oscillators.length; j++){ if(j==count&&j>0) { document.getElementById(‘sliderV’+ (j+1)).valueAsNumber = 1/Math.pow((j+1), 2);

val = 1/Math.pow((j+1),2); if(j==2||j==6) val*= (-1); sound[i].gainNode[j].gain.setValueAtTime(val, context.currentTime); count+=2; } else { if (j==0) { document.getElementById('sliderV'+ (j+1)).valueAsNumber=1; sound[i].gainNode[j].gain.setValueAtTime(1, context.currentTime); count+=2; } else { document.getElementById('sliderV'+ (j+1)).valueAsNumber=0; sound[i].gainNode[j].gain.setValueAtTime (0.0, context.currentTime); } } } };

Ogni volta che viene impostata o modificata una forma d’onda (con un preset o attraverso

gli slider), si aggiorna il visualizzatore grafico, definito come elemento HTML <canvas>, mostrando qual è la forma d’onda risultante che verrà suonata.

Il sintetizzatore è polifonico, questo significa che può suonare contemporaneamente

note diverse. Perchè questo fosse possibile è stata definita la classe Sound. Ogni oggetto

n2

!32

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Sound rappresenta un suono con la forma d’onda impostata con il procedimento descritto

sopra. Il costruttore della classe definisce i campi: this.context che fa riferimento al contesto audio corrente, this.oscillators[] e this.gainNode[] che sono array che rappresentano i dieci

oscillatori e i dieci nodi gain di ogni oggetto, il campo this.pitch che rappresenta il pitch di

ogni oggetto e che viene usato anche per identificarlo univocamente e infine il campo

this.pb[] che rappresenta dei filtri passabasso usati esclusivamente per risolvere un rumore

di glitch che si genera quando un oscillatore viene fermato. Nella classe sono definiti i seguenti metodi: initialize(pitch) che di fatto costruisce il grafo

audio per la sintesi additiva (visto sopra) per ogni oggetto Sound, il metodo

playSynth(pitch) che pone in esecuzione i dieci oscillatori e il metodo stopSynth() che li

ferma.

class Sound{ constructor(context) { this.context = context; this.oscillators= []; this.gainNode = []; this.pitch; this.pb=[]; }

initialize(pitch){ //crea nodi gain e oscillatori e connette osc—>gain-->masterGain […] }

playSynth(pitch){ this.initialize(pitch); for (var i=0; i<this.oscillators.length; i++){ this.oscillators[i].start(0); } } stopSynth(){ for (var i=0; i<this.gainNode.length; i++){ this.gainNode[i].gain.setTargetAtTime(0, this.context.currentTime, 0.015); this.pb[i].frequency.exponentialRampToValueAtTime(1000, this.context.currentTime); this.oscillators[i].stop(2); } } };

La sintesi additiva viene quindi inizializzata avviando il contesto audio, creando un array

sound[] cui viene aggiunto un oggetto della classe Sound, poi inizializzato:

!33

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

function avviaAddSynth(){ context.close(); context = new(window.AudioContext || window.webkitAudioContext)(); sound.push(new Sound(context)); sound[0].initialize(); […] };

Ogni volta che una nota viene suonata, viene invocato il metodo NoteOn(pitch, id) (con relativo metodo NoteOff(pitch, id) per fermarla). Il metodo NoteOn() legge il pitch che viene

suonato dalla tastiera e lo traduce in un valore in Hertz che indica la frequenza della

fondamentale. Dopodiché crea un oggetto Sound identificato da quel pitch e lo aggiunge

all’array, lo inizializza a quella frequenza e lo pone in esecuzione con playSynth().

Il metodo NoteOff(pitch), invocato ogni volta che una nota viene rilasciata, effettua una ricerca nell’array sound[] e, una volta trovato l’oggetto che ha lo stesso pitch che gli è stato

passato come argomento, ne ferma tutti gli oscillatori (di fatto stoppando la nota) e lo

rimuove dall’array.

function noteOn(pitch, id){ var freq= pitchToFreq(pitch); if(freq<=10000){ var tasto= document.getElementById(id); document.getElementById(‘sliderF’).valueAsNumber= freq.toFixed(2);

sound.push(new Sound(context)); sound[sound.length-1].playSynth(pitch); […] } };

Il valore id passato come argomento viene utilizzato per identificare i tasti del tastierino di

pianoforte visualizzato sullo schermo, in modo da cambiarne colore quando la nota

corrispondente viene suonata.

4.4.2. Modulazione di Frequenza (FM)

“Una modulazione è l’alterazione dell’ampiezza, della frequenza o della fase di un

oscillatore provocata da un’altro segnale”, come si legge in [9].Si sta dunque parlando di un tipo di sintesi non lineare in cui interagiscono due segnali: il

segnale modulante agisce e modifica i parametri del segnale portante (o carrier).

!34

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

La tecnica della sintesi FM consiste nella modulazione della frequenza (o fase) istantanea

della sinusoide portante, secondo l’andamento di un segnale modulante generalmente sinusoidale [8]. La formula di calcolo base della sintesi FM è il seguente:

Dove ! è la frequenza portante e 𝜙! è il segnale modulante che è una sinusoide di

ampiezza I (indice di modulazione) e frequenza ! :

Vediamo a questo punto che la sintesi FM di modulazione di frequenza può essere definita

attraverso la seguente formula:

Osservando il segnale prodotto s(t) nel dominio delle frequenze anziché del tempo,

notiamo che il suo spettro è a righe di frequenza ! con ampiezza definita dalla

funzione di Bessel ! . Si creano quindi infinite coppie di frequenze laterali che si

aggiungono alla frequenza della portante. Esse si collocano a ! ± ! , ! ±2 ! , ! ±3 ! , ! ±4 !

e così via. L’energia viene distribuita su queste bande laterali che si sono create in funzione

dell’indice di modulazione. Quando questo varia alcune componenti spettrali

diminuiscono ed altre aumentano, secondo l’andamento descritto dalla funzione di Bessel [8]. Nel seguente schema si nota che per implementare la sintesi FM sono necessari due

oscillatori di cui bisogna definire ampiezza e frequenza. L’uscita dell’oscillatore modulante

andrà a controllare la frequenza di quello portante generando la modulazione.

fc (t)

fm

fc + k fmJk(I )

fc fm fc fm fc fm fc fm

!35

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Fig. 4.4-2 Schema della sintesi per modulazione di frequenza [5].

Si vedrà come è stato implementato con le API JavaScript nel Prototipo per la sintesi del

suono con Web Audio API. Alcuni aspetti che sono già stati discussi precedentemente per la

sintesi additiva risultano essere rilevanti anche per la sintesi FM ma, per evitare

ripetizioni, ci si concentrerà solo gli aspetti caratterizzanti dell’implementazione di questa tecnica di sintesi. Ad esempio, ciò che riguarda la classe SoundFM, l’inizializzazione del

contesto audio, i metodi per la riproduzione delle note e la visualizzazione delle forme

d’onda, non verrà discusso in quanto ricalca il funzionamento della sintesi additiva.

Si entrerà ora nel merito della creazione dei nodi audio e delle loro connessioni all’interno

del grafo audio. Si osservi il codice della funzione initializeFM() (definita all’interno della classe SoundFM) che crea il grafo audio relativo ad ogni nota, cioè ad un oggetto SoundFM:

initializeFM(pitch){ this.pitch=pitch; this.masterGain= this.context.createGain(); this.masterGain.connect(this.context.destination);

!36

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

this.masterGain.gain.value= document.getElementById('sliderVM').value;

this.modulante=this.context.createOscillator(); this.gainNodeMod=this.context.createGain(); this.g=this.context.createGain(); this.carrier=this.context.createOscillator(); this.pb=this.context.createBiquadFilter();

this.pb.type=‘lowpass'; this.pb.frequency.value=20500;

this.modulante.connect(this.gainNodeMod); this.gainNodeMod.connect(this.carrier.frequency); this.carrier.connect(this.pb); this.pb.connect(this.g); this.g.connect(this.masterGain);

this.gainNodeMod.gain.value= document.getElementById("sliderV1").value; this.modulante.frequency.value= document.getElementById('sliderV2').value; this.carrier.frequency.value= document.getElementById(‘sliderF').value; };

In questo modo viene implementato lo schema visto nella Fig.4.4-2. Vengono creati due

oscillatori, uno portante e l’altro modulante, chiamati this.carrier e this.modulante.

L’oscillatore modulante viene connesso ad un GainNode a sua volta collegato al parametro

frequency dell’oscillatore portante. Questo è di fatto il passaggio fondamentale che consente che avvenga la modulazione:

this.gainNodeMod.connect(this.carrier.frequency);

Così si sta facendo in modo che l’uscita dell’oscillatore modulante vada a modificare la

frequenza portante con un indice di modulazione rappresentato dal valore del nodo

this.gainNodeMod. La frequenza e l’ampiezza della modulante sono i due parametri che si

possono modificare attraverso degli slider (elementi HTML <input type=“slider”>),

cambiando dunque la composizione spettrale del suono prodotto così come discusso poco sopra.

Un aspetto di cui infine è necessario parlare è quello del LFO (Low Frequency

Oscillator), che sarà valido anche per la sintesi AM ed RM che vedremo in seguito. Si è

scelto infatti di dare la possibilità ad un utente di impostare l’oscillatore modulante ad

!37

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

LFO. Questo significa che genera una sinusoide con frequenza inferiore a 20 Hz, cioè non

emette un suono udibile. Nel caso della sintesi FM questo risulta interessante in quanto il suono prodotto che viene ascoltato non è più composto da tante componenti spettrali che

si sommano alla portante, ma risulta essere un singolo suono che viene periodicamente

modificato in frequenza, prima verso l’acuto e poi verso il grave, generando un effetto di

vibrato. Anche i meno esperti riusciranno a capire, in questo modo, che cosa significa

modulare la frequenza di un suono portante con un altro segnale modulante di forma sinusoidale.

4.4.3. Modulazione di Ampiezza (AM) e Modulazione ad Anello (RM)

In questa sezione si parlerà congiuntamente della sintesi AM e della sintesi RM, poiché

entrambe sono definite nel campo delle sintesi moltiplicative [V]. Entrambe sono lineari ma

non tempo-invariati e trattano un tipo di trasformazione basata sulla moltiplicazione di

due segnali. Il caso più semplice è quello della sintesi RM e si vedrà quali sono le differenze con la sintesi AM. Ci si trova sempre nell’ambito delle modulazioni, dunque

bisogna considerare un segnale modulante che modifica un parametro del segnale portante

(o carrier). Nel caso della Modulazione di Ampiezza e della Modulazione ad Anello, il

parametro coinvolto nella modulazione è quello dell’ampiezza [V]. Nella sintesi RM il segnale portante ! viene modulato in ampiezza da un segnale sinusoidale di frequenza

! producendo il segnale ! , come si può osservare nell’equazione:

! 𝜋! !Si tratta di una moltiplicazione tra il segnale portante e quello modulante che produce una

variazione nello spettro del segnale: considerando ! lo spettro del segnale portante, la

modulazione produce un segnale con spettro ! . Sono state generate due copie dello spettro del segnale portante, ma queste sono traslate verso destra

e verso sinistra del valore ! , ossia la frequenza della modulante. Nel caso in cui l’ampiezza

della sinusoide modulante sia 0, il segnale di uscita sarà uguale a 0, dunque non viene

prodotto suono.Ciò che differenzia la sintesi AM dalla sintesi RM è il fatto che nella prima viene

introdotto un valore DC offset che viene sommato al segnale modulante, assente nella

f (t)f0 g(t)

g(t) = f (t) * Acos(2 f0t)

F( f1)G ( f ) = F( f1 + f0) + F( f1 − f0)

f0

!38

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

modulazione ad anello (cioè uguale a 0). Questo significa che la sinusoide modulante

viene traslata vero l’alto del valore di DC e si assume che la sua ampiezza massima abbia pari valore. Nel nostro caso ha significato assumere un valore di DC uguale a 1 per la

sintesi AM, ciò che si ottiene è:

! 𝜋! !

Nella sintesi AM, a differenza della sintesi RM, se il segnale modulante ha ampiezza 0, quello che si ottiene è il segnale portante originale non modulato.

Dal punto di vista spettrale otteniamo lo stesso risultato della sintesi RM ma viene

mantenuto anche lo spettro originale del segnale portante [V]: oltre le frequenze che si

sono create per traslazione, percepiremo dunque anche la frequenza portante.

Fig. 4.4-3. Screenshot delle forme d’onda estratti dal Prototipo per la sintesi del suono con Web Audio API. In ascissa c’è il tempo e in ordinata l’ampiezza. A sinistra la forma d’onda della sintesi RM, a destra quella

della sintesi AM. In blu la sinusoide modulante, in nero il segnale risultante dalla modulazione.

Si analizzeranno adesso alcuni aspetti dello sviluppo con la API JavaScript di queste due tecniche di sintesi. Si inizierà dall’osservare in che modo viene definito il grafo audio, che

risulta essere identico sia per la sintesi RM che per la AM:

g(t) = f (t) * [1 + Acos(2 f0t)]

!39

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

initializeAM(pitch){ this.pitch=pitch;

[…]

this.carrier=this.context.createOscillator(); this.modulante=this.context.createOscillator(); this.gainNodeMod=this.context.createGain(); this.gainNodeCar=this.context.createGain();

this.carrier.type='sawtooth';

this.modulante.connect(this.gainNodeMod); this.gainNodeMod.connect(this.gainNodeCar.gain); this.carrier.connect(this.gainNodeCar); this.gainNodeCar.connect(this.masterGain); […] this.modulante.frequency.value= document.getElementById('sliderV2').value;/ this.carrier.frequency.value= document.getElementById('sliderF').value; };

Nella funzione initializeAM() (definita all’interno della classe SoundAM) vengono creati i

due oscillatori portante e modulante, this.carrier e this.modulante, connessi ai rispettivi nodi

gain this.gainNodeCar e this.gainNodeMod. Il GainNode relativo alla modulante viene connesso all’AudioParam gain relativo al nodo gain della portante:

this.gainNodeMod.connect(this.gainNodeCar.gain);

In questo modo viene garantito che l’uscita dell’oscillatore modulante vada a modificare l’ampiezza dell’oscillatore della portante, generando di fatto la modulazione.

Per distinguere sintesi RM da AM bisogna impostare diversamente il DC offset,

andando ad agire sui valori di gain relativi agli oscillatori:

if(tipoSynth=='rm') { this.gainNodeCar.gain.value=0; this.gainNodeMod.gain.value= document.getElementById("sliderV1").value*2; } else{ this.gainNodeCar.gain.value=1; this.gainNodeMod.gain.value= document.getElementById("sliderV1").value; }

!40

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Nella sintesi RM il gain della portante viene impostato uguale a 0, mentre quello della

sintesi AM uguale ad 1. Ciò significa che l’ampiezza della portante modulata oscillerà al massimo tra valori compresi tra -1 e 1 per la RM e tra valori compresi tra 0 e 2 per la AM.

Vediamo quindi che la modulante nella RM è un segnale bipolare (oscilla cioè tra valori

positivi e negativi) mentre nella sintesi AM è unipolare. Si è ottenuto in questo modo il

risultato sperato.

Anche per queste due modulazioni è stata inserita la possibilità di scegliere come oscillatore modulante un LFO (Low Frequency Oscillator). In questo caso non viene

modificato lo spettro del segnale e si percepisce un suono che viene alzato e abbassato di

volume periodicamente, generando un effetto di tremolo.

4.4.4. La sintesi sottrattiva

Se la sintesi additiva, come si è già visto, genera suoni complessi a partire da semplici

segnali sinusoidali, la sintesi sottrattiva risulta essere ad essa complementare: parte da un

segnale complesso a larga banda e ne modifica lo spettro attraverso dei filtri, attenuando alcune componenti (sottrazione) ed eventualmente amplificandone delle altre. Lavorando

sui diversi parametri dei filtri il suono può quindi essere modificato producendo risultati

differenti [6].

Fig. 4.4-4. Schema della Sintesi Sottrattiva.

La sintesi sottrattiva ha un’interpretazione fisica che è quella che ha spinto molti ricercatori

a considerarla una tecnica di sintesi molto utile. Questa interpretazione fisica consiste in

un segnale acustico di eccitazione che viene inviato ad un sistema risonante, visione che si

adatta ad alcuni strumenti musicali. Ad esempio l’apparato fonatorio umano può essere

!41

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

visto come un sistema che produce una sorgente sonora impulsiva (delle corde vocali) o

rumorosa (del moto dell’aria) e la filtra, modificandone lo spettro attraverso le diverse parti dell’apparato. Dunque la sintesi sottrattiva può essere vista allo stesso modo, come

un sistema in cui c’è un blocco iniziale che genera il suono seguito in successione (senza

feedback) da un blocco di filtri che in cascata o in parallelo ne modificano lo spettro.

In questo caso è bene dunque conoscere in che modo i filtri operano sullo spettro del

segnale, cioè bisogna conoscerne la risposta in frequenza e in che modo i parametri del filtro la modificano.

I filtri che sono stati tenuti in considerazione per lo sviluppo del Prototipo per la sintesi del

suono con Web Audio API sono stati i filtri passa-basso (LP), i passa-banda (BP) e i passa-

alto (HP). Si osservi velocemente come questi filtri modificano un segnale nel dominio

delle frequenze. I passa-basso eliminano le componenti spettrali che sono superiori alla frequenza di taglio che viene impostata come parametro; i filtri passa-alto lavorano allo

stesso modo ma eliminano tutte le frequenze al di sotto della frequenza di taglio; i filtri

passa-banda invece lasciano passare solo una banda limitata dello spettro (intorno a quella

definita come frequenza centrale) e possono essere visti come combinazione di un filtro

passa-alto ed uno passa-basso. Questi filtri possono essere usati in parallelo uno per volta, ma potrebbero anche essere

creati sistemi di filtraggio più complessi. In questo caso l’obiettivo era fornire una visione

semplice ed intuitiva sul funzionamento della sintesi sottrattiva.

Nel Prototipo per la sintesi del suono con Web Audio API si possono impostare due tipi

diversi di sorgente sonora. Il primo è un rumore bianco, cioè un segnale non periodico che contiene energia a tutte le frequenze in modo casuale. Il rumore viene generato creando un

buffer stereo della durata di 10 secondi che viene riempito con una sequenza aleatoria di

numeri compresi tra -1 e 1:

var bufferSize= 10*this.context.sampleRate;

var whiteNoiseBuffer = this.context.createBuffer(2, bufferSize, this.context.sampleRate); for(var canale=0; canale<whiteNoiseBuffer.numberOfChannels; canale++){ var output= whiteNoiseBuffer.getChannelData(canale); for(var i=0; i<whiteNoiseBuffer.length; i++){ output[i]= Math.random()*2-1; } }

!42

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

this.source= this.context.createBufferSource(); this.source.buffer= whiteNoiseBuffer; this.source.loop=true;

Il buffer creato viene a sua volta assegnato al parametro buffer dell’oggetto this.source di

tipo BufferSource, che nella Web Audio API costituisce un nodo sorgente riproducibile.

Il secondo tipo di sorgente che si può impostare è un qualsiasi file audio caricato

dall’utente. Utilizzando l’elemento HTML <input> di tipo file, l’utente ha la possibilità di caricare il file sul Browser (si è già visto nel paragrafo 4.3 in che modo questo file può

essere letto, decodificato e impostato come sorgente audio). È stato scelto di dare agli

utenti (soprattutto quelli meno esperti) questa possibilità per una questione di

interattività: riprodurre un contenuto audio già conosciuto potrebbe rendere più gradevole

e intuitiva la comprensione del funzionamento dei filtri e la loro manipolazione. Come già è stato detto, i filtri che sono stati implementati sono un passa-banda, un

passa-basso ed un passa-alto. La sorgente audio viene connessa alternativamente ad un

filtro o ad un altro, questo significa che ci sarà un solo filtro attivo per volta.

I filtri vengono creati ed inizializzati col metodo initializeSottra() definito nella classe

SottraSound.

this.hp=this.context.createBiquadFilter(); this.hp.type='highpass'; var freq=document.getElementById('hpfrequency').valueAsNumber; var q=document.getElementById('hpQ').valueAsNumber; this.hp.frequency.setValueAtTime(freq, this.context.currentTime); this.hp.Q.setValueAtTime(q, this.context.currentTime);

this.bp1=this.context.createBiquadFilter(); this.bp1.type='bandpass'; var freq=document.getElementById('bp1frequency').valueAsNumber; var q=document.getElementById('bp1Q').valueAsNumber; this.bp1.frequency.setValueAtTime(freq, this.context.currentTime); this.bp1.Q.setValueAtTime(q, this.context.currentTime);

this.lp=this.context.createBiquadFilter(); this.lp.type='lowpass'; var freq=document.getElementById('lpfrequency').valueAsNumber; var q=document.getElementById('lpQ').valueAsNumber; this.lp.frequency.setValueAtTime(freq, this.context.currentTime); this.lp.Q.setValueAtTime(q, this.context.currentTime);

!43

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

I filtri vengono implementati attraverso i nodi BiquadFilter della Web Audio API, che ne

definisco i parametri di type, frequency e Q di cui già si è discusso nel paragrafo 4.3. I parametri frequency e Q possono essere modificati in navigazione attraverso degli slider.

Creati i filtri in fase di inizializzazione del grafo, la loro connessione verrà fatta

dinamicamente nel momento in cui l’utente preme il pulsante relativo a quel filtro. Verrà

infatti invocata la funzione addFilter() che si occupa della connessione del grafo dalla

sorgente alla destinazione:

function addFilter(tipo){ sottraSound.gain.disconnect(0); switch (tipo) { case 'hp': sottraSound.gain.connect(sottraSound.hp); sottraSound.hp.connect(sottraSound.masterGain); break; case 'bp1': sottraSound.gain.connect(sottraSound.bp1); sottraSound.bp1.connect(sottraSound.masterGain); break; case 'lp': sottraSound.gain.connect(sottraSound.lp); sottraSound.lp.connect(sottraSound.masterGain); break; case null: sottraSound.gain.connect(sottraSound.masterGain); break; }; […] };

4.4.5. La sintesi per modelli fisici

Fino ad ora sono state analizzate delle tecniche di sintesi generative. La sintesi per modelli

fisici, invece, ha un approccio differente in quanto cerca di rappresentare la dinamica degli oggetti che producono suono. Si basa quindi sull’uso di modelli formali che descrivono il

comportamento degli strumenti musicali [V]. I modelli sono composti da blocchi

funzionali: sono blocchi che rappresentano funzionalità differenti all’interno del

meccanismo di produzione del suono di uno strumento musicale. Ad esempio una prima

rappresentazione macroscopica in blocchi valida per tutti gli strumenti, è un modello composto da un blocco eccitatore e un blocco risonatore. Il risonatore è da intendere come

quella parte in cui avviene effettivamente la vibrazione, mentre l’eccitatore è ciò che

!44

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

provoca ed eventualmente sostiene la vibrazione. Possiamo immaginare una corda di

chitarra come risonatore vibrante e il plettro come suo eccitatore. Il meccanismo di eccitazione può essere differente a seconda dello strumento ma

generalmente viene diviso in due tipologie: feedforward, se l’eccitatore non riceve nessuna

informazione di ritorno dal risonatore, oppure feedback, se i due blocchi si scambiano

informazione in entrambe le direzioni [V]. Nella chitarra ad esempio il meccanismo di

eccitazione è feedforward perché il plettro, una volta eccitata la corda, lascia che questa sviluppi la vibrazione liberamente. Un meccanismo di feedback si verifica invece nei fiati,

dove il suono viene prodotto grazie ad una persistente eccitazione da parte dell’eccitatore.

Il modello fisico può spingersi a diversi gradi di complessità, rappresentando più o meno

nello specifico le caratteristiche fisiche dello strumento musicale. In generale sarà

comunque il risonatore a presentare una complessità maggiore, ma saranno entrambi i blocchi ad essere scomposti in altri sistemi dinamici.

Fig. 4.4-5. Schema di interazione tra eccitatore e risonatore nella Sintesi per Modelli Fisici

Tra i primi lavori di ricerca sulla sintesi per modelli fisici, si ricorda il lavoro di

Karplus e Strong che nel 1983 definirono il modello matematico di una corda pizzicata o percossa. Fu un lavoro pionieristico che aprì la strada a molti studi nel settore delle sintesi

per modelli fisici. Nel Prototipo per la sintesi del suono con Web Audio API è stato

implementato solo il modello della corda pizzicata di Karplus & Strong.

!45

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

Fig. 4.4-6. Modello della sintesi secondo l’algoritmo di Karplus e Strong.

Si osservi che il modello comprende due parti: la prima è il blocco eccitatore noise burst, la

seconda è il blocco risonatore costituito da un ciclo di feedback con una linea di ritardo e

un filtro passa-basso dove avviene attenuazione.

La sorgente sarà un rumore bianco (o comunque un suono ricco a tutte le frequenze) della

stessa lunghezza della linea di ritardo. Il campione di rumore verrà inviato in uscita ma verrà anche ritrasmesso al feedback. Qui interviene un ritardo (dal quale dipende la

frequenza della nota prodotta) e un filtro passa-basso (poiché è caratteristica delle corde

pizzicate produrre un’onda molto ricca alle alte frequenze in fase di eccitazione ma meno

in fase di risonanza). In questo passaggio il suono viene attenuato secondo un fattore di

scala che determinerà di fatto la durata della vibrazione della corda. Nel seguente frammento di codice si può vedere come è stato implementato nel Prototipo:

initializeKS(pitch){ this.pitch=pitch; this.freq= pitchToFreq(this.pitch); this.delayLine=(1/this.freq); this.bufferTime=this.delayLine;

this.bufferSize= this.bufferTime*this.context.sampleRate; this.buffer= this.context.createBuffer(2, this.bufferSize,this.context.sampleRate);

for (var i=0; i<this.buffer.numberOfChannels; i++){ var output= this.buffer.getChannelData(i); for(var j=0; j<this.buffer.length; j++)output[j]= Math.random()*2-1; }

this.source.buffer=this.buffer; this.source= this.context.createBufferSource();

!46

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

this.gain1= context.createGain(); this.gain2= context.createGain(); this.gainSound= context.createGain(); this.delay1= context.createDelay(this.delayLine); this.pb1= context.createBiquadFilter(); this.pbNoise= context.createBiquadFilter();

this.source.connect(this.pbNoise); this.pbNoise.connect(this.gain1); this.gain1.connect(this.gainSound);

this.gainSound.connect(this.context.destination);

this.gain1.connect(this.pb1); this.pb1.connect(this.delay1); this.delay1.connect(this.gain2); this.gain2.connect(this.delay1); this.gain2.connect(this.gainSound); this.gain1.gain.value=0.17; this.gainSound.gain.value=0.1;

this.pb1.type='lowpass'; this.pb1.frequency.value=document.getElementById("sliderV3").value; this.pbNoise.type='lowpass'; this.pbNoise.frequency.value= document.getElementById("sliderV1").value; this.delay1.delayTime.setValueAtTime(this.delayLine, this.context.currentTime); this.gain2.gain.value=document.getElementById(“sliderV2").value; };

Il rumore bianco viene creato, come già visto, generando numeri casuali compresi tra -1 e

1. La lunghezza del campione di rumore e della linea di ritardo viene calcolata in base alla

frequenza della nota da produrre, di cui viene calcolato il periodo this.delayLine. A questo punto si procede alla creazione del DelayNode, il cui parametro delayTime viene impostato

col valore calcolato. L’uscita del delay viene collegata al filtro passa-basso creato con una

frequenza di taglio di 15000 Hz. A questo punto viene inserito un gain node che serve per

attenuare il ciclo. Il valore di questo gain deve essere necessariamente compreso tra 0 e 1 e

costituisce il fattore di scala che determina la lunghezza del suono prodotto. É stato inoltre impostato un filtro passa-basso che filtra direttamente la sorgente di rumore

per poter aver la possibilità di modificare ulteriormente il timbro.

Si è scelto di lasciare come parametri modificabili il valore del gain di attenuazione,

della frequenza di taglio del passa-basso relativo al feedback e di quello relativo alla

sorgente, per poter lavorare sia sulla forma d’onda che sul timbro del suono.

!47

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

4.5. Web MIDI API

Si procederà ora a discutere brevemente della Web MIDI API e di come è stata utilizzata nell’applicativo. Come già è stato detto, inizialmente non rientrava tra gli obiettivi primari

quello di implementare l’aspetto MIDI, ma si è deciso di sviluppare l’argomento per

donare all’applicazione un valore aggiunto che la avvicinasse all’ambito più propriamente

musicale. In questo modo i sintetizzatori possono essere fatti suonare con un controller

MIDI, da cui vengo letti gli eventi NoteOn e NoteOff.Nel Web è stata creata la Web MIDI API di JavaScript per il controllo dell’interfaccia

MIDI dei browser. Questa è una interfaccia che supporta il protocollo MIDI, consente alle

applicazioni Web di enumerare, manipolare e selezionare input e output e di inviare

messaggi MIDI. Il concetto è quindi quello di abilitare il browser a comunicare

direttamente con dispositivi MIDI attraverso l’interfaccia offerto dal sistema, ma non vi è l’interesse di leggere e gestire gli Standard MIDI File [VI].

4.5.1. L’accesso: requestMIDIAccess()

Il primo aspetto importate della Web MIDI API è quello di ottenere l’accesso ai dispositivi

MIDI. Per fare questo si utilizza il metodo requestMIDIAccess() che ritorna un oggetto

Promise per accedere ai dispositivi MIDI connessi al computer dell’utente. Quando viene

dato il permesso da parte dell’utente si verifica una MIDIsuccessCallback che indica che la

richiesta ha avuto successo e viene creato un oggetto di tipo MIDIAccess (in caso di fallimento si verifica un errore di tipo DOMException):

navigator.requestMIDIAccess().then(onMIDISuccess, onMIDIFailure);

function onMIDISuccess(midiAccess) { midi = midiAccess; getDefaultInOutput(); programChange(0); } function onMIDIFailure(msg) { document.getElementById("esitoMIDI").innerHTML = "Messaggio di errore: " + msg; }

!48

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

4.5.2. Mapping di input e output MIDI

Per conoscere quali sono i dispositivi e le porte MIDI disponibili vengono utilizzate le due interfacce MIDIInputMap e MIDIOutputMap [VI]. Grazie all’oggetto MIDIAccess creato in

fase di connessione si può sapere quanti e quali sono i dispositivi MIDI in input o in

output e se ne può conoscere la chiave con il relativo ID.

function getDefaultInOutput() { var inputsToString = ""; midi.inputs.forEach(function (key, input) { if (inputsToString == "") { inputsToString += "<option selected='selected' value='" + key.id + "'>" + key.name + "</option>"; defaultInPort = key.id; } else inputsToString += "<option value='" + key.id + "'>" + key.name + "</ option>"; }); document.getElementById("chooseInput").innerHTML = inputsToString;

var outputsToString = ""; midi.outputs.forEach(function (key, output) { if (outputsToString == "") { outputsToString += "<option selected='selected' value='" + key.id + "'>" + key.name + "</option>"; defaultOutPort = key.id; } else outputsToString += "<option value='" + key.id + "'>" + key.name + "</option>"; }); document.getElementById("chooseOutput").innerHTML = outputsToString; };

In questo caso vengono mappati tutti i dispositivi input ed output. Così si possono creare

elementi HTML <option> che consentono all’utente di selezionare con quale dispositivo

MIDI comunicare. In JavaScript si imposta un input MIDI implementando un EventHandler, utilizzando l’attributo onmidimessage relativo all’input scelto, con il quale è

possibile leggere i messaggi MIDI che arrivano da quel dispositivo [VI]. Per impostare

l’output invece viene definita la porta MIDI di uscita per l’invio dei messaggi MIDI,

identificata dal key.id

!49

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

function changeOutput(outputId) { defaultOutPort = outputId; if (midi != null && defaultOutPort != null) output = midi.outputs.get(defaultOutPort); }

function changeInput(inputId) { defaultInPort = inputId; midi.inputs.forEach(function (key, input) { if (key.id == defaultInPort) { key.onmidimessage = MIDIMessageEventHandler; } }); }

4.5.3 Lettura dei dati MIDI: MIDIMessageEventHandler()

In questo modo è dunque possibile ricevere dei messaggi MIDI da un controller. La

funzione che consente di selezionare ed interpretare i messaggi è

MIDIMessageEventHandler(event):

function MIDIMessageEventHandler(event) { if (event.data[0] == 254) return; if (output != null){ if(event.data[1]<=96&&event.data[1]>=24){ […] switch (event.data[0] & 0xf0) { case 0x90: if (event.data[2]!=0) { switch (tipoSynth) { case 'additiva': noteOn(event.data[1], id); break; […] } break; } case 0x80: switch (tipoSynth) { case 'additiva': noteOff(event.data[1], id ); break; […] break; };

!50

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

L’attributo data dell’evento MIDI, costituisce un array che contiene i byte di dati MIDI del

messaggio. Si può accedere alla posizione di indice 1 dell’array con event.data[1], che contiene il pitch della nota in ingresso, mentre accedendo alla posizione di indice 2 con

event.data[2] si ricava la velocity. Leggendo questi dati si conoscono tutte le informazioni

necessarie per creare e suonare i sintetizzatori. Vengono infatti invocate le funzioni Web

Audio API con cui inizializzare e riprodurre le varie tecniche di sintesi: nell’esempio

precedente si vedono le funzioni noteOn() e noteOff() per la sintesi additiva che sono già state discusse nel paragrafo 4.3.

4.5.4 Compatibilità

Nella seguente figura si osserva che la Web MIDI API è supportata da pochissimi browser.

Tra quelli più diffusi è compatibile solo con Google Chrome:

Fig. 4.5 - 1 Compatibilità della Web MIDI API.

!51

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

4.6. Responsive Web

Si è già detto che il Prototipo per la sintesi del suono con Web Audio API ambisce ad essere una

applicazione Web responsive. Si discuterà rapidamente di alcune definizioni sull’argomento

e di come è stato trattato.

“Il Responsive Web design è l’approccio per il quale il design e lo sviluppo [di un sito Web] devono adattarsi alle azioni e all’ambiente dell’utente in base alla dimensione dello

schermo, alla piattaforma e all’orientamento [dei dispositivi]”. Questa è la definizione che

dà Kayla Knight nell’articolo [VIII]. Questo adattamento consiste dunque nell’uso di grids

o layout adattivi e in particolare delle media query. In questo modo l’aspetto grafico di una

pagina sarà adattabile a diverse tipologie di schermi e di dispositivi rendendo l’applicativo stesso molto più versatile e accessibile.

I due metodi principali utilizzati nello sviluppo dell’applicativo sono stati quello di

rendere “tutto flessibile” [VIII] e quello delle media query.

Il primo metodo consiste nel fissare le dimensioni di quasi tutti gli elementi,

utilizzando delle percentuali dello schermo anziché unità di misura fisse (ad esempio i pixel). In questo modo il layout assume già una prima forma adattiva, perché gli elementi

della pagina saranno visualizzati in funzione della grandezza dello schermo.

div#header { background-color:#1d91ce; background-size: contain; height:16vh; width: 100vw; } div#LIM_logo { background-image: url(images/lim_logo.png); background-repeat:no-repeat; background-size: contain; cursor:pointer; float: left; width: 9vw; height: 100%; }

!52

CAPITOLO 4. APPLICAZIONE WEB SVILUPPATA

In questi esempi estratti dal file stile.css, si osserva che l’altezza e la larghezza dei due

elementi <div> che rappresentano l’header della pagina e il logo al suo interno, vengono fissate con percentuali. Si può utilizzare sia il simbolo % che vw (view width) e vh (view

height), che si riferiscono direttamente alla larghezza e all’altezza dello schermo del

dispositivo, ossia alla sua Viewport. In questo esempio si vede inoltre che l’immagine di

sfondo del div LIM_logo si adatterà automaticamente poiché la sua dimensione viene

impostata con background-size: contain, cioè verrà scalata in funzione della dimensione del blocco che la contiene.

Il secondo metodo utilizzato è quello delle media query. Queste sono uno strumento

fornito da CSS3 che consente di verificare delle condizioni sui dispositivi in base alle quali

ne verrà definita la formattazione. Ad esempio una media query può selezionare di

leggere le informazioni sullo screen del dispositivo e fissare delle condizioni relative alla sua larghezza, altezza o orientamento. È estremamente utile poter definire la max-width e

la min-width per selezionare il tipo di dispositivo a cui si vuole fare riferimento.

@media only screen and (min-width: 320px) and (max-width: 480px) { […] }

Con questa media query vengono selezionati solo i dispositivi che hanno uno schermo di

larghezza compresa tra i 320 e i 480 pixel, ossia gli Smartphone.

!53

Capitolo 5Conclusioni e sviluppi futuri

5.1. Conclusioni e problemi riscontrati

Tutti gli obiettivi che erano stati stabiliti in fase di definizione del progetto sono stati quasi

totalmente raggiunti con buoni risultati. Sono state sviluppate tutte le tecniche di sintesi principali anche se non c’è stato tempo per

svilupparne altre (ad esempio la sintesi granulare o altre tecniche di sintesi per modelli

fisici). La sintesi additiva, la sintesi per modulazione di ampiezza (AM), la sintesi ad anello

(RM), la sintesi per modulazione di frequenza (FM), la sintesi sottrattiva e la sintesi per

modelli fisici della corda pizzicata, sono le tecniche di sintesi sviluppate correttamente utilizzando Web Audio API.

È stata implementata la lettura delle frequenze da controller MIDI utilizzando Web MIDI

API ma sono stati implementati anche altri metodi per la lettura delle note che non erano

stati considerati in fase di progettazione: si può utilizzare la tastiera del computer oppure

interagire con l’interfaccia utente per cliccare i tasti della tastiera di pianoforte di due ottave visualizzata su schermo.

Si è cercato di rendere responsive il sito utilizzando un dimensionamento in percentuali per

prevedere un adattamento automatico degli elementi e utilizzando anche delle media

query.

!54

CAPITOLO 5. CONCLUSIONI E SVILUPPI FUTURI

Sono stati incontrati problemi sopratutto per ciò che riguarda il layout della pagina, per un

motivo di scarsa esperienza personale sia per ciò che riguarda il linguaggio CSS che per ciò che riguarda la capacità personale di progettare il lato front-end di un sito. L’utilizzo di

media query ha creato molti problemi e non è stato possibile ottimizzarne il

funzionamento.

Ci sono stati problemi non del tutto risolti rispetto all’implementazione della sintesi

per modelli fisici della corda pizzicata. La determinazione della frequenza fondamentale non è consolidata e funziona solo su Firefox, alcune note presentano distorsioni da un

punto di vista spettrale e non si riescono a generare suoni con frequenze superiori a 349

Hz.

5.2. Sviluppi futuriSi possono immaginare degli sviluppi futuri e dei miglioramenti che potrebbero far

progredire l’applicativo realizzato. Tra questi si potrebbe considerare di implementare

altre tecniche di sintesi del suono: si pensi alla sintesi granulare, alla sintesi per

campionamento o alle molteplici sintesi per modelli fisici.

Potrebbe essere ampliata l’interazione con il protocollo MIDI, gestendo i numerosi e più complessi eventi MIDI che sono stati ad ora ignorati.

!55

Bibliografia

[1] Forouzan, Mosharraf - Reti di calcolatori un approccio top-down - Mc Graw-Hill - 2013, Italia.

[2] D. Raggett, A. Le Hors, I. Jacobs - HTML 4.01 Specification - W3C recommendation - 1999.

[3] U. Gascòn Gonzàlez - Javascript, ¡inspirate! - Leanpub - 2017, Spagna.

[4] J. Rothstein - MIDI: A Comprehensive Introduction - A-R Editions, Inc - 1995, U.S.A.

[5] R. Bianchini, A. Cipriani - Il suono virtuale - ConTempo s.a.s. - 1998, Italia.

[6] B. Smus - Web Audio API - O’Reilly - 2013, U.S.A.

[7] J. A. Moorer - Signal Processing Aspects of Computer Music--A Survey - Computer Music Journal, vol. 1, No. 1, pp. 4-37 - The MIT Press - 1977.

[8] G. De Poli - A Tutorial on Digital Sound Synthesis Techniques - Computer Music Journal, vol. 7 No. 4 - The MIT Press - 1983.

[9] C. Dodge, T. A. Jerse - Computer Music, p.80 - Schirmer - 1985, New York.

!56

Sitografia

[I] http://www.html.it/pag/16026/introduzione22/

[II] https://www.bbc.com/news/technology-20425376

[III] https://www.w3.org/TR/webaudio/

[IV] https://developer.mozilla.org/it/docs/Web/API/Web_Audio_API

[V] www.dei.unipd.it/~musica/Dispense/cap5.pdf

[VI] https://www.w3.org/TR/webmidi/

[VII] http://www.html.it/guide/responsive-web-design-la-guida/

[VIII] https://www.smashingmagazine.com/2011/01/guidelines-for-responsive-web-design/

[IX] https://ask.audio/articles/websynths-is-a-free-browser-modular-synth-that-sounds-incredible

[X] http://webaudio.github.io/demo-list/

[XI] http://www.innateagency.com/content/18/en/using-web-audio-api-enhance-mobile-apps

[XII] https://www.webaudioweekly.com

[XIII] http://www.lim.di.unimi.it/

!57