Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 05-05-2019, 02:23 PM   #41
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 1,906
Default

Ok, now I found it, strange, thought after reapack syncing, I should see it immediately in fx list, somehow it did not appear there, thought the other is the new one. After restarting Reaper, bobby could be found.


https://www.youtube.com/watch?v=TyllH-zkrho
TonE is offline   Reply With Quote
Old 05-05-2019, 03:23 PM   #42
Arthur McArthur
Human being with feelings
 
Join Date: Sep 2016
Location: Toronto
Posts: 482
Default

All of these plugins are top notch, Saike. I'm excited about the potential of Squashman. I think it's going to be killer on saturating the mids on 808s and bass while keeping the lows intact. Keep up the great work!
Arthur McArthur is offline   Reply With Quote
Old 05-06-2019, 02:44 AM   #43
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by TonE View Post
Ok, now I found it, strange, thought after reapack syncing, I should see it immediately in fx list, somehow it did not appear there, thought the other is the new one. After restarting Reaper, bobby could be found.
https://www.youtube.com/watch?v=TyllH-zkrho
Usually you still need to hit F5 on the plugin list to refresh it after syncing reapack

Quote:
Originally Posted by Arthur McArthur View Post
All of these plugins are top notch, Saike. I'm excited about the potential of Squashman. I think it's going to be killer on saturating the mids on 808s and bass while keeping the lows intact. Keep up the great work!
Ghehe thanks. And yeah, hopefully it should be pretty good at this once I'm done with it. I've written some python code that generates JSFX code for efficient halfband FIR anti-aliasing filters for various upsampling factors, but I've yet to unroll this into Squashman and the other plugs. First I want to do some thorough testing on it.

I am actually doubting whether to also include these higher quality anti-aliasing filters into Filther (as people might have gotten used to its very slightly muffled sound now, and might not like more transparent upsampling filters). Adding it as yet another option also sounds a bit meh as the UI is already super crowded. Maybe I could make the FIR button default to the high quality new ones, and outer mouse to get the old ones if someone really wants those.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-06-2019, 06:02 AM   #44
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,171
Default

Quote:
Originally Posted by sai'ke View Post
Usually you still need to hit F5 on the plugin list to refresh it after syncing reapack


Ghehe thanks. And yeah, hopefully it should be pretty good at this once I'm done with it. I've written some python code that generates JSFX code for efficient halfband FIR anti-aliasing filters for various upsampling factors, but I've yet to unroll this into Squashman and the other plugs. First I want to do some thorough testing on it.

I am actually doubting whether to also include these higher quality anti-aliasing filters into Filther (as people might have gotten used to its very slightly muffled sound now, and might not like more transparent upsampling filters). Adding it as yet another option also sounds a bit meh as the UI is already super crowded. Maybe I could make the FIR button default to the high quality new ones, and outer mouse to get the old ones if someone really wants those.
If its more efficient, Filther would of course profit by implementing it. I would suggest a FIR switch like yo mentioned. By the way: It seems you are the only one I know who calls the right mouse button the "outer mouse".

Squashman does already what I would expect from it. And I'm really surprised that no guitar freaks get into it because Squashman allows amazing distortion styles with nice slow transitions. Its also perfect for dirty drum loops of all kind. The way it gets grip is just stunning. And with the gain control there is nothing to be missed. Its kind of a three way distortion: 1. the drive/feed, 2. the wave shaper mod and 3. the gain control (okay, there is also frequency band etc. )

The Stereo Bub is also amazing. I tested it with drums and synths. It creates a very soft spreading which reminds me of cinematic soundscapes. Again a very useful and cool tool to play with. Bub means in German little boy. So its a nice name for a little tool.
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Old 05-07-2019, 02:04 AM   #45
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by Eliseat View Post
If its more efficient, Filther would of course profit by implementing it. I would suggest a FIR switch like yo mentioned. By the way: It seems you are the only one I know who calls the right mouse button the "outer mouse".
Really? Oh no. Now I wonder how many internet posts have my "signature" written all over them!

I think it's very slightly more CPU intensive, but the aliasing suppression is really quite a bit better so you might get away with lower oversampling rates which is then cheaper again.

Quote:
Originally Posted by Eliseat View Post
Squashman does already what I would expect from it. And I'm really surprised that no guitar freaks get into it because Squashman allows amazing distortion styles with nice slow transitions. Its also perfect for dirty drum loops of all kind. The way it gets grip is just stunning. And with the gain control there is nothing to be missed. Its kind of a three way distortion: 1. the drive/feed, 2. the wave shaper mod and 3. the gain control (okay, there is also frequency band etc. )
High quality oversampling coming up soon. I'm also considering stuff like per band widening, compression and manually triggered envelopes. I'm open to ideas by the way, but the tricky thing with this multiband setup is that whatever I do, is not allowed to distort the phases too much, otherwise the crossovers will not sum back together reliably (you'd get comb effects).

Quote:
Originally Posted by Eliseat View Post
The Stereo Bub is also amazing. I tested it with drums and synths. It creates a very soft spreading which reminds me of cinematic soundscapes. Again a very useful and cool tool to play with. Bub means in German little boy. So its a nice name for a little tool.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-07-2019, 09:42 AM   #46
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 7,151
Default

Sai'ke - what's tahn? Never seen this term outside of your plugins.
__________________
Myyy Wyyyrd Music
foxAsteria is offline   Reply With Quote
Old 05-07-2019, 09:51 AM   #47
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,171
Default

You mean tanh?

Only thing I know is tan as a mathematical function. I guess it has something to do with it. ~(˘▾˘~) But I have no idea. lol
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Old 05-07-2019, 09:53 AM   #48
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Hyperbolic tangent. The slightly uglier younger brother of the tan function.



Basically a smooth sigmoidal function that pops up in a lot of places in physics

It happens to be a pretty good approximation to the saturation behavior of an operational amplifier. Those things are everywhere in electronics.

It's pretty expensive though, so I use cheaper approximations where I can do so without sacrificing sound.

Since tan was mentioned, the hyperbolic trig functions are to x^2-y^2=1 what the regular trig functions are to x^2+y^2=1. Rather than describing things to do with circles, they describe things to do with hyperbola. They come up quite a bit considering they're the solution of some differential equations.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]

Last edited by sai'ke; 05-07-2019 at 10:22 AM. Reason: I should probably learn to use preview
sai'ke is offline   Reply With Quote
Old 05-07-2019, 02:25 PM   #49
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 1,906
Default

Quote:
Originally Posted by Arthur McArthur View Post
All of these plugins are top notch, Saike. I'm excited about the potential of Squashman. I think it's going to be killer on saturating the mids on 808s and bass while keeping the lows intact. Keep up the great work!
Did you check hackey trackey and patterns as well? They are magic, like saike and buzz.
TonE is offline   Reply With Quote
Old 05-07-2019, 02:27 PM   #50
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Added oversampling to the compressor. Only use it if you can really hear it, since it makes things a lot more expensive.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-07-2019, 03:09 PM   #51
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 7,151
Default

Quote:
Originally Posted by sai'ke View Post
Hyperbolic tangent. The slightly uglier younger brother of the tan function....
Ah yes...of course I have no idea what any of that means.... Man I remember when I used to think I was smart, haha.
__________________
Myyy Wyyyrd Music
foxAsteria is offline   Reply With Quote
Old 05-08-2019, 01:30 AM   #52
Sju
Human being with feelings
 
Join Date: Jun 2015
Posts: 686
Default

Thanks for implementing dry/wet per band!

Do you think it would be possible to have exclusive solo for bands?

Maybe it would even make sense to have that as the default action for right-click, and then shift+right-click bands if you want to solo several at the same time?
Sju is offline   Reply With Quote
Old 05-08-2019, 02:04 AM   #53
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by foxAsteria View Post
Ah yes...of course I have no idea what any of that means.... Man I remember when I used to think I was smart, haha.
Eh, it's probably my fault for not explaining it well. It's too easy to fall back on jargon .

Basically, it's just a function that smoothly maps values from the range -infinity to infinity to the range -1 to 1. It's both smooth and monotonic, which are two properties of curves that tend to lend themselves well to a soft pleasant sounding wave-shaper.

By smooth I mean that it is continuous, or that the derivatives (slopes) exist no matter where you compute them on the curve. For example, a square-wave is not smooth/continuous, since it's derivative is not defined on the place where it very suddenly transitions.

By monotonic I mean that the derivative never changes sign. So if you compute the slopes going from left to right, you never change whether you are going up or down (you always go up). A sine is for example smooth but not monotonic.

For reasons that get a little math-y, it just so happens that the input => output relation of many amplifiers can be described quite nicely by this function. People often like hearing what they are used to (I mean, music itself is at least partially "trained"), and all the years of exposure to audio amplified by such curves probably made us grow to like this type of soft distortion.

@Sju; Good idea. I will add such a mode.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-08-2019, 03:38 AM   #54
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,171
Default

Quote:
Originally Posted by sai'ke View Post
Added oversampling to the compressor. Only use it if you can really hear it, since it makes things a lot more expensive.
Great. In some situations its smoothing things a bit more. But oversampling does not work with the wet/dry adjustment because it creates a flange effect (very short delay).

I wonder if the tanh already gets used often because its really obvious that your saturation gets its grip in a smoother transition than most others plugins do. In fact that is in my opinion the biggest problem with usual distortion plugins because they often react different to hardware gear especially with the slow transition from softer distortions to the harder ones.
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Old 05-08-2019, 03:50 AM   #55
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by Eliseat View Post
Great. In some situations its smoothing things a bit more. But oversampling does not work with the wet/dry adjustment because it creates a flange effect (very short delay).

I wonder if the tanh already gets used often because its really obvious that your saturation gets its grip in a smoother transition than most others plugins do. In fact that is in my opinion the biggest problem with usual distortion plugins because they often react different to hardware gear especially with the slow transition from softer distortions to the harder ones.
Tanh is a relatively expensive operation. I guess fairly frequently people approximate the tanh with a cheaper alternative (in terms of CPU). So-called Padé approximations are pretty common (iterated fractions). Some people might also use a fraction of polynomials. In terms of "error" as quantified by squared distances, you can get pretty close with these, pretty fast.

In some cases, sticking in an approximation like that also lets you solve certain equations, rather than having to iterate over them. For filters this can really reduce the CPU cost by a lot and in a polyphonic synth, where you have filters running on a per voice basis, you often don't have a choice to do anything other than such approximations. Nobody wants a synth that eats 50% CPU

Another option that is frequently used are lookup tables, but then of course you have some rounding off to whatever entries you have in the lookup table going on. But what each plugin uses is guesswork. I'm happy you think it sounds nice, but I couldn't tell you what exactly it's doing differently.

Argh, good point regarding the comb filtering effect! It totally makes sense. With my sleepy head I forgot to do delay compensation for the FIR filter. @_@

I will fix this very soon and do a proper AB subtraction test with polarity inversion. Until then, keep oversampling off.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-08-2019, 06:22 AM   #56
nitsuj
Human being with feelings
 
nitsuj's Avatar
 
Join Date: Nov 2017
Posts: 164
Default

Quote:
Originally Posted by sai'ke View Post
Argh, good point regarding the comb filtering effect! It totally makes sense. With my sleepy head I forgot to do delay compensation for the FIR filter. @_@

I will fix this very soon and do a proper AB subtraction test with polarity inversion. Until then, keep oversampling off.
Heh, I just tried it out this morning and one of the first things I did was an inverse polarity test just to see how transparent you'd got it...and pretty much the whole spectrum came through!

Would be nice to know which FIR windowing algorithm you used and also the down/up sampling. Life was much easier with me with ReEQ because luckily there are no non-linearities and so zero padding was the way to go (and it was easier to optimise too).

BTW, I just had a look at your spectrum analyser too. Awesome! It's my go to now. I may deprecate/retire ReSpectrum and just focus on ReEQ.

Your compressor really is very nice indeed.
nitsuj is offline   Reply With Quote
Old 05-08-2019, 06:46 AM   #57
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

For 2X, I used the same Kaiser windowed sinc with the parameters as you did in ReEQ. The only difference is that I have to run the filter twice (once right after upsampling (which I just do by zero stuffing) and once before decimation). For the higher ones, I upped the number of taps to keep the transition band roughly the same.

Since most coefficients are zero, many can be skipped. In addition, the upsampling and post-upsampling filtering can be combined into a single step (polyphase FIR). I generate these polyphase filter functions from python from the same LPF kernel, immediately also omitting all the zeroes.

I'd be happy to share the python code as well once I get everything to properly null and pdc compensate. The kernel computation is pretty much a direct port from the site you referenced in ReEQ.

The spectrum analyzer, ghehe thanks. Yeah, I use it a lot, but uh, don't look at the code @_@. It started out as a quick hack of the stock one, and kind of grew out of control as I wanted more stuff. The code is a kind of embarrassing kludgy mess. I should really refactor this sometime when I find some time. It was my first foray into JSFX and it really shows

Edit: I should also still exploit the symmetry of those FIRs, which I don't yet.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]

Last edited by sai'ke; 05-08-2019 at 07:39 AM.
sai'ke is offline   Reply With Quote
Old 05-08-2019, 08:28 AM   #58
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,171
Default

Okay guys, it feels like I'm at an African market listening to people talking in Swahili. (・_・。)ゞ

It must be a good feeling to finally talk to someone who knows the same things.

But its very interesting.
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Old 05-08-2019, 09:09 AM   #59
nitsuj
Human being with feelings
 
nitsuj's Avatar
 
Join Date: Nov 2017
Posts: 164
Default

Quote:
Originally Posted by sai'ke View Post
The spectrum analyzer, ghehe thanks. Yeah, I use it a lot, but uh, don't look at the code @_@. It started out as a quick hack of the stock one, and kind of grew out of control as I wanted more stuff. The code is a kind of embarrassing kludgy mess. I should really refactor this sometime when I find some time. It was my first foray into JSFX and it really shows
I already looked at it (and the original) Don't sweat it though, you've got a good result. ReEQ was my first foray and I'm steadily tidying up and refactoring as I go.

Quote:
Originally Posted by sai'ke View Post

Edit: I should also still exploit the symmetry of those FIRs, which I don't yet.
Great! Would be a boon for Reaper JSFX devs to have a good reference source of oversampling.

If you look at the ReEQ oversampling include file you'll see that I managed to create further optimisations due to zero padding but I think that's because the zero padding only advanced the state of the filters and could be decimated. I managed to get rid of one buffer shuffle too as a result, instead doing it twice in one go.
nitsuj is offline   Reply With Quote
Old 05-08-2019, 12:47 PM   #60
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 7,151
Default

Quote:
Originally Posted by sai'ke View Post
Eh, it's probably my fault for not explaining it well. It's too easy to fall back on jargon .
Not at all, mate. It's my fault for assuming it was a simple question I could somehow understand with no background knowledge in any of that stuff.

Wish I had been more interested in math when I was in school! Thanks for humoring me.
__________________
Myyy Wyyyrd Music
foxAsteria is offline   Reply With Quote
Old 05-08-2019, 05:20 PM   #61
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 1,906
Default

Big respects to nitsuj and saike coding flow, flowing like this boomerang!


https://www.youtube.com/watch?v=zVtP39-XKsE
TonE is offline   Reply With Quote
Old 05-08-2019, 10:03 PM   #62
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 7,151
Default

Sai'ke I'm really loving this no-nonsense stereoizer. How did you make it so mono compatible? I set it up once and the same settings just keep working on anything for instant stereo yum.

Is there any chance the delay knob can avoid the clicking sound when using it? It would be fun to automate.

Mousewheel fine-control support would be handy too.
__________________
Myyy Wyyyrd Music
foxAsteria is offline   Reply With Quote
Old 05-09-2019, 02:50 AM   #63
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by foxAsteria View Post
Sai'ke I'm really loving this no-nonsense stereoizer. How did you make it so mono compatible? I set it up once and the same settings just keep working on anything for instant stereo yum.
Magic!
No, actually, the gist of it is that I add a signal to the left channel, and subtract exactly that signal from the right. Sum = 0.

You can see it nicely if you have a stereo spectral analyzer. Look at the result on the stereo spectrum analyzer (where you see left and right separate). You'll see notches on one where the other has peaks and vice versa

Quote:
Is there any chance the delay knob can avoid the clicking sound when using it? It would be fun to automate.
Probably. I only update stuff per block to save CPU, but the delay computations shouldn't be heavy so I could do them on a per sample basis. I will have a look at it, but then it probably starts sounding a bit like a phaser when you modulate it .

Quote:
Mousewheel fine-control support would be handy too.
Added to to-do list.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]

Last edited by sai'ke; 05-09-2019 at 05:31 AM.
sai'ke is offline   Reply With Quote
Old 05-09-2019, 02:56 AM   #64
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by nitsuj View Post
I already looked at it (and the original) Don't sweat it though, you've got a good result. ReEQ was my first foray and I'm steadily tidying up and refactoring as I go.
It's a lot cleaner than my first foray

Quote:
Originally Posted by nitsuj View Post
Great! Would be a boon for Reaper JSFX devs to have a good reference source of oversampling.

If you look at the ReEQ oversampling include file you'll see that I managed to create further optimisations due to zero padding but I think that's because the zero padding only advanced the state of the filters and could be decimated. I managed to get rid of one buffer shuffle too as a result, instead doing it twice in one go.
Actually, I've been using ReEq's firhalfband to check the code and coefficients that I generate. I will make sure to acknowledge it. It's nice to have a known-to-work reference

The polyphase one implicitly does advance history by two as it keeps a history 1/oversampling in size.

The symmetries I did not yet use though. I did add them yesterday, since they are still worth exploiting too.

I ran a few tests yesterday, but I don't fully null yet. I seem to be off by what seems to be half a sample from what I expect. I run the lowpass FIR twice, so I'd expect a ( 2 * (N-1)/2 ) / ratio delay.

I will have a closer look soon, but it was getting late yesterday and I had to go to bed, so I didn't push the new version yet
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]

Last edited by sai'ke; 05-09-2019 at 05:42 AM.
sai'ke is offline   Reply With Quote
Old 05-09-2019, 03:18 AM   #65
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

Quote:
I seem to be off by what seems by half a sample.
hahaaa-- it would seem similar to digging_half a hole?

you will get what you desire> with pure intentions.
as you guys create-- there are world records to be broken-try it--push yourselves constantly..please.


+not forgetting--the visible universe being magnetic in nature---but how does 1 achieve magnetism in a modern daw? easy. the hyperbolic shape actually defines the force vectors of magnet. (toroid being the inverse form)


so,like mac..he could not do this to begin,but with practice+persistance comes.....happiness? /successfull applications.

Bri1 is offline   Reply With Quote
Old 05-09-2019, 09:44 AM   #66
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 7,151
Default

Quote:
Originally Posted by sai'ke View Post
Magic!
I'm going with this explanation.
__________________
Myyy Wyyyrd Music
foxAsteria is offline   Reply With Quote
Old 05-09-2019, 02:14 PM   #67
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by foxAsteria View Post
I'm going with this explanation.
Works for me

I just pushed what I think fixed the oversampling for the compressor. Latency compensation should also be spot on now. I'll start building it into Squashman now as well.

In case anyone is interested in the code used to generate these filters:
Code:
# Code to generate JSFX code for upsampling and downsampling filters based on Kaiser windowed sinc anti-aliasing filters
# License: MIT
# Joep Vanlier 2019

import numpy as np
import matplotlib.pyplot as plt
import copy
from   scipy import signal as sig

# Generate anti aliasing filter
def genAAFilter(Att, M, factor):
    def Ino(x):
        # Zero order Bessel function
        d = 0
        ds = 1
        s = 1
        
        while(ds > s*1e-6):
            d += 2
            ds *= x*x/(d*d)
            s += ds
        
        return s;
    
    Fa = 0;
    Fb = 1 / (2*factor);
    
    Np = int((M-1)/2)
    A = np.zeros(M)
    A[0] = 2*(Fb-Fa);
    for j in range(1,Np+1):
        A[j] = (np.sin(2*j*np.pi*Fb)-np.sin(2*j*np.pi*Fa))/(j*np.pi);
    
    if (Att<21):
      Alpha = 0;
    elif (Att>50):
      Alpha = 0.1102*(Att-8.7);
    else:
      Alpha = 0.5842*Math.pow((Att-21), 0.4)+0.07886*(Att-21);
    
    # Window the ideal response with the Kaiser-Bessel window
    Inoalpha = Ino(Alpha);
    H = np.zeros(M)
    for j in range(Np+1):
      H[Np+j] = A[j]*Ino(Alpha*np.sqrt(1-(j*j/(Np*Np))))/Inoalpha;
    
    for j in range(Np+1):
      H[j] = H[M-1-j];
  
    return H  
    
def genFilterCode(H, idx, skipFactor):
    string = '';
    t = 0;
    
    # Find unique weights (there could be duplicates for symmetry reasons)
    # For the windowed sinc, (N-1)/2 duplicates actually.
    weightRefs = [];
    for i in range(len(H)):
        nidx = i;
        for j in range(i):
            if H[i] == H[j]:
                nidx = j;
                break;
        weightRefs.append(nidx)
    
    wHist = ['']*len(H);
    # Assign history to weight list
    for i in range(idx, len(H), skipFactor):
        # Loop over the history bit that is active for this polyphase filter
        # t holds the current history index, while i holds the current weight index
        
        # Look up the unique-ified weight for this
        wIdx = weightRefs[i]
        
        # Assign the history element to this list
        wHist[wIdx] = wHist[wIdx] + ' + h%d'%t
        
        t = t + 1;
        
    # Start printing code
    for i in range(len(H)):
        if np.abs(H[i]) > 1e-7:
            if len(wHist[i]) > 0:
                if H[i] > 0:
                    string = "%s + %s * (%s)" % (string, '{:.28f}'.format(H[i]), wHist[i][3:])
                    #string = "%s + w%d * (%s)" % (string, i, wHist[i][3:])
                else:
                    string = "%s - %s * (%s)" % (string, '{:.28f}'.format(abs(H[i])), wHist[i][3:])
                    #string = "%s - w%d * (%s)" % (string, i, wHist[i][3:])
    
    return string, t+1

def generateHeader(name, M, extra = ''):
    string = 'function %s\n' % name
    string = string + '  instance('
    for i in range(M):
        string = '%sh%d, ' % (string,i)
    string = string[0:-2];
    string = string + extra + ')\n  global()\n  local()\n';
        
    return string

def generateDownSampleFilter(name, M, factor, att):
    code = generateHeader(name, M)
    H = genAAFilter(att, M, factor);
    downSampleCode, maxHist = genFilterCode(H, 0, 1)
    code = code + '  (\n    ' + downSampleCode + '\n  );\n'
    
    return code, H, maxHist

def generateUpSampleFilter(name, M, factor, att):
    H = genAAFilter(att, M, factor);
    code = generateHeader(name, M, ", idx ")
    code = '%s  (\n    idx += 1;\n    ( idx == 0 ) ? (\n' % (code)
    
    for j in range(factor):
        upSampleCode, maxHist = genFilterCode(H, j, factor)
        if j < (factor-1):
            ifs =  ' : ( idx == %d ) ? (' % (j + 1)
        else:
            ifs = '';
        code = '%s      %s\n    )%s\n' % (code, upSampleCode, ifs)
    
    code = code + '  );';
                
    return code, H, maxHist

def generateInitializer(name, M):
    code = generateHeader(name, M)
    code = '%s  (\n     '%code
    
    for i in range(M):
        code = '%sh%d = ' % (code,i)
    
    code = '%s0\n  );' % code;
    
    return code;
    
def generateHistoryUpdater(name, M):
    code = generateHeader(name, M, ', idx')
    code = '%s  (\n'%code
    
    for i in range(1,M):
        code = '%s     h%d = h%d;\n' % (code,M-i,M-i-1)
    
    code = '%s\n     h0 = x;\n     idx = -1;\n  );' % code;
    
    return code;

# Attenuation in dB
Att = 96
    
fid  = open('saike_upsamplers.jsfx-inc', 'w') 

# Filter lengths for different oversampling ratios
lens = [65, 97, 129, 161, 193, 225, 257];

# Print out delays, make sure that these aren't fractional.
print( (.5*(np.array(lens)-1)+.5*(np.array(lens)-1))/np.array([2,3,4,5,6,7,8]) )

fid.write('@init\n')
j = 0;
upList = [];

# Compute oversampling kernels from x2 to x8
for factor in np.arange(2,9):
    downCode, H, maxHistDown = generateDownSampleFilter( 'downSample%d()'%factor, lens[j], factor, 96 )
    upCode, H, maxHistUp = generateUpSampleFilter( 'upSample%d()'%factor, lens[j], factor, 96 )
    
    upList.append(maxHistUp);
    
    fid.write(generateInitializer('init_upSampler%d()'%factor, lens[j]));
    fid.write('\n\n')
    
    fid.write(generateHistoryUpdater('update_upHist%d(x)'%factor, maxHistUp));
    fid.write('\n\n')
    
    fid.write(generateHistoryUpdater('update_downHist%d(x)'%factor, maxHistDown));
    fid.write('\n\n')
    
    fid.write(downCode)
    fid.write('\n\n')
    fid.write(upCode)
    fid.write('\n\n')
    j = j + 1;
        
fid.write('function upSample(N)\n')
fid.write('  instance()\n')
fid.write('  global()\n')
fid.write('  local()\n')
fid.write('(')
fid.write('	(N==2) ? this.upSample2()\n')
for factor in np.arange(3,9):
    fid.write('	: (N==%d) ? this.upSample%d()\n'%(factor,factor))
fid.write(');\n\n')
fid.write('function downSample(N)\n')
fid.write('  instance()\n')
fid.write('  global()\n')
fid.write('  local()\n')
fid.write('(\n')
fid.write('	(N==2) ? this.downSample2()\n')
for factor in np.arange(3,9):
    fid.write('	: (N==%d) ? this.downSample%d()\n'%(factor,factor))
fid.write(');\n\n')
fid.write('function updateDownHist(N, x)\n')
fid.write('  instance()\n')
fid.write('  global()\n')
fid.write('  local()\n')
fid.write('(\n')
fid.write('	(N==2) ? this.update_downHist2(x)\n')
for factor in np.arange(3,9):
    fid.write('	: (N==%d) ? this.update_downHist%d(x)\n'%(factor,factor))
fid.write(');\n\n')
fid.write('function updateUpHist(N, x)\n')
fid.write('  instance()\n')
fid.write('  global()\n')
fid.write('  local()\n')
fid.write('(\n')
fid.write('	(N==2) ? this.update_upHist2(x)\n')
for factor in np.arange(3,9):
    fid.write('	: (N==%d) ? this.update_upHist%d(x)\n'%(factor,factor))
fid.write(');\n\n')

fid.write('function getFIRdelay(N)\n')
fid.write('  instance()\n')
fid.write('  global()\n')
fid.write('  local()\n')
fid.write('(\n')
fid.write('    (N==1) ? 0\n');
for j in range(len(upList)):
    fid.write('	: (N==%d) ? %d\n'%(j+2,(upList[j]-1)))
fid.write(');\n\n') 
    
    
fid.close()
And to plot them:
Code:
import numpy as np
import matplotlib.pyplot as plt
import copy
from   scipy import signal as sig

# Verify transfer func spectrum
H2 = genAAFilter(96, 65, 2)
plt.subplot(2,1,1);
plt.plot(H)
plt.subplot(2,1,2);
w, h = sig.freqz(H2,1,1000)
plt.plot(w*2,np.log10(np.abs(h)))
To run it you need Python 3, numpy, scipy, and matplotlib. I'd recommend anaconda

Special thanks to nitsuj, because it was really nice having ReEq as reference for the x2 case and to check the optimizations
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]

Last edited by sai'ke; 05-09-2019 at 02:39 PM. Reason: added dependencies
sai'ke is offline   Reply With Quote
Old 05-09-2019, 03:29 PM   #68
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

Quote:
Latency compensation should also be spot on now. I'll start building it into Squashman now as well.




Special thanks to nitsuj, because it was really nice having ReEq as reference for the x2 case and to check the optimizations
niiice.squashman is probably gonna be a fav as well ..tempted to try,but am holding back until....... da magic
the thing with attention is it can be anywhere,any moment,in any shape or form.. but when 1 stays focused,with focused intentions..well...the cosmos opens up a little more ! lol.
good stuff-learning from others is no universal crime+ it's how we have expanded over the imaginary timeline/s of thought.
as we learn,we grow,as we grow we learn to show..the flow,of the go =momento + tempo.
Bri1 is offline   Reply With Quote
Old 05-09-2019, 04:20 PM   #69
nitsuj
Human being with feelings
 
nitsuj's Avatar
 
Join Date: Nov 2017
Posts: 164
Default

Quote:
Originally Posted by sai'ke View Post
Special thanks to nitsuj, because it was really nice having ReEq as reference for the x2 case and to check the optimizations
Glad it helped!

I've just tried your Tight Compressor with the PDC calc update. Works a treat. Some observations:

To test A/B invert polarity I put the compressor at 0dB threshold. I had SPAN on the master track with the maximum range of -140dB. On my test material I noticed a few low frequency bumps beyond -132dB and some high frequency signal at around 18kHz but pushed down past -96dB.

There's no way that's audible so I'd say it's a pretty clean result. Why do you think there's that slight difference though?

I tried Pro-C2 to see what that did. To my surprise, with threshold set to 0dB it did not null at all, pretty much all the spectrum was present in the difference leading me to believe that some phase issue was at play. However, I then changed Pro-C2's ratio to 1:1 and it gave a perfect null. I'm guessing that they look for a ratio of 1:1 and pretty much bypass.

Reacomp behaves the way you'd expect. If threshold is 0dB and/or ratio is 1:1 then you can bypass any signal processing. Something to bear in mind?
nitsuj is offline   Reply With Quote
Old 05-10-2019, 05:26 AM   #70
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
There's no way that's audible so I'd say it's a pretty clean result. Why do you think there's that slight difference though?
Good question. All I tested was tight vs tight (with and without oversampling). But I only looked up to a floor of -96.

I could try and bump the number of decimals I output for the coefficients. Maybe it's a round-off issue? I kind of doubt it though.

The way I understand it, it could just be some remnants of the copies that arise after oversampling? I mean, the brick wall gives me -96 dB in the stopband, but it's no ideal brick wall filter. I'm actually not sure if perfect reconstruction is an attainable goal?

As for the higher frequencies you observed, those might've already been edging slightly into the transition band.

Quote:
I tried Pro-C2 to see what that did. To my surprise, with threshold set to 0dB it did not null at all, pretty much all the spectrum was present in the difference leading me to believe that some phase issue was at play. However, I then changed Pro-C2's ratio to 1:1 and it gave a perfect null. I'm guessing that they look for a ratio of 1:1 and pretty much bypass.
Wait, I don't understand exactly what you did here. Pro-C2 vs Pro-C2?
Pro-C2 didn't null because it didn't pdc compensate? Or it compensated despite no processing happening?

Quote:
Reacomp behaves the way you'd expect. If threshold is 0dB and/or ratio is 1:1 then you can bypass any signal processing. Something to bear in mind?
Reacomp with oversampling? Is the oversampling working now? I remember seeing a video from Dan Worrall where the AA was doing some weird stuff. I guess it's fixed now?

I guess I could make a check for that, but it makes not so much sense to even have a compressor on the signal chain if it's at 0 dB or 1:1. I'd rather avoid a condition for this, since it makes testing the plugin less transparent. Or maybe I'm misinterpreting the suggestion

Edit: P.S. I just wanted to say I really appreciate you taking the time to take it through its paces. I think more eyes on this thing is really beneficial for the quality of the final result
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]

Last edited by sai'ke; 05-10-2019 at 05:50 AM.
sai'ke is offline   Reply With Quote
Old 05-10-2019, 10:21 AM   #71
dupont
Human being with feelings
 
dupont's Avatar
 
Join Date: Nov 2007
Location: France
Posts: 635
Default

stereoizer : if crossover is > 1khz, it is no more possible to adjust delay.
dupont is offline   Reply With Quote
Old 05-10-2019, 03:22 PM   #72
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by dupont View Post
stereoizer : if crossover is > 1khz, it is no more possible to adjust delay.
Should be fixed now. It was still updating the audio, just not the printed value on the knob

Also added your request Fox. It should now smoothly interpolate and shouldn't click anymore when changing the delay dial. I also added scroll wheel support (but scroll wheel + modifier isn't supported in JSFX at all it seems).
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-10-2019, 03:40 PM   #73
nitsuj
Human being with feelings
 
nitsuj's Avatar
 
Join Date: Nov 2017
Posts: 164
Default

Quote:
Originally Posted by sai'ke View Post
Good question. All I tested was tight vs tight (with and without oversampling). But I only looked up to a floor of -96.
That's cool. The test I did was against a signal without the compressor present and a signal processed by the compressor but with 0dB threshold. That should test only the oversampling.

Quote:
Originally Posted by sai'ke View Post
The way I understand it, it could just be some remnants of the copies that arise after oversampling? I mean, the brick wall gives me -96 dB in the stopband, but it's no ideal brick wall filter. I'm actually not sure if perfect reconstruction is an attainable goal?
I know it's a little different but ReEQ's oversampling nulls out in this regard. But I'm decimating. That's what I aimed for because Ableton's EQ8 nulls too and that was the benchmark.


Quote:
Originally Posted by sai'ke View Post
Wait, I don't understand exactly what you did here. Pro-C2 vs Pro-C2?
Pro-C2 didn't null because it didn't pdc compensate? Or it compensated despite no processing happening?
Pro-C2 against a track without it on. Not sure what the reason for the result was, could well be a change in amplitude...who knows.

Quote:
Originally Posted by sai'ke View Post
Reacomp with oversampling? Is the oversampling working now? I remember seeing a video from Dan Worrall where the AA was doing some weird stuff. I guess it's fixed now?
No, AA in Reacomp was badly broken so they just removed it. I was referring to the behaviour with 0dB threshold or 1:1 ratio.

Quote:
Originally Posted by sai'ke View Post
I guess I could make a check for that, but it makes not so much sense to even have a compressor on the signal chain if it's at 0 dB or 1:1. I'd rather avoid a condition for this, since it makes testing the plugin less transparent. Or maybe I'm misinterpreting the suggestion
I totally agree. If you had done this I'd have found myself looking through the code to disable it so I could do the tests.

Quote:
Originally Posted by sai'ke View Post
Edit: P.S. I just wanted to say I really appreciate you taking the time to take it through its paces. I think more eyes on this thing is really beneficial for the quality of the final result
You're welcome. It would be good to get a real compressor aficionado giving an opinion. I think it's a great compressor. A real candidate for go-to. What else does it need? Maybe a filtered side chain? Lookahead? But really, you've done the hard work.

What further plans do you have for it or are you just using it as a testing ground for Squashman?
nitsuj is offline   Reply With Quote
Old 05-10-2019, 04:47 PM   #74
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by vdubreeze View Post
Seeing that you're pulling some parts of Filther and giving them their own focused plugin (a great idea), allow me to ask if you'd consider doing a similar dedicated wah js with the terrific wah filters you have. I can't seem to get them to do exactly what I want within Filther so having a wah plugin where the parameters go from only a little further than one end of a normal wah parameter to just a little past it on the other end (rather than from deep earthquaking lava pit insanity to outer space war meteors with a wah in there somewhere in the middle ) I would love it !
I've added a standalone version of the wahs. You need both the wah and the compressor installed for it to work (it has an oversampling dependency that overlaps with the compressor).
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-10-2019, 05:37 PM   #75
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 665
Default

Quote:
Originally Posted by nitsuj View Post
That's cool. The test I did was against a signal without the compressor present and a signal processed by the compressor but with 0dB threshold. That should test only the oversampling.

I know it's a little different but ReEQ's oversampling nulls out in this regard. But I'm decimating. That's what I aimed for because Ableton's EQ8 nulls too and that was the benchmark.
Yeah. If I decimate with these same kernels, like so:

Code:
  downR.updateDownHist(overSampling, inR);
  downL.updateDownHist(overSampling, inL);
  
  spl0 = 2*downL.downSample(overSampling);
  spl1 = 2*downR.downSample(overSampling);
  
  downR.updateDownHist(overSampling, 0);
  downL.updateDownHist(overSampling, 0);
I also null exactly. If I run that same thing twice (so no poly-phase), I already get that very low signal level stuff. I think it's just because of the interpolation. But considering that I'm doing non-linear stuff, I do really need those interpolated samples.

Quote:
Pro-C2 against a track without it on. Not sure what the reason for the result was, could well be a change in amplitude...who knows.
Yeah, strange

Quote:
No, AA in Reacomp was badly broken so they just removed it. I was referring to the behaviour with 0dB threshold or 1:1 ratio.
Heh, well that's one way to solve it
To be honest, I really have to strain to hear a difference between 1x and 2x on most drum material. Only on relatively high pitched leads can I tell the difference.

Quote:
You're welcome. It would be good to get a real compressor aficionado giving an opinion. I think it's a great compressor. A real candidate for go-to. What else does it need? Maybe a filtered side chain? Lookahead? But really, you've done the hard work.

What further plans do you have for it or are you just using it as a testing ground for Squashman?
Filtered side chain would be nice I suppose. I wonder if not oversampling the side chain would be audible.

I'm not super happy with how much space the sliders are already taking though. I could remove the scrolling feature and have it toggle via double click on the graphical part or something. And I'm not sure whether anyone uses the "harsher" mode for instance.

I mean, I was considering implementing the same knobs as Squashman to sort of make this thing more graphical and less slider-y, but I'm not sure if that'd add that much. The nice thing about the sliders is that you can really enter values and that they are pretty easy to use. I honestly find them easier to use than knobs in most cases.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [Filther: Thread|Github|Reapack] | [More JSFX: Thread|Reapack]
sai'ke is offline   Reply With Quote
Old 05-11-2019, 02:30 AM   #76
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 5,476
Default

Very nice Tight Compressor. I don't mind the sliders. It could have its own thread
heda is offline   Reply With Quote
Old 05-11-2019, 09:18 AM   #77
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 1,442
Default

Tried 'Saike Tight Compressor' on bass guitar track, very impressive! Also like meters/graphs that display whats happening, very nice. Keep up the good work!
Edgemeal is offline   Reply With Quote
Old 05-11-2019, 09:57 AM   #78
sinkmusic
Human being with feelings
 
sinkmusic's Avatar
 
Join Date: Feb 2006
Location: decepticon mothership in a hidden place inside a mountain
Posts: 3,359
Default

I tried the Tight Compressor, and enjoyed it a lot on some drum tracks : thank you so much for your plugins !
I also like the very clever way to use JS graphic features
sinkmusic is online now   Reply With Quote
Old 05-11-2019, 10:39 AM   #79
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 1,906
Default

What about a new type of spectral analyzer, specialized for human voice in the range 32..4096 Hz?

See explanation with images: https://github.com/michaelsjackson/r...orums/issues/2
TonE is offline   Reply With Quote
Old 05-11-2019, 12:20 PM   #80
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,171
Default

Quote:
Originally Posted by sai'ke View Post
I've added a standalone version of the wahs. You need both the wah and the compressor installed for it to work (it has an oversampling dependency that overlaps with the compressor).
Lovely.

Only thing I found so far is that some changes create crackles. Have to take a closer look.

Many thanks, Sai'ke. (๑•̀ㅂ•́)و✧ Yeah!
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 04:51 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.