puzzle-box/build/sketch/music.cpp

211 lines
3.6 KiB
C++

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// The following functions are related to Beegees Easter Egg only
const unsigned int freqs[] = {
3520, // A
3729, // A#
3951, // B
2093, // C
2217, // C#
2349, // D
2489, // D#
2637, // E
2794, // F
2960, // F#
3136, // G
3322, // G#
};
const int scale[] = {
0, 2, 3, 5, 7, 8, 10
};
Player::Player() {
}
Player::PlayNote(int note, int octave, int duration)
void
playNote(int octave, int note, int duration)
{
unsigned int freq;
int i;
if (note >= 0) {
freq = freqs[note];
for (i = octave; i < 7; i += 1) {
freq /= 2;
}
tone(BUZZER2, freq, duration);
setLEDs(note + 1);
}
delay(duration);
setLEDs(0);
}
void
play(int bpm, char *tune)
{
unsigned int baseDuration = 60000 / bpm;
int duration = baseDuration;
int baseOctave = 4;
int octave = baseOctave;
int note = -2;
char *p = tune;
for (; *p; p += 1) {
boolean playNow = false;
switch (*p) {
case '>':
octave = baseOctave + 1;
break;
case '<':
octave = baseOctave - 1;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
playNow = true;
note = scale[*p - 'A'];
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
playNow = true;
octave += 1;
note = scale[*p - 'a'];
break;
case '_':
playNow = true;
note = -1;
break;
}
// Check for sharps or flats
switch (*(p+1)) {
case '#':
case '+':
note += 1;
if (note == 12) {
octave += 1;
note = 0;
}
p += 1;
break;
case '-':
note -= 1;
if (note == -1) {
octave -= 1;
note = 11;
}
p += 1;
break;
}
// Check for octave
switch (*(p+1)) {
case ',':
octave -= 1;
p += 1;
break;
case '\'':
octave += 1;
p += 1;
break;
}
// Check for duration
switch (*(p+1)) {
case '2':
duration *= 2;
p += 1;
break;
case '4':
duration *= 4;
p += 1;
break;
case '.':
duration += duration / 2;
p += 1;
break;
}
if (playNow) {
playNote(octave, note, duration);
note = -1;
octave = baseOctave;
duration = baseDuration;
}
if (checkButton()) {
noTone(BUZZER2);
return;
}
}
if (note >= 0) {
playNote(octave, note, duration);
}
noTone(BUZZER2);
}
// Do nothing but play bad beegees music
// This function is activated when user holds bottom right button during power up
void play_beegees()
{
while(checkButton() == CHOICE_NONE) {
play(104 * 4, "E-F_a-__E-2__C_B-,CE-_B-,C_E-__B-,_C_E-_F_a-_");
}
}
void lplay(unsigned int tempo, char *tune, int count)
{
int i;
for (i = 0; i < count; i += 1) {
play(tempo * 3, tune);
}
}
void play_march()
{
const int tempo = 80;
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "E-G-,B-,", 5);
play(tempo * 4, "B-");
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "E-G-,B-,", 5);
play(tempo * 4, "B-");
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "dGB-", 6);
lplay(tempo * 4, "dGB-", 6);
lplay(tempo * 4, "dGB-", 6);
lplay(tempo * 4, "e-G-B-", 5);
play(tempo * 4, "B-");
lplay(tempo * 4, "G-B-,F", 6);
lplay(tempo * 4, "E-G-,B-,", 5);
play(tempo * 4, "B-");
lplay(tempo * 4, "GB-,D", 6);
lplay(tempo * 4, "GB-,D", 6);
return;
}