Edward Baker
/
Melody
Example of playing melodies using DAC.
Fork of Melody by
main.cpp
- Committer:
- el16ecb
- Date:
- 2017-03-02
- Revision:
- 2:7804ced75c2f
- Parent:
- 1:7c149b76c057
File content as of revision 2:7804ced75c2f:
/* Melody Play a simple melody on the DAC using a look-up table for the sine waveform Includes a primitive graphic equalizer on the LEDs Craig A. Evans March 2014 */ #include "mbed.h" #include "tone.h" // note definitions #include <Joystick.h> #define PI 3.14159265359 Timer noteTimer; // timer for note duration AnalogOut aout(p18); // DAC on pin 18 BusOut leds(LED4,LED3,LED2,LED1); // LEDs for display Joystick stick = Joystick(p20,p19,p17); PwmOut red_led (p24); PwmOut green_led (p23); PwmOut blue_led (p22); void initArray(); // function to initialise sample array void tone(float frequency,float duration); // play a tone of set frequency for given duration void graphicEqualizer(int frequency); // displays pattern on LEDs depending on the frequency int n = 32; // number of samples float y[32]; // array to store samples float BPM = 73.0; // beats per minute Vector2D coord = stick.get_coord(); float xoffset = 1 - (coord.x/2); float yoffset = 1 - (coord.y/5); // comment one of the blocks out below - need noteArray[] and noteDuration[] /* // secret film melody... float noteArray[] = { NOTE_E4,NOTE_F4,NOTE_F4,NOTE_F4,NOTE_F4,NOTE_E4,NOTE_E4,NOTE_E4, NOTE_E4,NOTE_G4,NOTE_G4,NOTE_G4,NOTE_G4,NOTE_E4,NOTE_E4,NOTE_E4, NOTE_E4,NOTE_F4,NOTE_F4,NOTE_F4,NOTE_F4,NOTE_E4,NOTE_E4,NOTE_E4, NOTE_E4,NOTE_G4,NOTE_G4,NOTE_G4,NOTE_G4,NOTE_E4,NOTE_E4,NOTE_E4, NOTE_DS5,NOTE_D5,NOTE_B4,NOTE_A4,NOTE_B4,NOTE_E4,NOTE_G4,NOTE_DS5, NOTE_D5,NOTE_G4,NOTE_B4,NOTE_B4,NOTE_FS5,NOTE_F5,NOTE_B4,NOTE_D5, NOTE_AS5,NOTE_A5,NOTE_F5,NOTE_A5,NOTE_DS6,NOTE_D6 }; // durations of the notes // 1/8th, 1/16th, 1/4th etc. float noteDuration[] = { 8,16,16,8,4,8,8,8, 8,16,16,8,4,8,8,8, 8,16,16,8,4,8,8,8, 8,16,16,8,4,8,8,8, 8,2,8,8,1,8,4,8, 4,8,8,8,8,4,8,4, 8,4,8,4,8,3 }; */ // secret computer game melody... float noteArray[] = { //NOTE_E7, NOTE_E7, 0, NOTE_E7, // 0, NOTE_C7, NOTE_E7, 0, // NOTE_G7, 0, 0, 0, // NOTE_G6, 0, 0, 0, // // NOTE_C7, 0, 0, NOTE_G6, // 0, 0, NOTE_E6, 0, // 0, NOTE_A6, 0, NOTE_B6, // 0, NOTE_AS6, NOTE_A6, 0, // // NOTE_G6, NOTE_E7, NOTE_G7, // NOTE_A7, 0, NOTE_F7, NOTE_G7, // 0, NOTE_E7, 0,NOTE_C7, // NOTE_D7, NOTE_B6, 0, 0, // // NOTE_C7, 0, 0, NOTE_G6, // 0, 0, NOTE_E6, 0, // 0, NOTE_A6, 0, NOTE_B6, // 0, NOTE_AS6, NOTE_A6, 0, // // NOTE_G6, NOTE_E7, NOTE_G7, // NOTE_A7, 0, NOTE_F7, NOTE_G7, // 0, NOTE_E7, 0,NOTE_C7, // NOTE_D7, NOTE_B6, 0, 0 NOTE_G6, 0, NOTE_A7, 0, NOTE_E6, NOTE_E6, 0, NOTE_C6, NOTE_DS6, NOTE_D6, NOTE_C6, 0, NOTE_C6, 0, NOTE_D6, 0, NOTE_DS6, 0, NOTE_DS6, NOTE_D6, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_G6, NOTE_A7, NOTE_E6, NOTE_G7, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_D6, NOTE_C6, NOTE_E6, 0, NOTE_G6, 0, NOTE_A7, NOTE_E6, NOTE_G6, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_DS6, NOTE_E6, NOTE_DS6, NOTE_D6, NOTE_C6, NOTE_D6, NOTE_DS6, 0, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_G6, NOTE_D6, NOTE_E6, NOTE_D6, NOTE_C6, NOTE_D6, 0, NOTE_C6, 0, NOTE_D6, 0, NOTE_G6, 0, NOTE_A7, 0, NOTE_E6, NOTE_E6, 0, NOTE_C6, NOTE_DS6, NOTE_D6, NOTE_C6, 0, NOTE_C6, 0, NOTE_D6, 0, NOTE_DS6, 0, NOTE_DS6, NOTE_D6, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_G6, NOTE_A7, NOTE_E6, NOTE_G7, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_D6, NOTE_C6, NOTE_E6, 0, NOTE_G6, 0, NOTE_A7, NOTE_E6, NOTE_G6, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_DS6, NOTE_E6, NOTE_DS6, NOTE_D6, NOTE_C6, NOTE_D6, NOTE_DS6, 0, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_G6, NOTE_D6, NOTE_E6, NOTE_D6, NOTE_C6, NOTE_D6, 0, NOTE_C6, 0, NOTE_C6, 0, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_F6, NOTE_E6, NOTE_F6, NOTE_G6, NOTE_C6, 0, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_G6, NOTE_F6, NOTE_E6, NOTE_D6, NOTE_C6, NOTE_F5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_G5, NOTE_A6, NOTE_G5, NOTE_C6, 0, NOTE_C6, NOTE_B6, NOTE_C5, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_F6, NOTE_E6, NOTE_F6, NOTE_G6, NOTE_C6, 0, NOTE_B6, 0, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_F6, NOTE_E6, NOTE_F6, NOTE_G6, NOTE_C6, 0, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_G6, NOTE_F6, NOTE_E6, NOTE_D6, NOTE_C6, NOTE_F5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, 0, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_C6, NOTE_D6, NOTE_E6, NOTE_C6, NOTE_G5, NOTE_A6, NOTE_G5, NOTE_C6, 0, NOTE_C6, NOTE_B6, NOTE_C5, NOTE_G5, NOTE_A6, NOTE_C6, NOTE_F6, NOTE_E6, NOTE_F6, NOTE_G6, NOTE_C6, 0, NOTE_D6, 0, }; // durations of the notes // 1/8th, 1/16th, 1/4th etc. float noteDuration[] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, }; int main() { initArray(); // fill array with sine samples // calculate number of notes in array //sizeof() returns number of BYTES in array, // so divide by size of a float in BYTES to get number of elements int notes = sizeof(noteArray)/sizeof(float); while (1) { // loop through notes for(int i=0; i < notes; i++) { Vector2D coord = stick.get_coord(); int modi = (yoffset + coord.y/5)*noteArray[i]; float modt = (xoffset + coord.x/2)*noteDuration[i]; printf("%d %d \n",modi,i); // play note tone(modi,60.0/(BPM*modt)); // leave a short pause between notes wait(60.0/(BPM*modt)); } wait(1.0); // wait a second before repeating } } void initArray() { // create LUT - loop through array and calculate sine wave samples for (int i = 0; i < n ; i++) { y[i] = 0.5 + 0.5*sin(i*2*PI/n); } } void tone(float frequency,float duration) { int newfreq = int(frequency); graphicEqualizer(newfreq); // equalizer on LEDs if (frequency > 0) { // a frequency of 0 indicates no note played so only play a note if frequency is not 0 float dt = 1.0/(frequency*n) - (1.34e-6 + 1e-6); // calculate time step - take into account DAC time and wait() offset noteTimer.start(); // start timer while(noteTimer.read() < duration) { // keep looping while timer less than duration for (int i = 0; i < n ; i++) { // loop through samples and output analog waveform aout = y[i]; wait(dt); // leave appropriate delay for frequency } } noteTimer.stop(); // stop the timer noteTimer.reset(); // reset to 0 } else { // if no note played, have a simple delay wait(duration); } leds = 0; // turn off LEDs } // primitive graphic equalizer on the LEDs void graphicEqualizer(int frequency) { // these numbers are fairly random and picked to give a // decent effect when the melodies plays. // Will have to change for different melodies //printf("%f",float((frequency%63)/63.0)); red_led = ((frequency%31)/31.0); green_led = (((frequency)%37)/37.0); blue_led = (((frequency)%41)/41.0); }