-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmusic.ino
194 lines (170 loc) · 6.23 KB
/
music.ino
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* Play Melody
* -----------
*
* Program to play a simple theme_melody
*
* Tones are created by quickly pulsing a speaker on and off
* using PWM, to create signature frequencies.
*
* Each note has a frequency, created by varying the period of
* vibration, measured in microseconds. We'll use pulse-width
* modulation (PWM) to create that vibration.
* We calculate the pulse-width to be half the period; we pulse
* the speaker HIGH for 'pulse-width' microseconds, then LOW
* for 'pulse-width' microseconds.
* This pulsing creates a vibration of the desired frequency.
*
* (cleft) 2005 D. Cuartielles for K3
* Refactoring and comments 2006 [email protected]
* See NOTES in comments at end for possible improvements
*/
// TONES ==========================================
// Start by defining the relationship between
// note, period, & frequency.
#define c 3831 // 261 Hz
#define d 3401 // 294 Hz
#define e 3040 // 329 Hz
#define f 2865 // 349 Hz
#define g 2558 // 391 Hz
#define gS 2410 // 415 Hz
#define a 2273 // 440 Hz
#define aS 2198 // 455 Hz
#define b 2146 // 466 Hz
#define cH 1912 // 523 Hz
#define cSH 1805 // 554 Hz
#define dH 1704 // 587 Hz
#define dSH 1608 // 622 Hz
#define eH 1517 // 659 Hz
#define fH 1433 // 698 Hz
#define fSH 1351 // 740 Hz
#define gH 1276 // 784 Hz
#define gSH 1205 // 830 Hz
#define aH 1136 // 880 Hz
// Define a special note, 'R', to represent a rest
#define R 0
// SETUP ============================================
// Set up speaker on a PWM pin (digital 9, 10 or 11)
int speakerOut = 9;
void setupSounds() {
pinMode(speakerOut, OUTPUT);
}
// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES
// Initialize core variables
int tone_ = 0;
int beat = 0;
long duration = 0;
// PLAY TONE ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
long elapsed_time = 0;
if (tone_ > 0) { // if this isn't a Rest beat, while the tone has
// played less long than 'duration', pulse speaker HIGH and LOW
while (elapsed_time < duration) {
digitalWrite(speakerOut,HIGH);
delayMicroseconds(tone_ / 2);
// DOWN
digitalWrite(speakerOut, LOW);
delayMicroseconds(tone_ / 2);
// Keep track of how long we pulsed
elapsed_time += (tone_);
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}
void playMelody(int melody[], int beats[], int lenght){
//tone(8, 250,500);
for (int i=0; i<lenght; i++) {
tone_ = melody[i];
beat = beats[i];
duration = beat * tempo; // Set up timing
playTone();
// A pause between notes...
delayMicroseconds(pause);
}
}
// MELODY and TIMING =======================================
// theme_melody[] is an array of notes, accompanied by theme_beats[],
// which sets each note's relative length (higher #, longer note)
int theme_melody[] = {
cH, b, g, cH, b, e, R, cH, c, g, a, cH };
int theme_beats[] = {
16, 16, 16, 8, 8, 16, 32, 16, 16, 16, 8, 8 };
int theme_lenght = sizeof(theme_melody) / sizeof(int); // Melody length, for looping.
void playTheme(){
playMelody(theme_melody, theme_beats, theme_lenght);
}
int win_melody[] = {
a, a, a, f, cH, a, f, cH, a, eH, eH, eH, fH, cH, gS, f, cH, a, aH, a, a, aH,
gSH, gH, fSH, fH, fSH, R, aS, dSH, dH, cSH, cH, b, cH, R, f, gS, f, a, cH, a,
cH, eH, aH, a, a, aH, gSH, gH, fSH, fH, fSH, R, aS, dSH, dH, cSH, cH, b, cH,
R, f, gS, f, cH, a, f, c, a };
int win_beats[] = {
50, 50, 50, 35, 15, 50, 35, 15, 100, 50, 50, 50, 35, 15, 50, 35, 15, 100, 50, 35, 15, 50, 25, 25, 13, 13, 25, 20, 10, 50, 25, 25, 13, 13, 25, 20, 13, 50, 38, 13, 50, 38, 13, 100, 50, 35, 15, 50, 25, 25, 13, 13, 25, 20, 25, 50, 25, 25, 13, 13, 25, 20, 25, 50, 38, 13, 50, 38, 13, 100
};
int win_lenght = sizeof(win_melody) / sizeof(int); // Melody length, for looping.
void playWin(){
playMelody(win_melody, win_beats, win_lenght);
}
int dartok_melody[] = {
cH };
int dartok_beats[] = {
24 };
int dartok_lenght = sizeof(dartok_melody) / sizeof(int); // Melody length, for looping.
void playDartOk(int repeat){
while(repeat-- > 0){
playMelody(dartok_melody, dartok_beats, dartok_lenght);
if(repeat>0){
delay(10);
}
}
}
int dartfail_melody[] = {
e};
int dartfail_beats[] = {
24 };
int dartfail_lenght = sizeof(dartfail_melody) / sizeof(int); // Melody length, for looping.
void playDartFail(int repeat){
while(repeat-- > 0){
playMelody(dartfail_melody, dartfail_beats, dartfail_lenght);
if(repeat>0){
delay(10);
}
}
}
/*
* NOTES
* The program purports to hold a tone for 'duration' microseconds.
* Lies lies lies! It holds for at least 'duration' microseconds, _plus_
* any overhead created by incremeting elapsed_time (could be in excess of
* 3K microseconds) _plus_ overhead of looping and two digitalWrites()
*
* As a result, a tone of 'duration' plays much more slowly than a rest
* of 'duration.' rest_count creates a loop variable to bring 'rest' theme_beats
* in line with 'tone' theme_beats of the same length.
*
* rest_count will be affected by chip architecture and speed, as well as
* overhead from any program mods. Past behavior is no guarantee of future
* performance. Your mileage may vary. Light fuse and get away.
*
* This could use a number of enhancements:
* ADD code to let the programmer specify how many times the theme_melody should
* loop before stopping
* ADD another octave
* MOVE tempo, pause, and rest_count to #define statements
* RE-WRITE to include volume, using analogWrite, as with the second program at
* http://www.arduino.cc/en/Tutorial/PlayMelody
* ADD code to make the tempo settable by pot or other input device
* ADD code to take tempo or volume settable by serial communication
* (Requires 0005 or higher.)
* ADD code to create a tone offset (higer or lower) through pot etc
* REPLACE random theme_melody with opening bars to 'Smoke on the Water'
*/