|
|
|
11-06-2018, 07:06 AM
|
#1
|
Human being with feelings
Join Date: Oct 2018
Posts: 4
|
JSFX Plugin Creation (Help): Low Pass Filter
Hi there, I'm fairly new to the forum and am currently in the midst of preparing a jsfx plugin for a module that I am studying. I've never had any experience with creating a plugin or coding in general and I'm still a little confused at what each line of code does and I would like to seek some assistance in working this out.
From what I understand at the @init section, that is where we set up our variables for the plugin and @sample is where the input samples are then calculated and looped. spl0 and spl1 are the left and right channel outputs respectively. (But please correct me if I'm wrong cause I still feel like I'm missing a lot of stuff)
So far, I have come up with this code:
desc: First order low-pass filter
slider1:0<-120,6,0.1>Input gain
@init
bpos=0;
ip0=0; // initialise our variables to 0, so they are ready to use first time around the sample loop
ip1=0;
prev0=0;
prev1=0;
@slider
@block
@sample
ip0 = (10^(slider1/20))*spl0; // use slider position (dB scale) to control input level
ip1 = (10^(slider1/20))*spl1;
spl0=0.5*(ip0+prev0); // first-order low pass filter equation, add current sample to previous
spl1=0.5*(ip1+prev1);
prev0 = ip0; // store current sample so that next time around the loop it is available us as the previous sample
prev1 = ip1;
After the tutorial session with my lecturer I have a better understanding of how the code works but I was then given an exercise to progress with this.
I am supposed to implement this equation into the code:
Output[n] = (input[n]+input[n-1]+input[n-2])/3
Do I insert its as:
spl0 = (0.5*(ip0+prev0)+0.5((ip0+prev0-1)+0.5*(ip0+prev0-2))/3
I'm sure I'm doing something wrong but any piece of advice would be great. Thanks again
|
|
|
11-06-2018, 09:33 AM
|
#2
|
Human being with feelings
Join Date: May 2014
Location: Germany
Posts: 643
|
Quote:
Originally Posted by Revoan
Output[n] = (input[n]+input[n-1]+input[n-2])/3
Do I insert its as:
spl0 = (0.5*(ip0+prev0)+0.5((ip0+prev0-1)+0.5*(ip0+prev0-2))/3
|
No, this will not work. "prev0-1" simply subtracts 1 from prev0.
Have a look. Maybe it helps:
Code:
@init
bpos=0;
ip0=0; // initialise our variables to 0, so they are ready to use first time around the sample loop
ip1=0;
prev0_1=0; // Init n-1
prev1_1=0;
prev0_2=0; // Init n-2
prev1_2=0;
@slider
@block
@sample
ip0 = (10^(slider1/20))*spl0; // use slider position (dB scale) to control input level
ip1 = (10^(slider1/20))*spl1;
spl0=1/3*(ip0+prev0_l+prev0_2); // use of n, n-1 and n-2
spl1=1/3*(ip1+prev0_l+prev1_l);
prev0_2=prev0_l; // store n - 2
prev1_2=prev1_2;
prev0_l = ip0; // store n - 1
prev1_l = ip1;
Please note that the first and second call to function "sample" work with null pre filled data. The 3rd call and onwards uses data from spl.
Last edited by TBProAudio; 11-06-2018 at 09:39 AM.
|
|
|
11-06-2018, 10:40 AM
|
#3
|
Human being with feelings
Join Date: Jun 2017
Posts: 412
|
Also you are making a moving average filter so that's the reason you use the 0.5 in the first example - you are taking the average of two values. But in the second new version you are taking the average over 3 values so you use the 1/3, but you don't need the 0.5 multiplier anymore
|
|
|
11-06-2018, 10:48 AM
|
#4
|
Human being with feelings
Join Date: May 2014
Location: Germany
Posts: 643
|
Quote:
Originally Posted by Eddy
Also you are making a moving average filter so that's the reason you use the 0.5 in the first example - you are taking the average of two values. But in the second new version you are taking the average over 3 values so you use the 1/3, but you don't need the 0.5 multiplier anymore
|
Thanks for pointing this out. I missed this, sorry :-(
|
|
|
11-07-2018, 10:29 AM
|
#5
|
Human being with feelings
Join Date: Oct 2018
Posts: 4
|
Hi TBProAudio,
Thank you for your help. Its much appreciated. And yes, the code version you provided makes a little bit more sense than what I tried to attempt. However, after entering your code, the plugin works but I would like to take it a step further. So I looked at the default JSFX lowpass filter plugin included in reaper and was wondering if anyone could explain to me why the code is written in such a way? I understand that at the slider 1 and slider 2 options are for us to determine what the slider does in the plugin.
Code:
// This effect Copyright (C) 2004 and later Cockos Incorporated
// License: GPL - http://www.gnu.org/licenses/gpl.html
//
//Addl. Modification by Levi Wilbert
desc: low pass filter
slider1:8<0,10>frequency (Exp(0=20Hz, 10=20480Hz))
slider2:0.2<0,1>size (0=sharp, 1=dull)
@slider
damp=0.01+slider2*20;
c = 1/tan($pi*(20*pow(2, slider1))/srate);
fk = 1 / (1 + c*(c+damp));
fa1 = 2 * (1 - c*c) * fk;
fa0 = (1 + c*(c-damp)) * fk;
//damp!=oldamp ? fd1l=fd2l=fd1r=fd2r=0;
oldamp=damp;
@sample
fd0l = (fk*spl0) - (fa1*fd1l) - (fa0*fd2l);
fd0r = (fk*spl1) - (fa1*fd1r) - (fa0*fd2r);
spl0 = fd0l + fd1l + fd1l + fd2l;
spl1 = fd0r + fd1r + fd1r + fd2r;
fd2l = fd1l;
fd2r = fd1r;
fd1l = fd0l;
fd1r = fd0r;
*edited to insert code straight into the post*
Especially for what happens at:
@slider - I am still unclear as to how the equation works. Is this the standard equation one would use to create commands for a low pass filter? I don't quite understand what damp does but I'm guessing its related to slider 2.
@sample - Please do correct me if I'm wrong but from what I can observe and understand, the variables we set up in the slider section is then implemented into an equation in this section to create the low pass filter effect?
I understand I'm probably asking a lot of basic questions but I'm still trying to wrap my head around this jsfx coding. Thanks again
|
|
|
11-07-2018, 10:50 AM
|
#6
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
I don't understand that equation well enough to explain it to you. It is apparently what you need to do to generate coefficients that will make the type of filter that's implemented here. There are other filter types which can be much different.
I CAN tell you, though, that those coefficients never change unless you move a slider, and only need to be calculated when they change, so doing it for every sample we process is wasting CPU ticks. That's why they put that part in @sample. In your code, you should do the same with the db > ratio calculation (10^(slider1/20)). Store it in a variable in the @slider section and use that in @sample.
|
|
|
11-07-2018, 11:34 AM
|
#7
|
Human being with feelings
Join Date: Oct 2018
Posts: 4
|
Quote:
Originally Posted by ashcat_lt
I don't understand that equation well enough to explain it to you. It is apparently what you need to do to generate coefficients that will make the type of filter that's implemented here. There are other filter types which can be much different.
I CAN tell you, though, that those coefficients never change unless you move a slider, and only need to be calculated when they change, so doing it for every sample we process is wasting CPU ticks. That's why they put that part in @sample. In your code, you should do the same with the db > ratio calculation (10^(slider1/20)). Store it in a variable in the @slider section and use that in @sample.
|
Hi ashcat_lt,
Did you mean something like this?
Code:
@init
bpos=0;
ip0=0; // initialise our variables to 0, so they are ready to use first time around the sample loop
ip1=0;
prev0_1=0; // Init n-1
prev1_1=0;
prev0_2=0; // Init n-2
prev1_2=0;
@slider
ip0 = (10^(slider1/20))*spl0; // use slider position (dB scale) to control input level
ip1 = (10^(slider1/20))*spl1;
@block
@sample
spl0=1/3*(ip0+prev0_l+prev0_2); // use of n, n-1 and n-2
spl1=1/3*(ip1+prev0_l+prev1_l);
prev0_2=prev0_l; // store n - 2
prev1_2=prev1_2;
prev0_l = ip0; // store n - 1
prev1_l = ip1;
|
|
|
11-07-2018, 12:39 PM
|
#8
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
No.
First off you're eventually going to have to actually define slider1, but...
@slider
gain = 10^(slider1/20);
@sample
ip0 = gain * spl0;
ip1 = gain * spl1;
...
|
|
|
11-09-2018, 05:01 AM
|
#9
|
Human being with feelings
Join Date: Oct 2018
Posts: 4
|
Okay, so I've had some time to finally get back to work on the plugin again. With the current code, I've done some tests in Reaper using whitenoise and notice that theres actually a dip in the frequencies above 15kHz when turning the plugin on.
https://imgur.com/RYij8OO (Plugin off)
https://imgur.com/gO7ATcb (Plugin On)
So I guess one could say that the plugin is working? I'd like to add another slider to somehow control the frequency cut off, probably say from 4000Hz and above but I'm not sure how to go about that.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 03:59 PM.
|