00001 #pragma once
00002
00003 #if defined(ARDUINO) && ARDUINO >= 100
00004 # include "Arduino.h"
00005 #else
00006 # include "WProgram.h"
00007 # include "pins_arduino.h"
00008 #endif
00009
00010 #include <avr/pgmspace.h>
00011 #include <notes.h>
00012
00013 #define isdigit(n) (n >= '0' && n <= '9')
00014
00015 inline char read_byte(const char *p, bool pgm)
00016 {
00017 if (pgm)
00018 return pgm_read_byte(p);
00019 else
00020 return *p;
00021 }
00022
00023 inline uint16_t read_word(const uint16_t *p, bool pgm)
00024 {
00025 if (pgm)
00026 return pgm_read_word(p);
00027 else
00028 return *p;
00029 }
00030
00031 const prog_uint16_t notes[] PROGMEM =
00032 { 0,
00033 NOTE_C4,
00034 NOTE_CS4,
00035 NOTE_D4,
00036 NOTE_DS4,
00037 NOTE_E4,
00038 NOTE_F4,
00039 NOTE_FS4,
00040 NOTE_G4,
00041 NOTE_GS4,
00042 NOTE_A4,
00043 NOTE_AS4,
00044 NOTE_B4,
00045
00046 NOTE_C5,
00047 NOTE_CS5,
00048 NOTE_D5,
00049 NOTE_DS5,
00050 NOTE_E5,
00051 NOTE_F5,
00052 NOTE_FS5,
00053 NOTE_G5,
00054 NOTE_GS5,
00055 NOTE_A5,
00056 NOTE_AS5,
00057 NOTE_B5,
00058
00059 NOTE_C6,
00060 NOTE_CS6,
00061 NOTE_D6,
00062 NOTE_DS6,
00063 NOTE_E6,
00064 NOTE_F6,
00065 NOTE_FS6,
00066 NOTE_G6,
00067 NOTE_GS6,
00068 NOTE_A6,
00069 NOTE_AS6,
00070 NOTE_B6,
00071
00072 NOTE_C7,
00073 NOTE_CS7,
00074 NOTE_D7,
00075 NOTE_DS7,
00076 NOTE_E7,
00077 NOTE_F7,
00078 NOTE_FS7,
00079 NOTE_G7,
00080 NOTE_GS7,
00081 NOTE_A7,
00082 NOTE_AS7,
00083 NOTE_B7,
00084
00085 2*NOTE_C7,
00086 2*NOTE_CS7,
00087 2*NOTE_D7,
00088 2*NOTE_DS7,
00089 2*NOTE_E7,
00090 2*NOTE_F7,
00091 2*NOTE_FS7,
00092 2*NOTE_G7,
00093 2*NOTE_GS7,
00094 2*NOTE_A7,
00095 2*NOTE_AS7,
00096 2*NOTE_B7,
00097 0
00098 };
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 class Rtttl
00109 {
00110 uint8_t _pinSpk;
00111 #ifdef _Tone_h
00112 Tone m_tone;
00113 #endif
00114
00115 public:
00116 Rtttl()
00117 {
00118
00119 }
00120
00121 void begin(uint8_t tonePin)
00122 {
00123 this->_pinSpk = tonePin;
00124 #ifdef _Tone_h
00125
00126
00127 this->m_tone.begin(tonePin);
00128
00129 #endif
00130
00131 }
00132
00133 #ifdef _Tone_h
00134 void _tone(uint16_t freq)
00135 {
00136
00137 this->m_tone.play(freq);
00138 }
00139
00140 void _noTone()
00141 {
00142
00143 this->m_tone.stop();
00144 }
00145 #else
00146 void _tone(uint16_t freq)
00147 {
00148
00149 tone(this->_pinSpk, freq);
00150 }
00151
00152 void _noTone()
00153 {
00154
00155 noTone(this->_pinSpk);
00156 }
00157 #endif
00158
00159 void play_P(const prog_char *p, uint8_t octave_offset = 0)
00160 {
00161 _play(p, octave_offset, true);
00162 }
00163 void play(const char *p, uint8_t octave_offset = 0)
00164 {
00165 _play(p, octave_offset, false);
00166 }
00167
00168 void _play(const prog_char *p, uint8_t octave_offset, bool pgm)
00169 {
00170
00171
00172 byte default_dur = 4;
00173 byte default_oct = 6;
00174 int bpm = 63;
00175 int num;
00176 long wholenote;
00177 long duration;
00178 byte note;
00179 byte scale;
00180
00181
00182
00183
00184 while (read_byte(p, pgm) != ':')
00185 p++;
00186 p++;
00187
00188
00189 if (read_byte(p, pgm) == 'd')
00190 {
00191 p++;
00192 p++;
00193 num = 0;
00194 while (isdigit(read_byte(p, pgm)))
00195 {
00196 num = (num * 10) + (read_byte(p, pgm) - '0');
00197 p++;
00198 }
00199 if (num > 0)
00200 default_dur = num;
00201 p++;
00202 }
00203
00204
00205 if (read_byte(p, pgm) == 'o')
00206 {
00207 p++;
00208 p++;
00209 num = read_byte(p, pgm) - '0';
00210 p++;
00211 if (num >= 3 && num <= 7)
00212 default_oct = num;
00213 p++;
00214 }
00215
00216
00217 if (read_byte(p, pgm) == 'b')
00218 {
00219 p++;
00220 p++;
00221 num = 0;
00222 while (isdigit(read_byte(p, pgm)))
00223 {
00224 num = (num * 10) + (read_byte(p, pgm) - '0');
00225 p++;
00226 }
00227 bpm = num;
00228 p++;
00229 }
00230
00231
00232 wholenote = (60 * 1000L / bpm) * 4;
00233
00234
00235 while (read_byte(p, pgm))
00236 {
00237
00238 num = 0;
00239 while (isdigit(read_byte(p, pgm)))
00240 {
00241 num = (num * 10) + (read_byte(p, pgm) - '0');
00242 p++;
00243 }
00244
00245 if (num)
00246 duration = wholenote / num;
00247 else
00248 duration = wholenote / default_dur;
00249
00250
00251 note = 0;
00252
00253 switch (read_byte(p, pgm))
00254 {
00255 case 'c':
00256 note = 1;
00257 break;
00258 case 'd':
00259 note = 3;
00260 break;
00261 case 'e':
00262 note = 5;
00263 break;
00264 case 'f':
00265 note = 6;
00266 break;
00267 case 'g':
00268 note = 8;
00269 break;
00270 case 'a':
00271 note = 10;
00272 break;
00273 case 'b':
00274 note = 12;
00275 break;
00276 case 'p':
00277 default:
00278 note = 0;
00279 }
00280 p++;
00281
00282
00283 if (read_byte(p, pgm) == '#')
00284 {
00285 note++;
00286 p++;
00287 }
00288
00289
00290 if (read_byte(p, pgm) == '.')
00291 {
00292 duration += duration / 2;
00293 p++;
00294 }
00295
00296
00297 if (isdigit(read_byte(p, pgm)))
00298 {
00299 scale = read_byte(p, pgm) - '0';
00300 p++;
00301 }
00302 else
00303 {
00304 scale = default_oct;
00305 }
00306
00307 scale += octave_offset;
00308
00309 if (read_byte(p, pgm) == ',')
00310 p++;
00311
00312
00313
00314 if (note)
00315 {
00316 _tone(read_word(¬es[(scale - 4) * 12 + note], pgm));
00317 delay(duration);
00318 _noTone();
00319 }
00320 else
00321 {
00322 delay(duration);
00323 }
00324 }
00325 }
00326 };
00327