Although I am a slow learner, I'm teaching myself coding using YouTube and Google, and also by trying to understand code that looks interesting and seeing if I can learn about it and edit it.
In the audio library examples sketches is a really interesting synthesis example called "Guitar" some of which I understand and some of which is new.
As I understand it, the sketch uses *chord to reference chords.h which constructs the 6 six string chords of the guitar from a table of notes. I've attached Guitar.ino sketch and chords.h.
There is a series of 'if else' statements which loop to play the chords. So far so good and the sound is great.
Meanwhile I have been teaching myself about arrays and I thought - well I wonder whether I could declare an array of chords and then use a 'for loop' to go through them instead of using the 'if else' approach in the original sketch. It would then be a bit easier to populate the chords in the array to play different songs.
Something like...
What I am puzzled about is how to declare the array's data type. It isn't an int, a float, nor a string and I'm stuck at this point.
In my reading I can see that people advise that working with pointers is not for beginners and so I think I may be trying to run before I can walk but any advice to help me get to the next step would be very welcome.
Thanks in advance.
Robert
Guitar.ino
chords.h
In the audio library examples sketches is a really interesting synthesis example called "Guitar" some of which I understand and some of which is new.
As I understand it, the sketch uses *chord to reference chords.h which constructs the 6 six string chords of the guitar from a table of notes. I've attached Guitar.ino sketch and chords.h.
There is a series of 'if else' statements which loop to play the chords. So far so good and the sound is great.
Meanwhile I have been teaching myself about arrays and I thought - well I wonder whether I could declare an array of chords and then use a 'for loop' to go through them instead of using the 'if else' approach in the original sketch. It would then be a bit easier to populate the chords in the array to play different songs.
Something like...
HTML:
data type? chordArray []=(Aminor, Dminor, Cmajor, Emajor};
for (int = 0; i<4;i++)
{
chord = chordArray(i);
strum_up(chord, 1.0);
delay(hand_delay);
}
What I am puzzled about is how to declare the array's data type. It isn't an int, a float, nor a string and I'm stuck at this point.
In my reading I can see that people advise that working with pointers is not for beginners and so I think I may be trying to run before I can walk but any advice to help me get to the next step would be very welcome.
Thanks in advance.
Robert
Guitar.ino
Code:
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <SerialFlash.h>
#include "chords.h"
// Special thanks to Matthew Rahtz - http://amid.fish/karplus-strong/
AudioSynthKarplusStrong string1;
AudioSynthKarplusStrong string2;
AudioSynthKarplusStrong string3;
AudioSynthKarplusStrong string4;
AudioSynthKarplusStrong string5;
AudioSynthKarplusStrong string6;
AudioMixer4 mixer1;
AudioMixer4 mixer2;
AudioOutputI2S i2s1;
AudioConnection patchCord1(string1, 0, mixer1, 0);
AudioConnection patchCord2(string2, 0, mixer1, 1);
AudioConnection patchCord3(string3, 0, mixer1, 2);
AudioConnection patchCord4(string4, 0, mixer1, 3);
AudioConnection patchCord5(mixer1, 0, mixer2, 0);
AudioConnection patchCord6(string5, 0, mixer2, 1);
AudioConnection patchCord7(string6, 0, mixer2, 2);
AudioConnection patchCord8(mixer2, 0, i2s1, 0);
AudioConnection patchCord9(mixer2, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1;
const int finger_delay = 5;
const int hand_delay = 220;
int chordnum=0;
void setup() {
AudioMemory(15);
sgtl5000_1.enable();
sgtl5000_1.volume(0.6);
mixer1.gain(0, 0.15);
mixer1.gain(1, 0.15);
mixer1.gain(2, 0.15);
mixer1.gain(3, 0.15);
mixer2.gain(1, 0.15);
mixer2.gain(2, 0.15);
delay(700);
}
void strum_up(const float *chord, float velocity);
void strum_dn(const float *chord, float velocity);
void loop() {
const float *chord;
// each time through the loop, play a different chord
if (chordnum == 0) {
chord = Cmajor;
Serial.println("C major");
chordnum = 1;
} else if (chordnum == 1) {
chord = Gmajor;
Serial.println("G major");
chordnum = 2;
} else if (chordnum == 2) {
chord = Aminor;
Serial.println("A minor");
chordnum = 3;
} else {
chord = Eminor;
Serial.println("E minor");
chordnum = 0;
}
// then strum the 6 string several times
strum_up(chord, 1.0);
delay(hand_delay);
delay(hand_delay);
strum_up(chord, 1.0);
delay(hand_delay);
strum_dn(chord, 0.8);
delay(hand_delay);
delay(hand_delay);
strum_dn(chord, 0.8);
delay(hand_delay);
strum_up(chord, 1.0);
delay(hand_delay);
strum_dn(chord, 0.8);
delay(hand_delay);
strum_up(chord, 1.0);
delay(hand_delay);
delay(hand_delay);
strum_up(chord, 1.0);
delay(hand_delay);
strum_dn(chord, 0.7);
delay(hand_delay);
delay(hand_delay);
strum_dn(chord, 0.7);
delay(hand_delay);
strum_up(chord, 1.0);
delay(hand_delay);
strum_dn(chord, 0.7);
delay(hand_delay);
Serial.print("Max CPU Usage = ");
Serial.print(AudioProcessorUsageMax(), 1);
Serial.println("%");
}
void strum_up(const float *chord, float velocity)
{
if (chord[0] > 20.0) string1.noteOn(chord[0], velocity);
delay(finger_delay);
if (chord[1] > 20.0) string2.noteOn(chord[1], velocity);
delay(finger_delay);
if (chord[2] > 20.0) string3.noteOn(chord[2], velocity);
delay(finger_delay);
if (chord[3] > 20.0) string4.noteOn(chord[3], velocity);
delay(finger_delay);
if (chord[4] > 20.0) string5.noteOn(chord[4], velocity);
delay(finger_delay);
if (chord[5] > 20.0) string6.noteOn(chord[5], velocity);
delay(finger_delay);
}
void strum_dn(const float *chord, float velocity)
{
if (chord[5] > 20.0) string1.noteOn(chord[5], velocity);
delay(finger_delay);
if (chord[4] > 20.0) string2.noteOn(chord[4], velocity);
delay(finger_delay);
if (chord[3] > 20.0) string3.noteOn(chord[3], velocity);
delay(finger_delay);
if (chord[2] > 20.0) string4.noteOn(chord[2], velocity);
delay(finger_delay);
if (chord[1] > 20.0) string5.noteOn(chord[1], velocity);
delay(finger_delay);
if (chord[0] > 20.0) string6.noteOn(chord[0], velocity);
delay(finger_delay);
}
chords.h
Code:
#define NOTE_E2 82.41
#define NOTE_F2 87.31
#define NOTE_Fs2 92.50
#define NOTE_G2 98.00
#define NOTE_Gs2 103.82
#define NOTE_A2 110.00
#define NOTE_As2 116.54
#define NOTE_B2 123.47
#define NOTE_C3 130.81
#define NOTE_Cs3 138.59
#define NOTE_D3 146.83
#define NOTE_Ds3 155.56
#define NOTE_E3 164.81
#define NOTE_F3 174.61
#define NOTE_Fs3 185.00
#define NOTE_G3 196.00
#define NOTE_Gs3 207.65
#define NOTE_A3 220.00
#define NOTE_As3 233.08
#define NOTE_B3 246.94
#define NOTE_C4 261.63
#define NOTE_Cs4 277.18
#define NOTE_D4 293.66
#define NOTE_Ds4 311.13
#define NOTE_E4 329.63
#define NOTE_F4 349.23
#define NOTE_Fs4 369.99
#define NOTE_G4 392.00
#define NOTE_Gs4 415.30
#define NOTE_A4 440.00
#define NOTE_As4 466.16
#define NOTE_B4 493.88
// The equation for note to frequency is:
// float freq = 440.0f * exp2f((float)(note - 69) * 0.0833333f);
// according to http://www.guitar-chords.org.uk/
// and http://www.8notes.com/guitar_chord_chart/c.asp
//
// open = NOTE_E2 NOTE_A2 NOTE_D3 NOTE_G3 NOTE_B3 NOTE_E4
const float Cmajor[6] = { 0, NOTE_C3, NOTE_E3, NOTE_G3, NOTE_C4, NOTE_E4}; // C - E - G
const float Dmajor[6] = { 0, 0, NOTE_D3, NOTE_A3, NOTE_D4, NOTE_Fs4}; // D - F# - A
const float Emajor[6] = {NOTE_E2, NOTE_B2, NOTE_E3, NOTE_Gs3,NOTE_B3, NOTE_E4}; // E - G# - B
const float Fmajor[6] = { 0, NOTE_A2, NOTE_F3, NOTE_A3, NOTE_C4, NOTE_F4}; // F - A - C
const float Gmajor[6] = {NOTE_G2, NOTE_B2, NOTE_D3, NOTE_G3, NOTE_B3, NOTE_E4}; // G - B - D
const float Amajor[6] = { 0, NOTE_A2, NOTE_E3, NOTE_A3, NOTE_Cs4,NOTE_E4}; // A - C# - E
const float Bmajor[6] = { 0, NOTE_B2, NOTE_Fs3,NOTE_B3, NOTE_Ds4,NOTE_Fs4}; // B - D# - F#
const float Cminor[6] = { 0, NOTE_C3, NOTE_G3, NOTE_C4, NOTE_Ds4,NOTE_G4}; // C - D# - G
const float Dminor[6] = { 0, 0, NOTE_D3, NOTE_A3, NOTE_D4, NOTE_F4}; // D - F - A
const float Eminor[6] = {NOTE_E2, NOTE_B2, NOTE_E3, NOTE_G3, NOTE_B3, NOTE_E4}; // E - G - B
const float Fminor[6] = {NOTE_F2, NOTE_C3, NOTE_F3, NOTE_Gs3,NOTE_C4, NOTE_F4}; // F - G# - C
const float Gminor[6] = {NOTE_G2, NOTE_D3, NOTE_G3, NOTE_As3,NOTE_D3, NOTE_G4}; // G - A# - D
const float Aminor[6] = { 0, NOTE_A2, NOTE_E3, NOTE_A3, NOTE_C4, NOTE_E4}; // A - C - E
const float Bminor[6] = { 0, NOTE_B2, NOTE_Fs3,NOTE_B3, NOTE_D4, NOTE_Fs4}; // B - D - F#
// E2, F2, F2#, G2, G2#, A2, A2#, B2
// C3, C3#, D3, D3#, E3, F3, F3#, G3, G3#, A3, A3#, B3
// C4, C4#, D4, D4#, E4, F4, F4#, G4, G4#, A4, A4#, B4