


03262020, 04:38 AM

#1

Human being with feelings
Join Date: Sep 2013
Posts: 72

New Free Plugin Alert! ClassicChannel & ClassicBus
Hello good people! I'm constantly working on new projects as quarantine goes on. Here are two new toys for you.
https://www.patreon.com/posts/35284587
ClassicChannel
A tool meant to warm up your digital tracks. No global link this time, but slightly different coloration for each instance is mantained. Features pre/post emphasis and uses slightly more cpu than previous plugins. Use it on every track for cumulative effect, or just where needed. No particular indications here.
ClassicBus
A derivation of ClassicChannel with less coloration and harmonics, but with same character. Use it on busses or directly on your mixbuss for heavy coloration.
Suggested use:
ClassicChannel on every track as first insert; ClassicBus on every bus followed by ClassicChannel; ClassicBus on MixBus as first insert. This will seriously warm up your mix.
Warning: Use the trim input wisely unless you want a distorted mess.
Enjoy!



03272020, 02:25 AM

#2

Human being with feelings
Join Date: Dec 2007
Location: Germany
Posts: 246

Thanks a lot, for your time and effort!
Will try out as soon as possible.
BR,
HoJo



03272020, 04:42 AM

#3

Human being with feelings
Join Date: Oct 2013
Location: Seattle, WA
Posts: 806

In ClassicChannel (classic based on...?) why multiply atan by 0.14? This limits the amplitude to +/ 0.2 or so, right? So basically a really hard clip above 14 dB? This doesnt seem like something a console channel would ever do.
I would like to suggest a more generalized function:
spl0 = atan(a*spl0+0.001)*b;
where b is 1/a and a is between 0 and maybe 3, with lower numbers being less linear?
Graph it, you'll see what I mean.
Something similar can be done with the ClassicBus function, perhaps
spl0 = atan(a*spl0/(a+abs(spl0))+0.0001);
although I vastly prefer the first as it avoids the division and an abs() call.
A suggestion? Instead of making it completely a different random call every time you press play, perhaps have a knob that allows some degree of user control. Maybe even vary the parameters of the plugin over time?



03272020, 05:13 AM

#4

Human being with feelings
Join Date: Sep 2013
Posts: 72

Quote:
Originally Posted by SaulT
In ClassicChannel (classic based on...?) why multiply atan by 0.14? This limits the amplitude to +/ 0.2 or so, right? So basically a really hard clip above 14 dB? This doesnt seem like something a console channel would ever do.
I would like to suggest a more generalized function:
spl0 = atan(a*spl0+0.001)*b;
where b is 1/a and a is between 0 and maybe 3, with lower numbers being less linear?
Graph it, you'll see what I mean.
Something similar can be done with the ClassicBus function, perhaps
spl0 = atan(a*spl0/(a+abs(spl0))+0.0001);
although I vastly prefer the first as it avoids the division and an abs() call.

Hello SaulT. For me classic sound is the NEVE sound. Now, this plugin only draws inspiration from neve sound. It's far from it.
This plugin is calibrated to 18dbFS input. My goal is to get a fair amount of harmonics at that input level. So i need to multiply the signal in the atan function to get harmonics and subsequently divide it to gain match the input. Try removing the 0.14. It's gonna get loud!
Quote:
A suggestion? Instead of making it completely a different random call every time you press play, perhaps have a knob that allows some degree of user control. Maybe even vary the parameters of the plugin over time?

Thanks for pointing that out as i now discovered the ext_noinit parameter which avoids a call on every play.
I'm gonna fix this asap.
http://reaper.fm/sdk/js/js.php#sec_init



03272020, 10:10 PM

#5

Human being with feelings
Join Date: Oct 2013
Location: Seattle, WA
Posts: 806

Quote:
Hello SaulT. For me classic sound is the NEVE sound. Now, this plugin only draws inspiration from neve sound. It's far from it.

I've never had the opportunity to use one... but I'll say that this has gotten me wondering if I should dig out the electronics textbook so I can study the preamp and see what makes it tick, see if I can take a hack at modeling the sound!
Quote:
This plugin is calibrated to 18dbFS input. My goal is to get a fair amount of harmonics at that input level. So i need to multiply the signal in the atan function to get harmonics and subsequently divide it to gain match the input. Try removing the 0.14. It's gonna get loud!

Driving input, ok, makes sense. It doesn't compensate correctly, different material requires different compensation. This is especially noticeable with the +18 dB trim option, I get different results with sine, noise, and music. E.g. a gainOut value of 4 or so worked a lot better with noise but with music it was more like 2. Maybe consider using automatic volume compensation instead? E.g. take an RMS with a 300400 ms window of both the input and output and multiply the output by the ratio.
Something I also noticed is that adding 0.001 to atan() does effectively nothing. Raising that value does add some evenorder harmonics though, I thought that 0.3 or so had some good character while 0.8 sounded pleasing to me, although in a different way.
Also... needs oversampling!



03282020, 03:09 AM

#6

Human being with feelings
Join Date: Sep 2013
Posts: 72

Quote:
Originally Posted by SaulT
In ClassicChannel (classic based on...?) why multiply atan by 0.14? This limits the amplitude to +/ 0.2 or so, right? So basically a really hard clip above 14 dB? This doesnt seem like something a console channel would ever do.
I would like to suggest a more generalized function:
spl0 = atan(a*spl0+0.001)*b;
where b is 1/a and a is between 0 and maybe 3, with lower numbers being less linear?
Graph it, you'll see what I mean.
Something similar can be done with the ClassicBus function, perhaps
spl0 = atan(a*spl0/(a+abs(spl0))+0.0001);
although I vastly prefer the first as it avoids the division and an abs() call.
A suggestion? Instead of making it completely a different random call every time you press play, perhaps have a knob that allows some degree of user control. Maybe even vary the parameters of the plugin over time?

Quote:
Originally Posted by SaulT
I've never had the opportunity to use one... but I'll say that this has gotten me wondering if I should dig out the electronics textbook so I can study the preamp and see what makes it tick, see if I can take a hack at modeling the sound!
Driving input, ok, makes sense. It doesn't compensate correctly, different material requires different compensation. This is especially noticeable with the +18 dB trim option, I get different results with sine, noise, and music. E.g. a gainOut value of 4 or so worked a lot better with noise but with music it was more like 2. Maybe consider using automatic volume compensation instead? E.g. take an RMS with a 300400 ms window of both the input and output and multiply the output by the ratio.
Something I also noticed is that adding 0.001 to atan() does effectively nothing. Raising that value does add some evenorder harmonics though, I thought that 0.3 or so had some good character while 0.8 sounded pleasing to me, although in a different way.
Also... needs oversampling!

Yeah oversampling...too complex for me..i can't implement it. Help



03312020, 07:04 PM

#7

Human being with feelings
Join Date: Oct 2013
Location: Seattle, WA
Posts: 806

So I was thinking something like this...
volume compensation added
"preamp" input continuous from 18 to +18 dB
adjustable saturation
adjustable harmonic balance
pseudorandom channel variations with seed ("hey I like 506 but not 32 etc")
2x oversampling
I'm stopping there because it makes the point, but that's a start.
I would probably bump up the effect of channel variations, I think they're
pretty minimal. I would want more character in general, tbh, but I'm iffy
on how it handles higher signal levels, it fuzzes out on full mixes. Obvs this
isn't what it's built for, but that's still something to consider.
This is making me want to roll my own preamp plugin...
Code:
//tags: saturation glue tonal shaping
desc:ClassicChannel  St Remix
slider1:0<18,18,0.1>Input Trim (dB)
slider2:1<1,10,0.1>Saturation
slider3:0<0,1,0.01>evenorder coloration bias
slider4:0<0,1024,1>color seed (0 = random)
slider5:0<0,1,1{off,2x}>oversampling
//options:no_meter
@init
/* added code */
function singlepole(val,targ,coeff) (val*coeff + targ*(1coeff); );
function get_coeff(ms) ( exp(1/(srate*0.001*ms)); );
function get_prng() instance(seed) ( seed = (seed * 9821 + 6925) % 65531; seed/65531; );
function randval(x) instance(seed) ( seed = (seed * 9821 + 6925) % 65531; seed*x/65531; );
function rms(in) instance(rms,coeff,val) ( rms = singlepole(rms,in*in,coeff); val = sqrt(rms); );
function rms_set(ms) ( this.coeff = get_coeff(ms); );
//Halfband filter (19tap)
function os_os2()
instance(y18, y17, y16, y15, y14, y13, y12, y11, y10,
y9, y8, y7, y6, y5, y4, y3, y2, y1, y0)
(
y18 = y16; y17 = y15; y16 = y14; y15 = y13;
y14 = y12; y13 = y11; y12 = y10; y11 = y9;
y10 = y8; y9 = y7; y8 = y6; y7 = y5;
y6 = y4; y5 = y3; y4 = y2; y3 = y1;
y2 = y0;
);
function os_up2(x)
instance(x9, x8, x7, x6, x5, x4, x3, x2, x1, x0,
y18, y17, y16, y15, y14, y13, y12, y11, y10,
y9, y8, y7, y6, y5, y4, y3, y2, y1, y0)
(
x9 = x8; x8 = x7; x7 = x6; x6 = x5; x5 = x4; x4 = x3;
x3 = x2; x2 = x1; x1 = x0; x0 = x * 2;
this.os_os2();
y1 = 0.0028*(x0+x9)  0.0118*(x1+x8) + 0.0334*(x2+x7)
 0.0849*(x3+x6) + 0.3106*(x4+x5);
y0 = 0.5*x4;
);
function os_down2()
instance(y18, y16, y14, y12, y10, y9, y8, y6, y4, y2, y0)
(
0.0028*(y0+y18)  0.0118*(y2+y16) + 0.0334*(y4+y14)
 0.0849*(y6+y12) + 0.3106*(y8+y10) + 0.5*y9;
);
/* end added code */
function bqd(xn)
instance(a0,a1,a2,b1,b2,z1,z2,xn,xn_1,xn_2,yn,yn_1,yn_2)
(
yn = xn * a0 + z1;
z1 = xn * a1 + z2  b1 * yn;
z2 = xn * a2  b2 * yn;
yn;
);
function hpSet(F,Q)
instance(a0,a1,a2,b1,b2,xn,xn_1,xn_2,yn,yn_1,yn_2,V,K,norm,F,Q,peakGain)
(
F ?
(
V = 10^(abs(peakGain)/ 20.0);
K = tan($pi * F/osrate);
norm = 1 / (1 + K / Q + K * K);
a0 = 1 * norm;
a1 = 2 * a0;
a2 = a0;
b1 = 2 * (K * K  1) * norm;
b2 = (1  K / Q + K * K) * norm;
):(a0 = 1; a1 = a2 = b1 = b2 = 0;)
);
function lpSet(F,Q)
instance(a0,a1,a2,b1,b2,c0,d0,xn,xn_1,xn_2,yn,yn_1,yn_2,V,K,norm,F,Q,peakGain)
(
F ?
(
V = 10^(abs(peakGain)/ 20.0);
K = tan($pi * F/osrate);
norm = 1 / (1 + K / Q + K * K);
a0 = K * K * norm;
a1 = 2 * a0;
a2 = a0;
b1 = 2 * (K * K  1) * norm;
b2 = (1  K / Q + K * K) * norm;
):(a0 = 1; a1 = a2 = b1 = b2 = 0;)
);
function lsSet(F,peakGain)
instance(a0,a1,a2,b1,b2,c0,d0,xn,xn_1,xn_2,yn,yn_1,yn_2,V,K,norm,F,Q,peakGain)
(
V = 10^(abs(peakGain)/ 20.0);
K = tan($pi * F/osrate);
peakGain >= 0 ? // boost
(
norm = 1 / (1 + sqrt(2) * K + K * K);
a0 = (1 + sqrt(2*V) * K + V * K * K) * norm;
a1 = 2 * (V * K * K  1) * norm;
a2 = (1  sqrt(2*V) * K + V * K * K) * norm;
b1 = 2 * (K * K  1) * norm;
b2 = (1  sqrt(2) * K + K * K) * norm;
):(
norm = 1 / (1 + sqrt(2*V) * K + V * K * K);
a0 = (1 + sqrt(2) * K + K * K) * norm;
a1 = 2 * (K * K  1) * norm;
a2 = (1  sqrt(2) * K + K * K) * norm;
b1 = 2 * (V * K * K  1) * norm;
b2 = (1  sqrt(2*V) * K + V * K * K) * norm;
);
);
function hsSet(F,peakGain)
instance(a0,a1,a2,b1,b2,c0,d0,xn,xn_1,xn_2,yn,yn_1,yn_2,V,K,norm,F,Q,peakGain)
(
V = 10^(abs(peakGain)/ 20.0);
K = tan($pi * F/osrate);
peakGain >= 0 ? // boost
(
norm = 1 / (1 + sqrt(2) * K + K * K);
a0 = (V + sqrt(2*V) * K + K * K) * norm;
a1 = 2 * (K * K  V) * norm;
a2 = (V  sqrt(2*V) * K + K * K) * norm;
b1 = 2 * (K * K  1) * norm;
b2 = (1  sqrt(2) * K + K * K) * norm;
):(
norm = 1 / (V + sqrt(2*V) * K + K * K);
a0 = (1 + sqrt(2) * K + K * K) * norm;
a1 = 2 * (K * K  1) * norm;
a2 = (1  sqrt(2) * K + K * K) * norm;
b1 = 2 * (K * K  V) * norm;
b2 = (V  sqrt(2*V) * K + K * K) * norm;
);
);
function pkSet(F,Q,peakGain)
instance(a0,a1,a2,b1,b2,c0,d0,xn,xn_1,xn_2,yn,yn_1,yn_2,V,K,norm,F,Q,peakGain)
(
V = 10^(abs(peakGain)/ 20.0);
K = tan($pi * F/osrate);
peakGain >= 0 ? // boost
(
norm = 1 / (1 + 1/Q * K + K * K);
a0 = (1 + V/Q * K + K * K) * norm;
a1 = 2 * (K * K  1) * norm;
a2 = (1  V/Q * K + K * K) * norm;
b1 = a1;
b2 = (1  1/Q * K + K * K) * norm;
):(
norm = 1 / (1 + V/Q * K + K * K);
a0 = (1 + 1/Q * K + K * K) * norm;
a1 = 2 * (K * K  1) * norm;
a2 = (1  1/Q * K + K * K) * norm;
b1 = a1;
b2 = (1  V/Q * K + K * K) * norm;
);
);
c.hpF = 11; c.hpQ = 1.1;
c.lpF = 21000; c.lpQ = 0.2;
c.lsF = 90; c.lsG = 0.2;
c.hsF = 6000; c.hsG = 0.3;
c.p1F = 2000; c.p1Q = 0.2; c.p1G = 0.3;
c.p2F = 4500; c.p2Q = 0.2; c.p2G = 0.4;
c.empF = 100; c.empG = 12;
function channel_init()
instance(hp,lp,ls,hs,pk1,pk2,emph,demph)
(
emph.hsSet(c.empF,c.empG);
demph.hsSet(c.empF,c.empG);
hp.hpSet(c.hpF + r.randval(10), c.hpQ);
lp.lpSet(c.lpF  r.randval(1000), c.lpQ);
ls.lsSet(c.lsF, c.lsG + r.randval(0.1));
hs.hsSet(c.hsF, c.hsG  r.randval(0.1));
pk1.pkSet(c.p1F + r.randval(100), c.p1Q, c.p1G + r.randval(0.1));
pk2.pkSet(c.p2F  r.randval(100), c.p2Q, c.p2G  r.randval(0.1));
);
function channel_process(in)
instance(hp,lp,ls,hs,pk1,pk2,emph,demph,out)
(
in *= preamp;
in = emph.bqd(in);
// in = 0.14*atan(10*in+offset);
in = atan(color*spl0+offset) * icolor;
in = demph.bqd(in);
in = hp.bqd(in);
in = lp.bqd(in);
in = hs.bqd(in);
in = ls.bqd(in);
in = pk1.bqd(in);
in = pk2.bqd(in);
);
rms0.rms_set(300);
rms1.rms_set(300);
rms2.rms_set(300);
rms3.rms_set(300);
@slider
preamp = 10^(slider1 * 0.05);
color = slider2;
icolor = 1/color;
offset = slider3;
slider4 ? r.seed = slider4 : r.seed = (rand()*21)*65000;
oversample = 2^(slider5);
osrate = oversample * srate;
ch0.channel_init();
ch1.channel_init();
ch2.channel_init();
ch3.channel_init();
@sample
rms0.rms(spl0);
rms1.rms(spl1);
oversample == 2 ? (
s0.os_up2(spl0);
s1.os_up2(spl1);
s0.y1 = ch0.channel_process(s0.y1);
s0.y0 = ch0.channel_process(s0.y0);
s1.y1 = ch1.channel_process(s1.y1);
s1.y0 = ch1.channel_process(s1.y0);
spl0 = s0.os_down2();
spl1 = s1.os_down2();
) : (
spl0 = ch2.channel_process(spl0);
spl1 = ch3.channel_process(spl1);
);
rms2.rms(spl0);
rms3.rms(spl1);
spl0 *= rms0.val/rms2.val;
spl1 *= rms1.val/rms3.val;



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 12:47 PM.
