Browse Source

Add Synthesis Guitar example

dds
PaulStoffregen 8 years ago
parent
commit
516d871bfe
4 changed files with 174 additions and 3 deletions
  1. +138
    -0
      examples/Synthesis/Guitar/Guitar.ino
  2. +32
    -0
      examples/Synthesis/Guitar/chords.h
  3. +1
    -0
      keywords.txt
  4. +3
    -3
      synth_karplusstrong.h

+ 138
- 0
examples/Synthesis/Guitar/Guitar.ino View File

@@ -0,0 +1,138 @@
#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);
}

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);
}




+ 32
- 0
examples/Synthesis/Guitar/chords.h View File

@@ -0,0 +1,32 @@

#define NOTE_E2 82.41
#define NOTE_F2 87.31
#define NOTE_G2 98.00
#define NOTE_A2 110.0
#define NOTE_B2 123.5
#define NOTE_C3 130.8
#define NOTE_D3 146.8
#define NOTE_E3 164.8
#define NOTE_F3 174.6
#define NOTE_G3 196.0
#define NOTE_A3 220.0
#define NOTE_B3 246.9
#define NOTE_C4 261.6
#define NOTE_D4 293.7
#define NOTE_E4 329.6
#define NOTE_F4 349.2
#define NOTE_G4 392.0
#define NOTE_A4 440.0
#define NOTE_B4 493.9

// according to http://www.guitar-chords.org.uk/
// 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 Gmajor[6] = {NOTE_G2, NOTE_B2, NOTE_D3, NOTE_G3, NOTE_B3, NOTE_E4}; // G - B - D
const float Aminor[6] = { 0, NOTE_A2, NOTE_E3, NOTE_A3, NOTE_C4, NOTE_E4}; // A - C - E
const float Eminor[6] = {NOTE_E2, NOTE_B2, NOTE_E3, NOTE_G3, NOTE_B3, NOTE_E4}; // E - G - B

// 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


+ 1
- 0
keywords.txt View File

@@ -52,6 +52,7 @@ AudioSynthWaveformSineModulated KEYWORD2
AudioSynthWaveformDc KEYWORD2
AudioSynthNoiseWhite KEYWORD2
AudioSynthNoisePink KEYWORD2
AudioSynthKarplusStrong KEYWORD2
isPlaying KEYWORD2
positionMillis KEYWORD2
lengthMillis KEYWORD2

+ 3
- 3
synth_karplusstrong.h View File

@@ -45,7 +45,7 @@ public:
}
magnitude = velocity * 65535.0f;
int len = (AUDIO_SAMPLE_RATE_EXACT / frequency) + 0.5f;
if (len > 400) len = 400;
if (len > 536) len = 536;
bufferLen = len;
bufferIndex = 0;
state = 1;
@@ -55,12 +55,12 @@ public:
}
virtual void update(void);
private:
uint8_t state; // 0=steady output, 1=transitioning
uint8_t state; // 0=steady output, 1=begin on next update, 2=playing
uint16_t bufferLen;
uint16_t bufferIndex;
int32_t magnitude; // current output
static uint32_t seed; // must start at 1
int16_t buffer[400];
int16_t buffer[536]; // TODO: dynamically use audio memory blocks
};

#endif

Loading…
Cancel
Save