La version en français est disponible plus bas.
This library sets up a simple but complete notation system, called MELO, in order to write melodies (a series of musical notes in a single voice) in order to facilitate the bridge between musical notation and sound generation.
On the one hand, musical notation makes it possible to write a series of notes, according to standards known for a long time; letters and symbols are used to name notes, to specify rhythm changes or alterations (sharps, flats), or even repetitions.
On the other hand, the generation of a sound with Arduino (usually using a buzzer), should rather be expressed by the frequency of the sound (in Hz), its duration (in milliseconds) and its loudness (which depends on the material used).
As a musician, writing music for Arduino, in terms of Hz and milliseconds is definitely a drag and weighs down writing, while not taking advantage of the already rich musical notation. The Melody library is the bridge between the two.
The MELO notation (MELO stands for Melody) is a textual format which allows the simplified writing of a melody of a single voice. This notation is notably inspired by standard musical notation.
" c d e f g a b c* "
"g<<r-d- | g<< r-d-(g<dg<b)-d<*r | c*<<r-a-c*<<r-a- |(c*<af#<a)-d<r | (gr)- g. (bag | (gag)/3:1 f#)- f#. (ac*f# | ag)- g. (bag | (gag)/3:1 f#)- f#. (ac*f#)- | ((grgr)-- (gf#ef#)--)>> ((grgr)-- (baga)--)> | (brbr)-- (d*c*bc*)-- d*< r | ((de)+ | (d-c.)-c (c-b_.)- b_ | (( b-a.)- a (gf#ef# | (grarbr)>)- r )_)> "
" (cccde+d+ ceddc++)x2 | dddd (aa)+_ dc(b a g++)_ | cccde+d+ ceddc++ "
A sequence is the basic form of the MELO notation. It is made up of a series of notes or groups of notes, followed by a modifier. You can space these series of notes or groups apart or not. Each modifier will modify the note or the group of notes that precede it.
A note is represented by a letter (uppercase or lowercase), according to the standard nomenclature C (do), D (ré), E (mi) F (fa), G (sol), A (la), B (si) . We also add the letter R (rest) for the rests. By default, the notes are those of the 4th octave, where the note A is of frequency 440 Hz; they all have a relative duration of 1, corresponding to a 'quarter note' in standard musical notation.
A group makes it easy to apply a modifier to an entire sequence at once, in order to lighten the writing. A group is delimited by a pair of parentheses.
A modifier is a sequence of alterations that allows you to modify the pitch, duration, number of repetitions or loudness of a note or group of notes. You can specify several modifiers in a row; they have the properties of being commutative, that is to say that the order in which they are written will not matter.
A pitch modifier lets you raise or lower a note by a semitone or an octave.
A duration modifier allows you to multiply the duration of a note by a simple factor (2, 1/2 or 3/2); it also allows you to specify more precisely any type of time weighting (for example, for triplets). By default, all notes have a duration of 1.
A repeat modifier allows you to specify a number of consecutive repetitions for the note or group of notes concerned.
A sound intensity modifier allows you to increase or decrease the strength of the sound. A note has, by default, an intensity of 0; we can therefore go there with positive or negative values. Since the actual loudness depends on the hardware used, it is suggested to use a relative scale ranging from -3 (really really soft, or ppp) to +3 (really really loud, or fff).
An integer must be strictly positive (cannot be zero).
Allowed spaces include characters commonly used as spacers; we add the vertical bar '|', because it is often used in musical notation to identify measures and facilitate reading for the user. These spaces are optional and are ignored when decoding the text.
-" | cdec | cdec | " is equivalent to "cdeccdec"
Note : It is suggested to use the library Musician with Melody to make it easier to play sound with your hardware.
#include <Melody.h>
#define PIN_BUZZER 12
Melody melody("c d e f g a c*");
void setup() {
melody.setTempo(120); //May be changed whenever you want
}
void loop() {
melody.restart();
while(melody.hasNext()){
melody.next();
unsigned int freq = melody.getFrequency();
unsigned long duration = melody.getDuration();
int loudness = melody.getLoudness();
freq > 0 ? tone(PIN_BUZZER,freq,duration) : noTone();
// loudness could be use with a mapping, according to your buzzer or sound-producing hardware
//For Example :
/*
{
int realIntensity = map(loudness, -4, 4, 0, 1023);
myBuzzer.setIntensity(realIntensity);
}
*/
}
}
Melody(const char* score);
Melody(String score);
Melody(const char* score, unsigned int tempo);
Melody(String score, unsigned int tempo);
The constructor must receive the melody score (const char* or String), which is a text string formatted according to the MELO notation. You can specify the score and tempo right from the start, if needed.
If your MELO text string contains an invalid caracter or an invalid syntax, the Melody object will simply return the portion of the melody before the error was incountered.
For example:
Melody melody(" c d e f g k b");
Because of the invalid caracter 'k', this melody will be equivalent to:
Melody melody(" c d e f g ");
void setScore(const char * score)
void setScore(String score)
This method allows you to modify the score used, which is a text string formatted according to the MELO notation.
void setTempo(unsigned int tempo)
int getTempo()
This method allows you to read and modify the tempo of the music, which corresponds to the number of musical beats during one minute. For example, a tempo of 120 means that there will be 120 1-beat notes played for 1 minute - or each note will be 0.5 seconds long.
void restart()
This method allows you to restart melody iteration.
int length()
This method returns the total number of notes in the melody.
bool hasNext()
This method lets you know if there is a next note to play in the melody. It must be used with the next()) method;
void next()
This method skips to the next note of the melody.
int index()
This method returns the index of the current note, in zero base.
unsigned int getFrequency()
This method returns the value in Hz of the current note. If the value is zero, it means it is silence.
unsigned long getDuration()
This method returns the duration of the current note, in milliseconds.
int getLoudness()
This method returns the relative loudness of the current note.
Cette librairie instaure un système de notation simple mais complet, appelé MELO, afin d'écrire des mélodies (suite de notes musicales à une seule voix) dans le but de faciliter le pont entre la notation musicale et la génération du son.
D'un côté, la notation musicale permet d'écrire une suite de notes, selon des standards connus depuis longtemps; on y utilise des lettres et des symboles afin de nommer les notes, spécifier des changements de rythmes ou des altérations (dièses, bémols), ou même des répétitions.
De l'autre côté, la génération d'un son avec Arduino (habituellement à l'aide d'un buzzer), doit plutôt être exprimé par la fréquence du son (en Hz), sa durée (en millisecondes) et son intensité sonore (qui dépend du matériel utilisé).
En tant que musicien, écrire de la musique pour Arduino, en terme de Hz et de millisecondes est définitivement un frein et alourdit l'écriture, tout en ne mettant pas à profit la notation musicale déjà très riche. La librairie Melody vient faire le pont entre les deux.
La notation MELO (pour Melody) est un format textuel qui permet l'écriture simplifié d'une mélodie à une voix. Cette notation s'inspire notamment de la notation musicale standard.
Exemple :
" c d e f g a b c* "
"g<<r-d- | g<< r-d-(g<dg<b)-d<*r | c*<<r-a-c*<<r-a- |(c*<af#<a)-d<r | (gr)- g. (bag | (gag)/3:1 f#)- f#. (ac*f# | ag)- g. (bag | (gag)/3:1 f#)- f#. (ac*f#)- | ((grgr)-- (gf#ef#)--)>> ((grgr)-- (baga)--)> | (brbr)-- (d*c*bc*)-- d*< r | ((de)+ | (d-c.)-c (c-b_.)- b_ | (( b-a.)- a (gf#ef# | (grarbr)>)- r )_)> "
" (cccde+d+ ceddc++)x2 | dddd (aa)+_ dc(b a g++)_ | cccde+d+ ceddc++ "
La mélodie est la forme de base de la notation. Elle est formée d'une suite de note ou de groupe de notes, suivi de modificateur. On peut espacer ou non ces suites de notes ou groupes. Chaque modifieur viendra modifier la note ou le groupe de notes qui le précède.
Une note est représenté par une lettre (majuscule ou minuscule), selon la nomenclature standard C (do), D (ré), E (mi) F (fa), G (sol), A (la), B (si). On ajoute également la lettre R (rest) pour les silences. Par défaut, les notes sont celles de la 4e octave, où la note LA est de fréquence 440 Hz; elles ont toutes une durée relative de 1, correspondant à une noire en notation musicale standard.
Un groupe permet facilement d'appliquer un modifieur à toute une mélodie d'un seul coup, afin d'alléger l'écriture. Un groupe est délimité par une paire de parenthèses.
Un modifieur est une suite d'altération qui permet de modifier la hauteur, la durée, le nombre de répétition ou l'intensité sonore d'une note ou d'un groupe de notes. On peut spécifier plusieurs modifieurs de suite; ils ont la propriétés d'être commutatif, c'est-à-dire que l'ordre dans lequel on les écrit n'aura pas d'importance.
Un modifieur de hauteur du son permet d'augmenter ou d'abaisser une note d'un demi-ton ou d'un octave.
Un modifieur de durée permet de multiplier la durée d'une note par un facteur simple (2, 1/2 ou 3/2); il permet aussi de spécifier plus précisément n'importe quel type de pondération du temps (par exemple, pour les triolets). Par défaut, les notes ont toutes une durée de 1.
Un modifieur de répétition permet de spécifier un nombre de répétition consécutifs pour la note ou le groupe de notes concernés.
Un modifieur d'intensité sonore permet d'augmenter ou de diminuer la force du son. Une note a, par défaut, une intensité de 0; on peut donc y aller avec des valeurs positives ou négatives. Puisque l'intensité sonore réelle dépend du matériel utilisé, il est suggéré d'utiliser une échelle relative allant de -3 (ppp) à +3 (fff).
Un nombre entier doit être strictement positif (ne peut pas valoir zéro).
Les espaces permis incluent les caractères couramment utilisé comme espaceur; on y ajoute la barre verticale '|', car elle est souvent utilisée en notation musicale pour repérer les mesures et faciliter la lecture pour l'utilisateur. Ces espaces sont facultatifs et sont ignorés lors du décodage du texte.
-" | cdec | cdec | " est équivalent à "cdeccdec"
Note : Il est fortement suggéré d'utiliser la librairie Musician avec Melody pour faciliter le production du son avec votre périphérique.
#include <Melody.h>
#define PIN_BUZZER 12
Melody melody("c d e f g a c*");
void setup() {
melody.setTempo(120); //May be changed whenever you want
}
void loop() {
melody.restart();
while(melody.hasNext()){
melody.next();
unsigned int freq = melody.getFrequency();
unsigned long duration = melody.getDuration();
int loudness = melody.getLoudness();
freq > 0 ? tone(PIN_BUZZER,freq,duration) : noTone();
// loudness could be use with a mapping, according to your buzzer or sound-producing hardware
//For Example :
/*
{
int realIntensity = map(loudness, -4, 4, 0, 1023);
myBuzzer.setIntensity(realIntensity);
}
*/
}
}
Melody(const char* score);
Melody(String score);
Melody(const char* score, unsigned int tempo);
Melody(String score, unsigned int tempo);
Le constructeur doit recevoir le score du Melody (const char* ou String), soit une chaîne de texte formaté selon la notation MELO. On peut spécifier dès le départ le score et le tempo, au besoin.
Si votre chaîne de texte en notation MELO contient un caractère invalide ou une syntaxe invalide, l'objet Melody créé contiendra seulement la portion de la mélodie avant que l'erreur soit détectée.
Par exemple:
Melody melody(" c d e f g k b");
En raison de la lettre inconnue 'k', cette mélodie sera équivalente à :
Melody melody(" c d e f g ");
void setScore(const char * score)
void setScore(String score)
Cette méthode permet de modifier le score du Melody, soit une chaîne de texte formaté selon la notation MELO.
void setTempo(unsigned int tempo)
int getTempo()
Cette méthode permet de lire et modifier le tempo de la musique, qui correspond au nombre de temps musicaux durant une minute. Par exemple, un tempo de 120 signifie qu'il y aura 120 notes de 1 temps joué durant 1 minute - ou que chaque note durera 0.5 seconde.
void restart()
Cette méthode permet de redémarrer l'itération de la mélodie.
int length()
Cette méthode retourne le nombre total de notes dans la mélodie.
bool hasNext()
Cette méthode permet de savoir s'il y a une prochaine note à lire dans la mélodie. On doit l'utiliser avec la méthode next();
void next()
Cette méthode permet de passer à la prochaine note de la mélodie.
int index()
Cette méthode retourne l'index de la note courante, en base zéro.
unsigned int getFrequency()
Cette méthode retourne la valeur en Hz de la note courante. Si la valeur est de zéro, cela signifie qu'il s'agit d'un silence.
unsigned long getDuration()
Cette méthode retourne la durée de la note courante, en millisecondes.
int getLoudness()
Cette méthode retourne l'intensité sonore relative de la note courante.