-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBGMusic.cpp
111 lines (88 loc) · 2.65 KB
/
BGMusic.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
BGMusic.cpp - Background Music player using tone() for Arduino UNO R4
Copyright (c) 2024 embedded-kiddie All Rights Reserved.
This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
*/
#if 0
#define debug_begin(...) { Serial.begin(__VA_ARGS__); while(!Serial); }
#define debug_print(...) Serial.print(__VA_ARGS__)
#define debug_println(...) Serial.println(__VA_ARGS__)
#endif
#include "BGMusic.h"
// Duration between notes.
#define BREATH 10
// Instance of Music score player in background
static CBTimer cbtimer;
// Initialize static data menbers
MusicScore_t BGMusic::score = { 0, 0, 0, 0, false };
int (*BGMusic::duration_function)(int duration) = nullptr;
// Constructor / Destructor
BGMusic::BGMusic() {}
BGMusic::~BGMusic() {
end();
}
// Initialize music score sequencer
bool BGMusic::begin(int pin, const int notes[], int n_notes, int tempo, bool loop, bool start) {
debug_begin(9600);
score.pin = pin;
score.notes = notes;
score.notes_bigin = notes;
score.notes_end = notes + n_notes * 2;
score.wholenote = (60000 * 4) / tempo;
score.loop = loop;
if (start == true) {
return BGMusic::start();
} else {
return true;
}
}
// Instanciate the FspTimer and start it immediately
bool BGMusic::start(void) {
if (cbtimer.begin(TIMER_MODE_ONE_SHOT, CBTIMER_START_NOW, music_callback) == true) {
return cbtimer.start();
} else {
return false;
}
}
// Stop playing
bool BGMusic::stop(void) {
noTone(score.pin);
return cbtimer.stop();
}
// Delete the instanciate of FspTimer
void BGMusic::end(void) {
cbtimer.end();
}
// Play notes in music score sequentially
void BGMusic::music_callback(void) {
stop();
if (score.notes < score.notes_end) {
debug_print("note[0] = "); debug_println(score.notes[0]);
debug_print("note[1] = "); debug_println(score.notes[1]);
int note = *score.notes++;
int duration = *score.notes++;
// select the method of calculating duration
if (duration_function == nullptr) {
// https://github.com/robsoncouto/arduino-songs
duration = score.wholenote / duration;
// negative value for dotted note
if (duration < 0) {
duration = abs(duration) * 3 / 2;
}
}
else {
// you can select the original method
duration = duration_function(duration);
}
debug_print("duration = "); debug_println(duration);
tone(score.pin, (unsigned int)note, (unsigned long)(duration * 0.9));
// Instanciate the FspTimer and start it
cbtimer.begin(duration, music_callback);
}
// For repeated playback
else if (score.loop) {
score.notes = score.notes_bigin;
start();
}
}