timschneeb / RootlessJamesDSP

An implementation of the system-wide JamesDSP audio processing engine for non-rooted Android devices
GNU General Public License v3.0
841 stars 26 forks source link

Per channel EQ and time alignment #187

Open Switchleg1 opened 9 months ago

Switchleg1 commented 9 months ago

Hello,

First of all thank you for taking the time to develop this application, much appreciated! I was hoping to implement an EQ per channel for ppl that want to EQ a car for off axis response and time alignment. Taken care of the GUI and string encoding/decoding and working through the library now. In the meantime I have been using this dsp script if anyone is interested:

desc: My EQ

//delay slider1:0<0,3,0.1>Left Delay (ms) slider2:0<0,3,0.1>Right Delay (ms)

//eq slider10:0<-18,3,0.5>Left 250hz slider11:0<-18,3,0.5>Left 450hz slider12:0<-18,3,0.5>Left 900hz slider13:0<-18,3,0.5>Left 1500hz slider14:0<-18,3,0.5>Left 2000hz slider15:0<-18,3,0.5>Left 3000hz slider16:0<-18,3,0.5>Left 6000hz slider17:0<-18,3,0.5>Left 12000hz

slider20:0<-18,3,0.5>Right 250hz slider21:0<-18,3,0.5>Right 450hz slider22:0<-18,3,0.5>Right 900hz slider23:0<-18,3,0.5>Right 1500hz slider24:0<-18,3,0.5>Right 2000hz slider25:0<-18,3,0.5>Right 3000hz slider26:0<-18,3,0.5>Right 6000hz slider27:0<-18,3,0.5>Right 12000hz

@init //delay slider1 = 0; slider2 = 0;

delaylen_l = (slider1 srate 0.001 2)|0; delaylen_r = (slider2 srate 0.001 2)|0;

bpos = 0; bufsize = srate*0.1;

//eq slider10 = 0; slider11 = 0; slider12 = 0; slider13 = 0; slider14 = 0; slider15 = 0; slider16 = 0; slider17 = 0;

slider20 = 0; slider21 = 0; slider22 = 0; slider23 = 0; slider24 = 0; slider25 = 0; slider26 = 0; slider27 = 0;

iirBPSL = bufsize; reqSize = IIRBandSplitterInit(iirBPSL, srate, 350, 675, 1200, 1750, 2500, 4500, 9000); iirBPSR = iirBPSL + reqSize; // Shift the pointer reqSize = IIRBandSplitterInit(iirBPSR, srate, 350, 675, 1200, 1750, 2500, 4500, 9000);

eqL = iirBPSR + reqSize; eqL[0] = pow(10, slider10 / 20); eqL[1] = pow(10, slider11 / 20); eqL[2] = pow(10, slider12 / 20); eqL[3] = pow(10, slider13 / 20); eqL[4] = pow(10, slider14 / 20); eqL[5] = pow(10, slider15 / 20); eqL[6] = pow(10, slider16 / 20); eqL[7] = pow(10, slider17 / 20);

eqR = eqL + 8; eqR[0] = pow(10, slider20 / 20); eqR[1] = pow(10, slider21 / 20); eqR[2] = pow(10, slider22 / 20); eqR[3] = pow(10, slider23 / 20); eqR[4] = pow(10, slider24 / 20); eqR[5] = pow(10, slider25 / 20); eqR[6] = pow(10, slider26 / 20); eqR[7] = pow(10, slider27 / 20);

@sample //eq IIRBandSplitterProcess(iirBPSL, spl0, l0, l1, l2, l3, l4, l5, l6, l7); IIRBandSplitterProcess(iirBPSR, spl1, r0, r1, r2, r3, r4, r5, r6, r7);

l0 = eqL[0]; l1 = eqL[1]; l2 = eqL[2]; l3 = eqL[3]; l4 = eqL[4]; l5 = eqL[5]; l6 = eqL[6]; l7 = eqL[7];

r0 = eqR[0]; r1 = eqR[1]; r2 = eqR[2]; r3 = eqR[3]; r4 = eqR[4]; r5 = eqR[5]; r6 = eqR[6]; r7 = eqR[7];

spl0 = l0 + l1 + l2 + l3 + l4 + l5 + l6 + l7; spl1 = r0 + r1 + r2 + r3 + r4 + r5 + r6 + r7;

//delay bpos[0] = spl0; bpos[1] = spl1;

rdpos_l = bpos - delaylen_l; rdpos_r = bpos - delaylen_r; rdpos_l<0 ? rdpos_l += bufsize; rdpos_r<0 ? rdpos_r += bufsize; spl0 = rdpos_l[0]; spl1 = rdpos_r[1];

bpos += 2; bpos >= bufsize ? bpos -= bufsize;

abdessalaam commented 8 months ago

I would love separate L-R EQ (though for hearing loss compensation rather than in car listening). Where to put / how to implement this script, in the meantime? Thank you!

Switchleg1 commented 8 months ago

Hi Pawel,

You can enable 'live programmable dsp' then select a type (any type will do). At this point click 'edit selected script' and paste the contents of your desired scripted within it. You can either make the adjustments in this window or by going into the 'additional script parameters'

I am currently using this eq which has 8 parametric EQ per channel, delay and an all pass filter.

desc: My EQ 6

//Swap channels swapChannels:0<0,1,1>Swap Channels

//Pre gain leftPreGain:0<-3,0,0.1>Left Pre Gain (db) rightPreGain:0<-3,0,0.1>Right Pre Gain (db)

//Delay leftDelay:0<0,3,0.1>Left Delay (ms) rightDelay:0<0,3,0.1>Right Delay (ms)

//Allpass leftAllPassFreq:0<0,7000,50>Left All Pass Freq rightAllPassFreq:0<0,7000,50>Right All Pass Freq

//EQ left1Freq:1000<10,15000,50>Left 1 Freq left1Gain:0<-18,6,1>Left 1 Gain left1Q:1<0.1,6,0.1>Left 1 Q

left2Freq:1000<10,15000,50>Left 2 Freq left2Gain:0<-18,6,1>Left 2 Gain left2Q:1<0.1,6,0.1>Left 2 Q

left3Freq:1000<10,15000,50>Left 3 Freq left3Gain:0<-18,6,1>Left 3 Gain left3Q:1<0.1,6,0.1>Left 3 Q

left4Freq:1000<10,15000,50>Left 4 Freq left4Gain:0<-18,6,1>Left 4 Gain left4Q:1<0.1,6,0.1>Left 4 Q

left5Freq:1000<10,15000,50>Left 5 Freq left5Gain:0<-18,6,1>Left 5 Gain left5Q:1<0.1,6,0.1>Left 5 Q

left6Freq:1000<10,15000,50>Left 6 Freq left6Gain:0<-18,6,1>Left 6 Gain left6Q:1<0.1,6,0.1>Left 6 Q

left7Freq:1000<10,15000,50>Left 7 Freq left7Gain:0<-18,6,1>Left 7 Gain left7Q:1<0.1,6,0.1>Left 7 Q

left8Freq:1000<10,15000,50>Left 6 Freq left8Gain:0<-18,6,1>Left 6 Gain left8Q:1<0.1,6,0.1>Left 6 Q

right1Freq:1000<10,15000,50>Right 1 Freq right1Gain:0<-18,6,1>Right 1 Gain right1Q:1<0.1,6,0.1>Right 1 Q

right2Freq:1000<10,15000,50>Right 2 Freq right2Gain:0<-18,6,1>Right 2 Gain right2Q:1<0.1,6,0.1>Right 2 Q

right3Freq:1000<10,15000,50>Right 3 Freq right3Gain:0<-18,6,1>Right 3 Gain right3Q:1<0.1,6,0.1>Right 3 Q

right4Freq:1000<10,15000,50>Right 4 Freq right4Gain:0<-18,6,1>Right 4 Gain right4Q:1<0.1,6,0.1>Right 4 Q

right5Freq:1000<10,15000,50>Right 5 Freq right5Gain:0<-18,6,1>Right 5 Gain right5Q:1<0.1,6,0.1>Right 5 Q

right6Freq:1000<10,15000,50>Right 6 Freq right6Gain:0<-18,6,1>Right 6 Gain right6Q:1<0.1,6,0.1>Right 6 Q

right7Freq:1000<10,15000,50>Right 7 Freq right7Gain:0<-18,6,1>Right 7 Gain right7Q:1<0.1,6,0.1>Right 7 Q

right8Freq:1000<10,15000,50>Right 8 Freq right8Gain:0<-18,6,1>Right 8 Gain right8Q:1<0.1,6,0.1>Right 8 Q

@init //Swap channels slider swapChannels = 0;

//Pre gain sliders leftPreGain = -2.00; rightPreGain = -0.50;

//Delay sliders leftDelay = 1.16; rightDelay = 0.00;

//Allpass sliders leftAllPassFreq = 0; rightAllPassFreq = 450;

//EQ sliders left1Freq = 125; left1Gain = -2.2; left1Q = 3.00;

left2Freq = 295; left2Gain = -10.0; left2Q = 3.00;

left3Freq = 629; left3Gain = -4.0; left3Q = 4.00;

left4Freq = 800; left4Gain = -5.0; left4Q = 2.5;

left5Freq = 1000; left5Gain = -1.5; left5Q = 2.5;

left6Freq = 2500; left6Gain = -2.0; left6Q = 2.0;

left7Freq = 6000; left7Gain = -2.0; left7Q = 2.0;

left8Freq = 9000; left8Gain = -6.0; left8Q = 1.00;

right1Freq = 120; right1Gain = -2.0; right1Q = 3.50;

right2Freq = 208; right2Gain = -4.0; right2Q = 2.34;

right3Freq = 304; right3Gain = 0.0; right3Q = 7.53;

right4Freq = 630; right4Gain = -8.0; right4Q = 3.0;

right5Freq = 990; right5Gain = -10.0; right5Q = 3.0;

right6Freq = 2300; right6Gain = -3.0; right6Q = 2.0;

right7Freq = 6500; right7Gain = -5.0; right7Q = 2.0;

right8Freq = 9000; right8Gain = -5.0; right8Q = 2.0;

//Delay functions function BuildDelay(lDelay, rDelay)( this.leftDelayLen = round(leftDelay srate 0.001) 2; this.rightDelayLen = round(rightDelay srate 0.001) 2;

this.bPos = 0;
this.bufSize = srate * 0.1;

);

function ProcessDelay()( this.bPos[0] = spl0; this.bPos[1] = spl1;

leftPos  = this.bPos - this.leftDelayLen;
rightPos = this.bPos - this.rightDelayLen;

leftPos  < 0 ? leftPos += this.bufSize;
rightPos < 0 ? rightPos += this.bufSize;

spl0 = leftPos[0];
spl1 = rightPos[1];

this.bPos += 2;
this.bPos >= this.bufSize ? this.bPos -= this.bufSize;

);

//DSP functions function BuildAllpass(frequency)( omega = tan($PI * (frequency / srate));

this.in0  = 0;
this.in1  = 0;
this.out0 = 0;
this.out1 = 0;

this.a1   = (omega - 1) / (omega + 1);
this.a2   = 0;
this.b0   = this.a1;
this.b1   = 1;
this.b2   = 0;

);

function BuildParametric(frequency, gain, q)( omega = (2.f $PI frequency) / srate; sn = sin(omega); cs = cos(omega); alpha = sn / (2 * q); ax = pow(10, gain / 40); a0 = 1 + (alpha / ax);

this.in0  = 0;
this.in1  = 0;
this.out0 = 0;
this.out1 = 0;

this.a1   = -(2 * cs) / a0;
this.a2   = (1 - (alpha / ax)) / a0;
this.b1   = -(2 * cs);
this.b0   = (1 + (alpha * ax));
this.b2   = (1 - (alpha * ax));

);

function ProcessIIRFilter(inSample)( outSample = this.b0 inSample + this.b1 this.in0 + this.b2 * this.in1

//Pre gain init leftPreGainValue = pow(10, leftPreGain / 20); rightPreGainValue = pow(10, rightPreGain / 20);

//Delay init mainDelay.BuildDelay(leftDelay, rightDelay);

//All pass init leftAllPassFreq > 20 ? leftAllpassFilter.BuildAllpass(leftAllPassFreq); rightAllPassFreq > 20 ? rightAllpassFilter.BuildAllpass(rightAllPassFreq);

//EQ init left1Gain != 0 ? left1Parametric.BuildParametric(left1Freq, left1Gain, left1Q); left2Gain != 0 ? left2Parametric.BuildParametric(left2Freq, left2Gain, left2Q); left3Gain != 0 ? left3Parametric.BuildParametric(left3Freq, left3Gain, left3Q); left4Gain != 0 ? left4Parametric.BuildParametric(left4Freq, left4Gain, left4Q); left5Gain != 0 ? left5Parametric.BuildParametric(left5Freq, left5Gain, left5Q); left6Gain != 0 ? left6Parametric.BuildParametric(left6Freq, left6Gain, left6Q); left7Gain != 0 ? left7Parametric.BuildParametric(left7Freq, left7Gain, left7Q); left8Gain != 0 ? left8Parametric.BuildParametric(left8Freq, left8Gain, left8Q);

right1Gain != 0 ? right1Parametric.BuildParametric(right1Freq, right1Gain, right1Q); right2Gain != 0 ? right2Parametric.BuildParametric(right2Freq, right2Gain, right2Q); right3Gain != 0 ? right3Parametric.BuildParametric(right3Freq, right3Gain, right3Q); right4Gain != 0 ? right4Parametric.BuildParametric(right4Freq, right4Gain, right4Q); right5Gain != 0 ? right5Parametric.BuildParametric(right5Freq, right5Gain, right5Q); right6Gain != 0 ? right6Parametric.BuildParametric(right6Freq, right6Gain, right6Q); right7Gain != 0 ? right7Parametric.BuildParametric(right7Freq, right7Gain, right7Q); right8Gain != 0 ? right8Parametric.BuildParametric(right8Freq, right8Gain, right8Q);

@sample //Swap channels swapChannels == 1 ? swapValue = spl0; swapChannels == 1 ? spl0 = spl1; swapChannels == 1 ? spl1 = swapValue;

//Pre gain spl0 = leftPreGainValue; spl1 = rightPreGainValue;

//Allpass leftAllPassFreq > 20 ? spl0 = leftAllpassFilter.ProcessIIRFilter(spl0); rightAllPassFreq > 20 ? spl1 = rightAllpassFilter.ProcessIIRFilter(spl1);

//EQ left1Gain != 0 ? spl0 = left1Parametric.ProcessIIRFilter(spl0); left2Gain != 0 ? spl0 = left2Parametric.ProcessIIRFilter(spl0); left3Gain != 0 ? spl0 = left3Parametric.ProcessIIRFilter(spl0); left4Gain != 0 ? spl0 = left4Parametric.ProcessIIRFilter(spl0); left5Gain != 0 ? spl0 = left5Parametric.ProcessIIRFilter(spl0); left6Gain != 0 ? spl0 = left6Parametric.ProcessIIRFilter(spl0); left7Gain != 0 ? spl0 = left7Parametric.ProcessIIRFilter(spl0); left8Gain != 0 ? spl0 = left8Parametric.ProcessIIRFilter(spl0);

right1Gain != 0 ? spl1 = right1Parametric.ProcessIIRFilter(spl1); right2Gain != 0 ? spl1 = right2Parametric.ProcessIIRFilter(spl1); right3Gain != 0 ? spl1 = right3Parametric.ProcessIIRFilter(spl1); right4Gain != 0 ? spl1 = right4Parametric.ProcessIIRFilter(spl1); right5Gain != 0 ? spl1 = right5Parametric.ProcessIIRFilter(spl1); right6Gain != 0 ? spl1 = right6Parametric.ProcessIIRFilter(spl1); right7Gain != 0 ? spl1 = right7Parametric.ProcessIIRFilter(spl1); right8Gain != 0 ? spl1 = right8Parametric.ProcessIIRFilter(spl1);

//Delay mainDelay.ProcessDelay();

abdessalaam commented 8 months ago

Amazing, thank you. I have saved your example as a separate script (Pawel_EQ_LR.eel) and imported it — now just need to tweak it. It's so helpful :)

Switchleg1 commented 8 months ago

Glad to hear it! Set the all pass filters on both channels to 0 as well as the delays on both channels!

On Mon, Jan 8, 2024, 3:49 PM Pawel @.***> wrote:

Amazing, thank you. I have saved your example as a separate script (Pawel_EQ_LR.eel) and imported it — now just need to tweak it. It's so helpful :)

— Reply to this email directly, view it on GitHub https://github.com/ThePBone/RootlessJamesDSP/issues/187#issuecomment-1881944061, or unsubscribe https://github.com/notifications/unsubscribe-auth/AVIWVJ52A6V3SX72DIQLM5DYNRZXDAVCNFSM6AAAAAA7JMBFGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBRHE2DIMBWGE . You are receiving this because you authored the thread.Message ID: @.***>

abdessalaam commented 8 months ago

I did. Here is my script, in case it's helpful for anyone (and may I suggest that equalization / compensation for hearing loss is added to the app description in Play Store? I spent ages looking for one, and this one is just amazing!).

desc: Hearing Loss Compensation
//Get the values from your audiogram

//Swap channels
swapChannels:0<0,1,1>Swap Channels

//Pre gain
leftPreGain:0<-3,0,0.1>Left Pre Gain (db)
rightPreGain:0<-3,0,0.1>Right Pre Gain (db)

//Delay
leftDelay:0<0,3,0.1>Left Delay (ms)
rightDelay:0<0,3,0.1>Right Delay (ms)

//Allpass
leftAllPassFreq:0<0,7000,50>Left All Pass Freq
rightAllPassFreq:0<0,7000,50>Right All Pass Freq

//EQ
left1Freq:1000<10,15000,50>Left 1 Freq
left1Gain:0<-18,6,1>Left 1 Gain
left1Q:1<0.1,6,0.1>Left 1 Q

left2Freq:1000<10,15000,50>Left 2 Freq
left2Gain:0<-18,6,1>Left 2 Gain
left2Q:1<0.1,6,0.1>Left 2 Q

left3Freq:1000<10,15000,50>Left 3 Freq
left3Gain:0<-18,6,1>Left 3 Gain
left3Q:1<0.1,6,0.1>Left 3 Q

left4Freq:1000<10,15000,50>Left 4 Freq
left4Gain:0<-18,6,1>Left 4 Gain
left4Q:1<0.1,6,0.1>Left 4 Q

left5Freq:1000<10,15000,50>Left 5 Freq
left5Gain:0<-18,6,1>Left 5 Gain
left5Q:1<0.1,6,0.1>Left 5 Q

left6Freq:1000<10,15000,50>Left 6 Freq
left6Gain:0<-18,6,1>Left 6 Gain
left6Q:1<0.1,6,0.1>Left 6 Q

left7Freq:1000<10,15000,50>Left 7 Freq
left7Gain:0<-18,6,1>Left 7 Gain
left7Q:1<0.1,6,0.1>Left 7 Q

left8Freq:1000<10,15000,50>Left 8 Freq
left8Gain:0<-18,6,1>Left 8 Gain
left8Q:1<0.1,6,0.1>Left 8 Q

left9Freq:1000<10,15000,50>Left 9 Freq
left9Gain:0<-19,6,1>Left 9 Gain
left9Q:1<0.1,6,0.1>Left 9 Q

left10Freq:1000<10,15000,50>Left 10 Freq
left10Gain:0<-110,6,1>Left 10 Gain
left10Q:1<0.1,6,0.1>Left 10 Q

left11Freq:1100<11,15000,50>Left 11 Freq
left11Gain:0<-111,6,1>Left 11 Gain
left11Q:1<0.1,6,0.1>Left 11 Q

right1Freq:1000<10,15000,50>Right 1 Freq
right1Gain:0<-18,6,1>Right 1 Gain
right1Q:1<0.1,6,0.1>Right 1 Q

right2Freq:1000<10,15000,50>Right 2 Freq
right2Gain:0<-18,6,1>Right 2 Gain
right2Q:1<0.1,6,0.1>Right 2 Q

right3Freq:1000<10,15000,50>Right 3 Freq
right3Gain:0<-18,6,1>Right 3 Gain
right3Q:1<0.1,6,0.1>Right 3 Q

right4Freq:1000<10,15000,50>Right 4 Freq
right4Gain:0<-18,6,1>Right 4 Gain
right4Q:1<0.1,6,0.1>Right 4 Q

right5Freq:1000<10,15000,50>Right 5 Freq
right5Gain:0<-18,6,1>Right 5 Gain
right5Q:1<0.1,6,0.1>Right 5 Q

right6Freq:1000<10,15000,50>Right 6 Freq
right6Gain:0<-18,6,1>Right 6 Gain
right6Q:1<0.1,6,0.1>Right 6 Q

right7Freq:1000<10,15000,50>Right 7 Freq
right7Gain:0<-18,6,1>Right 7 Gain
right7Q:1<0.1,6,0.1>Right 7 Q

right8Freq:1000<10,15000,50>Right 8 Freq
right8Gain:0<-18,6,1>Right 8 Gain
right8Q:1<0.1,6,0.1>Right 8 Q

right9Freq:1000<10,15000,50>right 9 Freq
right9Gain:0<-19,6,1>right 9 Gain
right9Q:1<0.1,6,0.1>right 9 Q

right10Freq:1000<10,15000,50>right 10 Freq
right10Gain:0<-110,6,1>right 10 Gain
right10Q:1<0.1,6,0.1>right 10 Q

right11Freq:1100<11,15000,50>right 11 Freq
right11Gain:0<-111,6,1>right 11 Gain
right11Q:1<0.1,6,0.1>right 11 Q

@init
//Swap channels slider
swapChannels = 0;

//Pre gain sliders
leftPreGain  = -3.00;
rightPreGain = -3.00;

//Delay sliders
leftDelay  = 0.00;
rightDelay = 0.00;

//Allpass sliders
leftAllPassFreq  = 0;
rightAllPassFreq = 0;

//EQ sliders
left1Freq = 125;
left1Gain = 0;
left1Q    = 3.00;

left2Freq = 250;
left2Gain = 2.00;
left2Q    = 3.00;

left3Freq = 500;
left3Gain = 1.8;
left3Q    = 4.00;

left4Freq = 800;
left4Gain = 1.8;
left4Q    = 2.5;

left5Freq = 1000;
left5Gain = 1.8;
left5Q    = 2.5;

left6Freq = 1650;
left6Gain = 3.0;
left6Q    = 2.0;

left7Freq = 2000;
left7Gain = 4.0;
left7Q    = 2.0;

left8Freq = 3400;
left8Gain = 4.5;
left8Q    = 1.00;

left9Freq = 4000;
left9Gain = 6.0;
left9Q    = 1.00;

left10Freq = 6700;
left10Gain = 8.5;
left10Q    = 1.00;

left11Freq = 8000;
left11Gain = 8.5;
left11Q    = 1.00;

right1Freq = 125;
right1Gain = 0;
right1Q    = 3.00;

right2Freq = 250;
right2Gain = 1.5;
right2Q    = 3.00;

right3Freq = 500;
right3Gain = 1.00;
right3Q    = 4.00;

right4Freq = 800;
right4Gain = 0.8;
right4Q    = 2.5;

right5Freq = 1000;
right5Gain = 0.5;
right5Q    = 2.5;

right6Freq = 1650;
right6Gain = 0.4;
right6Q    = 2.0;

right7Freq = 2000;
right7Gain = 0;
right7Q    = 2.0;

right8Freq = 3400;
right8Gain = 1.5;
right8Q    = 1.00;

right9Freq = 4000;
right9Gain = 2.00;
right9Q    = 1.00;

right10Freq = 6700;
right10Gain = 4.00;
right10Q    = 1.00;

right11Freq = 8000;
right11Gain = 4.00;
right11Q    = 1.00;

//Delay functions
function BuildDelay(lDelay, rDelay)(
    this.leftDelayLen  = round(leftDelay * srate * 0.001) * 2;
    this.rightDelayLen = round(rightDelay * srate * 0.001) * 2;

    this.bPos = 0;
    this.bufSize = srate * 0.1;
);

function ProcessDelay()(
    this.bPos[0] = spl0;
    this.bPos[1] = spl1;

    leftPos  = this.bPos - this.leftDelayLen;
    rightPos = this.bPos - this.rightDelayLen;

    leftPos  < 0 ? leftPos += this.bufSize;
    rightPos < 0 ? rightPos += this.bufSize;

    spl0 = leftPos[0];
    spl1 = rightPos[1];

    this.bPos += 2;
    this.bPos >= this.bufSize ? this.bPos -= this.bufSize;
);

//DSP functions
function BuildAllpass(frequency)(
    omega     = tan($PI * (frequency / srate));

    this.in0  = 0;
    this.in1  = 0;
    this.out0 = 0;
    this.out1 = 0;

    this.a1   = (omega - 1) / (omega + 1);
    this.a2   = 0;
    this.b0   = this.a1;
    this.b1   = 1;
    this.b2   = 0;
);

function BuildParametric(frequency, gain, q)(
    omega = (2.f * $PI * frequency) / srate;
    sn    = sin(omega);
    cs    = cos(omega);
    alpha = sn / (2 * q);
    ax    = pow(10, gain / 40);
    a0    = 1 + (alpha / ax);

    this.in0  = 0;
    this.in1  = 0;
    this.out0 = 0;
    this.out1 = 0;

    this.a1   = -(2 * cs) / a0;
    this.a2   = (1 - (alpha / ax)) / a0;
    this.b1   = -(2 * cs);
    this.b0   = (1 + (alpha * ax));
    this.b2   = (1 - (alpha * ax));
);

function ProcessIIRFilter(inSample)(
    outSample = this.b0 * inSample + this.b1 * this.in0 + this.b2 * this.in1
- this.a1 * this.out0 - this.a2 * this.out1;
    this.in1  = this.in0;
    this.in0  = inSample;
    this.out1 = this.out0;
    this.out0 = outSample;

    outSample;
);

//Pre gain init
leftPreGainValue  = pow(10, leftPreGain  / 20);
rightPreGainValue = pow(10, rightPreGain / 20);

//Delay init
mainDelay.BuildDelay(leftDelay, rightDelay);

//All pass init
leftAllPassFreq > 20 ? leftAllpassFilter.BuildAllpass(leftAllPassFreq);
rightAllPassFreq > 20 ? rightAllpassFilter.BuildAllpass(rightAllPassFreq);

//EQ init
left1Gain != 0 ? left1Parametric.BuildParametric(left1Freq, left1Gain,
left1Q);
left2Gain != 0 ? left2Parametric.BuildParametric(left2Freq, left2Gain,
left2Q);
left3Gain != 0 ? left3Parametric.BuildParametric(left3Freq, left3Gain,
left3Q);
left4Gain != 0 ? left4Parametric.BuildParametric(left4Freq, left4Gain,
left4Q);
left5Gain != 0 ? left5Parametric.BuildParametric(left5Freq, left5Gain,
left5Q);
left6Gain != 0 ? left6Parametric.BuildParametric(left6Freq, left6Gain,
left6Q);
left7Gain != 0 ? left7Parametric.BuildParametric(left7Freq, left7Gain,
left7Q);
left8Gain != 0 ? left8Parametric.BuildParametric(left8Freq, left8Gain,
left8Q);
left9Gain != 0 ? left9Parametric.BuildParametric(left9Freq, left9Gain,
left9Q);
left10Gain != 0 ? left10Parametric.BuildParametric(left10Freq, left10Gain,
left10Q);
left11Gain != 0 ? left11Parametric.BuildParametric(left11Freq, left11Gain,
left11Q);

right1Gain != 0 ? right1Parametric.BuildParametric(right1Freq, right1Gain,
right1Q);
right2Gain != 0 ? right2Parametric.BuildParametric(right2Freq, right2Gain,
right2Q);
right3Gain != 0 ? right3Parametric.BuildParametric(right3Freq, right3Gain,
right3Q);
right4Gain != 0 ? right4Parametric.BuildParametric(right4Freq, right4Gain,
right4Q);
right5Gain != 0 ? right5Parametric.BuildParametric(right5Freq, right5Gain,
right5Q);
right6Gain != 0 ? right6Parametric.BuildParametric(right6Freq, right6Gain,
right6Q);
right7Gain != 0 ? right7Parametric.BuildParametric(right7Freq, right7Gain,
right7Q);
right8Gain != 0 ? right8Parametric.BuildParametric(right8Freq, right8Gain,
right8Q);
right9Gain != 0 ? right9Parametric.BuildParametric(right9Freq, right9Gain,
right9Q);
right10Gain != 0 ? right10Parametric.BuildParametric(right10Freq, right10Gain,
right10Q);
right11Gain != 0 ? right11Parametric.BuildParametric(right11Freq, right11Gain,
right11Q);

@sample
//Swap channels
swapChannels == 1 ? swapValue = spl0;
swapChannels == 1 ? spl0 = spl1;
swapChannels == 1 ? spl1 = swapValue;

//Pre gain
spl0 *= leftPreGainValue;
spl1 *= rightPreGainValue;

//Allpass
leftAllPassFreq  > 20 ? spl0 = leftAllpassFilter.ProcessIIRFilter(spl0);
rightAllPassFreq > 20 ? spl1 = rightAllpassFilter.ProcessIIRFilter(spl1);

//EQ
left1Gain != 0 ? spl0 = left1Parametric.ProcessIIRFilter(spl0);
left2Gain != 0 ? spl0 = left2Parametric.ProcessIIRFilter(spl0);
left3Gain != 0 ? spl0 = left3Parametric.ProcessIIRFilter(spl0);
left4Gain != 0 ? spl0 = left4Parametric.ProcessIIRFilter(spl0);
left5Gain != 0 ? spl0 = left5Parametric.ProcessIIRFilter(spl0);
left6Gain != 0 ? spl0 = left6Parametric.ProcessIIRFilter(spl0);
left7Gain != 0 ? spl0 = left7Parametric.ProcessIIRFilter(spl0);
left8Gain != 0 ? spl0 = left8Parametric.ProcessIIRFilter(spl0);
left9Gain != 0 ? spl0 = left9Parametric.ProcessIIRFilter(spl0);
left10Gain != 0 ? spl0 = left9Parametric.ProcessIIRFilter(spl0);
left11Gain != 0 ? spl0 = left9Parametric.ProcessIIRFilter(spl0);

right1Gain != 0 ? spl1 = right1Parametric.ProcessIIRFilter(spl1);
right2Gain != 0 ? spl1 = right2Parametric.ProcessIIRFilter(spl1);
right3Gain != 0 ? spl1 = right3Parametric.ProcessIIRFilter(spl1);
right4Gain != 0 ? spl1 = right4Parametric.ProcessIIRFilter(spl1);
right5Gain != 0 ? spl1 = right5Parametric.ProcessIIRFilter(spl1);
right6Gain != 0 ? spl1 = right6Parametric.ProcessIIRFilter(spl1);
right7Gain != 0 ? spl1 = right7Parametric.ProcessIIRFilter(spl1);
right8Gain != 0 ? spl1 = right8Parametric.ProcessIIRFilter(spl1);
right9Gain != 0 ? spl0 = right9Parametric.ProcessIIRFilter(spl0);
right10Gain != 0 ? spl0 = right9Parametric.ProcessIIRFilter(spl0);
right11Gain != 0 ? spl0 = right9Parametric.ProcessIIRFilter(spl0);

//Delay
mainDelay.ProcessDelay();
FlavioPonte commented 7 months ago

Hello... Very useful as I was looking for something like this. May I ask you what type of filter this uses, like peak filter, etc.

Switchleg1 commented 7 months ago

Hi FlavioPonte,

They are parametric biquad IIR filters.

On Sun, Jan 28, 2024 at 5:15 PM FlavioPonte @.***> wrote:

Hello... Very useful as I was looking for something like this. May I ask you what type of filter this uses, like peak filter, etc.

— Reply to this email directly, view it on GitHub https://github.com/ThePBone/RootlessJamesDSP/issues/187#issuecomment-1913775005, or unsubscribe https://github.com/notifications/unsubscribe-auth/AVIWVJ366I322JNTAEQBJTTYQ3S3JAVCNFSM6AAAAAA7JMBFGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJTG43TKMBQGU . You are receiving this because you authored the thread.Message ID: @.***>

FlavioPonte commented 7 months ago

Thank you for your work.