First of all thanks for answering my previous questions the info was very helpful!
I've written an Arduino prog based on the Melody Example, which plays guitar tabs (how to read tabs) instead of plain notes. The big difference is that you dont have to enter the notes, but you enter the tab information directly as it is represented in the tab files which are found easily on the internet. String a, fret 11 will become char 'a' in the strings array and 11 in the frets array.
The playNote function takes this info and calculates the highTime for every note - the frequency of the note is calculated from the tab info.
So basically, this tab becomes these arrays:
//Nirvana - Come As You Are (intro)
int length = 16; // the number of notes
char strings[] = "eeeeaeaeeeeaeea "; // a space represents a rest
short frets[] = { 0, 0, 1, 2, 0, 2, 0, 2, 2, 1, 0, 2, 0, 0, 2, 0 };
int tempo = 200;
(I simply copied the values from the tab to the arrays)
Now here's the whole compilable code:
/* guitar tabs player */
int speakerPin = 9;
//Nirvana - Come As You Are (intro)
int length = 16; // the number of notes
char strings[] = "eeeeaeaeeeeaeea "; // a space represents a rest
short frets[] = { 0, 0, 1, 2, 0, 2, 0, 2, 2, 1, 0, 2, 0, 0, 2, 0 };
int tempo = 200;
void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
void playNote(char string, int fret, int duration) {
char names[] = { 'e', 'a', 'd', 'g', 'b', 'E'};
double freqs[] = { 82.4, 110.0, 146.8, 196.0, 246.9, 329.6};
// play the tone corresponding to the note name
for (int i = 0; i < 6; i++) {
if (names[i] == string) {
double freq = freqs[i];
double mult = 1.0595;
if(fret > 0) {
for(int j = 0; j < fret; j++)
mult*=mult;
freq *= mult;
}
int tone = (int)((1.0/(2*freq))*1000000);
playTone(tone, duration);
}
}
}
void setup() {
pinMode(speakerPin, OUTPUT);
}
void loop() {
for (int i = 0; i < length; i++) {
if (strings[i] == ' ') {
digitalWrite(speakerPin, LOW);
delay(tempo);
} else {
playNote(strings[i], frets[i], tempo);
}
// pause between notes
delay(tempo / 4);
}
}
If you run it, you'll hear the song (or somethin that resembles it).
Now the questions!
A. I want to write an automatic converter from tab to array but, some tabs contain two strings info in one fret row - basically two strings played at once, whats the math for combining frequencies of simultaneously played sounds?
B. Is there a way to improve the accuracy of the sound? On my buzzer I can hardly recognize the songs. Is it because the buzzer can't play it, or is my prog lacking some fancy sound algorithms?
Thanks!