ArduinoLibs
Melody.cpp
00001 /*
00002  * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020  * DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #include "Melody.h"
00024 #if defined(ARDUINO) && ARDUINO >= 100
00025 #include <Arduino.h>
00026 #else
00027 #include <WProgram.h>
00028 #endif
00029 
00085 Melody::Melody(uint8_t pin)
00086     : _pin(pin)
00087     , playing(false)
00088     , _loopCount(0)
00089     , loopsLeft(0)
00090     , notes(0)
00091     , lengths(0)
00092     , size(0)
00093     , posn(0)
00094     , duration(0)
00095     , startNote(0)
00096 {
00097 }
00098 
00131 void Melody::setLoopDuration(unsigned long ms)
00132 {
00133     unsigned long duration = 0;
00134     for (unsigned int index = 0; index < size; ++index)
00135         duration += (1000 / lengths[index]) * 13 / 10;
00136     _loopCount = (int)(ms / duration);
00137     if (!_loopCount)
00138         _loopCount = 1;     // Play the melody at least once.
00139 }
00140 
00146 void Melody::play()
00147 {
00148     stop();
00149     if (size == 0)
00150         return;         // No melody to play.
00151     loopsLeft = _loopCount;
00152     posn = 0;
00153     playing = true;
00154     nextNote();
00155 }
00156 
00162 void Melody::playOnce()
00163 {
00164     stop();
00165     if (size == 0)
00166         return;         // No melody to play.
00167     loopsLeft = 1;
00168     posn = 0;
00169     playing = true;
00170     nextNote();
00171 }
00172 
00178 void Melody::stop()
00179 {
00180     if (!playing)
00181         return;
00182     playing = false;
00183     noTone(_pin);
00184 }
00185 
00199 void Melody::setMelody(const int *notes, const uint8_t *lengths, unsigned int size)
00200 {
00201     stop();
00202     this->notes = notes;
00203     this->lengths = lengths;
00204     this->size = size;
00205 }
00206 
00214 void Melody::run()
00215 {
00216     if (!playing)
00217         return;
00218     if ((millis() - startNote) >= duration) {
00219         noTone(_pin);
00220         nextNote();
00221     }
00222 }
00223 
00224 void Melody::nextNote()
00225 {
00226     if (posn >= size) {
00227         if (loopsLeft != 0 && --loopsLeft <= 0) {
00228             stop();
00229             return;
00230         }
00231         posn = 0;
00232     }
00233     duration = 1000 / lengths[posn];
00234     if (notes[posn] != NOTE_REST)
00235         tone(_pin, notes[posn], duration);
00236     ++posn;
00237     duration = duration * 13 / 10;      // i.e., duration * 1.3
00238     startNote = millis();
00239 }
 All Classes Files Functions Variables Enumerations Enumerator