change tone sounds by altering the waveforms
Dependencies: mbed
Fork of 5_songs by
main.cpp
- Committer:
- maclobdell
- Date:
- 2016-05-21
- Revision:
- 8:77227ecac915
- Parent:
- 7:4730853634bf
- Child:
- 9:bf01a27b649f
File content as of revision 8:77227ecac915:
#include "mbed.h" // this tells us to load mbed related functions #include "tones.h" // list of all the tones and their frequencies PwmOut buzzer(D3); // our buzzer is a PWM output (pulse-width modulation) static int BPM = 80; static void silence() { buzzer.write(0.0f); // silence! } // this is our function that plays a tone. // Takes in a tone frequency, and after duration (in ms.) we stop playing again static void play_tone(int tone, int duration) { int tone_period_us = 1000000/tone; /* for (long i = 0; i < duration * 1000L; i += tone_period_us * 2) { // let's change the buzzer's volume depending on how far we are float pct = (float)i / (float)(duration * 1000L); buzzer = (1 - pct) / 4; // high to low wait_us(tone_period_us); buzzer = 0.0f; wait_us(tone_period_us); } */ #define PI 3.14159265 for (long i = 0; i < duration * 1000L; i += tone_period_us * 2) { // let's change the buzzer's volume depending on how far we are float pct = (float)i / (float)(duration * 1000L); // make 4 sinus forms (8 * PI), then map it from -1..1 to 0.1..0.6, // then divide by 8 to not make too much sound buzzer = (sin(pct * (8 * PI)) / 2 + 0.6) / 8; wait_us(tone_period_us); buzzer = 0.0f; wait_us(tone_period_us); } buzzer = 0.0f; } static void play_song(int notes_left, int* melody, int* duration) { // melody and duration are pointers, they point to the array of tones and durations we declared earlier // every time we play a note we up these pointers (move one element forward) // so the current tone is always the first element of melody (same for duration) int length; while(notes_left > 0) { int tone = melody[0]; // BPM is quarter notes per minute, so length in milliseconds is: length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000))); play_tone(tone, length); // after the full length of this tone, we up the melody, and down the notes_left notes_left--; melody++; duration++; } // we're done! just finish this note and silence wait_ms(length / 2); silence(); } // this code runs when the microcontroller starts up int main() { // declare a melody int melody[] = { NOTE_C4, NOTE_D4, NOTE_DS4, NOTE_C4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_FS4, NOTE_G4 }; // note durations: 4 = quarter note, 8 = eighth note, etc.: // the rapid succession of 16th notes produces a twill effect int duration[] = { 2, 8, 4, 4, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; // melody & duration are on the heap, need to get them on the stack int *m = new int[sizeof(melody) / sizeof(int)]; memcpy(m, melody, sizeof(melody)); int *d = new int[sizeof(duration) / sizeof(int)]; memcpy(d, duration, sizeof(duration)); if (sizeof(melody) != sizeof(duration)) { printf("Melody and duration do not have same number of elements! Aborting!\r\n"); return 1; } play_song(sizeof(melody) / sizeof(int), m, d); return 0; }