La libreria che andiamo a presentare consente di riprodurre musica attraverso il linguaggio di programmazione Java. Questo avviene passando le note musicali, sottoforma di stringhe come parametro dell’oggetto ‘Player’.
Inoltre è possibile scegliere lo strumento da utilizzare, creare ritmi e molto altro ancora. Una volta creata la melodia, sarà possibile salvarla in formato MIDI e usarla a nostro piacimento.
Introduzione
Vi è mai capitato di avere una melodia in testa, di voler provare a suonarla senza saper suonare strumenti musicali? Volete creare un sottofondo musicale per la vostra applicazione, per il sito internet, o per il gioco, ma non sapete come fare? Siete nel posto giusto! Se conoscete qualche nozione di programmazione e (e magari qualche rudimento di teoria musicale) da oggi grazie a JFugue lo potete fare tutto ciò!
Prepariamo l’ambiente di lavoro
Innanzi tutto scarichiamo la libreria dal suo sito ufficiale [1]: dalla pagina principale effettuaiamo il download dell’ultima versione di JFugue (al momento della pubblicazione di questo articolo si tratta della 4.0.3). Nella pagina dei Download troviamo i file sorgenti, la documentazione e le versioni precedenti della libreria. In particolare, il file che ci interessa è jfugue-4.0.3.jar. Provando a scaricare il file, potreste trovarlo in formato in ZIP; nessun problema: una volta scaricato rinominatelo in JAR e funzionerà tutto in maniera perfetta. Scarichiamo questo file e copiamolo nella nostra cartella di lavoro. Adesso è tutto pronto per iniziare ad usare la nostra API musicale.
La nostra prima composizione
Creiamo un oggetto di tipo Player e creiamo una nuova istanza, in questo modo:
Player player = new Player();
Scriviamo la nostra melodia sotto forma di stringa e passiamola come parametro al metodo play:
// Scala Musicale String melodia = "C D E F G A B"; player.play(melodia);
Bene: se avete sentito una scala musicale, abbiamo creato la nostra melodia. Semplice no? Notate bene che le note sono scritte secondo lo standard anglosassone (fatto abbastanza scontato per chi si occupi in qualche modo di musica e informatica). Nella tabella 1 sono riportate le corrispondenze con la notazione italiana.
Tabella 1 – Denominazione delle note e della pausa nello standard italiano e in quello anglosassone. La lettera maiuscola ci servirà per indicare quale nota suonare.
Durata delle note
Adesso che abbiamo rotto il ghiaccio con JFugue, proviamo a scrivere una melodia complessa cercando di dare anche una durata alle note. La durata di ogni nota, infatti segue dei principi ben precisi: la durata viene contata non tanto in termini assoluti (millisecondi etc.) ma in termini relativi alla “misura” o “battuta” e alle altre note (intero, quarto, ottavo etc.). La tabella 2 mostra un riassunto di questo concetto di teoria musicale.
Tabella 2 – La durata delle note in riferimento alla battuta di 4/4. La lettera minuscola tra parentesi ci servirà per indicare la durata della nota.
Un’altra considerazione da fare è quella della altezza del suono da utilizzare. La stessa nota, per esempio un DO, può essere più grave o più acuta a seconda della ottava cui appartiene (vedi lo schema in [4]). Per definire una nota, quindi, dobbiamo anche scegliere un’ottava da 0-10 e mettere questo numero accanto alla nota musicale e prima del tempo di battuta: in pratica, facendo riferimento a quanto detto fin qui, per scrivere una nota, dobbiamo usare uno schema composto da “lettera nota + numero ottava + lettera di durata”), per esempio in questo modo:
C4w
che significa “un DO appartenente alla 4a ottava e che dura una intera battuta (semibreve)”. Vediamo un esempio di codice:
// ESEMPIO: "Ding ding dong" Player player = new Player(); String melodia = "C5q G4q C5h", player.play(melodia); [1]
Stabiliamo il tempo
In musica, il tempo indica quanto velocemente un brano deve essere suonato: in pratica indica la “velocità complessiva” del brano. Spesso è la prima cosa che viene specificata all’inizio della “Stringa Musicale” che andiamo a scrivere. Esso viene descritto come T[tempo] dove al posto di “tempo” dobbiamo mettere il tempo desiderato. Per scegliere un tempo possiamo vedere la tabella 3, in cui i diversi tempi sono anche riferiti ai BPM (“beats per minute”).
Tabella 3 – Intervalli di tempo in JFugue, con riferimento ai BPM.
Ecco alcuni esempi, in cui si vede come sia possibile scegliere o il nome del tempo (Allegro, Andante etc.) oppure indicare direttamente i BPM.
player.play("T[Allegro] V0 I0 G6q A5q V1 A5q G6q"); player.play("T120 V0 I[Piano] G5q G5q V9 [Hand_Clap]q Rq"); // T[Allegro] e T120 sono la stessa cosa
Accordi e inversioni
Se la melodia è il susseguirsi di singole note, l’armonia consiste nel suonare contemporaneamente diverse note distinte fra loro secondo precisi intervalli: si tratta degli accordi. Nella nostra tradizione musicale, la maggior parte delle opere musicali scritte si basano proprio su accordi. Nella tabella 4 è riportato il nome JFugue corrispondente per tutti gli accordi musicali.
Tabella 4 – Le tipologie di accordi e la loro denominazione in JFugue.
La stringa accordo deve essere composta dal nome della nota, l’accordo, la tonalità della scala e la durata, come avviene nell’esempio qui sotto
Player player = new Player(); player.play("Cmaj5q F#min2h Bbmin13^^^");
Notate bene che ad esempio, l’accordo Cmaj può essere scritto come C+E+G. Avrete sicuramente notato, in quanto appena scritto, la nota Bbmin13^^^. Questa nota presenta la particolarità “^”. Questo carattere indica che la nota viene suonata con 3 inversioni di accordo.
Legature fra note
In una partitura, un legame che collega due note della stessa altezza indica che le due note sono suonate come se fossero una nota sola, con la durata complessiva pari alla somma delle durate delle note legate. Si parla di legature di valore. A cosa possono servire? In JFugue le legature possono anche essere utilizzate per collegare le note e creare una durata combinata che altrimenti non potrebbe essere indicata con le normali lettere di durata: per esempio una “half note” più una croma. La figura 1 riporta un esempio.
Figura 1 – Esempio di legature e “traduzione” in JFugue.
Gruppi irregolari e terzine
I “gruppi irregolari” sono gruppi di note la cui durata non si conforma alla naturale suddivisione ritmica del brano musicale. Nella notazione tradizionale sono caratterizzate da un numero scritto sopra la loro legatura. Le terzine sono un caso particolare di gruppi irregolari in cui ci sono 3 note nel gruppo: in pratica, nel tempo in cui dovrebbero essere suonate 2 note, ne vengono invece suonate 3. Le terzine sono i gruppi irregolari più comuni, ma ne sono possibili anche altri. JFugue consente di rendere i gruppi irregolari con il simbolo di asterisco seguito da il numero di note effettivamente suonate, i due punti e la durata effettiva: le terzine vengono pertanto indicate come “*3:2”, le quintine come “*5:4”. Ecco un esempio di codice:
// Queste due righe di codice sono equivalenti player.play("Eq* Fq* Gq*"); player.play("Eq*3:2 Fq*3:2 Gq*3:2"); // 5 note suonate in un tempo di durata 4 player.play("Ci*5:4 Ei*5:4 Gi*5:4 Ei*5:4 Gi:5*4");
L’uso dei Pattern
L’utilizzo dell’oggetto Pattern in JFugue può risultare molto importante se si utilizza più volte uno stesso frammento di brano. Pattern consente di memorizzare una melodia e di richiamarla nel codice ogni qualvolta ci faccia comodo. Ma vediamolo in dettaglio:
//Brano 1 Pattern pattern1 = new Pattern("C5q D5q E5q C5q"); //Brano 2 Pattern pattern2 = new Pattern("E5q F5q G5h"); //Brano 3 Pattern pattern3 = new Pattern("G5i A5i G5i F5i E5q C5q"); //Brano 4 Pattern pattern4 = new Pattern("C5q G4q C5h"); // Mettiamo tutti i pattern insieme Pattern song = new Pattern(); song.add(pattern1, 2); // aggiungiamo pattern1' a 'song' 2 volte song.add(pattern2, 2); // aggiungiamo pattern2' a 'song' 2 volte song.add(pattern3, 2); // aggiungiamo pattern3' a 'song' 2 volte song.add(pattern4, 2); // aggiungiamo pattern4' a 'song' 2 volte // Ascoltiamo Player player = new Player(); player.play(song);
Nell’esempio abbiamo creato 4 Pattern diversi, poi abbiamo creato il Pattern “song” e gli abbiamo aggiunto 2 volte ogni Pattern che avevamo creato. Infine abbiamo passato il Pattern finale chiamato “song” al metodo play di player. Mandando in esecuzione il codice dovreste ascoltare una canzone a voi familiare!
Sento le voci!
Nell’esempio precedente avrete sicuramente riconosciuto il celebre “Fra’ Martino, campanaro…” Adesso riscriviamo il brano aggiungendo le cosiddette voci. Le voci servono a creare delle melodie sovrapposte tra di loro, come avviene per esempio nei cori e controcori. Sicuramente capirete meglio vedendo il codice e ascoltando la melodia rispetto alla precedente.
// Pattern doppia pausa Pattern doubleMeasureRest = new Pattern("Rw Rw"); // Prima voce Pattern round1 = new Pattern("V0"); round1.add(song); // Seconda voce Pattern round2 = new Pattern("V1"); round2.add(doubleMeasureRest); round2.add(song); // Terza voce Pattern round3 = new Pattern("V2"); round3.add(doubleMeasureRest, 2); round3.add(song); // Mettiamo le voci insieme Pattern roundSong = new Pattern(); roundSong.add(round1); roundSong.add(round2); roundSong.add(round3); // Suoniamo! player.play(roundSong);
Ritmi e percussioni
La libreria JFugue ci permette di creare anche dei “Ritmi” di sottofondo alla nostra melodia musicale: questo avviene creando una nuova istanza dell’oggetto Rhythm.
Rhythm rhythm = new Rhythm();
Ogni ritmo può avere uno o più livelli di percussioni che vengono emesse sotto la melodia. Perche’ più livelli? Pensate a una batteria, in cui contemporaneamente l’esecutore suona la cassa con un piede, l’hi-hat con un altro, un piatto con un braccio e un tamburo con un altro.
Per scrivere il ritmo di un livello, usiamo questa tecnica: assegniamo ad ogni strumento componente le percussioni un simbolo: per esempio, un simbolo per la cassa (“bass drum”), un simbolo per il rullante (“acoustic snare”) e così via. Successivamente, effettueremo una sostituzione in cui specifichiamo il rapporto tra simbolo e percussione. In tal modo, dovremo semplicemente pensare a scrivere un ritmo di percussioni con i simboli, per esempio “ooO’ ooO’ ooO’ OOO'”, dove la lettera minuscolo (o) potrebbe rappresentare uno snare drum, la maiuscola (O) una bass drum, e l’apostrofo (‘) un hi-hat. Ecco l’esempio:
rhythm.setLayer(1, "O..oO...O..oOO.."); rhythm.setLayer(2, "..*...*...*...*."); rhythm.setLayer(3, "^^^^^^^^^^^^^^^^"); rhythm.setLayer(4, "...............!"); rhythm.addSubstitution('O', "[BASS_DRUM]i"); rhythm.addSubstitution('o', "Rs [BASS_DRUM]s"); rhythm.addSubstitution('*', "[ACOUSTIC_SNARE]i"); rhythm.addSubstitution('^', "[PEDAL_HI_HAT]s Rs"); rhythm.addSubstitution('!', "[CRASH_CYMBAL_1]s Rs"); rhythm.addSubstitution('.', "Ri"); // creo il pattern per il ritmo Pattern pattern = rhythm.getPattern(); // ripeto il ritmo quattro volte pattern.repeat(4); // Suona! Player player = new Player(); player.play(pattern);
Che ve ne pare? Non sentite un suono elettrizzante? Non vi piace? Allora date un’occhiata alle percussioni nella tabella 5 e provate voi a creare il vostro ritmo!
Tabella 5 – Valori e denominazione delle percussioni in JFugue.
Strumenti musicali
Adesso che avete avuto una panoramica di tutte le funzionalità di JFugue possiamo cambiare il nostro pianoforte, strumento utilizzato di default, con un bel piano elettrico, oppure con una chitarra o un flauto: avete solo l’imbarazzo della scelta! Vediamo in dettaglio un esempio:
player.play("I[Piano] C5q D5q I[Flute] G5q F5q");
Ovviamente se volete cambiare strumento musicale, basta cambiare la stringa tra le parentesi quadre, facendo riferimento alla tabella 6.
Tabella 6 – L’intera gamma degli strumenti e la denominazione in JFugue.
Creiamo il file MIDI
Dopo che ci siamo sbizzarriti con la fantasia a creare la nostra melodia, salviamola per farla ascoltare ai nostri amici, per creare dei file karaoke o perchè no, per usarla come suoneria per il nostro cellulare! A tal fine, creeremo un file MIDI, un formato standard [4] che viene letto da moltissimi dispositivi, software e hardware.
// melodia = stringa contenente le note //C:\melodia.midi = path di destinazione del file midi player.saveMidi(melodia, "C:\melodia.mid");
Non ci resta che mandare in esecuzione il programma e verificare se il nostro file è stato salvato. Clicchiamo infine su “melodia.mid” con il nostro player musicale predefinito di sistema per ascoltare la nostra melodia
Conclusione
Nel nostro viaggio all’interno della programmazione musicale tramite il linguaggio Java abbiamo scoperto l’API Java JFugue, libreria per creare e suonare musica. Abbiamo introdotto alcuni riferimenti alla teoria musicale per provare a comporre la nostra prima melodia. Con JFugue possiamo suonare musica, accordi, spartiti e mettere in sottofondo il ritmo percussivo che più ci piace. Infine possiamo salvare la nostra melodia in formato MIDI. Tutto in maniera semplice: basta solo conoscere un po’ di teoria musicale e il gioco è fatto.
Sul sito della libreria creata dal prolifico David Koelle [3] sono presenti anche delle informazioni riguardanti JFugue con l’utilizzo di NetBeans e LilyPond uno strumento open source per scrivere musica con JFugue. Inoltre è presente anche un’area di scambio musicale, dove ogni autore può pubblicare la propria composizione.
Questa è una delle poche librerie Java che esistono che permette di comporre musica a un livello non elementare. Non è molto conosciuta, quindi spero che questo contributo possa spingere la comunità di sviluppatori Java a conoscere questa importante risorsa, a diffonderla e, perche’ no, magari anche a migliorarla! Sul sito [5], infatti, è presente la “lista dei desideri” in cui sono riportate tutte le funzionalità da implementare in futuro: dategli un’occhiata e, se la musica e la programmazione vi appassionano, allora potete contribuire sicuramente!
Riferimenti
[1] JFugue. Java API for Music Programming 2002-2010
[2] David Koelle, The Complete Guide to JFugue 2008
http://www.jfugue.org/book.html
[3] David Koelle è l’inventore di JFugue nonche’ sviluppatore di altri progetti
[4] Il protocollo MIDI, voce “Musical Instrument Digital Interface” su Wikipedia
http://it.wikipedia.org/wiki/Musical_Instrument_Digital_Interface
[5] La wishlist sul sito di JFugue
http://www.jfugue.org/wishlist.html
[6] La voce JFugue su Wikipedia
http://en.wikipedia.org/wiki/JFugue