Massive noise

sorin_jay

Member
Okay, so I've been trying to figure out this noise issue for several months. I'm taking audio in through the line in port, doing some audio processing, going from the built in line out to an amplifier board, then to two speakers. The teensy and audio shield are on a 4 layer pcb I made with ground and power planes, with a lot of capacitors on power (buttons, screen, voltage regulator, potentiometers also on pcb).

After a lot of testing, I'm fairly certain that the issue is with the audio shield and not anything else. Specifically, I think it has to do with the funky grounding. On the audio shield, there is a note saying "Don't connect Vground and Ground". However, Vgnd and Gnd are automatically connected -- the top left pin (gnd) and the line in/out gnds(vgnd) beep on the multimeter. Just to test, I removed the pin connecting the audioshield to the teensy on the top left ground, while making sure that the teensy was still connected to ground, but this made the noise issue a bit worse.
I've gone through 4 teensy 4.1/rev D audio shield, and only just now noticed that the Vgnd is shorted to board gnd simply through regularly soldiering. All of the boards had the short, I promise I have neat soldering. After I removed the pin connecting the audio shield gnd to board gnd in the top left, I got large noise on the portable speaker without any amplifying board.

When my circuit is connected to a small portable speaker, the audio is great. When the circuit is connected to the amplifier and those speakers (bigger), there is massive noise. Even without audio coming in, there is noise. Connecting the amplifier board ground and the teensy ground has no effect.

When playing audio through a prerecorded wav file, the audio is clear on the portable speaker and still has noise on the amp+speakers. When I touch my finger to the line in pins, the noise worsens.

I've wrapped the circuit in aluminum foil to see if it was picking up rf. No change in the noise. The code is not the source of error, as it happens whenever the circuit has power for any sketch passing through audio.

The questions are:
1) Should the Line in/Line out(Vgnd) be connected to the board's ground?
2) While there is no issue in the amp or the circuit on their own, together they are weird. However, connecting their grounds made no change. What else should I do to join them?
2) What are other things you would try to get rid of the noise issue?

This is a google album with photos of my pcb

https://photos.google.com/share/AF1...?key=V3JzY01OQWF1V0dodzBHT2V6RzBjSlFLZGhra21B
(I'll add a video of noise and different tests tomorrow)

This is the main code that I'm using, but again it happens with all code, even using Mr. Stoffregen's simple recorder sketch to playback sound from sd card.

Code:
/*

look at button pins for the layout, it's just an array of 8 buttons and 4 potentiometers.
  - You'll have to change the potentiometer max and min values in the map() functions for your own setup.

What code does:
if playing is active, buttons edit which effects are active
if editing is active, the last toggeled effect is the one who'se parameters are being effected
if live-edit-playing, the changes are sent out immediatly, 
  - fun to do with freeverb quickly up and down for roomsize.
  - also good for testing effects.
  
Todo: Add implimentation for wack frequency harmonizer, under name "read frequency" is called every time. Otherwise, just use most recent.
buttons that toggle delay, freeverb, chorus, bitCrusheron, flange, and harmonize to on/off
  -harmonize has two modes, main harmonize editing and instrument editing
    -main 
      -edits how often the instrument repeats/is triggered, except waveform which is constant
      -has the number of semitones above that are being played
    -instrument
      -has effects for each instrument: drums,strings,waveform

button that toggles between playing or editing mode, double tap does live-edit-playing



Todo: Add implimentation for wack frequency harmonizer, under name "read frequency" is called every time. Otherwise, just use most recent.
using pure data
4 vsliders, ctlout 100 101 102 and 103. These are potentiometers
button that toggles delay on or off,
button that toggles freeverb on or off, 
button that toggles chorus on and off, 
button that toggles bitcrusher on and off, 
button that toggles flange on and off, 
button that toggles harmonize on and off,
  -harmonize has two modes, main harmonize editing and instrument editing
    -main 
      -edits how often the instrument repeats/is triggered, except waveform which is constant
      -has the number of semitones above that are being played
    -instrument
      -has effects for each instrument: drums,strings,waveform

button that toggles between playing or editing mode 

button tonesweep,for testing effect sounds, is ctlout 110

ssd1306 display connected on i2c



if playing is active, the two buttons edit which effect is active
if editing is active, the last toggeled effect is the one who'se parameters are being effected
*/

//audio
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

//screen
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//timers
#include <elapsedMillis.h>

// GUItool: begin automatically generated code
AudioSynthSimpleDrum     harmonizeDrum;          //xy=111.0000114440918,436.20000648498535
AudioSynthWaveform       harmonizeWaveform;      //xy=112.00000762939453,401.1999816894531
AudioSynthKarplusStrong  harmonizeString;        //xy=119.00000381469727,470.20000743865967
AudioSynthSimpleDrum     padDrum1;          //xy=159.00000381469727,534.0000076293945
AudioInputI2S            i2s1;           //xy=214,317.20001220703125
AudioMixer4              harmonizeMixer;         //xy=309.99999237060547,386.2000045776367
AudioMixer4              padMixer;         //xy=312.99999237060547,465.200008392334
AudioMixer4              inputMixer;     //xy=333,317.1999931335449
AudioAnalyzeNoteFrequency notefreq1;      //xy=509,291.20001220703125
AudioMixer4              fullMixer;         //xy=511.7999954223633,373.0000057220459
AudioEffectChorus        chorus1;        //xy=635,502.20001220703125
AudioEffectBitcrusher    bitcrusher1;    //xy=638,450.20001220703125
AudioEffectFreeverb      freeverb1;      //xy=639,550.2000122070312
AudioEffectFlange        flange1;        //xy=641.9999961853027,375.20000553131104
AudioEffectDelay         delay1;         //xy=646,637.2000122070312
AudioMixer4              finalMixer;     //xy=789,610.2000122070312
AudioAmplifier           amp1;           //xy=911,605.2000122070312
AudioOutputI2S           i2s2;           //xy=1037,606.2000122070312
AudioConnection          patchCord1(harmonizeDrum, 0, harmonizeMixer, 2);
AudioConnection          patchCord2(harmonizeWaveform, 0, harmonizeMixer, 1);
AudioConnection          patchCord3(harmonizeString, 0, harmonizeMixer, 3);
AudioConnection          patchCord4(padDrum1, 0, padMixer, 0);
AudioConnection          patchCord5(i2s1, 0, inputMixer, 0);
AudioConnection          patchCord6(i2s1, 1, inputMixer, 1);
AudioConnection          patchCord7(harmonizeMixer, 0, fullMixer, 1);
AudioConnection          patchCord8(padMixer, 0, fullMixer, 2);
AudioConnection          patchCord9(inputMixer, notefreq1);
AudioConnection          patchCord10(inputMixer, 0, fullMixer, 0);
AudioConnection          patchCord11(fullMixer, flange1);
AudioConnection          patchCord12(chorus1, freeverb1);
AudioConnection          patchCord13(bitcrusher1, chorus1);
AudioConnection          patchCord14(freeverb1, delay1);
AudioConnection          patchCord15(flange1, bitcrusher1);
AudioConnection          patchCord16(delay1, 0, finalMixer, 0);
AudioConnection          patchCord17(delay1, 1, finalMixer, 1);
AudioConnection          patchCord18(delay1, 2, finalMixer, 2);
AudioConnection          patchCord19(delay1, 3, finalMixer, 3);
AudioConnection          patchCord20(finalMixer, amp1);
AudioConnection          patchCord21(amp1, 0, i2s2, 0);
AudioConnection          patchCord22(amp1, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=373,592.2000122070312
// GUItool: end automatically generated code


#define SCREENADDRESS 0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

//light stuff:
const int delayOnLightPin = 0;//TODO: assign actual pin numbers
const int freeverbOnLightPin = 1;
const int bitCrusherOnLightPin = 2;
const int chorusOnLightPin = 3;
const int flangeOnLightPin = 4;
const int harmonizeOnLightPin = 5;

//button stuff

const int harmonizeButtonPin = 25;
const int padPin = 26;//TODO: only for breadboard, eventually use midi keyboard
const int chorusButtonPin = 27;
const int flangeButtonPin = 28;
const int freeverbButtonPin = 29;
const int bitCrusherButtonPin = 30;
const int editPlayStatePin = 31;
const int delayButtonPin = 32;

bool delayHitHigh = true;
bool freeverbHitHigh = true;
bool chorusHitHigh = true;
bool bitCrusherHitHigh = true;
bool flangeHitHigh = true;
bool editPlayStateHitHigh = true;
bool harmonizeHitHigh = true;
bool padHitHigh = true;

int buttonReadVal;

//potentiometer stuff
const int pot1Pin = 39;
const int pot2Pin = 41;
const int pot3Pin = 40;
const int pot4Pin = 38;

double pot1;
double pot2;
double pot3;
double pot4;

//audio stuff
enum last_effect_selected {delayEffect,freeverbEffect,chorusEffect,bitCrusherEffect,flangeEffect,harmonizeEffect};
last_effect_selected lastEffectSelected;

bool freeverbOn = false;
bool delayOn = false;
bool chorusOn = false;
bool bitCrusherOn = false;
bool flangeOn = false;
bool toneSweepOn = false;
bool harmonizeOn = false;

bool playing = true;
bool liveEditingPlaying = false;
int playingButtonDoubleTapTimer = 500;//if mode button hit twice in 40 millis, switch to live editing and playing


bool updateFreeverbDisplay = true;//if you need to update screen, this is true. Otherwise, it is false. This way, screen is not being sent messages a lot.
bool updateDelayDisplay = true;
bool updateChorusDisplay = true;
bool updateBitCrusherDisplay = true;
bool updateFlangeDisplay = true;
bool updateHarmonizeDisplay = true;

double delayCh0 = 50;//200
double delayCh1= 80;//400
double delayCh2= 110;//600
double delayCh3= 0;

double roomSize = .4;//.3
double damping = .8;//.8

double bitSampleRate =  2800;//2800;// 44100 passthrough, full sample rate
double crushBits = 2;//3;//16 passthrough, no bits compressed

short chorusBuffer[16*AUDIO_BLOCK_SAMPLES];
int chorusNumVoices = 3;//3;//1 means solo origional, each additional is another voice

int maxFlangeHertz = 5;//5;//completely arbitrary, just didn't want to have a big scale when thousands of decimals make decent changes.
int flangeLength = 2;//2;//flangelength is used to control every other variable at once in an interesting way
short flangeBuffer[AUDIO_BLOCK_SAMPLES * 4];
int flangeOffset = AUDIO_BLOCK_SAMPLES;
int flangeDepth = AUDIO_BLOCK_SAMPLES/2;
double flangeDelayRate = 3;//3;

int harmonizeCurrentFrequency = 440;//frequency analyzed from fft
int readFrequency;//if using normal, don't use wack. Wack samples a ton and has everything, harmonize current is just the most recent reading.
int editingInstrument = 0;//0 means editing these three effects:

enum harmonize_type{waveform,drum,string};// waveform, 1 drum, 2 string
harmonize_type harmonizeType;

double harmonizeNumSemiTones = 7;//will be integers, but for use in the pow() function it has to be x.0
int harmonizeActivatePeriod = 500;//how often should the drum or string plucked notes repeat.

//editing instrument means editing these effects for whatever harmonize type

//drums
int harmonizeDrumFrequency = 440;
int harmonizeDrumLength = 500;
float harmonizeDrumSecondMix = .5;
float harmonizeDrumPitchMod = .5;

int padDrum1Frequency = 55;
int padDrum1Length = 60;
float padDrum1SecondMix = .5;
float padDrum1DrumPitchMod = .5;

double stringFrequency;
float stringVelocity; 

int waveformFrequency; 
enum waveform_type {sine,sawtooth,bl_sawtooth,rv_sawtooth,bl_rv_sawtooth,square,bl_square,triangle,var_triangle,arbitrary,pulse,bl_pulse,sampleHold};
waveform_type waveformType;

int waveformList[13] = {
  WAVEFORM_SINE,
  WAVEFORM_SAWTOOTH,
  WAVEFORM_BANDLIMIT_SAWTOOTH,
  WAVEFORM_SAWTOOTH_REVERSE,
  WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE,
  WAVEFORM_SQUARE,
  WAVEFORM_BANDLIMIT_SQUARE,
  WAVEFORM_TRIANGLE,
  WAVEFORM_TRIANGLE_VARIABLE,
  WAVEFORM_ARBITRARY,
  WAVEFORM_PULSE,
  WAVEFORM_BANDLIMIT_PULSE,
  WAVEFORM_SAMPLE_HOLD,
};

double volume = 0.3; 

elapsedMillis liveEditdoubleTapTimer = 0;
elapsedMillis potsTimer = 0;
elapsedMillis lastButtonSampleTimer;//checking buttons every 50 millis
elapsedMillis harmonizePlayTimer = 0;//checking time compared to harmonize note activation
elapsedMillis printMemUsageTimer = 0;//printing memory max usage

void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  
  display.begin(SSD1306_SWITCHCAPVCC, SCREENADDRESS);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("ssd1306 failed"));
    for(;;);
  }
  
  display.setCursor(22, 0);
  display.clearDisplay();
  display.display();
  display.setCursor(26, 0);
  display.print(". ");
  display.display();
  delay(200);
  display.setCursor(30, 0);
  display.print(". ");
  display.display();
  delay(200);
  display.setCursor(34, 0);
  display.print(". ");
  display.display();
  display.clearDisplay();
  //buttons
    pinMode(delayButtonPin,INPUT);
    pinMode(freeverbButtonPin,INPUT);
    pinMode(bitCrusherButtonPin,INPUT);
    pinMode(chorusButtonPin,INPUT);
    pinMode(flangeButtonPin,INPUT);
    pinMode(harmonizeButtonPin, INPUT);
    pinMode(editPlayStatePin,INPUT);
    pinMode(padPin,INPUT);

    digitalWrite(delayButtonPin, HIGH);//writing high, will check if hit low to see when pressed
    digitalWrite(freeverbButtonPin, HIGH);
    digitalWrite(bitCrusherButtonPin, HIGH);
    digitalWrite(chorusButtonPin, HIGH);
    digitalWrite(flangeButtonPin, HIGH);
    digitalWrite(harmonizeButtonPin, HIGH);
    digitalWrite(editPlayStatePin, HIGH);
    digitalWrite(padPin, HIGH);

  //lights
    pinMode(delayOnLightPin,OUTPUT);
    pinMode(freeverbOnLightPin,OUTPUT);
    pinMode(bitCrusherOnLightPin,OUTPUT);
    pinMode(chorusOnLightPin,OUTPUT);
    pinMode(flangeOnLightPin,OUTPUT);
    pinMode(harmonizeOnLightPin,OUTPUT);
  

  AudioMemory(1000);
  sgtl5000_1.enable();
  sgtl5000_1.volume(1.0);
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
  sgtl5000_1.autoVolumeControl(1,3,0,-18,6,8);

  inputMixer.gain(0,1.0);
  inputMixer.gain(1,1.0);

  harmonizeWaveform.begin(1,440,WAVEFORM_SAWTOOTH);

  harmonizeDrum.frequency(harmonizeDrumFrequency);
  harmonizeDrum.length(harmonizeDrumLength);
  harmonizeDrum.secondMix(harmonizeDrumSecondMix);
  harmonizeDrum.pitchMod(harmonizeDrumPitchMod);
  //string is defined when it is called
  
  padDrum1.frequency(padDrum1Frequency);
  padDrum1.length(padDrum1Length);
  padDrum1.secondMix(padDrum1SecondMix);
  padDrum1.pitchMod(padDrum1DrumPitchMod);

  harmonizeMixer.gain(0,1.0);//empty now, used as linein in previous versions.
  harmonizeMixer.gain(1,1.0);//waveform
  harmonizeMixer.gain(2,1.0);//drum
  harmonizeMixer.gain(3,1.0);//string
  
  padMixer.gain(0,1.0);
  padMixer.gain(1,1.0);
  padMixer.gain(2,1.0);
  padMixer.gain(3,1.0);

  fullMixer.gain(0,1.0);
  fullMixer.gain(1,1.0);
  fullMixer.gain(2,1.0);
  fullMixer.gain(3,1.0);

  flange1.begin(flangeBuffer,flangeLength*AUDIO_BLOCK_SAMPLES,flangeOffset,flangeDepth,flangeDelayRate);

  bitcrusher1.bits(crushBits);
  bitcrusher1.sampleRate(bitSampleRate);  

  chorus1.begin(chorusBuffer,16*AUDIO_BLOCK_SAMPLES,chorusNumVoices);

  freeverb1.roomsize(roomSize);
  freeverb1.damping(damping);

  delay1.delay(0,delayCh0);
  delay1.delay(1,delayCh1);
  delay1.delay(2,delayCh2);
  delay1.delay(3,delayCh3);

  finalMixer.gain(0,1.0);
  finalMixer.gain(1,1.0);
  finalMixer.gain(2,1.0);
  finalMixer.gain(3,1.0);

  amp1.gain(volume);

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(22, 0);
  display.print("Audio working!");
  display.display();
  delay(200);

  notefreq1.begin(.5);//.5 is the level of certanty of a frequency required to register it.
  freeverbOn = false;
  delayOn = false;
  chorusOn = false;
  bitCrusherOn = false;
  flangeOn = false;
  toneSweepOn = false;
  harmonizeOn = false;
}

void loop() {
  //main code:
    //triggerToneSweep();
  checkButtons();
  if(liveEditingPlaying == true){
    liveEditPlay();
  }
  else{
    if(playing == true){
      sendOutEffectParams();
      }
    else{
      updateEffectParams();
    }
  }
  updateDisplays();
  /*  
  if(printMemUsageTimer>=5000){
    Serial.println("============================================");
    Serial.println(AudioMemoryUsageMax());
    printMemUsageTimer = 0;
  }*/
  while(notefreq1.available()){    
    readFrequency = notefreq1.read();
  }
}

//TODO: get all light pins, then write this function in loop

void liveEditPlay(){ 
  updateEffectParams();
  sendOutEffectParams();
  Serial.println("LiveEditPlayCall");
}

void writeStatusLights(){
  if(delayOn){
   digitalWrite(delayOnLightPin,HIGH);
  }else{
    digitalWrite(delayOnLightPin,LOW);
  }
  if(freeverbOn){
    digitalWrite(freeverbOnLightPin,HIGH);
  }else{
    digitalWrite(freeverbOnLightPin,LOW);
  }
  if(chorusOn){
    digitalWrite(chorusOnLightPin,HIGH);
  }else{
    digitalWrite(chorusOnLightPin,LOW);
  }
  if(bitCrusherOn){
    digitalWrite(bitCrusherOnLightPin,HIGH);
  }else{
    digitalWrite(bitCrusherOnLightPin,LOW);
  }
  if(flangeOn){
    digitalWrite(bitCrusherOnLightPin,HIGH);
  }else{
    digitalWrite(flangeOnLightPin,LOW);
  } 
  if(harmonizeOn){
    digitalWrite(harmonizeOnLightPin,HIGH);
  }else{
    digitalWrite(harmonizeOnLightPin,LOW);
  } 
}
void triggerToneSweep(){
  Serial.println("tonesweep start: ");
  Serial.println("========Tonesweep=======");
  for(int freq = 200; freq <= 500; freq+=5){
    harmonizeWaveform.frequency(freq);
    delay(10);
  }
  for(int freq = 500; freq >= 200; freq-=5){
    harmonizeWaveform.frequency(freq);
    delay(10);
  }
  Serial.println("tonesweep end");
}

void updateDisplays(){
  switch(lastEffectSelected){
    case delayEffect:
      displayDelay();
      break;
    case freeverbEffect:
      displayFreeverb();
      break;
    case chorusEffect:
      displayChorus(); 
      break;
    case bitCrusherEffect:
      displayBitCrusher();
      break;
    case flangeEffect:
      displayFlange();
      break;
    case harmonizeEffect:
      displayHarmonize();
      break;
  }
}

void displayStatus(){
  if(liveEditingPlaying == true){
    display.setCursor(10,50);
    display.print("M: EP");
  }else{
    if(playing){
      display.setCursor(10, 50);
      display.print("M: P");
    }
    else{
      display.setCursor(10, 50);
      display.print("M: E");
    }
  }
}

void displayEffectOn(){
  display.setCursor(100,50);
  display.print("On");
}
void displayEffectOff(){
  display.setCursor(100,50);
  display.print("Off");
}
void displayDelay(){
  if(updateDelayDisplay == true){
    display.clearDisplay();
    display.setCursor(0,0);
    display.println("Delay: ");
    display.print("d1: "); display.println(delayCh0); 
    display.print("d2: "); display.println(delayCh1);
    display.print("d3: "); display.println(delayCh2); 
    display.print("d4: "); display.println(delayCh3);
    displayStatus();
    if(delayOn){displayEffectOn();}
    else{displayEffectOff();}
    display.display();
    updateDelayDisplay = false;
  }
}
void displayFreeverb(){ 
  if(updateFreeverbDisplay == true){   
    display.clearDisplay();
    display.setCursor(0,0);
    display.println("Freeverb: ");
    display.print("rS: "); display.println(roomSize);
    display.print("dp: "); display.println(damping);  
    displayStatus();
    if(freeverbOn){displayEffectOn();}
      else{displayEffectOff();}
    display.display();
    updateFreeverbDisplay = false;
  }
}
void displayChorus(){
  if(updateChorusDisplay == true){
    display.clearDisplay();
    display.setCursor(0,0);
    display.println("chorus: ");
    display.print("nV: "); display.println(chorusNumVoices);
    displayStatus();
    if(chorusOn){displayEffectOn();}
      else{displayEffectOff();}
    display.display();
    updateChorusDisplay = false;
  }
}
void displayBitCrusher(){
  if(updateBitCrusherDisplay == true){
    display.clearDisplay();
    display.setCursor(0,0);
    display.println("bitCrusher: ");
    display.print("cB: "); display.println(crushBits);
    display.print("sR: "); display.println(bitSampleRate);
    displayStatus();
    if(bitCrusherOn){displayEffectOn();}
      else{displayEffectOff();}
    display.display();
    updateBitCrusherDisplay = false;
  }
}
void displayFlange(){
  if(updateFlangeDisplay == true){
    display.clearDisplay();
    display.setCursor(0,0);
    display.println("flange: ");
    display.print("fL: "); display.println(flangeLength);
    display.print("fO: "); display.println(flangeOffset);
    display.print("fD: "); display.println(flangeDepth); 
    display.print("dR: "); display.println(flangeDelayRate);
    displayStatus();
    if(flangeOn){displayEffectOn();}
    else{displayEffectOff();}
    display.display();
    updateFlangeDisplay = false;
  }
}
void displayHarmonize(){ 
  if(updateHarmonizeDisplay == true){ 
    display.clearDisplay();
    display.setCursor(0,0);
    display.print("Harmonize: ");
   
    if(editingInstrument == 0){//editing overall harmonize  
      display.println("OS");//overall select
      display.print("type: ");
      switch(harmonizeType){
        case waveform:
          display.println("waveform");
          break;
        case drum:
          display.println("drums");
          break;
        case string:
          display.println("strings");
      }
      display.print("nSt: "); display.println(harmonizeNumSemiTones);
      display.print("per: "); display.println(harmonizeActivatePeriod);
      display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
      display.print("hfreq: "); 
      switch(harmonizeType){
        case waveform:
          display.println(waveformFrequency);
          break;
        case drum:
          display.println(harmonizeDrumFrequency);
          break;
        case string:
          display.println(stringFrequency);
      }//harmonize frequency
    }else if(editingInstrument == 1){
      display.print("IS: ");//instrument select
      switch(harmonizeType){
        case waveform:
          display.println(" Wave");
          display.println("v type v");   
          switch(waveformType){
            case sine:
              display.println("SINE");
              break;
            case sawtooth:
              display.println("SAWTOOTH");
              break;
            case bl_sawtooth:
              display.println("BL_SAWTOOTH");
              break;
            case rv_sawtooth:
              display.println("SAWTOOTH_RV");
              break;
            case bl_rv_sawtooth:
              display.println("BL_SAWTOOTH_RV");
              break;
            case square:
              display.println("SQUARE");
              break;
            case bl_square:
              display.println("BL_SQUARE");
              break;
            case triangle:
              display.println("TRIANGLE");
              break;
            case var_triangle:
              display.println("TRIANGLE_VARIABLE");
              break;
            case arbitrary:
              display.println("ARBITRARY");
              break;
            case pulse:
              display.println("PULSE");
              break;
            case bl_pulse:
              display.println("BL_PULSE");
              break;
            case sampleHold:
              display.println("SAMPLEHOLD");
              break;
            }
            display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
            display.print("hfreq: "); display.println(waveformFrequency);//harmonize frequency
          break;
        case drum:
          display.println("Drum");
          display.print("Len: "); display.println(harmonizeDrumLength);
          display.print("SecMx: "); display.println(harmonizeDrumSecondMix);
          display.print("PitMod: "); display.println(harmonizeDrumPitchMod);
          display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
          display.print("hfreq: "); display.println(harmonizeDrumFrequency);//harmonize frequency
          break;
        case string:
          display.println("String");
          display.print("Vel: "); display.println(stringVelocity);
          display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
          display.print("hfreq: "); display.println(stringFrequency);//harmonize frequency
          break;
      }    
    }
    displayStatus();
    if(harmonizeOn){displayEffectOn();}
    else{displayEffectOff();}
    display.display();
    updateHarmonizeDisplay = false;
  }
}
void sendOutEffectParams(){
  // v done in buttons
  Serial.println("sendOutEffectParamsCall");
  updateFreeverbDisplay = true;
  updateDelayDisplay = true;
  updateChorusDisplay = true;
  updateBitCrusherDisplay = true;
  updateFlangeDisplay = true;
  updateHarmonizeDisplay = true;
  if(freeverbOn == true){
    freeverb1.roomsize(roomSize); freeverb1.damping(damping); 
  }
  if(delayOn == true){
    //Serial.println("  outputting delay");
    delay1.delay(0,delayCh0);delay1.delay(1,delayCh1);delay1.delay(2,delayCh2);delay1.delay(3,delayCh3);
  }
  if(chorusOn == true){
    chorus1.voices(chorusNumVoices);
    //Serial.print("    nVoices: ");//Serial.println(chorusNumVoices);
  }
  if(bitCrusherOn == true){
    if(crushBits == 0){crushBits = 1;}
    bitcrusher1.bits(crushBits);
    bitcrusher1.sampleRate(bitSampleRate);     
  }
  if(flangeOn == true){
    flange1.voices(flangeOffset,flangeDepth,flangeDelayRate);
  }
  if(harmonizeOn == true){   
    harmonizeCurrentFrequency = readFrequency; // use readFrequency for wack harmonize effect  
    updateHarmonizeDisplay = true;  

    switch(harmonizeType){
      case waveform://waveform
        harmonizeMixer.gain(1,1.0);
        harmonizeMixer.gain(2,0.0);
        harmonizeMixer.gain(3,0.0);

        waveformFrequency = harmonizeCurrentFrequency * pow(pow(2.0,harmonizeNumSemiTones),1/12.0); 
        harmonizeWaveform.frequency(waveformFrequency);
        harmonizeWaveform.begin(waveformList[waveformType]);//waveformlist is an array of waveforms, type is 0 to 12
        break;
      case drum: // drums
        harmonizeMixer.gain(1,0.0);
        harmonizeMixer.gain(2,1.0);
        harmonizeMixer.gain(3,0.0);
        if(harmonizePlayTimer >= harmonizeActivatePeriod){
          harmonizeDrumFrequency = harmonizeCurrentFrequency * pow(pow(2.0,harmonizeNumSemiTones),1/12.0); 
          harmonizeDrum.frequency(harmonizeDrumFrequency);
          harmonizeDrum.length(harmonizeDrumLength);
          harmonizeDrum.secondMix(harmonizeDrumSecondMix);
          harmonizeDrum.pitchMod(harmonizeDrumPitchMod);
          harmonizeDrum.noteOn();
          harmonizePlayTimer = 0;
          Serial.println("played drums");
        }
        break;
      case string://string
        harmonizeMixer.gain(1,0.0);
        harmonizeMixer.gain(2,0.0);
        harmonizeMixer.gain(3,1.0);
        if(harmonizePlayTimer >= harmonizeActivatePeriod){
          stringFrequency = harmonizeCurrentFrequency * pow(pow(2,harmonizeNumSemiTones),1/12.0);
          harmonizeString.noteOn(stringFrequency, stringVelocity);
          harmonizePlayTimer = 0;
          Serial.println("played strings");
        }        
        break;
    }
  }
  if(delayOn == false){
    delay1.delay(0,0);delay1.delay(1,0);delay1.delay(2,0);delay1.delay(3,0);
  }
  if(freeverbOn == false){
      freeverb1.roomsize(0); freeverb1.damping(0);
  }
  if(chorusOn == false){
    chorus1.voices(1);
  }
  if(bitCrusherOn == false){
    bitcrusher1.bits(16);
    bitcrusher1.sampleRate(44100);   
  }
  if(flangeOn == false){
    flange1.voices(0,0,0);
  }
  if(harmonizeOn == false){
    harmonizeMixer.gain(1,0.0);
    harmonizeMixer.gain(2,0.0);
    harmonizeMixer.gain(3,0.0);
  }    
}
void readPots(){
  if(potsTimer >= 50){
    pot1 = map(analogRead(pot1Pin),0,1000,0,127);
    pot2 = map(analogRead(pot2Pin),0,1000,0,127);
    pot3 = map(analogRead(pot3Pin),0,1000,0,127);
    pot4 = map(analogRead(pot4Pin),0,1000,0,127);
    potsTimer = 0;    
  }
}

void updateEffectParams(){
  Serial.println("updateEffectParamsCall");
  readPots();
  switch(lastEffectSelected){
    case delayEffect://delay
      updateDelayDisplay = true;
      delayCh0 = floor(map(pot1,0,127,0,2000));//floor(1000 * ((float)pot1/(63.5)));//quarter of 127, that way max is 4000 aka 4 seconds
      delayCh1 = floor(map(pot2,0,127,0,2000));//floor(1000 * ((float)pot2/(63.5)));
      delayCh2 = floor(map(pot3,0,127,0,2000));//floor(1000 * ((float)pot3/(63.5)));
      delayCh3 = floor(map(pot4,0,127,0,2000));// floor(1000 * ((float)pot4/(63.5)));  
      break;
    case freeverbEffect:
      //freeverb
      updateFreeverbDisplay = true;
      roomSize = map(pot1,0,127,0,1);//(float)pot1/127;
      damping = map(pot2,0,127,0,1);//(float)pot2/127;
      break;
    case chorusEffect:
      //chorus
      updateChorusDisplay = true;
      chorusNumVoices = floor(map(pot1,0,127,0.5,10.5));//floor((float)(pot1/25.4)+.9);//5 voices
      break;
    case bitCrusherEffect:
      //bitcrusher
      updateBitCrusherDisplay = true;
      crushBits = floor(map(pot1,127,0,1.5,16.5));
      bitSampleRate = floor(map(pot2,127,0,1.5,44100.5));
      break;
    case flangeEffect:
      //flange
      updateFlangeDisplay = true;
      flangeLength = floor(map(pot1,0,127,0.5,16.5));
      flangeOffset = floor(map(pot2,0,127,0.5,flangeLength+0.5)) * AUDIO_BLOCK_SAMPLES;
      flangeDepth = floor(map(pot3,0,127,0.5,flangeLength+0.5)) * AUDIO_BLOCK_SAMPLES;
      flangeDelayRate = map(pot4,0,127,0,maxFlangeHertz);
      break;
    case harmonizeEffect:
      //harmonize
      updateHarmonizeDisplay = true;
      editingInstrument = floor(map(pot1,0,127,0.5,1.5));//the .5 is so that the sliders are able to get to both reliably, but only between 1 or 2 with floor

      //TODO: rename editingInstrument to harmonizeEditingState
      if(editingInstrument == 0){//editing overall harmonize  
        harmonizeType = int(floor(map(pot2,0,127,0.5,2.5)));
        harmonizeNumSemiTones = floor(map(pot3,0,127,.5,12.9));
        harmonizeActivatePeriod = floor(map(pot4,0,127,0,3000));//TODO: make logerithmic, so that lower values up to 1000 have fine control, then less control for high values up to 3000.
      }
      else if(editingInstrument == 1){
        switch(harmonizeType){
          case waveform://waveform
            harmonizeMixer.gain(1,1.0);
            harmonizeMixer.gain(2,0.0);
            harmonizeMixer.gain(3,0.0);
            waveformType = int(floor(map(pot2,0,127,0.5,12.5)));//each of the waveform types, sine,sawtooth,bandlimitSawtooth,etc.
            break;
          case drum: // drums
            harmonizeMixer.gain(1,0.0);
            harmonizeMixer.gain(2,1.0);
            harmonizeMixer.gain(3,0.0);
            harmonizeDrumLength = map(pot2,0,127,0,800);
            harmonizeDrumSecondMix = map(pot3,0,127,0,1);
            harmonizeDrumPitchMod = map(pot4,0,127,0,1);
            break;
          case string://string
            harmonizeMixer.gain(1,0.0);
            harmonizeMixer.gain(2,0.0);
            harmonizeMixer.gain(3,1.0);
            stringVelocity = map(pot2,0,127,0,1);     
            break;
        }
      }
      break;
  }
}
void checkButtons(){
  if(lastButtonSampleTimer >= 50){
    buttonReadVal = digitalRead(freeverbButtonPin);
    if(freeverbHitHigh == true && buttonReadVal == LOW){
      if(playing == true){
        freeverbOn = !freeverbOn;
      }
      freeverbHitHigh = false;
      lastEffectSelected = (freeverbEffect);//0 means edits will apply to delays, 1 freeverb, 2 chorus, 3 bitcrusher 4 flange, 5 harmonize
      updateFreeverbDisplay = true;
      //Serial.println("freeverbHit");
    }else if(buttonReadVal == HIGH){
      freeverbHitHigh = true;
    }

    buttonReadVal = digitalRead(delayButtonPin);
    if(delayHitHigh == true && buttonReadVal == LOW){
      if(playing){
        delayOn = !delayOn;
      }
      delayHitHigh = false;
      lastEffectSelected = (delayEffect);
      updateDelayDisplay = true;
      //Serial.println("delayHit"); 
      
    }else if(buttonReadVal == HIGH){
      delayHitHigh = true;
    }

    buttonReadVal = digitalRead(chorusButtonPin);
    if(chorusHitHigh == true && buttonReadVal == LOW){
      if(playing){
        chorusOn = !chorusOn;
      }
      chorusHitHigh = false;
      lastEffectSelected = (chorusEffect);
      updateChorusDisplay = true;
      //Serial.println("chorusHit");
    }else if(buttonReadVal == HIGH){
      chorusHitHigh = true;
    }

    buttonReadVal = digitalRead(bitCrusherButtonPin);
    if(bitCrusherHitHigh == true && buttonReadVal == LOW){
      if(playing){
        bitCrusherOn = !bitCrusherOn;
      }
      bitCrusherHitHigh = false;
      updateBitCrusherDisplay = true;
      lastEffectSelected = bitCrusherEffect;
      //Serial.println("bitCrusherHit"); 
    }else if(buttonReadVal == HIGH){
      bitCrusherHitHigh = true;
    }

    buttonReadVal = digitalRead(flangeButtonPin);
    if(flangeHitHigh == true && buttonReadVal == LOW){
      if(playing){
        flangeOn = !flangeOn;
      }
      flangeHitHigh = false;
      lastEffectSelected = (flangeEffect);
      updateFlangeDisplay = true;
      //Serial.println("flangeHit"); 
    }else if(buttonReadVal == HIGH){
      flangeHitHigh = true;
    }

    buttonReadVal = digitalRead(harmonizeButtonPin);
    if(harmonizeHitHigh == true && buttonReadVal == LOW){
      if(playing){
        harmonizeOn = !harmonizeOn;
      }
      harmonizeHitHigh = false;
      updateHarmonizeDisplay = true;
      lastEffectSelected = (harmonizeEffect);
    }else if(buttonReadVal == HIGH){
      harmonizeHitHigh = true;
    }

    buttonReadVal = digitalRead(editPlayStatePin); 
    if(editPlayStateHitHigh == true && buttonReadVal == LOW){
      if(liveEditdoubleTapTimer <= playingButtonDoubleTapTimer){
        liveEditingPlaying = true;
      }
      else{
         playing = !playing;
         liveEditingPlaying = false;
      }

      editPlayStateHitHigh = false;
      
      updateFreeverbDisplay = true;//if you need to update screen, this is true. Otherwise, it is false.
      updateDelayDisplay = true;
      updateChorusDisplay = true;
      updateBitCrusherDisplay = true;
      updateFlangeDisplay = true;
      updateHarmonizeDisplay = true;

      liveEditdoubleTapTimer = 0;

    }else if(buttonReadVal == HIGH){
      editPlayStateHitHigh = true;
    }

    buttonReadVal = digitalRead(padPin);
    if(padHitHigh == true && buttonReadVal == LOW){
      padDrum1.noteOn();
      padHitHigh = false;
    }else if(buttonReadVal == HIGH){
      padHitHigh = true;
    }
    lastButtonSampleTimer = 0;
  }
}
 
Last edited:
Code:
/*

look at button pins for the layout, it's just an array of 8 buttons and 4 potentiometers.
- You'll have to change the potentiometer max and min values in the map() functions for your own setup.

What code does:
if playing is active, buttons edit which effects are active
if editing is active, the last toggeled effect is the one who'se parameters are being effected
if live-edit-playing, the changes are sent out immediatly,
- fun to do with freeverb quickly up and down for roomsize.
- also good for testing effects.

Todo: Add implimentation for wack frequency harmonizer, under name "read frequency" is called every time. Otherwise, just use most recent.
buttons that toggle delay, freeverb, chorus, bitCrusheron, flange, and harmonize to on/off
-harmonize has two modes, main harmonize editing and instrument editing
-main
-edits how often the instrument repeats/is triggered, except waveform which is constant
-has the number of semitones above that are being played
-instrument
-has effects for each instrument: drums,strings,waveform

button that toggles between playing or editing mode, double tap does live-edit-playing



Todo: Add implimentation for wack frequency harmonizer, under name "read frequency" is called every time. Otherwise, just use most recent.
using pure data
4 vsliders, ctlout 100 101 102 and 103. These are potentiometers
button that toggles delay on or off,
button that toggles freeverb on or off,
button that toggles chorus on and off,
button that toggles bitcrusher on and off,
button that toggles flange on and off,
button that toggles harmonize on and off,
-harmonize has two modes, main harmonize editing and instrument editing
-main
-edits how often the instrument repeats/is triggered, except waveform which is constant
-has the number of semitones above that are being played
-instrument
-has effects for each instrument: drums,strings,waveform

button that toggles between playing or editing mode

button tonesweep,for testing effect sounds, is ctlout 110

ssd1306 display connected on i2c



if playing is active, the two buttons edit which effect is active
if editing is active, the last toggeled effect is the one who'se parameters are being effected
*/

//audio
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

//screen
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//timers
#include <elapsedMillis.h>

// GUItool: begin automatically generated code
AudioSynthSimpleDrum harmonizeDrum; //xy=111.0000114440918,436.20000648498535
AudioSynthWaveform harmonizeWaveform; //xy=112.00000762939453,401.1999816894531
AudioSynthKarplusStrong harmonizeString; //xy=119.00000381469727,470.20000743865967
AudioSynthSimpleDrum padDrum1; //xy=159.00000381469727,534.0000076293945
AudioInputI2S i2s1; //xy=214,317.20001220703125
AudioMixer4 harmonizeMixer; //xy=309.99999237060547,386.2000045776367
AudioMixer4 padMixer; //xy=312.99999237060547,465.200008392334
AudioMixer4 inputMixer; //xy=333,317.1999931335449
AudioAnalyzeNoteFrequency notefreq1; //xy=509,291.20001220703125
AudioMixer4 fullMixer; //xy=511.7999954223633,373.0000057220459
AudioEffectChorus chorus1; //xy=635,502.20001220703125
AudioEffectBitcrusher bitcrusher1; //xy=638,450.20001220703125
AudioEffectFreeverb freeverb1; //xy=639,550.2000122070312
AudioEffectFlange flange1; //xy=641.9999961853027,375.20000553131104
AudioEffectDelay delay1; //xy=646,637.2000122070312
AudioMixer4 finalMixer; //xy=789,610.2000122070312
AudioAmplifier amp1; //xy=911,605.2000122070312
AudioOutputI2S i2s2; //xy=1037,606.2000122070312
AudioConnection patchCord1(harmonizeDrum, 0, harmonizeMixer, 2);
AudioConnection patchCord2(harmonizeWaveform, 0, harmonizeMixer, 1);
AudioConnection patchCord3(harmonizeString, 0, harmonizeMixer, 3);
AudioConnection patchCord4(padDrum1, 0, padMixer, 0);
AudioConnection patchCord5(i2s1, 0, inputMixer, 0);
AudioConnection patchCord6(i2s1, 1, inputMixer, 1);
AudioConnection patchCord7(harmonizeMixer, 0, fullMixer, 1);
AudioConnection patchCord8(padMixer, 0, fullMixer, 2);
AudioConnection patchCord9(inputMixer, notefreq1);
AudioConnection patchCord10(inputMixer, 0, fullMixer, 0);
AudioConnection patchCord11(fullMixer, flange1);
AudioConnection patchCord12(chorus1, freeverb1);
AudioConnection patchCord13(bitcrusher1, chorus1);
AudioConnection patchCord14(freeverb1, delay1);
AudioConnection patchCord15(flange1, bitcrusher1);
AudioConnection patchCord16(delay1, 0, finalMixer, 0);
AudioConnection patchCord17(delay1, 1, finalMixer, 1);
AudioConnection patchCord18(delay1, 2, finalMixer, 2);
AudioConnection patchCord19(delay1, 3, finalMixer, 3);
AudioConnection patchCord20(finalMixer, amp1);
AudioConnection patchCord21(amp1, 0, i2s2, 0);
AudioConnection patchCord22(amp1, 0, i2s2, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=373,592.2000122070312
// GUItool: end automatically generated code


#define SCREENADDRESS 0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

//light stuff:
const int delayOnLightPin = 0;//TODO: assign actual pin numbers
const int freeverbOnLightPin = 1;
const int bitCrusherOnLightPin = 2;
const int chorusOnLightPin = 3;
const int flangeOnLightPin = 4;
const int harmonizeOnLightPin = 5;

//button stuff

const int harmonizeButtonPin = 25;
const int padPin = 26;//TODO: only for breadboard, eventually use midi keyboard
const int chorusButtonPin = 27;
const int flangeButtonPin = 28;
const int freeverbButtonPin = 29;
const int bitCrusherButtonPin = 30;
const int editPlayStatePin = 31;
const int delayButtonPin = 32;

bool delayHitHigh = true;
bool freeverbHitHigh = true;
bool chorusHitHigh = true;
bool bitCrusherHitHigh = true;
bool flangeHitHigh = true;
bool editPlayStateHitHigh = true;
bool harmonizeHitHigh = true;
bool padHitHigh = true;

int buttonReadVal;

//potentiometer stuff
const int pot1Pin = 39;
const int pot2Pin = 41;
const int pot3Pin = 40;
const int pot4Pin = 38;

double pot1;
double pot2;
double pot3;
double pot4;

//audio stuff
enum last_effect_selected { delayEffect, freeverbEffect, chorusEffect, bitCrushe rEffect, flangeEffect, harmonizeEffect };
last_effect_selected lastEffectSelected;

bool freeverbOn = false;
bool delayOn = false;
bool chorusOn = false;
bool bitCrusherOn = false;
bool flangeOn = false;
bool toneSweepOn = false;
bool harmonizeOn = false;

bool playing = true;
bool liveEditingPlaying = false;
int playingButtonDoubleTapTimer = 500;//if mode button hit twice in 40 millis, switch to live editing and playing


bool updateFreeverbDisplay = true;//if you need to update screen, this is true. Otherwise, it is false. This way, screen is not being sent messages a lot.
bool updateDelayDisplay = true;
bool updateChorusDisplay = true;
bool updateBitCrusherDisplay = true;
bool updateFlangeDisplay = true;
bool updateHarmonizeDisplay = true;

double delayCh0 = 50;//200
double delayCh1 = 80;//400
double delayCh2 = 110;//600
double delayCh3 = 0;

double roomSize = .4;//.3
double damping = .8;//.8

double bitSampleRate = 2800;//2800;// 44100 passthrough, full sample rate
double crushBits = 2;//3;//16 passthrough, no bits compressed

short chorusBuffer[16 * AUDIO_BLOCK_SAMPLES];
int chorusNumVoices = 3;//3;//1 means solo origional, each additional is another voice

int maxFlangeHertz = 5;//5;//completely arbitrary, just didn't want to have a big scale when thousands of decimals make decent changes.
int flangeLength = 2;//2;//flangelength is used to control every other variable at once in an interesting way
short flangeBuffer[AUDIO_BLOCK_SAMPLES * 4];
int flangeOffset = AUDIO_BLOCK_SAMPLES;
int flangeDepth = AUDIO_BLOCK_SAMPLES / 2;
double flangeDelayRate = 3;//3;

int harmonizeCurrentFrequency = 440;//frequency analyzed from fft
int readFrequency;//if using normal, don't use wack. Wack samples a ton and has everything, harmonize current is just the most recent reading.
int editingInstrument = 0;//0 means editing these three effects:

enum harmonize_type { waveform, drum, string };// waveform, 1 drum, 2 string
harmonize_type harmonizeType;

double harmonizeNumSemiTones = 7;//will be integers, but for use in the pow() function it has to be x.0
int harmonizeActivatePeriod = 500;//how often should the drum or string plucked notes repeat.

//editing instrument means editing these effects for whatever harmonize type

//drums
int harmonizeDrumFrequency = 440;
int harmonizeDrumLength = 500;
float harmonizeDrumSecondMix = .5;
float harmonizeDrumPitchMod = .5;

int padDrum1Frequency = 55;
int padDrum1Length = 60;
float padDrum1SecondMix = .5;
float padDrum1DrumPitchMod = .5;

double stringFrequency;
float stringVelocity;

int waveformFrequency;
enum waveform_type { sine, sawtooth, bl_sawtooth, rv_sawtooth, bl_rv_sawto oth, square, bl_square, triangle, var_triangle, arbitra ry, pulse, bl_pulse, sampleHold };
waveform_type waveformType;

int waveformList[13] = {
WAVEFORM_SINE,
WAVEFORM_SAWTOOTH,
WAVEFORM_BANDLIMIT_SAWTOOTH,
WAVEFORM_SAWTOOTH_REVERSE,
WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE,
WAVEFORM_SQUARE,
WAVEFORM_BANDLIMIT_SQUARE,
WAVEFORM_TRIANGLE,
WAVEFORM_TRIANGLE_VARIABLE,
WAVEFORM_ARBITRARY,
WAVEFORM_PULSE,
WAVEFORM_BANDLIMIT_PULSE,
WAVEFORM_SAMPLE_HOLD,
};

double volume = 0.3;

elapsedMillis liveEditdoubleTapTimer = 0;
elapsedMillis potsTimer = 0;
elapsedMillis lastButtonSampleTimer;//checking buttons every 50 millis
elapsedMillis harmonizePlayTimer = 0;//checking time compared to harmonize note activation
elapsedMillis printMemUsageTimer = 0;//printing memory max usage

void setup() {
	Serial.begin(9600);
	Serial.println("Start");

	display.begin(SSD1306_SWITCHCAPVCC, SCREENADDRESS);
	if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
		Serial.println(F("ssd1306 failed"));
		for (;;
	}

	display.setCursor(22, 0);
		display.clearDisplay();
		display.display();
		display.setCursor(26, 0);
		display.print(". ");
		display.display();
		delay(200);
		display.setCursor(30, 0);
		display.print(". ");
	display.display();
	delay(200);
	display.setCursor(34, 0);
	display.print(". ");
	display.display();
	display.clearDisplay();
	//buttons
	pinMode(delayButtonPin, INPUT);
	pinMode(freeverbButtonPin, INPUT);
	pinMode(bitCrusherButtonPin, INPUT);
	pinMode(chorusButtonPin, INPUT);
	pinMode(flangeButtonPin, INPUT);
	pinMode(harmonizeButtonPin, INPUT);
	pinMode(editPlayStatePin, INPUT);
	pinMode(padPin, INPUT);

	digitalWrite(delayButtonPin, HIGH);//writing high, will check if hit low to see when pressed
	digitalWrite(freeverbButtonPin, HIGH);
	digitalWrite(bitCrusherButtonPin, HIGH);
	digitalWrite(chorusButtonPin, HIGH);
	digitalWrite(flangeButtonPin, HIGH);
	digitalWrite(harmonizeButtonPin, HIGH);
	digitalWrite(editPlayStatePin, HIGH);
	digitalWrite(padPin, HIGH);

	//lights
	pinMode(delayOnLightPin, OUTPUT);
	pinMode(freeverbOnLightPin, OUTPUT);
	pinMode(bitCrusherOnLightPin, OUTPUT);
	pinMode(chorusOnLightPin, OUTPUT);
	pinMode(flangeOnLightPin, OUTPUT);
	pinMode(harmonizeOnLightPin, OUTPUT);


	AudioMemory(1000);
	sgtl5000_1.enable();
	sgtl5000_1.volume(1.0);
	sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
	sgtl5000_1.autoVolumeControl(1, 3, 0, -18, 6, 8);

	inputMixer.gain(0, 1.0);
	inputMixer.gain(1, 1.0);

	harmonizeWaveform.begin(1, 440, WAVEFORM_SAWTOOTH);

	harmonizeDrum.frequency(harmonizeDrumFrequency);
	harmonizeDrum.length(harmonizeDrumLength);
	harmonizeDrum.secondMix(harmonizeDrumSecondMix);
	harmonizeDrum.pitchMod(harmonizeDrumPitchMod);
	//string is defined when it is called

	padDrum1.frequency(padDrum1Frequency);
	padDrum1.length(padDrum1Length);
	padDrum1.secondMix(padDrum1SecondMix);
	padDrum1.pitchMod(padDrum1DrumPitchMod);

	harmonizeMixer.gain(0, 1.0);//empty now, used as linein in previous versions.
	harmonizeMixer.gain(1, 1.0);//waveform
	harmonizeMixer.gain(2, 1.0);//drum
	harmonizeMixer.gain(3, 1.0);//string

	padMixer.gain(0, 1.0);
	padMixer.gain(1, 1.0);
	padMixer.gain(2, 1.0);
	padMixer.gain(3, 1.0);

	fullMixer.gain(0, 1.0);
	fullMixer.gain(1, 1.0);
	fullMixer.gain(2, 1.0);
	fullMixer.gain(3, 1.0);

	flange1.begin(flangeBuffer, flangeLength * AUDIO_BLOC K_SAMPLES, flangeOffset, flangeDepth, flangeDelayRate);

	bitcrusher1.bits(crushBits);
	bitcrusher1.sampleRate(bitSampleRate);

	chorus1.begin(chorusBuffer, 16 * AUDIO_BLOCK_SAMPLES, chorusNumVoices);

	freeverb1.roomsize(roomSize);
	freeverb1.damping(damping);

	delay1.delay(0, delayCh0);
	delay1.delay(1, delayCh1);
	delay1.delay(2, delayCh2);
	delay1.delay(3, delayCh3);

	finalMixer.gain(0, 1.0);
	finalMixer.gain(1, 1.0);
	finalMixer.gain(2, 1.0);
	finalMixer.gain(3, 1.0);

	amp1.gain(volume);

	display.clearDisplay();
	display.setTextSize(1);
	display.setTextColor(SSD1306_WHITE);
	display.setCursor(22, 0);
	display.print("Audio working!");
	display.display();
	delay(200);

	notefreq1.begin(.5);//.5 is the level of certanty of a frequency required to register it.
	freeverbOn = false;
	delayOn = false;
	chorusOn = false;
	bitCrusherOn = false;
	flangeOn = false;
	toneSweepOn = false;
	harmonizeOn = false;
}

void loop() {
	//main code:
	//triggerToneSweep();
	checkButtons();
	if (liveEditingPlaying == true) {
		liveEditPlay();
	}
	else {
		if (playing == true) {
			sendOutEffectParams();
		}
		else {
			updateEffectParams();
		}
	}
	updateDisplays();
	/*
	if(printMemUsageTimer>=5000){
	Serial.println("================================== ==========");
	Serial.println(AudioMemoryUsageMax());
	printMemUsageTimer = 0;
	}*/
	while (notefreq1.available()) {
		readFrequency = notefreq1.read();
	}
}

//TODO: get all light pins, then write this function in loop

void liveEditPlay() {
	updateEffectParams();
	sendOutEffectParams();
	Serial.println("LiveEditPlayCall");
}

void writeStatusLights() {
	if (delayOn) {
		digitalWrite(delayOnLightPin, HIGH);
	}
	else {
		digitalWrite(delayOnLightPin, LOW);
	}
	if (freeverbOn) {
		digitalWrite(freeverbOnLightPin, HIGH);
	}
	else {
		digitalWrite(freeverbOnLightPin, LOW);
	}
	if (chorusOn) {
		digitalWrite(chorusOnLightPin, HIGH);
	}
	else {
		digitalWrite(chorusOnLightPin, LOW);
	}
	if (bitCrusherOn) {
		digitalWrite(bitCrusherOnLightPin, HIGH);
	}
	else {
		digitalWrite(bitCrusherOnLightPin, LOW);
	}
	if (flangeOn) {
		digitalWrite(bitCrusherOnLightPin, HIGH);
	}
	else {
		digitalWrite(flangeOnLightPin, LOW);
	}
	if (harmonizeOn) {
		digitalWrite(harmonizeOnLightPin, HIGH);
	}
	else {
		digitalWrite(harmonizeOnLightPin, LOW);
	}
}
void triggerToneSweep() {
	Serial.println("tonesweep start: ");
	Serial.println("========Tonesweep=======");
	for (int freq = 200; freq <= 500; freq += 5) {
		harmonizeWaveform.frequency(freq);
		delay(10);
	}
	for (int freq = 500; freq >= 200; freq -= 5) {
		harmonizeWaveform.frequency(freq);
		delay(10);
	}
	Serial.println("tonesweep end");
}

void updateDisplays() {
	switch (lastEffectSelected) {
	case delayEffect:
		displayDelay();
		break;
	case freeverbEffect:
		displayFreeverb();
		break;
	case chorusEffect:
		displayChorus();
		break;
	case bitCrusherEffect:
		displayBitCrusher();
		break;
	case flangeEffect:
		displayFlange();
		break;
	case harmonizeEffect:
		displayHarmonize();
		break;
	}
}

void displayStatus() {
	if (liveEditingPlaying == true) {
		display.setCursor(10, 50);
		display.print("M: EP");
	}
	else {
		if (playing) {
			display.setCursor(10, 50);
			display.print("M: P");
		}
		else {
			display.setCursor(10, 50);
			display.print("M: E");
		}
	}
}

void displayEffectOn() {
	display.setCursor(100, 50);
	display.print("On");
}
void displayEffectOff() {
	display.setCursor(100, 50);
	display.print("Off");
}
void displayDelay() {
	if (updateDelayDisplay == true) {
		display.clearDisplay();
		display.setCursor(0, 0);
		display.println("Delay: ");
		display.print("d1: "); display.println(delayCh0);
		display.print("d2: "); display.println(delayCh1);
		display.print("d3: "); display.println(delayCh2);
		display.print("d4: "); display.println(delayCh3);
		displayStatus();
		if (delayOn) { displayEffectOn(); }
		else { displayEffectOff(); }
		display.display();
		updateDelayDisplay = false;
	}
}
void displayFreeverb() {
	if (updateFreeverbDisplay == true) {
		display.clearDisplay();
		display.setCursor(0, 0);
		display.println("Freeverb: ");
		display.print("rS: "); display.println(roomSize);
		display.print("dp: "); display.println(damping);
		displayStatus();
		if (freeverbOn) { displayEffectOn(); }
		else { displayEffectOff(); }
		display.display();
		updateFreeverbDisplay = false;
	}
}
void displayChorus() {
	if (updateChorusDisplay == true) {
		display.clearDisplay();
		display.setCursor(0, 0);
		display.println("chorus: ");
		display.print("nV: "); display.println(chorusNumVoices);
		displayStatus();
		if (chorusOn) { displayEffectOn(); }
		else { displayEffectOff(); }
		display.display();
		updateChorusDisplay = false;
	}
}
void displayBitCrusher() {
	if (updateBitCrusherDisplay == true) {
		display.clearDisplay();
		display.setCursor(0, 0);
		display.println("bitCrusher: ");
		display.print("cB: "); display.println(crushBits);
		display.print("sR: "); display.println(bitSampleRate);
		displayStatus();
		if (bitCrusherOn) { displayEffectOn(); }
		else { displayEffectOff(); }
		display.display();
		updateBitCrusherDisplay = false;
	}
}
void displayFlange() {
	if (updateFlangeDisplay == true) {
		display.clearDisplay();
		display.setCursor(0, 0);
		display.println("flange: ");
		display.print("fL: "); display.println(flangeLength);
		display.print("fO: "); display.println(flangeOffset);
		display.print("fD: "); display.println(flangeDepth);
		display.print("dR: "); display.println(flangeDelayRate);
		displayStatus();
		if (flangeOn) { displayEffectOn(); }
		else { displayEffectOff(); }
		display.display();
		updateFlangeDisplay = false;
	}
}
void displayHarmonize() {
	if (updateHarmonizeDisplay == true) {
		display.clearDisplay();
		display.setCursor(0, 0);
		display.print("Harmonize: ");

		if (editingInstrument == 0) {//editing overall harmonize
			display.println("OS");//overall select
			display.print("type: ");
			switch (harmonizeType) {
			case waveform:
				display.println("waveform");
				break;
			case drum:
				display.println("drums");
				break;
			case string:
				display.println("strings");
			}
			display.print("nSt: "); display.println(harmonizeNumSemiTones);
			display.print("per: "); display.println(harmonizeActivatePeriod);
			display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
			display.print("hfreq: ");
			switch (harmonizeType) {
			case waveform:
				display.println(waveformFrequency);
				break;
			case drum:
				display.println(harmonizeDrumFrequency);
				break;
			case string:
				display.println(stringFrequency);
			}//harmonize frequency
		}
		else if (editingInstrument == 1) {
			display.print("IS: ");//instrument select
			switch (harmonizeType) {
			case waveform:
				display.println(" Wave");
				display.println("v type v");
				switch (waveformType) {
				case sine:
					display.println("SINE");
					break;
				case sawtooth:
					display.println("SAWTOOTH");
					break;
				case bl_sawtooth:
					display.println("BL_SAWTOOTH");
					break;
				case rv_sawtooth:
					display.println("SAWTOOTH_RV");
					break;
				case bl_rv_sawtooth:
					display.println("BL_SAWTOOTH_RV");
					break;
				case square:
					display.println("SQUARE");
					break;
				case bl_square:
					display.println("BL_SQUARE");
					break;
				case triangle:
					display.println("TRIANGLE");
					break;
				case var_triangle:
					display.println("TRIANGLE_VARIABLE");
					break;
				case arbitrary:
					display.println("ARBITRARY");
					break;
				case pulse:
					display.println("PULSE");
					break;
				case bl_pulse:
					display.println("BL_PULSE");
					break;
				case sampleHold:
					display.println("SAMPLEHOLD");
					break;
				}
				display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
				display.print("hfreq: "); display.println(waveformFrequency);//harmonize frequency
				break;
			case drum:
				display.println("Drum");
				display.print("Len: "); display.println(harmonizeDrumLength);
				display.print("SecMx: "); display.println(harmonizeDrumSecondMix);
				display.print("PitMod: "); display.println(harmonizeDrumPitchMod);
				display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
				display.print("hfreq: "); display.println(harmonizeDrumFrequency);//harmonize frequency
				break;
			case string:
				display.println("String");
				display.print("Vel: "); display.println(stringVelocity);
				display.print("rfreq: "); display.println(harmonizeCurrentFrequency);//read frequency
				display.print("hfreq: "); display.println(stringFrequency);//harmonize frequency
				break;
			}
		}
		displayStatus();
		if (harmonizeOn) { displayEffectOn(); }
		else { displayEffectOff(); }
		display.display();
		updateHarmonizeDisplay = false;
	}
}
void sendOutEffectParams() {
	// v done in buttons
	Serial.println("sendOutEffectParamsCall");
	updateFreeverbDisplay = true;
	updateDelayDisplay = true;
	updateChorusDisplay = true;
	updateBitCrusherDisplay = true;
	updateFlangeDisplay = true;
	updateHarmonizeDisplay = true;
	if (freeverbOn == true) {
		freeverb1.roomsize(roomSize); freeverb1.damping(damping);
	}
	if (delayOn == true) {
		//Serial.println(" outputting delay");
		delay1.delay(0, delayCh0); delay1.delay(1, delayCh1); delay1.delay(2, delayCh2); delay1.delay(3, delayCh3);
	}
	if (chorusOn == true) {
		chorus1.voices(chorusNumVoices);
		//Serial.print(" nVoices: ");//Serial.println(chorusNumVoices);
	}
	if (bitCrusherOn == true) {
		if (crushBits == 0) { crushBits = 1; }
		bitcrusher1.bits(crushBits);
		bitcrusher1.sampleRate(bitSampleRate);
	}
	if (flangeOn == true) {
		flange1.voices(flangeOffset, flangeDepth, flangeDela yRate);
	}
	if (harmonizeOn == true) {
		harmonizeCurrentFrequency = readFrequency; // use readFrequency for wack harmonize effect
		updateHarmonizeDisplay = true;

		switch (harmonizeType) {
		case waveform://waveform
			harmonizeMixer.gain(1, 1.0);
			harmonizeMixer.gain(2, 0.0);
			harmonizeMixer.gain(3, 0.0);

			waveformFrequency = harmonizeCurrentFrequency * pow(pow(2.0, harmonizeNumSemiTones), 1 / 12.0);
			harmonizeWaveform.frequency(waveformFrequency);
			harmonizeWaveform.begin(waveformList[waveformType]);//waveformlist is an array of waveforms, type is 0 to 12
			break;
		case drum: // drums
			harmonizeMixer.gain(1, 0.0);
			harmonizeMixer.gain(2, 1.0);
			harmonizeMixer.gain(3, 0.0);
			if (harmonizePlayTimer >= harmonizeActivatePeriod) {
				harmonizeDrumFrequency = harmonizeCurrentFrequency * pow(pow(2.0, harmonizeNumSemiTones), 1 / 12.0);
				harmonizeDrum.frequency(harmonizeDrumFrequency);
				harmonizeDrum.length(harmonizeDrumLength);
				harmonizeDrum.secondMix(harmonizeDrumSecondMix);
				harmonizeDrum.pitchMod(harmonizeDrumPitchMod);
				harmonizeDrum.noteOn();
				harmonizePlayTimer = 0;
				Serial.println("played drums");
			}
			break;
		case string://string
			harmonizeMixer.gain(1, 0.0);
			harmonizeMixer.gain(2, 0.0);
			harmonizeMixer.gain(3, 1.0);
			if (harmonizePlayTimer >= harmonizeActivatePeriod) {
				stringFrequency = harmonizeCurrentFrequency * pow(pow(2, harmonizeNumSemiTones), 1 / 12.0);
				harmonizeString.noteOn(stringFrequency, stringVelocity);
				harmonizePlayTimer = 0;
				Serial.println("played strings");
			}
			break;
		}
	}
	if (delayOn == false) {
		delay1.delay(0, 0); delay1.delay(1, 0); delay1.delay(2, 0); delay1.delay(3, 0);
	}
	if (freeverbOn == false) {
		freeverb1.roomsize(0); freeverb1.damping(0);
	}
	if (chorusOn == false) {
		chorus1.voices(1);
	}
	if (bitCrusherOn == false) {
		bitcrusher1.bits(16);
		bitcrusher1.sampleRate(44100);
	}
	if (flangeOn == false) {
		flange1.voices(0, 0, 0);
	}
	if (harmonizeOn == false) {
		harmonizeMixer.gain(1, 0.0);
		harmonizeMixer.gain(2, 0.0);
		harmonizeMixer.gain(3, 0.0);
	}
}
void readPots() {
	if (potsTimer >= 50) {
		pot1 = map(analogRead(pot1Pin), 0, 1000, 0, 127);
		pot2 = map(analogRead(pot2Pin), 0, 1000, 0, 127);
		pot3 = map(analogRead(pot3Pin), 0, 1000, 0, 127);
		pot4 = map(analogRead(pot4Pin), 0, 1000, 0, 127);
		potsTimer = 0;
	}
}

void updateEffectParams() {
	Serial.println("updateEffectParamsCall");
	readPots();
	switch (lastEffectSelected) {
	case delayEffect://delay
		updateDelayDisplay = true;
		delayCh0 = floor(map(pot1, 0, 127, 0, 2000));//floor(1000 * ((float)pot1/(63.5)));//quarter of 127, that way max is 4000 aka 4 seconds
		delayCh1 = floor(map(pot2, 0, 127, 0, 2000));//floor(1000 * ((float)pot2/(63.5)));
		delayCh2 = floor(map(pot3, 0, 127, 0, 2000));//floor(1000 * ((float)pot3/(63.5)));
		delayCh3 = floor(map(pot4, 0, 127, 0, 2000));// floor(1000 * ((float)pot4/(63.5)));
		break;
	case freeverbEffect:
		//freeverb
		updateFreeverbDisplay = true;
		roomSize = map(pot1, 0, 127, 0, 1);//(float)pot1/127;
		damping = map(pot2, 0, 127, 0, 1);//(float)pot2/127;
		break;
	case chorusEffect:
		//chorus
		updateChorusDisplay = true;
		chorusNumVoices = floor(map(pot1, 0, 127, 0.5, 10.5));//floor((float)(pot1/25.4)+.9);//5 voices
		break;
	case bitCrusherEffect:
		//bitcrusher
		updateBitCrusherDisplay = true;
		crushBits = floor(map(pot1, 127, 0, 1.5, 16.5));
		bitSampleRate = floor(map(pot2, 127, 0, 1.5, 44100.5));
		break;
	case flangeEffect:
		//flange
		updateFlangeDisplay = true;
		flangeLength = floor(map(pot1, 0, 127, 0.5, 16.5));
		flangeOffset = floor(map(pot2, 0, 127, 0.5, flangeLength + 0.5)) * AUDIO_BLOCK_SAMPLES;
		flangeDepth = floor(map(pot3, 0, 127, 0.5, flangeLength + 0.5)) * AUDIO_BLOCK_SAMPLES;
		flangeDelayRate = map(pot4, 0, 127, 0, maxFlangeHertz);
		break;
	case harmonizeEffect:
		//harmonize
		updateHarmonizeDisplay = true;
		editingInstrument = floor(map(pot1, 0, 127, 0.5, 1.5));//the .5 is so that the sliders are able to get to both reliably, but only between 1 or 2 with floor

		//TODO: rename editingInstrument to harmonizeEditingState
		if (editingInstrument == 0) {//editing overall harmonize
			harmonizeType = int(floor(map(pot2, 0, 127, 0.5, 2.5)));
			harmonizeNumSemiTones = floor(map(pot3, 0, 127, .5, 12.9));
			harmonizeActivatePeriod = floor(map(pot4, 0, 127, 0, 3000));//TODO: make logerithmic, so that lower values up to 1000 have fine control, then less control for high values up to 3000.
		}
		else if (editingInstrument == 1) {
			switch (harmonizeType) {
			case waveform://waveform
				harmonizeMixer.gain(1, 1.0);
				harmonizeMixer.gain(2, 0.0);
				harmonizeMixer.gain(3, 0.0);
				waveformType = int(floor(map(pot2, 0, 127, 0.5, 12.5)));//each of the waveform types, sine,sawtooth,bandlimitSawtooth,etc.
				break;
			case drum: // drums
				harmonizeMixer.gain(1, 0.0);
				harmonizeMixer.gain(2, 1.0);
				harmonizeMixer.gain(3, 0.0);
				harmonizeDrumLength = map(pot2, 0, 127, 0, 800);
				harmonizeDrumSecondMix = map(pot3, 0, 127, 0, 1);
				harmonizeDrumPitchMod = map(pot4, 0, 127, 0, 1);
				break;
			case string://string
				harmonizeMixer.gain(1, 0.0);
				harmonizeMixer.gain(2, 0.0);
				harmonizeMixer.gain(3, 1.0);
				stringVelocity = map(pot2, 0, 127, 0, 1);
				break;
			}
		}
		break;
	}
}
void checkButtons() {
	if (lastButtonSampleTimer >= 50) {
		buttonReadVal = digitalRead(freeverbButtonPin);
		if (freeverbHitHigh == true && buttonReadVal == LOW) {
			if (playing == true) {
				freeverbOn = !freeverbOn;
			}
			freeverbHitHigh = false;
			lastEffectSelected = (freeverbEffect);//0 means edits will apply to delays, 1 freeverb, 2 chorus, 3 bitcrusher 4 flange, 5 harmonize
			updateFreeverbDisplay = true;
			//Serial.println("freeverbHit");
		}
		else if (buttonReadVal == HIGH) {
			freeverbHitHigh = true;
		}

		buttonReadVal = digitalRead(delayButtonPin);
		if (delayHitHigh == true && buttonReadVal == LOW) {
			if (playing) {
				delayOn = !delayOn;
			}
			delayHitHigh = false;
			lastEffectSelected = (delayEffect);
			updateDelayDisplay = true;
			//Serial.println("delayHit");

		}
		else if (buttonReadVal == HIGH) {
			delayHitHigh = true;
		}

		buttonReadVal = digitalRead(chorusButtonPin);
		if (chorusHitHigh == true && buttonReadVal == LOW) {
			if (playing) {
				chorusOn = !chorusOn;
			}
			chorusHitHigh = false;
			lastEffectSelected = (chorusEffect);
			updateChorusDisplay = true;
			//Serial.println("chorusHit");
		}
		else if (buttonReadVal == HIGH) {
			chorusHitHigh = true;
		}

		buttonReadVal = digitalRead(bitCrusherButtonPin);
		if (bitCrusherHitHigh == true && buttonReadVal == LOW) {
			if (playing) {
				bitCrusherOn = !bitCrusherOn;
			}
			bitCrusherHitHigh = false;
			updateBitCrusherDisplay = true;
			lastEffectSelected = bitCrusherEffect;
			//Serial.println("bitCrusherHit");
		}
		else if (buttonReadVal == HIGH) {
			bitCrusherHitHigh = true;
		}

		buttonReadVal = digitalRead(flangeButtonPin);
		if (flangeHitHigh == true && buttonReadVal == LOW) {
			if (playing) {
				flangeOn = !flangeOn;
			}
			flangeHitHigh = false;
			lastEffectSelected = (flangeEffect);
			updateFlangeDisplay = true;
			//Serial.println("flangeHit");
		}
		else if (buttonReadVal == HIGH) {
			flangeHitHigh = true;
		}

		buttonReadVal = digitalRead(harmonizeButtonPin);
		if (harmonizeHitHigh == true && buttonReadVal == LOW) {
			if (playing) {
				harmonizeOn = !harmonizeOn;
			}
			harmonizeHitHigh = false;
			updateHarmonizeDisplay = true;
			lastEffectSelected = (harmonizeEffect);
		}
		else if (buttonReadVal == HIGH) {
			harmonizeHitHigh = true;
		}

		buttonReadVal = digitalRead(editPlayStatePin);
		if (editPlayStateHitHigh == true && buttonReadVal == LOW) {
			if (liveEditdoubleTapTimer <= playingButtonDoubleTapTimer) {
				liveEditingPlaying = true;
			}
			else {
				playing = !playing;
				liveEditingPlaying = false;
			}

			editPlayStateHitHigh = false;

			updateFreeverbDisplay = true;//if you need to update screen, this is true. Otherwise, it is false.
			updateDelayDisplay = true;
			updateChorusDisplay = true;
			updateBitCrusherDisplay = true;
			updateFlangeDisplay = true;
			updateHarmonizeDisplay = true;

			liveEditdoubleTapTimer = 0;

		}
		else if (buttonReadVal == HIGH) {
			editPlayStateHitHigh = true;
		}

		buttonReadVal = digitalRead(padPin);
		if (padHitHigh == true && buttonReadVal == LOW) {
			padDrum1.noteOn();
			padHitHigh = false;
		}
		else if (buttonReadVal == HIGH) {
			padHitHigh = true;
		}
		lastButtonSampleTimer = 0;
	}
}
When posting code could you please post it between CODE tags using the # button above.
It makes your code easier to read and therefore easier for someone to potentially help you.
Unfortunately I have no experience with audio so I am not that person.
 
1) Should the Line in/Line out(Vgnd) be connected to the board's ground?
Vgnd is NOT the ground for the Line in/Line out signals - it's the virtual ground for headphone output. It should definitely NOT be connected to the regular GND througholes. See the also the schematic.

If connected, than something is wrong on your board - check for stray solderblobs or metal particles that should not be there.

Don't want to be rude, but some solderpoints are sub-optimal. You may want to increase the temperature of your soldering-iron such that the solder flows nicely. Most solderjoints look a bit too 'cold'.

top.png

I could not tell for sure from your post how you connected the external amp but it must be connected using the line-out pads, not the headphone output!

Paul
 
The floating ground for the headphone output is a circuit trick to avoid needing physically large DC-blocking capacitors when the SGTL5000 chip is used in something like a mobile phone. Only use the headphone output for headphones!
 
Back
Top