Melody Player is an Arduino library to play melodies on buzzers on ESP8266 and ESP32 in a non-blocking manner. Melodies can be written directly in code or loaded from file. It supports Ring Tone Text Transfer Language (RTTTL) format and a custom format developed specifically to enjoy all the benefits of this library.
Arduino cores provide tone() function to emit a PWM signal, and it is often used to play beeps on a buzzer. Modulating the PWM frequency, you can play sounds at a given frequency, i.e., you can play a note, and it is relatively easy to play a monophonic melody. However, the Arduino ecosystem lacks of a structured and easy way to accomplish this task (i.e., each developer have to write bloating code for it). So, I started to write a simple snippet to asynchronously play sequences of notes on a buzzer without bloating user-code with long parsing and playback methods. Moreover, since ESP8266 and ESP32 cores provide a file system for the embedded flash melody, I wanted a melody format easy to remember, human-readable and editable with a simple text editor. From this context Melody Player was born, improved, and extended over time.
You can find Melody Player on Arduino and PlatformIO library registries. You can install it through Arduino IDE, or you can use the respective command-line tools running:
arduino-cli lib install "Melody Player"
or:
pio lib install "fabianoriccardi/Melody Player"
Here a quick overview of the main methods to use this library. Initialize MelodyPlayer by specifying the pin where the buzzer is attached to:
MelodyPlayer player(4);
Load the RTTTL melody from file (remember to initialize the file system before this call):
Melody melody = MelodyFactory.loadRtttlFile("/the-anthem.rtttl");
Check if the melody is loaded correctly:
if(!melody) {
Serial.println("Cannot play this melody");
}
Play it using blocking or non-blocking methods:
player.play(melody);
or
player.playAsync(melody);
In case of non-blocking playback, you can check if the melody is running:
if(player.isPlaying()){
Serial.println("Playing...");
}
and pause/continue to play/stop the melody through:
player.pause();
player.play();
player.stop();
You can write a melody in a text file, accordingly to the following specifications:
title={Name of the melody}
timeUnit={Base time in millisecond}
length={Array length}
format={This value can be "integer" or "string", and it specifies how the tone frequency is represented in the following array}
{Array composed by pair <frequency; duration> and spit by '|' (pipe character)}
where:
A small pause is automatically added between 2 consecutive pairs. You can add comments using '#' at the begin of the line.
Example 1: this melody codifies 2 "beeps" using the "string" codification:
title=Beep
timeUnit=200
length=1
format=string
G7,3|SILENCE,1|G7,3
Example 2: the same melody using the "integer" codification:
title=Beep
timeUnit=200
length=1
format=integer
3136,3|0,1|3136,3