-
Notifications
You must be signed in to change notification settings - Fork 1
/
speaker.cpp
137 lines (121 loc) · 3.61 KB
/
speaker.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <NewTone.h>
#include "speaker.h"
#include "pitches.h"
Speaker::Speaker(int speakerPin)
{
this->speakerPin = speakerPin;
this->nextCount = 0;
if(speakerPin != -1)
pinMode(speakerPin,OUTPUT);
}
void Speaker::play(Melody melody, int count)
{
if(this->melody == melody)
{
this->count += count;
}
else
{
if(this->count > 0)
{
// wait until the current one finishes, queue the new one
// if the queue has the same melody, increment the count,
// otherwise replace it
if(this->nextMelody == melody)
{
this->nextCount += count;
}
else
{
this->nextMelody = melody;
this->nextCount = count;
}
}
else if(this->count == -1)
{
// the current one is playing forever, make it stoppped after 1 iteration
this->nextMelody = melody;
this->nextCount = count;
this->count = 1;
}
else
{
// nothing is played, start this one
this->melody = melody;
this->count = count;
this->state = 0;
}
}
}
void Speaker::countDown()
{
this->state = 0;
if(this->count > 0) this->count --;
// start to play the queued one if count became 0
if(this->count == 0 && this->nextCount != 0)
{
this->melody = this->nextMelody;
this->count = this->nextCount;
this->nextCount = 0;
}
}
void Speaker::stop()
{
this->count = 0;
}
bool Speaker::loop()
{
if(speakerPin == -1) return false;
if(this->count != 0)
{
if(melody == SIREN)
{
int wait = 1;
int time = 10;
if(this->state == 0) this->state = 150; // start at freq 150
if(this->state <= 1800) // go up to 1800
{
NewTone(speakerPin, this->state++, time); // Beep pin, freq, time
sleep_milli(wait);
}
else if(this->state > 1800 && this->state < 1800 + 1800 - 150) // go down to 150
{
NewTone(speakerPin, 1800 - (this->state - 1800), time);
sleep_milli(wait);
this->state++;
}
else
{
countDown();
}
}
else if(melody == MELODY1)
{
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4, 4, 4, 4, 4 };
// stop the tone playing:
noNewTone(speakerPin);
int thisNote = state++;
if(thisNote < 8) // number of notes
{
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/noteDurations[thisNote];
NewTone(speakerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
sleep_milli(pauseBetweenNotes);
}
else
{
countDown();
}
}
}
return true;
}