change tone sounds by altering the waveforms

Dependencies:   mbed

Fork of 5_songs by MakingMusicWorkshop

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?

UserRevisionLine numberNew 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 }