Piface

Piface

Thursday, August 16, 2012

Here is the code for the Arduino 8-Bit Delay guitar pedal.  It has been written to accommodate the using of 8 digital outputs through an R2R digital to analog conversion system.  Just follow the schematic and use this code.


This is the code for the Arduino Realtime Audio- DELAY EFFECT
-it corresponds to the schematic, and requires an R2R Digital to Analog converter on 8 digital pins of the Arduino

//Arduino Realtime Audio-  Delay Effect-
//R2R digital to analog converter on digital pins 0-7
//Guitar input from a preamp that delivers 0-5V on analog pin 1
//Potentiometer middle lug to analog 0 with pins to Arduino 5V and ground

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //clearing registry bits
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))  //setting registry bits

boolean div32;
boolean div16;
// interrupt variables accessed globally
volatile boolean f_sample;
volatile byte badc0;
volatile byte badc1;
volatile byte ibb;

int cnta;
int icnt;
int cnt2;
int iw1;
int iw;
byte bb; //OUTPUT???
byte dd[1024]; // Audio Memory Array 8-Bit

int numberPin = 2; // analog pin to read the buttons
int numberVal;  //BUTTON VALUE

void setup()
{
//R2R: Initialize output ports  MAKES PINS 0-7 OUTPUT TO DAC
// PORTD = B11111111;
for(int i=0; i < 8; i++){
  pinMode(i, OUTPUT);
}

fill_sinewave();    // reload wave after 1 second


// set adc prescaler to 64 for 19kHz sampling frequency
//DETERMINES DIVISION FACTOR BETWEEN SYSTEM CLOCK FREQUENCY AND
//INPUT CLOCK OF ADC

cbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);

//ADMUX SELECTS ANALOG INPUT CHANNEL

sbi(ADMUX,ADLAR); // 8-Bit ADC in ADCH Register PRESENTED LEFT-ADJUSTED
sbi(ADMUX,REFS0); // VCC Reference
cbi(ADMUX,REFS1);
cbi(ADMUX,MUX0);  // Set Input Multiplexer to Channel 0
cbi(ADMUX,MUX1);
cbi(ADMUX,MUX2);
cbi(ADMUX,MUX3);

// Timer2 Clock Prescaler to : 1
sbi (TCCR2B, CS20);
cbi (TCCR2B, CS21);
cbi (TCCR2B, CS22);

//cli(); // disable interrupts to avoid distortion

//TIMER/COUNTER INTERRUPT MASK REGISTER
cbi (TIMSK0,TOIE0); // disable Timer0 !!! delay is off now  OVERFLOW INTERRUPT ENABLE
sbi (TIMSK2,TOIE2); // enable Timer2 Interrupt

iw1=badc1; //NO IDEA

  DDRB=B00111111;//SETS DIGITAL LED PINS AS OUTPUTS
  DDRC=B00100000;//SETS ANALOG 5 AS OUTPUT
}

void loop()
{
while (!f_sample) {  // wait for Sample Value from ADC  WHAT DOES THIS DO?
}  // Cycle 15625 KHz = 64uSec

f_sample=false;  //VALUE OF BOOLEAN "f_sample"

bb=dd[icnt] ; // read the delay buffer
iw = 127-bb ; // substract offset
iw = iw * badc0 / 255;  // scale delayed sample with potentiometer
iw1 = 127 - badc1; // substract offset from new sample
iw1=iw1+iw;  // add delayed sample and new sample

if (iw1 < -127) iw1=-127; // Audio limiter

if (iw1 > 127) iw1=127;  // Audio limiter

bb= 127+iw1; // add offset
dd[icnt]=bb; // store sample in audio buffer
icnt++;
icnt = icnt & 1023;  // limit bufferindex 0..511

PORTD=bb;  //Sends the output to the R2R digital to analog converter on digital pins 0-7

} // loop
//******************************************************************

void fill_sinewave(){
float pi = 3.141592;
float dx ;
float fd ;
float fcnt;
dx=2 * pi / 512; // fill the 512 byte bufferarry
for (iw = 0; iw <= 511; iw++){ // with 50 periods sinewawe
fd= 127*sin(fcnt); // fundamental tone
fcnt=fcnt+dx;  // in the range of 0 to 2xpi  and 1/512 increments
bb=127+fd; // add dc offset to sinewawe
dd[iw]=bb; // write value into array

}
}

//******************************************************************
// Timer2 Interrupt Service at 62.5 KHz
// here the audio and pot signal is sampled in a rate of: 16Mhz / 256 / 2 / 2 = 15625 Hz
// runtime : xxxx microseconds

//TIMER/COUNTER 2 OVERFLOW INTERRUPT

ISR(TIMER2_OVF_vect) {

  div32=!div32; // divide timer2 frequency / 2 to 31.25kHz
if (div32){
div16=!div16; //
if (div16) {  // sample channel 0 and 1 alternately so each channel is sampled with 15.6kHz
badc0=ADCH; // get ADC channel 0
sbi(ADMUX,MUX0);  // set multiplexer to channel 1
}
else
{
badc1=ADCH; // get ADC channel 1
cbi(ADMUX,MUX0);  // set multiplexer to channel 0
f_sample=true;
}
ibb++;
ibb--;
ibb++;
ibb--; // short delay before start conversion
sbi(ADCSRA,ADSC); // start next conversion
}

}