Welcome, Guest
Username: Password: Remember me

TOPIC: Schoreder's Reverb

Schoreder's Reverb 6 years 1 month ago #698

  • AndrewHPavei
  • AndrewHPavei's Avatar
  • OFFLINE
  • New Member
  • Posts: 7
  • Thank you received: 5
  • Karma: 2
Hello guys,

Some time ago I've posted severals cods based on PedalSHIELD Library and some new ones.
Now I come back to post a New version of my Schoreder's Reverb.
This new version use a optimization algorithm in fixed point 16bits. For this reason now is possible program this heavy code use 44.1 KHz without problem.
/*------------ Schroeder’s reverberator  ---------------*/
//======================================================================================================//
// FOOTSWITCH ------------------ TURN ON/OFF THE EFFECT
// MIX SWITCH ------------- [ON] ADD ORIGINAL SOUND, [OFF] ONLY EFFECT
//======================================================================================================//
//
//Based on :[1] www.electrosmash.com/pedalshield configurations,
//          [2] AES Brasil 2011 - article "Filtros e Efeitos de Áudio Analógicos e Digitais"
//          [3] Zolzer, U.; “DAFX: Digital Audio Effects” John Wiley & Sons, Ltd – 2002.
//          [4] Oppenheim, A., V.; “Applications of Digital Signal Processing”, ”, Prentice Hall, 1978.
//          [6] Schroeder; M. R., “Natural Sounding Artificial reverberation” J. Audio Eng. Soc, 10; 1962.
//          [7] Orfanidis, S. J.; “Introduction to Signal processing”, Prentice Hall, 2009.
//
// Developed by Andrew Henrique Pavei, (This email address is being protected from spambots. You need JavaScript enabled to view it.), as part of the Final Paper to 
//Electrical Engeneering Graduation of Federal University of Santa Catarina (UFSC), Brazil and AES Brazil 2016 
//LECTURE "Implementações de Efeitos de Áudio utilizando Arduino DUE e PedalSHIELD"
//======================================================================================================//
// In development, Delays and gains based on MATLAB Code of [2].
// Schroeder’s Reverberator Functions :
//                                      x1(n) = x(n) + a1.x1(n-D1)                  [138]
//                                      x2(n) = x(n) + a2.x2(n-D2)                  [139]
//          Comb Filters IIR            x3(n) = x(n) + a3.x3(n-D3)                  [140]
//                                      x4(n) = x(n) + a4.x4(n-D4)                  [141]
//
//                                      x5(n) = [b1.x1(n) + b2.x2(n) + b3.x3(n) + b4.x4(n)]/4
//
//          All-pass Filters            x6(n) = a5.x6(n-D5) - a5.x5(n) + x5(n-D5)   [142]
//                                      y(n) = a6.y(n-D6) - a6.x6(n) + x6(n-D6)     [143]
//
//======================================================================================================//
 #include <fix16.h>
                        //  8k  16k
#define D1   2000       //  238 476
#define D2   2000       //  297 594
#define D3   2000       //  329 658
#define D4   2000       //  350 700
#define D5   4000       //  775 1550   
#define D6   2000      //  263 526 

 
  int DV1 = 560;
  int DV2 = 1184;
  int DV3 = 656;
  int DV4 = 704;
  int DV5 = 1552;
  int DV6 = 528;
 
 
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;
 
fix16_t in0,in1,out0,out1;
 
fix16_t a1 = 46393, a2 = 42572, a3 = 40632, a4 = 39426, a5 = 48064, a6 = 43673;
fix16_t b1 = 64881, b2 = 62259 , b3 = 58982 , b4 = 52429;
int index5 = 0, index6 = 0;
 
int temp1 = 0, temp2 = 0, temp3 = 0,temp4 = 0,temp5 = 0,temp6 = 0;
 
fix16_t X1[D1] = {0};
fix16_t X2[D2] = {0};
fix16_t X3[D3] = {0};
fix16_t X4[D4] = {0};
fix16_t X5[D5] = {0};
fix16_t X6[D6] = {0};
 
fix16_t S1 = 0, S2 =  0, S3 =  0, S4 =  0, S5 = 0, S6 = 0, S7 = 0, S51 = 0;
 
int DC1 = 0, DC2 = 0, DC3 = 0, DC4 = 0, DC5 = 1, DC6 = 1;
 
int toggle_value = 0;
int effect=0;
 
void setup()
{
 //Serial.begin(9600);
  //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, 656 ); // sets <> 8 Khz interrupt rate
  //8KHz,  value = 1312 (10500000/8000 = 1312) --------------- 8KHz (1/8KHz = 125us)
  //16KHz, value = 656 (10500000/16000 = 656)
  //32KHz, value = 328 (10500000/32000 = 328)
  //44.1Hz, value = 238 (10500000/44100 = 238) -------------- 44.1KHz (1/44KHz=22.6us)
  //48KHz, value = 218 (10500000/48000 = 218)
  //88.2KHz, value = 119 (10500000/88200 = 119)
  //96KHz, value = 109  (10500000/96000 = 109)
 
  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_PULLUP);
  pinMode(TOGGLE, INPUT_PULLUP);
  attachInterrupt(TOGGLE, switch_handler, CHANGE);
 
}
 
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
  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
//Serial.println(effect);
}
 
 
//Interrupt at 8KHz rate (every 125us)
void TC4_Handler()
{
  //Clear status allowing the interrupt to be fired again.
  TC_GetStatus(TC1, 1);
 
  if (effect==0)
{ 
 
   DV1 = 560;
   DV2 = 1184;
   DV3 = 656;
   DV4 = 704;
   DV5 = 1552;
   DV6 = 528;
  digitalWrite(LED, HIGH);
//  digitalWrite(48, HIGH);
//  digitalWrite(49, HIGH);
 
}
 
if (effect==1)
{ 
   DV1 = 863;
   DV2 = 1583;
   DV3 = 957;
   DV4 = 1003;
   DV5 = 1557;
   DV6 = 1523;
  digitalWrite(LED, HIGH);
//  digitalWrite(48, HIGH);
//  digitalWrite(49, HIGH);
 
}
if (effect==2) {
//  DV1 = map(POT0>>1,0,2047,1,2000);
//  DV2 = map(POT1>>1,0,2047,1,2000);
//  DV3 = map(POT2>>1,0,2047,1,2000); 
  temp1 = map(POT0>>1,0,2047,1,2000);
  temp2 = map(POT1>>1,0,2047,1,2000);
  temp3 = map(POT2>>1,0,2047,1,2000);  
   digitalWrite(LED, LOW);
//   digitalWrite(48, HIGH);
//   digitalWrite(49, LOW);
  if(temp1 > DV1)
    DV1++;
  else if(temp1 < DV1)
    DV1--;
 
  if(temp2 > DV2)
    DV2++;
  else if(temp2 < DV2)
    DV2--;
 
    if(temp3 > DV3)
    DV3++;
  else if(temp3 < DV3)
    DV3--;
}
if (effect==3) {
    temp4 = map(POT0>>1,0,2047,1,2000);
    temp5 = map(POT1>>1,0,2047,1,4000);
    temp6 = map(POT2>>1,0,2047,1,2000);
  if(temp4 > DV4)
    DV4++;
  else if(temp4 < DV4)
    DV4--;
 
  if(temp5 > DV5)
    DV5++;
  else if(temp5 < DV5)
    DV5--;
 
    if(temp6 > DV6)
    DV6++;
  else if(temp6 < DV3)
    DV3--;
 
 
  digitalWrite(LED, LOW);
//  digitalWrite(48, LOW);
//  digitalWrite(49, HIGH);
}
 
  in0 = in_ADC0<<16;
 
  X1[DC1] = fix16_add(in0,fix16_mul(a1,X1[DC1]));
  X2[DC2] = fix16_add(in0,fix16_mul(a2,X2[DC2]));
  X3[DC3] = fix16_add(in0,fix16_mul(a3,X3[DC3]));
  X4[DC4] = fix16_add(in0,fix16_mul(a4,X4[DC4]));
 
  S1 = fix16_mul(b1,X1[DC1]);
  S2 = fix16_mul(b2,X2[DC2]);
  S3 = fix16_mul(b3,X3[DC3]);
  S4 = fix16_mul(b4,X4[DC4]);
 
  DC1++; if (DC1 >= DV1) DC1 = 0;
  DC2++; if (DC2 >= DV2) DC2 = 0;
  DC3++; if (DC3 >= DV3) DC3 = 0;
  DC4++; if (DC4 >= DV4) DC4 = 0;
 
S5 = fix16_div(fix16_add(fix16_add(S1,S2),fix16_add(S3,S4)),262144);
// S5 = (S1 + S2 + S3 + S4)/4; <<< equivalente
 
  X5[index5] = fix16_add(S5, fix16_mul(a5, X5[DC5]));
  S6 = fix16_add(fix16_mul(fix16_sub(0,a5),X5[index5]),X5[DC5]);
 
  DC5++; if (DC5 >= DV5) DC5 = 0;
  index5++; if (index5 >= DV5) index5 = 0;
 
  X6[index6] = fix16_add(S6, fix16_mul(a6, X6[DC6]));
  //X6[index6] = (S6 + a6 * X6[DC6]);
  S7 = fix16_add(fix16_mul(fix16_sub(0,a6),X6[index6]),X6[DC6]);
  //S7 = -a6 * X6[index6] + X6[DC6];
 
  DC6++; if (DC6 >= DV6) DC6 = 0;
  index6++; if (index6 >= DV6) index6 = 0;
 
  out0 = S7;
  out_DAC0 = out0>>14;
 
  //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 0
//  dacc_write_conversion_data(DACC_INTERFACE, out_DAC1); //write on DAC
}
void switch_handler()
{
  delayMicroseconds(100000); //debouncing protection
  if (toggle_value!=digitalRead(TOGGLE)) effect++;
  delayMicroseconds(100000); //debouncing protection
  toggle_value=digitalRead(TOGGLE);
  if (effect==4) effect=0;
}

You should also add the library in attachment in your Arduino IDE.

<< I still have some problems with noise , ok :silly: :whistle: >>
Attachments:
Last Edit: 6 years 1 month ago by AndrewHPavei.
The administrator has disabled public write access.
The following user(s) said Thank You: Ray, BowDown

Schoreder's Reverb 6 years 1 month ago #699

  • Ray
  • Ray's Avatar
  • OFFLINE
  • Moderator
  • Posts: 702
  • Thank you received: 152
  • Karma: 44
Fantastic contribution, looks very well documented :woohoo: I am linking this from the main How to Start Programming topic
THANKS.
Last Edit: 6 years 1 month ago by Ray.
The administrator has disabled public write access.
The following user(s) said Thank You: AndrewHPavei

Schoreder's Reverb 6 years 1 month ago #705

  • AndrewHPavei
  • AndrewHPavei's Avatar
  • OFFLINE
  • New Member
  • Posts: 7
  • Thank you received: 5
  • Karma: 2
Thank you Ray
The administrator has disabled public write access.
The following user(s) said Thank You: Ray

Schoreder's Reverb 6 years 5 days ago #749

  • BowDown
  • BowDown's Avatar
  • OFFLINE
  • Senior Member
  • Posts: 55
  • Thank you received: 6
  • Karma: 2
I get an error with compiling this effect.

C:\Program Files (x86)\Arduino\examples\00.Pedal\Schoreders_Reverb\Schoreders_Reverb.ino:31:20: fatal error: fix16.h: No such file or directory

In the beginning you are including a header called ficed16.h

It doesnt seem to be included in the Arduino IDE
The administrator has disabled public write access.

Schoreder's Reverb 6 years 4 days ago #753

  • Ray
  • Ray's Avatar
  • OFFLINE
  • Moderator
  • Posts: 702
  • Thank you received: 152
  • Karma: 44
Hi, the fix16.h file is included in the zip project. If you download the compressed folder and run it should be fine!
The administrator has disabled public write access.
Time to create page: 0.183 seconds
Powered by Kunena Forum
Joomla SEF URLs by Artio