gramophone2(1)

NOME
gramophone2 - GRAMophone e' un generatore algoritmico per la composizione musicale.

USO
gramophone2 [-c|-d] sourcefile [midifile]

OPZIONI

-c  e' un'opzione che consente di effettuare semplicemente il controllo della sintassi del sorgente senza generare la musica.

-d  e' un'opzione che consente di attivare una modalita' di debug, con stampa a video dei valori dei parametri della composition, dei parametri dei players e delle note generate.

DESCRIZIONE
In GRAMophone la generazione della musica viene realizzata tramite l'uso di due tipi di grammatiche formali: la grammatica regolare di Chomsky (o di tipo 3) per un approccio TOP DOWN alla composizione e una versione ridotta della grammatica di Lindenmayer per un approccio BOTTOM UP.

CONCETTI BASE DI GRAMophone
GRAMophone si basa in parte su un'idea di Jon McCormack, da cui riprende il concetto di virtual player (musicista virtuale). Il player e' associato ad una traccia MIDI ed e' responsabile per l'interpretazione delle istruzioni che gli vengono date, che nel caso generale significa suonare note (mandare messaggi MIDI). L'insieme dei player in GRAMophone forma l'orchestra, che esegue una compositione.

Un qualunque numero di player puo' essere impiegato in una composition, anche se le caratteristiche dell'hardware potrebbero fissare una limitazione sul numero.

Generalmente ogni player suona un proprio strumento e ciascuno ha un insieme differente di regole. Un singolo player e' caratterizzato da un insieme di parametri comuni a tutta l'orchestra e/o un insieme di parametri personali.

I parametri che caratterizzano l'orchestra sono:

    il tipo di grammatica utilizzata per la generazione (Chomsky o Lindenmayer);

    il metronomo;

    la misura;

    il numero di iterazioni per il processo delle produzioni.

Le caratteristiche personali di ciascun player sono:

    il tipo di grammatica utilizzata per la generazione (Chomsky o Lindenmayer);

    lo strumento suonato;

    il canale MIDI a cui e' associato;

    il numero di iterazioni per il processo delle produzioni.

Le note suonate dai player mantengono uno stato corrente che consiste di:

    ottava

    volume

    durata

    rilascio

Queste caratteristiche possono essere controllate parametricamente tramite la dichiarazione da parte di ciascun player di variabili ad esse associate. GRAMophone, infine, offre la possibilita' di generare musica in maniera non deterministica, sia con la grammatica di Chomsky sia con quella di Lindenmayer.

GUIDA A GRAMophone
Di seguito viene riportata la piu' semplice composizione algoritmica che si puo' generare con GRAMophone, per introdurne i concetti fondamentali. Questa composizione genera semplicemente la nota LA e viene presentata sia con il metodo di Chomsky sia con quello di Lindenmayer.

composition "Give Me A" of "Schroeder" {

  //this composition generates the A note with the Chomsky grammar

  grammar chomsky
  tempo 120
  time_signature 4/4
  %
  player Schroeder {
    instrument 0
    %
    @composition->A[,,,];
  }
}

composition "Give Me A" of "Schroeder" {
  //this composition generates the A note with the Lindenmayer grammar
  grammar lindenmayer
  tempo 120
  time_signature 4/4
  %
  player Schroeder {
    instrument 0
    %
    axiom->A[,,,];
  }
}

LE PAROLE CHIAVE composition E of

Ogni composizione algoritmica deve iniziare con la parola chiave composition, a cui deve seguire una stringa (racchiusa tra doppi apici) con il nome della composizione. Di seguito e' richiesta la parola chiave of, a cui deve seguire un'altra stringa con il copyright del brano.

IL BLOCCO DELLA COMPOSIZIONE

Il blocco della composizione e' delimitato dalle parentesi graffe. e' suddiviso in tre sezioni: una sezione per la definizione dei parametri della composizione, una per la dichiarazione e la inizializzazione delle eventuali variabili globali e una sezione orchestra, dove si definiscono i vari player che "suoneranno" il pezzo. Le prime due sezioni sono separate dal simbolo %.

LA PAROLA CHIAVE player

Ciascun player si definisce tramite la parola chiave player, seguita da un identificatore.

IL BLOCCO DEL player

Il blocco del player e' delimitato dalle parentesi graffe ed e' diviso in tre sezioni: una sezione per la definizione dei parametri della traccia associata al player, una parte di dichiarazione e inizializzazione per le eventuali variabili locali del player e la sezione per le regole formali. Le prime due sezioni sono separate dal simbolo %.

COMMENTI

In GRAMophone, i commenti sono C-like: devono iniziare con la coppia di caratteri '/*' e devono terminare con la coppia di caratteri '*/'. Fra l'asterisco e la barra non devono essere inseriti spazi. Tutto cio' che si trova tra queste coppie di simboli verra' ignorato dal parser di GRAMophone. e' possibile definire anche intere linee di commento. Le righe di commento iniziano con il simbolo // e terminano alla fine della riga, come nel caso dei due esempi iniziali.

Sezione di definizione parametri della composition

Qui si dichiarano i parametri comuni a tutti i player dell'orchestra. I parametri che possono essere dichiarati sono:

    grammar

    resolution

    iterations

    tempo

    time_signature

Questa sezione deve terminare con il simbolo %.

grammar

Questo parametro e' obbligatorio e definisce il tipo di grammatica che verra' usato per la generazione. Il tipo puo' essere chomsky o lindenmayer.

resolution

Questo parametro indica il numero di unita' di tempo per la durata di 1/4. Se omesso, verra' usato il valore di default 480.

iterations

Questo parametro indica il numero di iterazioni per la generazione. Ha un significato differente a seconda del tipo di grammatica scelto, come verra' spiegato in seguito. Se omesso, viene utilizzato il valore di default 1.

tempo

Questo parametro indica il metronomo della composizione. Se omesso, viene utilizzato il valore di default 120.

time_signature

Questo parametro indica la misura della composizione. Se omesso, viene utilizzato il valore di default 4/4.

Sezione di dichiarazione variabili globali della composition

Le variabili servono per controllare parametricamente gli attributi di una nota e verrano spiegate in seguito.

Sezione di definizione parametri del player

Qui si dichiarano i parametri personali e le variabili di ciascun player. I parametri personali che possono essere dichiarati sono:

    instrument

    channel

    iterations

Questa sezione deve terminare con il simbolo %.

instrument

Questo parametro indica il tipo di strumento da far suonare al player. Gli strumenti di GRAMophone coincidono con il set di strumenti del General MIDI. Il range di valori accettati va da 0 a 127; ci sono quindi 128 strumenti da cui scegliere. Di seguito viene riportata una tabella con il codice e lo strumento a cui esso fa riferimento:

    0 Piano

    1 Brite Piano

    2 HammerPiano

    3 Honkey Tonk

    4 New Tines

    5 Digital Piano

    6 Harpsichord

    7 Clavi

    8 Celesta

    9 Glocken

    10 Music Box

    11 Vibes

    12 Marimba

    13 Xylophon

    14 Tubular Bell

    15 Santur

    16 Full Organ

    17 Percussive Organ

    18 BX-3 Organ

    19 Church Organ

    20 Positive

    21 Musette

    22 Harmonica

    23 Tango

    24 Classic Guitar

    25 Acoustic Guitar

    26 Jazz Guitar

    27 Clean Guitar

    28 Mute Guitar

    29 Overdrive Guitar

    30 Distorted Guitar

    31 Harmonics

    32 Jazz Bass

    33 Deep Bass

    34 Pick Bass

    35 Fretless Bass

    36 Slap Bass 1

    37 Slap Bass 2

    38 Syntethized Bass 1

    39 Syntethized Bass 2

    40 Violin

    41 Viola

    42 Cello

    43 Contra Bass

    44 Tremolo String

    45 Pizzicato

    46 Harp

    47 Timpani

    48 Marcato

    49 Slow String

    50 Analog Pad

    51 String Pad

    52 Choir

    53 Doo Voice

    54 Voices

    55 Orchestra Hit

    56 Trumpet

    57 Trombone

    58 Tuba

    59 Mute Trumpet

    60 French Horn

    61 Brass Section

    62 Synthetized Brass 1

    63 Synthetized Brass 2

    64 Soprano Sax

    65 Alto Sax

    66 Tenor Sax

    67 Baritone Sax

    68 Sweet Oboe

    69 English Horn

    70 Bassoon Oboe

    71 Clarinet

    72 Piccolo

    73 Flute

    74 Recorder

    75 Pan Flute

    76 Bottle

    77 Shakhukuhachi

    78 Whistle

    79 Ocarina

    80 Square Lead

    81 Saw Lead

    82 Caliope Lead

    83 Chiff Lead

    84 Charang Lead

    85 Air Chorus

    86 Rezzo4ths

    87 Bass & Lead

    88 Fantasia

    89 Warm Pad

    90 Poly Synth Pad

    91 Ghost Pad

    92 Bowed Pad

    93 Metal Pad

    94 Halo Pad

    95 Sweep Pad

    96 Ice Rain

    97 Soundtrack

    98 Crystal

    99 Atmosphere

    100 Brightness

    101 Goblin

    102 Echo Drop

    103 Star Theme

    104 Sitar

    105 Banjo

    106 Shamisen

    107 Koto

    108 Kalimba

    109 Scotland

    110 Fiddle

    111 Shanai

    112 Metal Bell

    113 Agogo

    114 Steel Drums

    115 Wood Blok

    116 Taiko Drum

    117 Melodic Tom

    118 Synth Tom

    119 Reverse Cymbal

    120 Fret Noise

    121 Noise Chiff

    122 Seashore

    123 Birds

    124 Telephone

    125 Helicopter

    126 Stadium!!

    127 Gunshot

Se il parametro instrument viene omesso, viene utilizzato il valore di default 0.

channel

Questo parametro indica quale canale Midi associare al player. I canali possibili sono 16. Il canale 10 e' speciale ed e' riservato alle percussioni. Se omesso, viene assegnato il valore di default 1.

iterations

Questo parametro indica il numero di iterazioni per la generazione. Ha un significato differente a seconda del tipo di grammatica scelto, come verra' spiegato in seguito. Se il parametro iterations e' presente anche nella parte dichiarativa della composition, quest'ultimo verra' ignorato.

Sezione di dichiarazione variabili locali del player

Le variabili servono per controllare parametricamente gli attributi di una nota e verrano spiegate in seguito.

COME SI SCRIVONO LE NOTE IN GRAMophone

Le note in GRAMophone sono la prima categoria di simboli terminali in GRAMophone.

GRAMophone usa la notazione inglese per il nome delle note:

    la nota LA e' A;

    la nota SI e' B;

    la nota DO e' C;

    la nota RE e' D;

    la nota MI e' E;

    la nota FA e' F;

    la nota SOL e' G;

I nomi delle note devono essere scritti obbligatoriamente in maiuscolo. I simboli bemolle e diesis sono rappresentati rispettivamente dal carattere 'b' minuscolo e '#'; essi vanno scritti di seguito senza spazi al nome della nota: A#, Gb, eccetera.

ATTRIBUTI DELLE NOTE

Le note sono caratterizzate da quattro attributi: l'ottava, l'intensita', la durata e il rilascio. In GRAMophone questi quattro attributi sono chiamati rispettivamente octave, velocity, duration e release. L'attributo octave varia da -2 a 8, mentre gli attributi velocity e release variano da 0 a 127. Se la nota viene scritta senza specificare alcun attributo, vengono utilizzati i valori di default: 3 per l'ottava, 64 per l'intensita' e il rilascio, il valore di default corrente della resolution (semiminima) per la durata. Nell'esempio "Give me A" nel corpo della produzione e' scritto semplicemente A[,,,]. Questo vuol dire che viene generata una nota LA suonata alla terza ottava, della durata di 1/4 e con un'intensita' ed un rilascio pari a 64.

DEFINIRE GLI ATTRIBUTI DI UNA NOTA

Per definire gli attributi di una nota, questi vanno scritti all'interno di parentesi quadre che seguono senza spazi il nome della nota. Ciascuna nota puo' avere al massimo quattro attributi e puo' essere definito solo un attributo per ciascun tipo.

L'ordine con cui vanno definiti gli attributi di diverso tipo e' il seguente:

    ottava

    intensita'

    durata

    rilascio

Se non vengono definiti tutti e tre i tipi di attributo, per quelli mancati vengono utilizzati i valori di default.

Esempi di note con attributi sono i seguenti:

    C[2, 50+60/2, 240*4,] - suona un Do alla seconda ottava, con un'intensita' di 80, la durata di 960 (minima con resolution impostata a 480) ed un rilascio di 64 (valore di default);

    Db[4,,,] - suona un RE bemolle alla quarta ottava, usando i valori di default per la velocity, la duration e la release;

    F#[,,,] - usa i valori di default per tutti gli attributi;

Esempi errati sono i seguenti:

    Db[3, 127, 960, 64, x] - troppi attributi (x e' una variabile).

PAUSE

Le pause sono un'altra categoria dei simboli terminali di GRAMophone. Si indicano con la lettera R e accettano solo il tipo di attributo duration. Se non specificato, viene utilizzato il valore di default della resolution. La definizione dell'attributo avviene in maniera analoga alle note.

Esempi di pause sono i seguenti:

    R[480/2] - una pausa che dura 240 (il tempo di una croma con resolution a 480);

    R[] - usa il valore di default per l'attributo di tipo duration.

ACCORDI

Gli accordi sono l'ultima categoria di simboli terminali usati da GRAMophone. Un accordo e' una serie di note suonate simultaneamente. In GRAMophone le note suonate in un accordo sono racchiuse tra due simboli '^'.

Esempi di accordi sono i seguenti:

    ^C[,,,]E[,,,]G[,,,]^ - suona un accordo di DO maggiore, utilizzando i valori di default per ciascuna nota.

    ^A[2,80,240,]C[2,,240,]E[2,,240,]^ - suona un accordo di LA minore della durata di 1/8, con tutte le note suonate alla seconda ottava con un rilascio di 64 (valore di default), con la prima nota dell'accordo suonata ad un'intensita' di 80 e le restanti due ad un'intensita' di 64 (valore di default).

RUOLO DI R NEGLI ACCORDI COMPLESSI

Non sempre le note in un accordo hanno la stessa durata. Ad esempio puo' capitare che in una battuta, mentre suona una nota C[2,,1920,] della durata di 4/4, il musicista debba contemporaneamente suonare quattro note della durata di una semiminima ciascuna nel seguente ordine: C[,,,], E[,,,], G[,,,], Bb[,,,]. All'interno dell'accordo quindi bisogna trovare un modo per dire a GRAMophone che le note C[2,,1920,] e C[,,,] devono cominciare a suonare nello stesso istante, che E[,,,] deve iniziare a suonare dopo una pausa di 1/4, G[,,,] dopo 2/4 e Bb[,,,] dopo 3/4. In GRAMophone questo si scrive nella seguente maniera:

^C[2,,1920,]C[,,,]R[]E[,,,]R[960]G[,,,]R[1440]Bb[,,,]^

Cioe' davanti a ciascuna nota dell'accordo si puo' definire una pausa che rappresenta il tempo che bisogna aspettare prima che la nota inizi a suonare.

L'ordine con cui si scrivono le note nell'accordo non ha importanza. L'accordo precedente si puo' scrivere anche come:

^R[]E[,,,]C[2,,1920,]R[1440]Bb[,,,]C[,,,]R[960]G[,,,]^

IDENTIFICATORI

Alcune entita' del linguaggio di GRAMophone, come ad esempio le variabili, le macros ed i simboli non terminali della grammatica di Chomsky, devono avere dei nomi per mezzo dei quali possano essere identificate. Questi nomi vengono chiamati identificatori e vengono scelti dal compositore. Gli identificatori usati dal linguaggio di GRAMophone riprendono gli identificatori del linguaggio Pascal. Infatti un identificatore e' formato da una lettera seguita da una sequenza di lettere o cifre. Gli identificatori di GRAMophone, inoltre, devono essere obbligatoriamente scritti in minuscolo.

Grammatica di Chomsky

SIMBOLI NON TERMINALI

Nella grammatica di Chomsky i simboli non terminali servono per dare una struttura e uno 'stile' alla composizione musicale. I simboli non terminali si scrivono con un carattere '@' seguito senza spazi da un identificatore. La grammatica di Chomsky utilizzata da GRAMophone e' libera dal contesto, quindi la testa delle produzioni puo' essere solo un non terminale.

IL SIMBOLO NON TERMINALE @composition

e' il simbolo non terminale che corrisponde a quella che sara' la composizione finale del singolo player ed e' obbligatorio.

OPERATORE DI PRODUZIONE

e' definito dalla sequenza di caratteri '->' e separa la testa della produzione dal corpo della produzione.

CORPO DELLA PRODUZIONE

Puo' contenere sequenze di simboli terminali (note, pause e accordi) e di simboli non terminali. Ciascuna produzione deve terminare con un punto e virgola.

OPERATORE | (OR)

Una produzione puo' essere non deterministica, cioe' presentare due o piu' possibilita' tra cui scegliere durante la generazione. Il corpo di una produzione non deterministica e' formato dalle varie possiblita' separate dall'operatore |. Ad esempio

@non_det->A[,,,]B[,,,]@Seq1|^A[,,,]B[,,,]C[,,,]^@Seq2R[]C[,,,];

e' una produzione non deterministica.

SIGNIFICATO DELLE ITERAZIONI NELLA GRAMMATICA DI CHOMSKY

Nella grammatica di Chomsky possono capitare produzioni che contengono cicli, cioe' produzioni nel cui corpo sono presenti simboli non terminali che fanno riferimento alla produzione che si sta processando, ad esempio:

@Sequenza1->B[,,,]A[,,,]C[,,,]@Sequenza1;

Per evitare un loop infinito durante la generazione, il simbolo non terminale @Sequenza1 viene processato un numero di volte pari al parametro iterations.

Grammatica di Lindenmayer

La grammatica di Lindenmayer tratta solo simboli terminali e quella adottata da GRAMophone puo' essere libera dal contesto o operare in un contesto polifonico. Nella testa delle produzioni possono esserci quindi singole note o accordi. Ogni produzione e' separata da un punto e virgola.

AXIOM

e' la produzione iniziale da cui parte la generazione. e' obbligatoria.

OPERATORE DI PRODUZIONE

e' definito dalla sequenza di caratteri '->' e separa la testa della produzione dal corpo della produzione.

OPERATORE | (OR)

Una produzione puo' essere non deterministica, cioe' presentare due o piu' possibilita' tra cui scegliere durante la generazione. Il corpo di una produzione non deterministica e' formato dalle varie possibilita' separate dall'operatore |. Ad esempio

A[,,,]->A[,,,]B[,,,]|C[,,,]D[,,,];

e' una produzione non deterministica.

SIGNIFICATO DELLE ITERAZIONI NELLA GRAMMATICA DI LINDENMAYER

A ciascun passo vengono applicate alla stringa di note corrente tutte le produzioni della grammatica contemporaneamente. Il parametro iterations in questo caso rappresenta il numero di passi da effettuare.

Uso delle variabili

DICHIARAZIONE E INIZIALIZZAZIONE DELLE VARIABILI

GRAMophone e' in grado di controllare gli attributi di una nota parametricamente mediante l'uso di variabili. Queste variabili si dichiarano nella parte dichiarativa del player e possono essere di tipo octave, velocity, duration e msb. Una variabile si dichiara scrivendo il tipo seguito da uno o piu' identificatori separati da una virgola e la dichiarazione dev'essere terminata da un punto e virgola. Per ogni player un identificatore puo' essere dichiarato solo una volta.

Sono dichiarazioni corrette le seguenti:

    velocity x, y;

    octave oct, z;

    duration w;

Sono dichiarazioni scorrette le seguenti:

    velocity x, x;

    octave z;

    duration z;

Dopo la parte dichiarativa e prima della grammatica e' possibile inizializzare le variabili dichiarate mediante l'operatore =.

Un Esempio di dichiarazione e inizializzazione e' il seguente:

    velocity x;

    x=0;

USARE LE VARIABILI CON LE NOTE

Le variabili si usano nelle espressioni degli attributi della nota. GRAMophone esegue il controllo dei tipi nelle espressioni, quindi ad esempio non e' possibile sommare una variabile di tipo octave con una di tipo velocita'.

Un esempio di nota variabile e' la seguente:

    velocity x;

    duration z, w;

    A[4,x,z+w,].

ESEMPIO
composition "Crescendo" of "Schroeder" {

  //this composition generates 64 A notes with a growing velocity

  grammar chomsky
  tempo 120
  time_signature 4/4
  iterations 64
  %
  player Schroeder {
    instrument 40
    %
    velocity x=0;

    @composition->[A,x=x+1,,]@composition;
  }
}

CONDIZIONI

Nelle produzioni sia della grammatica di Chomsky sia della grammatica di Lindenmayer e' possibile definire delle condizioni sulle variabili eventualmente presenti nel corpo delle produzioni. Se la condizione e' verificata, la produzione viene processata altrimenti no. Una condizione si definisce subito dopo il nome della produzione tramite il simbolo '?' seguito da una o piu' espressioni booleane.

Gli operatori booleani sono:

    !    not

    &&    and

    ||    or

Gli operatori relazionali sono:

    ==    uguale

    !=    diverso

    <    minore

    >    maggiore

    <=    minore o uguale

    >=    maggiore o uguale

Un esempio di produzione con condizione e' la seguente:

@battuta?x!=0->A[,x=x-10,,]@battuta;

il suo significato e' il seguente: finche' x e' diverso da zero, genera la produzione @battuta, altrimenti no.

Discography, la libreria di GRAMophone

GRAMophone e' in grado di includere librerie esterne, che vengono chiamate discografie. Per includere in un file sorgente una discografia si usa la parola chiave discography, seguita dal nome del file che la identifica. Una discography puo' essere inclusa in qualsiasi punto del file sorgente, purche' il suo contenuto sia in sintonia con la posizione del sorgente dove e' stata inserita.

Macros

e' possibile definire macros utilizzando la parola chiave define, seguita da un identificatore scritto obbligatoriamente in minuscolo e da una stringa chiusa tra doppi apici. Le macros vanno definite obbligatoriamente all'inizio della composizione sorgente, prima cioe' della parola chiave composition. Ad esempio, se vogliamo scrivere semplicemente a al posto di A[,,,], bisogna definire la seguente macro:

define a "A[,,,]"

LA FUNZIONE repeat()

La funzione repeat() prende come argomento un valore di tipo msb ed una sequenza di Chomsky o Lindenmayer. Permette di ripetere la sequenza inserita per un numero di volte pari al valore di tipo msb inserito.

LA FUNZIONE rand()

La funzione rand() prende come argomento un'espressione e ritorna un valore casuale minore del risultato dell'espressione.

Operatori melodici di GRAMophone

transpose()

L'operatore transpose() prende come argomento un valore di tipo msb ed una sequenza di Chomsky o Lindenmayer. Genera una sequenza in cui tutte le note della sequenza presa come argomento vengono trasposte di un numero di semitoni pari al valore di tipo msb inserito.

inversion()

L'operatore inversion() prende come argomento una sequenza di Chomsky o Lindenmayer. Genera una sequenza in cui gli intervalli tra la prima e le restanti note della sequenza presa come argomento vengono calcolati in direzione opposta.

retrograde()

L'operatore retrograde() prende come argomento una sequenza di Chomsky o Lindenmayer. Genera una sequenza contraria a quella inserita come argomento.

AUTORE
Giovanni Ferranti <giovanni_at_giovanniferranti_dot_it>