Created
October 22, 2016 15:45
-
-
Save dmiddlecamp/5a93cf5b66404876b7e5d4bfa8783014 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "math.h" | |
const char nyan_cat_intro[] = "DS5,16,E5,16,FS5,8,B5,8,DS5,16,E5,16,FS5,16,B5,16,CS6,16,DS6,16,CS6,16,AS5,16,B5,8,FS5,8,DS5,16,E5,16,FS5,8,B5,8,CS6,16,AS5,16,B5,16,CS6,16,E6,16,DS6,16,E6,16,B5,16\n"; | |
const char nyan_cat_melody[] = "FS5,8,GS5,8,DS5,16,DS5,16,R,16,B4,16,D5,16,CS5,16,B4,16,R,16,B4,8,CS5,8,D5,8,D5,16,CS5,16,B4,16,CS5,16,DS5,16,FS5,16,GS5,16,DS5,16,FS5,16,CS5,16,DS5,16,B4,16,CS5,16,B4,16,DS5,8,FS5,8,GS5,16,DS5,16,FS5,16,CS5,16,DS5,16,B4,16,D5,16,DS5,16,D5,16,CS5,16,B4,16,CS5,16,D5,8,B4,16,CS5,16,DS5,16,FS5,16,CS5,16,DS5,16,CS5,16,B4,16,CS5,8,B4,8,CS5,8,FS5,8,GS5,8,DS5,16,DS5,16,R,16,B4,16,D5,16,CS5,16,B4,16,R,16,B4,8,CS5,8,D5,8,D5,16,CS5,16,B4,16,CS5,16,DS5,16,FS5,16,GS5,16,DS5,16,FS5,16,CS5,16,DS5,16,B4,16,CS5,16,B4,16,DS5,8,FS5,8,GS5,16,DS5,16,FS5,16,CS5,16,DS5,16,B4,16,D5,16,DS5,16,D5,16,CS5,16,B4,16,CS5,16,D5,8,B4,16,CS5,16,DS5,16,FS5,16,CS5,16,DS5,16,CS5,16,B4,16,CS5,8,B4,8,CS5,8,B4,8,FS4,16,GS4,16,B4,8,FS4,16,GS4,16,B4,16,CS5,16,DS5,16,B4,16,E5,16,DS5,16,E5,16,FS5,16,B4,8,B4,8,FS4,16,GS4,16,B4,16,FS4,16,E5,16,DS5,16,CS5,16,B4,16,FS4,16,DS4,16,E4,16,FS4,16,B4,8,FS4,16,GS4,16,B4,8,FS4,16,GS4,16,B4,16,B4,16,CS5,16,DS5,16,B4,16,FS4,16,GS4,16,FS4,16,B4,8,B4,16,AS4,16,B4,16,FS4,16,GS4,16,E4,16,E5,16,DS5,16,E5,16,FS5,16,B4,8,AS4,8,B4,8,FS4,16,GS4,16,B4,8,FS4,16,GS4,16,B4,16,CS5,16,DS5,16,B4,16,E5,16,DS5,16,E5,16,FS5,16,B4,8,B4,8,FS4,16,GS4,16,B4,16,FS4,16,E5,16,DS5,16,CS5,16,B4,16,FS4,16,DS4,16,E4,16,FS4,16,B4,8,FS4,16,GS4,16,B4,8,FS4,16,GS4,16,B4,16,B4,16,CS5,16,DS5,16,B4,16,FS4,16,GS4,16,FS4,16,B4,8,B4,16,AS4,16,B4,16,FS4,16,GS4,16,B4,16,E5,16,DS5,16,E5,16,FS5,16,B4,8,CS5,8\n"; | |
String nyan_song = String(nyan_cat_melody); | |
char inputStr[2048]; | |
char* note; | |
char* duration; | |
int bpm = 110; | |
void setup() { | |
pinMode(D0, OUTPUT); | |
nyan_song.toCharArray(inputStr, nyan_song.length()); | |
note = strtok(inputStr,","); | |
duration = strtok(NULL,", \n"); | |
} | |
void loop() { | |
//tone(D0, 220, 500); | |
playNote(note, atoi(duration)); | |
if (duration != NULL) { | |
// advance the note | |
note = strtok(NULL,","); | |
duration = strtok(NULL,", \n"); | |
} | |
else { | |
nyan_song.toCharArray(inputStr, nyan_song.length()); | |
note = strtok(inputStr,","); | |
duration = strtok(NULL,", \n"); | |
} | |
// delay(1000); | |
} | |
void playNote(String note, int duration) { | |
int noteNum = 0; | |
int noteSharp = 0; | |
int noteFlat = 0; | |
int octave = 5; | |
int freq = 256; | |
int octIndex = note.length()-1; // octave is the last char | |
String tempOctave = note.substring(octIndex, octIndex+1); | |
octave = tempOctave.toInt(); | |
String tempNote = note.substring(0, octIndex); | |
tempNote.toUpperCase(); | |
if (tempNote.length()==2) { | |
if (tempNote.charAt(1)=='S' || tempNote.charAt(1)=='#') { | |
noteSharp = 1; | |
} else if (tempNote.charAt(1)=='B') { | |
noteFlat = 1; | |
} | |
} | |
// Using 240 instead of 250 after calibrating at 60 BPM and 240 BPM with a stopwatch. | |
// Seems to work well with and without Serial logging, so that is ok to leave uncommented below. | |
if (duration != 0) { | |
duration = 1000*240/bpm/duration; | |
} | |
switch (tempNote.charAt(0)) { | |
case 'C': | |
noteNum = 0 + noteSharp; | |
break; | |
case 'D': | |
noteNum = 2 + noteSharp - noteFlat; | |
break; | |
case 'E': | |
noteNum = 4 - noteFlat; | |
break; | |
case 'F': | |
noteNum = 5 + noteSharp; | |
break; | |
case 'G': | |
noteNum = 7 + noteSharp - noteFlat; | |
break; | |
case 'A': | |
noteNum = 9 + noteSharp - noteFlat; | |
break; | |
case 'B': | |
noteNum = 11 - noteFlat; | |
break; | |
case 'R': // Rest note 'R' or 'REST' | |
octave = -1; | |
break; | |
default: | |
break; | |
} | |
// based on equation at http://www.phy.mtu.edu/~suits/NoteFreqCalcs.html and the Verdi tuning | |
// fn = f0*(2^1/12)^n where n = number of half-steps from the reference frequency f0 | |
freq = float(256*pow(1.05946,( 12.0*(octave-4) +noteNum))); | |
// C4^ (2^1/12)^ 12 half-steps in an octave ^how many extra half-steps within that octave, 0 for 'C' | |
// Serial.printlnf("%-3s o:%-2d f:%-5d d:%d", tempNote.c_str(), octave, int(freq), duration); | |
if (octave != -1) tone(D0, int(freq), duration); | |
delay(duration); | |
if (octave != -1) noTone(D0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment