Class to play tones, various sounds and music in MML format using a PWM channel.
PwmSound.cpp@0:185bcd9f8e19, 2014-03-30 (annotated)
- Committer:
- paulg
- Date:
- Sun Mar 30 22:50:27 2014 +0000
- Revision:
- 0:185bcd9f8e19
- Child:
- 1:67056b9df9ff
Initial release.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
paulg | 0:185bcd9f8e19 | 1 | /****************************************************************************** |
paulg | 0:185bcd9f8e19 | 2 | * File: PwmSound.cpp |
paulg | 0:185bcd9f8e19 | 3 | * Author: Paul Griffith |
paulg | 0:185bcd9f8e19 | 4 | * Created: 25 Mar 2014 |
paulg | 0:185bcd9f8e19 | 5 | * Last Edit: see below |
paulg | 0:185bcd9f8e19 | 6 | * Version: see below |
paulg | 0:185bcd9f8e19 | 7 | * |
paulg | 0:185bcd9f8e19 | 8 | * Description: |
paulg | 0:185bcd9f8e19 | 9 | * Class to play tones, various sounds and simple tunes using a PWM channel. |
paulg | 0:185bcd9f8e19 | 10 | * Inspired by Jim Hamblem's Speaker class. Thanks Jim! |
paulg | 0:185bcd9f8e19 | 11 | * |
paulg | 0:185bcd9f8e19 | 12 | * Refer to the tutorial "Using a Speaker for Audio Output" in the Cookbook. |
paulg | 0:185bcd9f8e19 | 13 | * The mbed LPC1768 PWM pins will drive a small speaker without amplification. |
paulg | 0:185bcd9f8e19 | 14 | * Connect speaker via a 220R resistor and 100uF 10V capacitor (+ve to mbed). |
paulg | 0:185bcd9f8e19 | 15 | * |
paulg | 0:185bcd9f8e19 | 16 | * Copyright (c) 2014 Paul Griffith, MIT License |
paulg | 0:185bcd9f8e19 | 17 | * |
paulg | 0:185bcd9f8e19 | 18 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
paulg | 0:185bcd9f8e19 | 19 | * of this software and associated documentation files (the "Software"), to |
paulg | 0:185bcd9f8e19 | 20 | * deal in the Software without restriction, including without limitation the |
paulg | 0:185bcd9f8e19 | 21 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
paulg | 0:185bcd9f8e19 | 22 | * sell copies of the Software, and to permit persons to whom the Software is |
paulg | 0:185bcd9f8e19 | 23 | * furnished to do so, subject to the following conditions: |
paulg | 0:185bcd9f8e19 | 24 | * |
paulg | 0:185bcd9f8e19 | 25 | * The above copyright notice and this permission notice shall be included in |
paulg | 0:185bcd9f8e19 | 26 | * all copies or substantial portions of the Software. |
paulg | 0:185bcd9f8e19 | 27 | * |
paulg | 0:185bcd9f8e19 | 28 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
paulg | 0:185bcd9f8e19 | 29 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
paulg | 0:185bcd9f8e19 | 30 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
paulg | 0:185bcd9f8e19 | 31 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
paulg | 0:185bcd9f8e19 | 32 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
paulg | 0:185bcd9f8e19 | 33 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
paulg | 0:185bcd9f8e19 | 34 | * IN THE SOFTWARE. |
paulg | 0:185bcd9f8e19 | 35 | * |
paulg | 0:185bcd9f8e19 | 36 | * Modifications: |
paulg | 0:185bcd9f8e19 | 37 | * Ver Date By Details |
paulg | 0:185bcd9f8e19 | 38 | * 0.00 25Mar14 PG File created. |
paulg | 0:185bcd9f8e19 | 39 | * 1.00 30Mar14 PG Initial release. |
paulg | 0:185bcd9f8e19 | 40 | * |
paulg | 0:185bcd9f8e19 | 41 | ******************************************************************************/ |
paulg | 0:185bcd9f8e19 | 42 | |
paulg | 0:185bcd9f8e19 | 43 | #include "mbed.h" |
paulg | 0:185bcd9f8e19 | 44 | #include "PwmSound.h" |
paulg | 0:185bcd9f8e19 | 45 | |
paulg | 0:185bcd9f8e19 | 46 | extern Serial pc; |
paulg | 0:185bcd9f8e19 | 47 | |
paulg | 0:185bcd9f8e19 | 48 | // Standard note pitches in Hz |
paulg | 0:185bcd9f8e19 | 49 | // First entry is a dummy, real note numbers start at 1 |
paulg | 0:185bcd9f8e19 | 50 | // Seven octaves, twelve notes per octave |
paulg | 0:185bcd9f8e19 | 51 | // C, C#, D, D#, E, F, F#, G, G#, A, A#, B |
paulg | 0:185bcd9f8e19 | 52 | // Middle C is element 37 (262Hz) |
paulg | 0:185bcd9f8e19 | 53 | |
paulg | 0:185bcd9f8e19 | 54 | int notePitches[1+84] = { |
paulg | 0:185bcd9f8e19 | 55 | 1, //dummy |
paulg | 0:185bcd9f8e19 | 56 | 33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62, |
paulg | 0:185bcd9f8e19 | 57 | 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, 117, 123, |
paulg | 0:185bcd9f8e19 | 58 | 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, |
paulg | 0:185bcd9f8e19 | 59 | 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, |
paulg | 0:185bcd9f8e19 | 60 | 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, |
paulg | 0:185bcd9f8e19 | 61 | 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, |
paulg | 0:185bcd9f8e19 | 62 | 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, |
paulg | 0:185bcd9f8e19 | 63 | }; |
paulg | 0:185bcd9f8e19 | 64 | |
paulg | 0:185bcd9f8e19 | 65 | // Constructor |
paulg | 0:185bcd9f8e19 | 66 | |
paulg | 0:185bcd9f8e19 | 67 | PwmSound::PwmSound(PinName pin) : _pin(pin) { |
paulg | 0:185bcd9f8e19 | 68 | _duration = 0.25; |
paulg | 0:185bcd9f8e19 | 69 | _volume = 1.0; |
paulg | 0:185bcd9f8e19 | 70 | _tempo = 120; //120 beats/minute |
paulg | 0:185bcd9f8e19 | 71 | _length = 4; //quarter note (crotchet) |
paulg | 0:185bcd9f8e19 | 72 | _style = PwmSound::NORMAL; |
paulg | 0:185bcd9f8e19 | 73 | _pin = 0.0; |
paulg | 0:185bcd9f8e19 | 74 | _playing = false; |
paulg | 0:185bcd9f8e19 | 75 | } |
paulg | 0:185bcd9f8e19 | 76 | |
paulg | 0:185bcd9f8e19 | 77 | // Play a tone on output pin |
paulg | 0:185bcd9f8e19 | 78 | // 2 versions for convenience when using default duration |
paulg | 0:185bcd9f8e19 | 79 | // |
paulg | 0:185bcd9f8e19 | 80 | // Parameters: |
paulg | 0:185bcd9f8e19 | 81 | // frequency - frequency of tone in Hz |
paulg | 0:185bcd9f8e19 | 82 | // duration - duration of tone in seconds |
paulg | 0:185bcd9f8e19 | 83 | // if duration = 0.0, tone continues in background until stopped |
paulg | 0:185bcd9f8e19 | 84 | // volume - crude volume control (0.0-1.0), alters PWM duty cycle 0-50% |
paulg | 0:185bcd9f8e19 | 85 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 86 | // Uses: current volume (duty cycle) |
paulg | 0:185bcd9f8e19 | 87 | |
paulg | 0:185bcd9f8e19 | 88 | void PwmSound::tone(float frequency, float duration) { |
paulg | 0:185bcd9f8e19 | 89 | _pin.period(1.0 / frequency); |
paulg | 0:185bcd9f8e19 | 90 | _pin = _volume / 2.0; |
paulg | 0:185bcd9f8e19 | 91 | if (duration == 0.0) { |
paulg | 0:185bcd9f8e19 | 92 | _playing = true; |
paulg | 0:185bcd9f8e19 | 93 | return; |
paulg | 0:185bcd9f8e19 | 94 | } |
paulg | 0:185bcd9f8e19 | 95 | wait(duration); |
paulg | 0:185bcd9f8e19 | 96 | _pin = 0.0; |
paulg | 0:185bcd9f8e19 | 97 | } |
paulg | 0:185bcd9f8e19 | 98 | |
paulg | 0:185bcd9f8e19 | 99 | void PwmSound::tone(float frequency) { |
paulg | 0:185bcd9f8e19 | 100 | _pin.period(1.0 / frequency); |
paulg | 0:185bcd9f8e19 | 101 | _pin = _volume / 2.0; |
paulg | 0:185bcd9f8e19 | 102 | if (_duration == 0.0) { |
paulg | 0:185bcd9f8e19 | 103 | _playing = true; |
paulg | 0:185bcd9f8e19 | 104 | return; |
paulg | 0:185bcd9f8e19 | 105 | } |
paulg | 0:185bcd9f8e19 | 106 | wait(_duration); |
paulg | 0:185bcd9f8e19 | 107 | _pin = 0.0; |
paulg | 0:185bcd9f8e19 | 108 | } |
paulg | 0:185bcd9f8e19 | 109 | |
paulg | 0:185bcd9f8e19 | 110 | // Stop background tone or sound generation |
paulg | 0:185bcd9f8e19 | 111 | |
paulg | 0:185bcd9f8e19 | 112 | void PwmSound::stop(void) { |
paulg | 0:185bcd9f8e19 | 113 | _playing = false; |
paulg | 0:185bcd9f8e19 | 114 | _pin = 0.0; |
paulg | 0:185bcd9f8e19 | 115 | } |
paulg | 0:185bcd9f8e19 | 116 | |
paulg | 0:185bcd9f8e19 | 117 | // Set default duration |
paulg | 0:185bcd9f8e19 | 118 | // |
paulg | 0:185bcd9f8e19 | 119 | // Parameters: |
paulg | 0:185bcd9f8e19 | 120 | // duration - duration of tone in seconds |
paulg | 0:185bcd9f8e19 | 121 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 122 | |
paulg | 0:185bcd9f8e19 | 123 | void PwmSound::duration(float duration) { |
paulg | 0:185bcd9f8e19 | 124 | _duration = duration; |
paulg | 0:185bcd9f8e19 | 125 | } |
paulg | 0:185bcd9f8e19 | 126 | |
paulg | 0:185bcd9f8e19 | 127 | // Set default volume |
paulg | 0:185bcd9f8e19 | 128 | // |
paulg | 0:185bcd9f8e19 | 129 | // Parameters: |
paulg | 0:185bcd9f8e19 | 130 | // volume - crude volume control (0.0 - 1.0), alters PWM duty cycle 0 - 50% |
paulg | 0:185bcd9f8e19 | 131 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 132 | |
paulg | 0:185bcd9f8e19 | 133 | void PwmSound::volume(float volume) { |
paulg | 0:185bcd9f8e19 | 134 | _volume = volume; |
paulg | 0:185bcd9f8e19 | 135 | } |
paulg | 0:185bcd9f8e19 | 136 | |
paulg | 0:185bcd9f8e19 | 137 | // Beeps of various types and other sounds |
paulg | 0:185bcd9f8e19 | 138 | // Note: buzz, siren and trill use a ticker and callback to |
paulg | 0:185bcd9f8e19 | 139 | // support continuous sound in background |
paulg | 0:185bcd9f8e19 | 140 | // |
paulg | 0:185bcd9f8e19 | 141 | // Parameters: |
paulg | 0:185bcd9f8e19 | 142 | // n - number of cycles, 0 for continuous sound in background |
paulg | 0:185bcd9f8e19 | 143 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 144 | |
paulg | 0:185bcd9f8e19 | 145 | void PwmSound::bip(int n) { |
paulg | 0:185bcd9f8e19 | 146 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 147 | tone(1047.0, 0.10); |
paulg | 0:185bcd9f8e19 | 148 | wait(0.03); |
paulg | 0:185bcd9f8e19 | 149 | } |
paulg | 0:185bcd9f8e19 | 150 | } |
paulg | 0:185bcd9f8e19 | 151 | |
paulg | 0:185bcd9f8e19 | 152 | void PwmSound::beep(int n) { |
paulg | 0:185bcd9f8e19 | 153 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 154 | tone(969.0, 0.3); |
paulg | 0:185bcd9f8e19 | 155 | wait(0.1); |
paulg | 0:185bcd9f8e19 | 156 | } |
paulg | 0:185bcd9f8e19 | 157 | } |
paulg | 0:185bcd9f8e19 | 158 | |
paulg | 0:185bcd9f8e19 | 159 | void PwmSound::bleep(int n) { |
paulg | 0:185bcd9f8e19 | 160 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 161 | tone(800.0, 0.4); |
paulg | 0:185bcd9f8e19 | 162 | wait(0.1); |
paulg | 0:185bcd9f8e19 | 163 | } |
paulg | 0:185bcd9f8e19 | 164 | } |
paulg | 0:185bcd9f8e19 | 165 | |
paulg | 0:185bcd9f8e19 | 166 | void PwmSound::buzz(int n) { |
paulg | 0:185bcd9f8e19 | 167 | if (n == 0) { |
paulg | 0:185bcd9f8e19 | 168 | _setup(1900.0, 300.0, 0.01); |
paulg | 0:185bcd9f8e19 | 169 | return; |
paulg | 0:185bcd9f8e19 | 170 | } |
paulg | 0:185bcd9f8e19 | 171 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 172 | for (int j = 0; j < 20; j++) { |
paulg | 0:185bcd9f8e19 | 173 | tone(1900.0, 0.01); |
paulg | 0:185bcd9f8e19 | 174 | tone(300.0, 0.01); |
paulg | 0:185bcd9f8e19 | 175 | } |
paulg | 0:185bcd9f8e19 | 176 | } |
paulg | 0:185bcd9f8e19 | 177 | } |
paulg | 0:185bcd9f8e19 | 178 | |
paulg | 0:185bcd9f8e19 | 179 | void PwmSound::siren(int n) { |
paulg | 0:185bcd9f8e19 | 180 | if (n == 0) { |
paulg | 0:185bcd9f8e19 | 181 | _setup(969.0, 800.0, 0.5); |
paulg | 0:185bcd9f8e19 | 182 | return; |
paulg | 0:185bcd9f8e19 | 183 | } |
paulg | 0:185bcd9f8e19 | 184 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 185 | tone(969.0, 0.5); |
paulg | 0:185bcd9f8e19 | 186 | tone(800.0, 0.5); |
paulg | 0:185bcd9f8e19 | 187 | } |
paulg | 0:185bcd9f8e19 | 188 | } |
paulg | 0:185bcd9f8e19 | 189 | |
paulg | 0:185bcd9f8e19 | 190 | void PwmSound::trill(int n) { |
paulg | 0:185bcd9f8e19 | 191 | if (n == 0) { |
paulg | 0:185bcd9f8e19 | 192 | _setup(969.0, 800.0, 0.05); |
paulg | 0:185bcd9f8e19 | 193 | return; |
paulg | 0:185bcd9f8e19 | 194 | } |
paulg | 0:185bcd9f8e19 | 195 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 196 | if (i > 0) { |
paulg | 0:185bcd9f8e19 | 197 | tone(800.0, 0.05); //make the trills sound continouus |
paulg | 0:185bcd9f8e19 | 198 | } |
paulg | 0:185bcd9f8e19 | 199 | tone(969.0, 0.05); |
paulg | 0:185bcd9f8e19 | 200 | tone(800.0, 0.05); |
paulg | 0:185bcd9f8e19 | 201 | tone(969.0, 0.05); |
paulg | 0:185bcd9f8e19 | 202 | tone(800.0, 0.05); |
paulg | 0:185bcd9f8e19 | 203 | tone(969.0, 0.05); |
paulg | 0:185bcd9f8e19 | 204 | tone(800.0, 0.05); |
paulg | 0:185bcd9f8e19 | 205 | tone(969.0, 0.05); |
paulg | 0:185bcd9f8e19 | 206 | tone(800.0, 0.05); |
paulg | 0:185bcd9f8e19 | 207 | tone(969.0, 0.05); |
paulg | 0:185bcd9f8e19 | 208 | } |
paulg | 0:185bcd9f8e19 | 209 | } |
paulg | 0:185bcd9f8e19 | 210 | |
paulg | 0:185bcd9f8e19 | 211 | void PwmSound::phone(int n) { |
paulg | 0:185bcd9f8e19 | 212 | for (int i = 0; i < n; i++) { |
paulg | 0:185bcd9f8e19 | 213 | trill(); |
paulg | 0:185bcd9f8e19 | 214 | wait(0.10); |
paulg | 0:185bcd9f8e19 | 215 | trill(); |
paulg | 0:185bcd9f8e19 | 216 | wait(0.7); |
paulg | 0:185bcd9f8e19 | 217 | } |
paulg | 0:185bcd9f8e19 | 218 | } |
paulg | 0:185bcd9f8e19 | 219 | |
paulg | 0:185bcd9f8e19 | 220 | // Continuous sound setup and callback routines |
paulg | 0:185bcd9f8e19 | 221 | |
paulg | 0:185bcd9f8e19 | 222 | void PwmSound::_setup(float freq1, float freq2, float duration) { |
paulg | 0:185bcd9f8e19 | 223 | _freq1 = freq1; |
paulg | 0:185bcd9f8e19 | 224 | _freq2 = freq2; |
paulg | 0:185bcd9f8e19 | 225 | _beat = false; |
paulg | 0:185bcd9f8e19 | 226 | _sustainTkr.attach(this, &PwmSound::_sustain, duration); |
paulg | 0:185bcd9f8e19 | 227 | tone(freq1, 0.0); //start the sound |
paulg | 0:185bcd9f8e19 | 228 | _playing = true; |
paulg | 0:185bcd9f8e19 | 229 | } |
paulg | 0:185bcd9f8e19 | 230 | |
paulg | 0:185bcd9f8e19 | 231 | void PwmSound::_sustain(void) { |
paulg | 0:185bcd9f8e19 | 232 | if (_playing == false) { |
paulg | 0:185bcd9f8e19 | 233 | _sustainTkr.detach(); //detach callback to stop sound |
paulg | 0:185bcd9f8e19 | 234 | _pin = 0.0; |
paulg | 0:185bcd9f8e19 | 235 | } else { |
paulg | 0:185bcd9f8e19 | 236 | _beat = !_beat; |
paulg | 0:185bcd9f8e19 | 237 | tone( (_beat ? _freq2 : _freq1), 0.0); |
paulg | 0:185bcd9f8e19 | 238 | } |
paulg | 0:185bcd9f8e19 | 239 | } |
paulg | 0:185bcd9f8e19 | 240 | |
paulg | 0:185bcd9f8e19 | 241 | // Play a musical note on output pin |
paulg | 0:185bcd9f8e19 | 242 | // |
paulg | 0:185bcd9f8e19 | 243 | // Parameters: |
paulg | 0:185bcd9f8e19 | 244 | // number - 0 = rest, notes from 1 to 84, middle C (262Hz) = 37 |
paulg | 0:185bcd9f8e19 | 245 | // length - duration of note (1-64), 1 = whole note (semibreve) |
paulg | 0:185bcd9f8e19 | 246 | // 2 = half note (minim) |
paulg | 0:185bcd9f8e19 | 247 | // 4 = quarter note (crotchet) = 1 beat |
paulg | 0:185bcd9f8e19 | 248 | // 8 = eighth note (quaver) |
paulg | 0:185bcd9f8e19 | 249 | // etc |
paulg | 0:185bcd9f8e19 | 250 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 251 | // Uses: current tempo, music style and volume (duty cycle) |
paulg | 0:185bcd9f8e19 | 252 | |
paulg | 0:185bcd9f8e19 | 253 | void PwmSound::note(int number, int length) { |
paulg | 0:185bcd9f8e19 | 254 | int frequency; |
paulg | 0:185bcd9f8e19 | 255 | float duration, play, rest; |
paulg | 0:185bcd9f8e19 | 256 | |
paulg | 0:185bcd9f8e19 | 257 | //pc.printf("<number %d, length %d, volume %f, ", number, length, volume); |
paulg | 0:185bcd9f8e19 | 258 | if (number < 1 || number > 84) { //convert bad note to a rest |
paulg | 0:185bcd9f8e19 | 259 | number = 0; |
paulg | 0:185bcd9f8e19 | 260 | } |
paulg | 0:185bcd9f8e19 | 261 | frequency = notePitches[number]; |
paulg | 0:185bcd9f8e19 | 262 | |
paulg | 0:185bcd9f8e19 | 263 | duration = 240.0 / (_tempo * length); |
paulg | 0:185bcd9f8e19 | 264 | if (_style == PwmSound::STACCATO) { //staccato |
paulg | 0:185bcd9f8e19 | 265 | play = duration * 0.75; |
paulg | 0:185bcd9f8e19 | 266 | rest = duration * 0.25; |
paulg | 0:185bcd9f8e19 | 267 | } else if (_style == PwmSound::LEGATO) { //legato |
paulg | 0:185bcd9f8e19 | 268 | play = duration; |
paulg | 0:185bcd9f8e19 | 269 | rest = 0; |
paulg | 0:185bcd9f8e19 | 270 | } else { //normal |
paulg | 0:185bcd9f8e19 | 271 | play = duration * 0.875; |
paulg | 0:185bcd9f8e19 | 272 | rest = duration * 0.125; |
paulg | 0:185bcd9f8e19 | 273 | } |
paulg | 0:185bcd9f8e19 | 274 | //pc.printf("f %d, d %f, p %f, r %f>\n", frequency, duration, play, rest); |
paulg | 0:185bcd9f8e19 | 275 | if (number > 0) { |
paulg | 0:185bcd9f8e19 | 276 | _pin.period(1.0 / frequency); |
paulg | 0:185bcd9f8e19 | 277 | _pin = _volume / 2.0; |
paulg | 0:185bcd9f8e19 | 278 | } |
paulg | 0:185bcd9f8e19 | 279 | wait(play); |
paulg | 0:185bcd9f8e19 | 280 | _pin = 0.0; |
paulg | 0:185bcd9f8e19 | 281 | wait(rest); |
paulg | 0:185bcd9f8e19 | 282 | } |
paulg | 0:185bcd9f8e19 | 283 | |
paulg | 0:185bcd9f8e19 | 284 | // Set default tempo |
paulg | 0:185bcd9f8e19 | 285 | // |
paulg | 0:185bcd9f8e19 | 286 | // Parameters: |
paulg | 0:185bcd9f8e19 | 287 | // tempo - tempo in BPM |
paulg | 0:185bcd9f8e19 | 288 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 289 | |
paulg | 0:185bcd9f8e19 | 290 | void PwmSound::tempo(int tempo) { |
paulg | 0:185bcd9f8e19 | 291 | _tempo = tempo; |
paulg | 0:185bcd9f8e19 | 292 | } |
paulg | 0:185bcd9f8e19 | 293 | |
paulg | 0:185bcd9f8e19 | 294 | // Set default music style |
paulg | 0:185bcd9f8e19 | 295 | // |
paulg | 0:185bcd9f8e19 | 296 | // Parameters: |
paulg | 0:185bcd9f8e19 | 297 | // style - STAACATO, NORMAL or LEGATO |
paulg | 0:185bcd9f8e19 | 298 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 299 | |
paulg | 0:185bcd9f8e19 | 300 | void PwmSound::style(MusicStyle style) { |
paulg | 0:185bcd9f8e19 | 301 | _style = style; |
paulg | 0:185bcd9f8e19 | 302 | } |
paulg | 0:185bcd9f8e19 | 303 | |
paulg | 0:185bcd9f8e19 | 304 | // Play a simple tune from note data in an array. |
paulg | 0:185bcd9f8e19 | 305 | // |
paulg | 0:185bcd9f8e19 | 306 | // Parameters: |
paulg | 0:185bcd9f8e19 | 307 | // tune - pointer to char array containing tune data |
paulg | 0:185bcd9f8e19 | 308 | // first entry is tempo |
paulg | 0:185bcd9f8e19 | 309 | // second entry is music style (STACCATO, NORMAL, LEGATO) |
paulg | 0:185bcd9f8e19 | 310 | // subsequent entries are note number/length pairs |
paulg | 0:185bcd9f8e19 | 311 | // final entry must be 0, 0 |
paulg | 0:185bcd9f8e19 | 312 | // Returns: nothing |
paulg | 0:185bcd9f8e19 | 313 | // Uses: current volume |
paulg | 0:185bcd9f8e19 | 314 | |
paulg | 0:185bcd9f8e19 | 315 | void PwmSound::tune(unsigned char* tune) { |
paulg | 0:185bcd9f8e19 | 316 | int t, number, length; |
paulg | 0:185bcd9f8e19 | 317 | |
paulg | 0:185bcd9f8e19 | 318 | t = *tune++; |
paulg | 0:185bcd9f8e19 | 319 | if (t == 0) { |
paulg | 0:185bcd9f8e19 | 320 | return; |
paulg | 0:185bcd9f8e19 | 321 | } |
paulg | 0:185bcd9f8e19 | 322 | tempo(t); |
paulg | 0:185bcd9f8e19 | 323 | style( (MusicStyle) *tune++); |
paulg | 0:185bcd9f8e19 | 324 | while (true) { |
paulg | 0:185bcd9f8e19 | 325 | number = *tune++; |
paulg | 0:185bcd9f8e19 | 326 | length = *tune++; |
paulg | 0:185bcd9f8e19 | 327 | if (number == 0 && length == 0) { |
paulg | 0:185bcd9f8e19 | 328 | break; |
paulg | 0:185bcd9f8e19 | 329 | } |
paulg | 0:185bcd9f8e19 | 330 | note(number, length); |
paulg | 0:185bcd9f8e19 | 331 | } |
paulg | 0:185bcd9f8e19 | 332 | } |
paulg | 0:185bcd9f8e19 | 333 | |
paulg | 0:185bcd9f8e19 | 334 | // END of PwmSound.cpp |