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