2013-08-26 20:39:15 +02:00
|
|
|
#include <pentabug/music.h>
|
|
|
|
|
|
|
|
#include <avr/io.h>
|
2013-08-27 00:22:38 +02:00
|
|
|
|
|
|
|
#include <pentabug/timer.h>
|
|
|
|
#include <pentabug/lifecycle.h>
|
2013-08-29 23:25:46 +02:00
|
|
|
#include <pentabug/hal.h>
|
2013-08-26 20:39:15 +02:00
|
|
|
|
|
|
|
static void tune(void) {
|
2013-08-30 17:23:38 +02:00
|
|
|
buzzer_inv();
|
2013-08-26 20:39:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void set_note(uint16_t note, uint8_t octave) {
|
|
|
|
if(note != NOTE_PAUSE) {
|
2013-08-30 17:31:18 +02:00
|
|
|
// bring buzzer to a state where inverting it creates sound
|
2013-08-30 17:23:38 +02:00
|
|
|
buzzer_up();
|
2013-08-30 17:31:18 +02:00
|
|
|
// start timer with doubled frequency of tone we want to play
|
2013-08-26 20:39:15 +02:00
|
|
|
start_timer(PRESCALE_8, note >> octave, tune);
|
|
|
|
} else {
|
2013-08-30 17:31:18 +02:00
|
|
|
// do nothing when paused
|
2013-08-30 17:23:38 +02:00
|
|
|
stop_note();
|
2013-08-26 20:39:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void stop_note(void) {
|
2013-08-30 17:31:18 +02:00
|
|
|
// turn buzzer off to save energy
|
2013-08-30 17:23:38 +02:00
|
|
|
buzzer_off();
|
2013-08-30 17:31:18 +02:00
|
|
|
// we do not need the timer anymore
|
2013-08-26 20:39:15 +02:00
|
|
|
stop_timer();
|
|
|
|
}
|
2013-08-27 00:22:38 +02:00
|
|
|
|
2013-08-30 19:57:51 +02:00
|
|
|
void play_melody(const uint16_t notes[], size_t len, uint8_t octave, int speed) {
|
2013-08-27 00:22:38 +02:00
|
|
|
int pause = speed / 20;
|
2013-08-29 23:09:01 +02:00
|
|
|
uint8_t length = 4;
|
2013-08-27 00:22:38 +02:00
|
|
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for(i = 0; i < len; ++i) {
|
|
|
|
if(notes[i] == MLDY_PAUSE) {
|
2013-08-30 17:31:18 +02:00
|
|
|
// user defined pause
|
2013-08-27 00:22:38 +02:00
|
|
|
++i;
|
2013-08-30 17:31:18 +02:00
|
|
|
wait_ms(notes[i]);
|
2013-08-29 23:09:01 +02:00
|
|
|
} else if(notes[i] == MLDY_LENGTH) {
|
2013-08-30 17:31:18 +02:00
|
|
|
// sets length for next tone
|
2013-08-29 23:09:01 +02:00
|
|
|
++i;
|
|
|
|
length = notes[i];
|
2013-08-27 00:22:38 +02:00
|
|
|
} else {
|
2013-08-30 17:31:18 +02:00
|
|
|
// play note
|
2013-08-27 00:22:38 +02:00
|
|
|
set_note(notes[i], octave);
|
|
|
|
test_stop_app();
|
2013-08-29 23:09:01 +02:00
|
|
|
wait_ms(speed * 4 / length);
|
2013-08-27 00:22:38 +02:00
|
|
|
|
2013-08-30 17:31:18 +02:00
|
|
|
// pause after note
|
2013-08-27 00:22:38 +02:00
|
|
|
stop_note();
|
|
|
|
test_stop_app();
|
2013-08-29 23:09:01 +02:00
|
|
|
wait_ms(pause);
|
|
|
|
|
2013-08-30 17:31:18 +02:00
|
|
|
// reset length for next note
|
2013-08-29 23:09:01 +02:00
|
|
|
length = 4;
|
2013-08-27 00:22:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|