-
-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Per channel EQ and time alignment #187
Comments
I would love separate L-R EQ (though for hearing loss compensation rather than in car listening). |
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
- 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);
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();
|
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 :) |
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
<#187 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AVIWVJ52A6V3SX72DIQLM5DYNRZXDAVCNFSM6AAAAAA7JMBFGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBRHE2DIMBWGE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
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!).
|
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. |
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
<#187 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AVIWVJ366I322JNTAEQBJTTYQ3S3JAVCNFSM6AAAAAA7JMBFGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJTG43TKMBQGU>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Thank you for your work. |
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;
The text was updated successfully, but these errors were encountered: