Welcome, Guest
Username: Password: Remember me

TOPIC: Chorus / Vibrato Pedal.

Chorus / Vibrato Pedal. 6 years 8 months ago #18

  • JR
  • JR's Avatar
  • OFFLINE
  • Senior Member
  • Posts: 77
  • Thank you received: 31
  • Karma: 6
The Chorus effect just generates a delayed signal, but the delay is not constant but variable or "modulated". In most of the effect the variation of the delay time follows a sinusoidal or triangular waveform called LFO (Low Frequency Oscillator).

If the output signal is the original guitar signal with this variable delay, the effect is usually called Vibrato. Alternatively, if the delayed signal is mixed with the original one is called chorus.

chorus_vibrato.ino pedal creates a chorus/vibrato pedal configurable in speed, depth and volume. The led blinks at the same speed as the LFO:
  • Potentiometer 0: Adjust the Depth of the effect.
  • Potentiometer 1: Not used.
  • Potentiometer 2: Set the output Volume.
  • Mix Switch: when it's OFF (up)= vibrato, when it's ON (down): chorus
  • Led: Blinks at the same speed as the effect.

chorus_vibrato.ino:
// Licensed under a Creative Commons Attribution 3.0 Unported License.
// Based on rcarduino.blogspot.com previous work.
// www.electrosmash.com/pedalshield
 
/*chorus_vibrato.ino creates a chorus guitar effect by delaying the signal and
modulating this delay with a triangular waveform.*/
 
int in_ADC0, in_ADC1, out_DAC0, out_DAC1;  //variables for 2 ADCs values (ADC0, ADC1)
int POT0, POT1, POT2; //variables for 3 pots (ADC8, ADC9, ADC10)
int LED = 3;
int FOOTSWITCH = 7; 
int TOGGLE = 2; 
#define MAX_DELAY 500
#define MIN_DELAY 200

uint16_t sDelayBuffer0[MAX_DELAY+500];
uint16_t sDelayBuffer1[MAX_DELAY+500];
unsigned int DelayCounter = 0;
unsigned int Delay_Depth = 300;
unsigned int count_up=1;
int p;
 
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, 109); // 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
 
  //pedalSHIELD 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);
 
  //Store current readings  
  sDelayBuffer0[DelayCounter] = in_ADC0;
 
  //Adjust Delay Depth based in pot0 position.
  POT0=map(POT0>>2,0,1024,1,25); //25 empirically chosen
 
  DelayCounter++;
  if(DelayCounter >= Delay_Depth) 
  {
    DelayCounter = 0; 
    if(count_up)
    {
       digitalWrite(LED, HIGH);
       for(p=0;p<POT0+1;p++) 
       sDelayBuffer0[Delay_Depth+p]=sDelayBuffer0[Delay_Depth-1]; 
       Delay_Depth=Delay_Depth+POT0;
       if (Delay_Depth>=MAX_DELAY)count_up=0;
    }
    else
    {
       digitalWrite(LED, LOW); 
       Delay_Depth=Delay_Depth-POT0;
       if (Delay_Depth<=MIN_DELAY)count_up=1;
    }
  }
 
  out_DAC0 = sDelayBuffer0[DelayCounter];
 
  //Add volume control based in POT2
  out_DAC0=map(out_DAC0,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, 0);       //write on DAC
}

You can listen this Chorus effect in SoundCloud.

File Attachment:

File Name: chorus_vibrato.rar
File Size: 2 KB


There are a lot of ways to implement s a chorus effect. In the Sound on Sound website there is a great article explaining different techniques and approaches to be used when coding this pedal.
keep it simple
Last Edit: 6 years 7 months ago by JR.
The administrator has disabled public write access.
Time to create page: 0.244 seconds
Powered by Kunena Forum
Joomla SEF URLs by Artio