ArduinoLibs
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Melody.cpp
1 /*
2  * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "Melody.h"
24 #if defined(ARDUINO) && ARDUINO >= 100
25 #include <Arduino.h>
26 #else
27 #include <WProgram.h>
28 #endif
29 
85 Melody::Melody(uint8_t pin)
86  : _pin(pin)
87  , playing(false)
88  , _loopCount(0)
89  , loopsLeft(0)
90  , notes(0)
91  , lengths(0)
92  , size(0)
93  , posn(0)
94  , duration(0)
95  , startNote(0)
96 {
97 }
98 
131 void Melody::setLoopDuration(unsigned long ms)
132 {
133  unsigned long duration = 0;
134  for (unsigned int index = 0; index < size; ++index)
135  duration += (1000 / lengths[index]) * 13 / 10;
136  _loopCount = (int)(ms / duration);
137  if (!_loopCount)
138  _loopCount = 1; // Play the melody at least once.
139 }
140 
147 {
148  stop();
149  if (size == 0)
150  return; // No melody to play.
151  loopsLeft = _loopCount;
152  posn = 0;
153  playing = true;
154  nextNote();
155 }
156 
163 {
164  stop();
165  if (size == 0)
166  return; // No melody to play.
167  loopsLeft = 1;
168  posn = 0;
169  playing = true;
170  nextNote();
171 }
172 
179 {
180  if (!playing)
181  return;
182  playing = false;
183  noTone(_pin);
184 }
185 
199 void Melody::setMelody(const int *notes, const uint8_t *lengths, unsigned int size)
200 {
201  stop();
202  this->notes = notes;
203  this->lengths = lengths;
204  this->size = size;
205 }
206 
215 {
216  if (!playing)
217  return;
218  if ((millis() - startNote) >= duration) {
219  noTone(_pin);
220  nextNote();
221  }
222 }
223 
224 void Melody::nextNote()
225 {
226  if (posn >= size) {
227  if (loopsLeft != 0 && --loopsLeft <= 0) {
228  stop();
229  return;
230  }
231  posn = 0;
232  }
233  duration = 1000 / lengths[posn];
234  if (notes[posn] != NOTE_REST)
235  tone(_pin, notes[posn], duration);
236  ++posn;
237  duration = duration * 13 / 10; // i.e., duration * 1.3
238  startNote = millis();
239 }
void setMelody(const int *notes, const uint8_t *lengths, unsigned int size)
Sets the melody to the size elements of notes and lengths.
Definition: Melody.cpp:199
void stop()
Stops playing the melody.
Definition: Melody.cpp:178
void run()
Runs the melody control loop.
Definition: Melody.cpp:214
void playOnce()
Plays the melody once and then stops.
Definition: Melody.cpp:162
Melody(uint8_t pin)
Constructs a new melody playing object for pin.
Definition: Melody.cpp:85
void setLoopDuration(unsigned long ms)
Sets the maximum number of loops to last no longer than ms milliseconds.
Definition: Melody.cpp:131
void play()
Starts playing the melody, or restarts it if already playing.
Definition: Melody.cpp:146