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.