/*
* Test code for playing melodies.
*
* https://github.com/arduino12 11/12/2021
*/
#include "notes.h"
#include "melodies.h"
#define SPEAKER_PIN (8)
#define BUTTON_PIN (10)
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
const uint16_t *melodies[] = {
MELODY_360_START,
MELODY_360_GOOD,
MELODY_HAPPY_BIRTHDAY,
MELODY_LITTLE_JONATHAN,
MELODY_HANUKKAH,
MELODY_HATIKVA,
};
bool is_button_pressed()
{
return !digitalRead(BUTTON_PIN);
}
bool beep_delay_button(uint16_t freq, uint32_t ms)
{
if (freq)
tone(SPEAKER_PIN, freq);
else
noTone(SPEAKER_PIN);
ms += millis();
while (millis() < ms)
if (is_button_pressed()) {
noTone(SPEAKER_PIN);
while (is_button_pressed());
delay(100);
return true;
}
return false;
}
bool play_melody(const uint16_t *melody)
{
uint16_t note, duration, note_1_32_ms = 7500 / pgm_read_word(melody++);
while (1) {
note = pgm_read_word(melody++);
if (note == NOTE_END)
return false;
duration = note_1_32_ms * pgm_read_byte(NOTE_BEAT_1_32 + (note >> NOTE_BEAT_BIT));
if (beep_delay_button(note & NOTE_BEAT_MASK, duration))
return true;
if (beep_delay_button(0, note_1_32_ms * 2)) // short note pause
return true;
}
}
void setup()
{
pinMode(SPEAKER_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
delay(1000); // needed for simulation only because the first call to tone takes time to start
}
void loop()
{
static uint8_t cur_melody_index = 0;
if (play_melody(melodies[cur_melody_index])) {
while (!is_button_pressed())
delay(100);
while (is_button_pressed())
delay(100);
}
else
delay(1000);
if (++cur_melody_index >= ARRAY_COUNT(melodies))
cur_melody_index = 0;
}