change tone sounds by altering the waveforms
Dependencies: mbed
Fork of 5_songs by
main.cpp@2:610196c7b41c, 2016-05-12 (annotated)
- Committer:
- maclobdell
- Date:
- Thu May 12 17:36:35 2016 +0000
- Revision:
- 2:610196c7b41c
- Parent:
- 1:8922cc02aec7
- Child:
- 3:c04186a77ede
fixed play tone function to not set frequency as the period
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
maclobdell | 0:0fb17f0d39e7 | 1 | #include "mbed.h" // this tells us to load mbed related functions |
maclobdell | 1:8922cc02aec7 | 2 | #include "tones.h" // list of all the tones and their frequencies |
maclobdell | 1:8922cc02aec7 | 3 | #include "rtos.h" // using the rtos for timing features. Just want to block the play_song function until it is time to play the next note. |
maclobdell | 0:0fb17f0d39e7 | 4 | |
maclobdell | 0:0fb17f0d39e7 | 5 | PwmOut buzzer(D3); // our buzzer is a PWM output (pulse-width modulation) |
maclobdell | 0:0fb17f0d39e7 | 6 | |
maclobdell | 0:0fb17f0d39e7 | 7 | static int BPM = 120; |
maclobdell | 0:0fb17f0d39e7 | 8 | |
maclobdell | 0:0fb17f0d39e7 | 9 | static void silence() { |
maclobdell | 0:0fb17f0d39e7 | 10 | buzzer.write(0.0f); // silence! |
maclobdell | 0:0fb17f0d39e7 | 11 | } |
maclobdell | 0:0fb17f0d39e7 | 12 | |
maclobdell | 0:0fb17f0d39e7 | 13 | // this is our function that plays a tone. |
maclobdell | 0:0fb17f0d39e7 | 14 | // Takes in a tone frequency, and after duration (in ms.) we stop playing again |
maclobdell | 0:0fb17f0d39e7 | 15 | static void play_tone(int tone) { |
maclobdell | 2:610196c7b41c | 16 | buzzer.period_us(1000000/(tone)); |
maclobdell | 0:0fb17f0d39e7 | 17 | buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud |
maclobdell | 0:0fb17f0d39e7 | 18 | } |
maclobdell | 0:0fb17f0d39e7 | 19 | |
maclobdell | 0:0fb17f0d39e7 | 20 | static void play_song(int notes_left, int* melody, int* duration) { |
maclobdell | 1:8922cc02aec7 | 21 | |
maclobdell | 0:0fb17f0d39e7 | 22 | // YOUR CODE HERE |
maclobdell | 2:610196c7b41c | 23 | //REMOVE |
maclobdell | 2:610196c7b41c | 24 | // melody and duration are pointers, they point to the array of tones and durations we declared earlier |
maclobdell | 2:610196c7b41c | 25 | // every time we play a note we up these pointers (move one element forward) |
maclobdell | 2:610196c7b41c | 26 | // so the current tone is always the first element of melody (same for duration) |
maclobdell | 2:610196c7b41c | 27 | |
maclobdell | 2:610196c7b41c | 28 | int length; |
maclobdell | 2:610196c7b41c | 29 | |
maclobdell | 2:610196c7b41c | 30 | while(notes_left > 0) |
maclobdell | 2:610196c7b41c | 31 | { |
maclobdell | 2:610196c7b41c | 32 | |
maclobdell | 2:610196c7b41c | 33 | int tone = melody[0]; |
maclobdell | 2:610196c7b41c | 34 | // BPM is quarter notes per minute, so length in milliseconds is: |
maclobdell | 2:610196c7b41c | 35 | length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000))); |
maclobdell | 2:610196c7b41c | 36 | |
maclobdell | 2:610196c7b41c | 37 | play_tone(tone); |
maclobdell | 2:610196c7b41c | 38 | |
maclobdell | 2:610196c7b41c | 39 | // after half the length of this tone, we silence |
maclobdell | 2:610196c7b41c | 40 | Thread::wait(length / 2); //block this main thread until it is time to silence. This lets other threads run. |
maclobdell | 2:610196c7b41c | 41 | silence(); |
maclobdell | 2:610196c7b41c | 42 | |
maclobdell | 2:610196c7b41c | 43 | //after the full length of this tone, call next note |
maclobdell | 2:610196c7b41c | 44 | Thread::wait(length); //block this main thread until it is time to play the next note. This lets other threads run. |
maclobdell | 2:610196c7b41c | 45 | |
maclobdell | 2:610196c7b41c | 46 | // after the full length of this tone, we up the melody, and down the notes_left |
maclobdell | 2:610196c7b41c | 47 | |
maclobdell | 2:610196c7b41c | 48 | notes_left--; |
maclobdell | 2:610196c7b41c | 49 | melody++; |
maclobdell | 2:610196c7b41c | 50 | duration++; |
maclobdell | 1:8922cc02aec7 | 51 | |
maclobdell | 2:610196c7b41c | 52 | } |
maclobdell | 2:610196c7b41c | 53 | |
maclobdell | 2:610196c7b41c | 54 | // we're done! just finish this note and silence |
maclobdell | 2:610196c7b41c | 55 | Thread::wait(length / 2); //block this main thread until it is time to silence. This lets other threads run. |
maclobdell | 2:610196c7b41c | 56 | silence(); |
maclobdell | 2:610196c7b41c | 57 | |
maclobdell | 2:610196c7b41c | 58 | //END REMOVE |
maclobdell | 0:0fb17f0d39e7 | 59 | } |
maclobdell | 0:0fb17f0d39e7 | 60 | |
maclobdell | 0:0fb17f0d39e7 | 61 | // this code runs when the microcontroller starts up |
maclobdell | 1:8922cc02aec7 | 62 | int main() { |
maclobdell | 2:610196c7b41c | 63 | |
maclobdell | 0:0fb17f0d39e7 | 64 | // declare a melody |
maclobdell | 0:0fb17f0d39e7 | 65 | int melody[] = { |
maclobdell | 2:610196c7b41c | 66 | NOTE_G4, NOTE_G4, NOTE_G4, NOTE_DS3, NOTE_AS4, |
maclobdell | 2:610196c7b41c | 67 | NOTE_G4, NOTE_DS3, NOTE_AS4, NOTE_G4, |
maclobdell | 2:610196c7b41c | 68 | NOTE_D4, NOTE_D4, NOTE_D4, NOTE_DS4, NOTE_AS4, |
maclobdell | 2:610196c7b41c | 69 | NOTE_FS4, NOTE_DS4, NOTE_AS4, NOTE_G4 |
maclobdell | 0:0fb17f0d39e7 | 70 | }; |
maclobdell | 2:610196c7b41c | 71 | |
maclobdell | 0:0fb17f0d39e7 | 72 | // note durations: 4 = quarter note, 8 = eighth note, etc.: |
maclobdell | 0:0fb17f0d39e7 | 73 | int duration[] = { |
maclobdell | 2:610196c7b41c | 74 | 2, 2, 2, 4, 4, |
maclobdell | 2:610196c7b41c | 75 | 2, 4, 4, 1, |
maclobdell | 2:610196c7b41c | 76 | 2, 2, 2, 4, 4, |
maclobdell | 2:610196c7b41c | 77 | 2, 4, 4, 1 |
maclobdell | 2:610196c7b41c | 78 | }; |
maclobdell | 0:0fb17f0d39e7 | 79 | |
maclobdell | 0:0fb17f0d39e7 | 80 | // melody & duration are on the heap, need to get them on the stack |
maclobdell | 0:0fb17f0d39e7 | 81 | int *m = new int[sizeof(melody) / sizeof(int)]; |
maclobdell | 0:0fb17f0d39e7 | 82 | memcpy(m, melody, sizeof(melody)); |
maclobdell | 0:0fb17f0d39e7 | 83 | int *d = new int[sizeof(duration) / sizeof(int)]; |
maclobdell | 0:0fb17f0d39e7 | 84 | memcpy(d, duration, sizeof(duration)); |
maclobdell | 0:0fb17f0d39e7 | 85 | |
maclobdell | 0:0fb17f0d39e7 | 86 | if (sizeof(melody) != sizeof(duration)) { |
maclobdell | 0:0fb17f0d39e7 | 87 | printf("Melody and duration do not have same number of elements! Aborting!\r\n"); |
maclobdell | 2:610196c7b41c | 88 | return 1; |
maclobdell | 0:0fb17f0d39e7 | 89 | } |
maclobdell | 0:0fb17f0d39e7 | 90 | |
maclobdell | 0:0fb17f0d39e7 | 91 | play_song(sizeof(melody) / sizeof(int), m, d); |
maclobdell | 2:610196c7b41c | 92 | |
maclobdell | 2:610196c7b41c | 93 | return 0; |
maclobdell | 0:0fb17f0d39e7 | 94 | } |