Welcome, Guest
Username: Password: Remember me

TOPIC: Super Reverb Pedal.

Super Reverb Pedal. 6 years 8 months ago #17

  • JR
  • JR's Avatar
  • OFFLINE
  • Senior Member
  • Posts: 77
  • Thank you received: 31
  • Karma: 6
The reverb effect simulates the sound that results from reflections from surrounding walls. To simulate it most digital reverbs produce two parts: the early Reflections and the reverb component, which are just the signal delayed with different timings.

Reverb.ino uses the 2 DACs to create this two components: DAC0 generates the early reflections and DAC1 does the reverb component (which is the early reflections with more delay). Both components are adjusted independently using POT0 and POT1:
  • Pot 0: Adjusts the first reflection of the sound.
  • Pot 1: Adjusts the second reflection of the sound.
  • Pot 2: Controls the output volume.
  • Mix Switch: Shoud be ON (down) to add the direct sound trajectory.
  • Toggle Switch: Switchs betseen reverb(delayed signals) and super-reverb(echoed signals).

reverb.ino:
/* reverb.ino creates two copies of the guitar signal to be delayed independently producing
  a reverb-like sound, the toggle switch selects between delaying or echoing the signals*/
// Licensed under a Creative Commons Attribution 3.0 Unported License.
// Based on rcarduino.blogspot.com previous work.
// www.electrosmash.com/pedalshield
 
int in_ADC0, in_ADC1;  //variables for 2 ADCs values (ADC0, ADC1)
int POT0, POT1, POT2, out_DAC0, out_DAC1; //variables for 3 pots (ADC8, ADC9, ADC10)
int LED = 3;
int FOOTSWITCH = 7; 
int TOGGLE = 2; 
 
#define MAX_DELAY_A 20000
#define MAX_DELAY_B 20000
uint16_t DelayBuffer_A[MAX_DELAY_A];
uint16_t DelayBuffer_B[MAX_DELAY_B];
unsigned int DelayCounter_A = 0;
unsigned int DelayCounter_B = 0;
unsigned int Delay_Depth_A, Delay_Depth_B;
 
void setup()
{
  //turn on the timer clock in the power management controller
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(ID_TC4);
 
  //we want wavesel 01 with RC 
  TC_Configure(TC1,1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK2);
  TC_SetRC(TC1, 1, 238); // sets <> 44.1 Khz interrupt rate
  TC_Start(TC1, 1);
 
  // enable timer interrupts on the timer
  TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;
  TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;
 
  //Enable the interrupt in the nested vector interrupt controller 
  //TC4_IRQn where 4 is the timer number * timer channels (3) + the channel number 
  //(=(1*3)+1) for timer1 channel1 
  NVIC_EnableIRQ(TC4_IRQn);
 
  //ADC Configuration
  ADC->ADC_MR |= 0x80;   // DAC in free running mode.
  ADC->ADC_CR=2;         // Starts ADC conversion.
  ADC->ADC_CHER=0x1CC0;  // Enable ADC channels 0,1,8,9 and 10  
 
  //DAC Configuration
  analogWrite(DAC0,0);  // Enables DAC0
  analogWrite(DAC1,0);  // Enables DAC0
 
  //Pin Configuration
  pinMode(LED, OUTPUT);  
  pinMode(FOOTSWITCH, INPUT);     
  pinMode(TOGGLE, INPUT);     
}
 
void loop()
{
  //Read the ADCs
  while((ADC->ADC_ISR & 0x1CC0)!=0x1CC0);// wait for ADC 0, 1, 8, 9, 10 conversion complete.
  in_ADC0=ADC->ADC_CDR[7];           // read data from ADC0
  in_ADC1=ADC->ADC_CDR[6];           // read data from ADC1  
  POT0=ADC->ADC_CDR[10];                // read data from ADC8        
  POT1=ADC->ADC_CDR[11];                // read data from ADC9   
  POT2=ADC->ADC_CDR[12];                // read data from ADC10     
}
 
//Interrupt at 44.1KHz rate (every 22.6us)
void TC4_Handler()
{
  //Clear status allowing the interrupt to be fired again.
  TC_GetStatus(TC1, 1);
 
    //Check the TOGGLE SWITCH and select between super-reverb and reverb.
    if (digitalRead(TOGGLE))
  { 
     //Store current readings in ECHO mode
     DelayBuffer_A[DelayCounter_A]=(in_ADC0 + (DelayBuffer_A[DelayCounter_A]))>>1;
     DelayBuffer_B[DelayCounter_B]=(in_ADC1 + (DelayBuffer_B[DelayCounter_B]))>>1; 
     digitalWrite(LED, HIGH); 
  }
 
    else 
  {
     //Store current readings in DELAY mode  
     DelayBuffer_A[DelayCounter_A]  = in_ADC0 ;
     DelayBuffer_B[DelayCounter_B]  = in_ADC1 ;  
     digitalWrite(LED, LOW);
  }
 
  //Adjust Delay Depth based in POT0 and POT1 position.
  Delay_Depth_A =map(POT0>>3,0,512,1,MAX_DELAY_A);
  Delay_Depth_B =map(POT1>>3,0,512,1,MAX_DELAY_B);
 
  //Increse/reset delay counter.   
  DelayCounter_A++;
  DelayCounter_B++;
  if(DelayCounter_A >= Delay_Depth_A) DelayCounter_A = 0; 
  if(DelayCounter_B >= Delay_Depth_B) DelayCounter_B = 0; 
 
  //Calculate the output as the sum of DelayBuffer_A + DelayBuffer_B 
  out_DAC0 = (DelayBuffer_A[DelayCounter_A]);
  out_DAC1 = (DelayBuffer_B[DelayCounter_B]);
 
  //Add volume feature based in pot2 position.
  out_DAC0=map(out_DAC0,0,4095,1,POT2);
  out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
  //Write the DACs
  dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
  dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
  dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
  dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
}

You can listen how this Reverb effect sounds in SounCloud.

File Attachment:

File Name: reverb.rar
File Size: 2 KB
keep it simple
Last Edit: 6 years 7 months ago by JR.
The administrator has disabled public write access.

Super Reverb Pedal. 9 months 1 week ago #2006

Hi! I don't quite understand how the interrupt is used. I know it's used to set/change the current values of the effect but I can't figure out when it's triggered or why.I hope you can explain it to me. Thanks in advance.
The administrator has disabled public write access.
Time to create page: 0.208 seconds
Powered by Kunena Forum
Joomla SEF URLs by Artio