|
|
|
08-07-2021, 08:18 AM
|
#1
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
JS Saturation vs Sonnox Inflator
FWIW, I've found that a setting of 95 in JS Saturation gives the best null against Sonnox Inflator with curve setting 0. Dry/Wet knob equates to the Inflator "Effect" amount. Not quite as good a null as Melda WaveShaper with the custom presets from gearspace but not bad!
Can anyone achieve a better null using another JS plugin? I can't seem to get very close with the Waveshaping Distortion JS or airwindows.
Last edited by chmaha; 08-11-2021 at 05:56 AM.
|
|
|
08-08-2021, 01:55 AM
|
#2
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
I made a JSFX version of inflator using the algorithm from that gearslutz thread, should I upload it?
|
|
|
08-08-2021, 03:23 AM
|
#3
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Definitely! That would be brilliant...
|
|
|
08-08-2021, 12:06 PM
|
#4
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
Okay I just uploaded the JSFX to my ReaPack Repository:
https://github.com/RCJacH/ReaScripts...ster/index.xml
It's called RCInflator (RC prefix for sorting).
It's a very simple implementation of the curve algorithm rather than the actual Sonnox plugin that I wrote for someone else in 10 minutes few months ago. It only has four controls:
1. input gain
2. Effect, which is dry/wet, identical to reaper's native dry/wet knob.
3. Curve, which is the algorithm
4. Output gain
There's no clipping or multi-band waveshaping, which some said to be THE sound of Sonnox Inflator plugin.
|
|
|
08-09-2021, 10:09 AM
|
#5
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Thanks so much...I will check it out shortly.
|
|
|
08-09-2021, 05:39 PM
|
#6
|
Human being with feelings
Join Date: Nov 2014
Location: Can Tho - Viet Nam
Posts: 305
|
I tried it and it's great
|
|
|
08-09-2021, 08:21 PM
|
#7
|
Human being with feelings
Join Date: Aug 2020
Location: Colombia
Posts: 165
|
Quote:
Originally Posted by RCJacH
Okay I just uploaded the JSFX to my ReaPack Repository:
https://github.com/RCJacH/ReaScripts...ster/index.xml
It's called RCInflator (RC prefix for sorting).
It's a very simple implementation of the curve algorithm rather than the actual Sonnox plugin that I wrote for someone else in 10 minutes few months ago. It only has four controls:
1. input gain
2. Effect, which is dry/wet, identical to reaper's native dry/wet knob.
3. Curve, which is the algorithm
4. Output gain
There's no clipping or multi-band waveshaping, which some said to be THE sound of Sonnox Inflator plugin.
|
GUI in process
|
|
|
08-09-2021, 08:57 PM
|
#8
|
Human being with feelings
Join Date: Nov 2014
Location: Can Tho - Viet Nam
Posts: 305
|
Quote:
Originally Posted by dagamusik
GUI in process
|
Wow! Amazing Good Job!
|
|
|
08-10-2021, 12:17 AM
|
#9
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by dagamusik
GUI in process
|
Wow, this is great. Can't wait to see the finished version...
|
|
|
08-10-2021, 01:01 AM
|
#10
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
I was thinking of adding it to squashman as an option, but I'm a bit skeptical about the implementation of this waveshaper provided here.
I graphed what it looks like, but the response for negative values looks really weird.
I suspect that polynomial was only used to describe the positive part from [0-1]? Which is somewhat more well behaved.
You can fix the implementation by replacing
with
and reintroducing the sign back after calculating the polynomial.
Instead of:
Code:
spl0 = s0 * wet + spl0 * dry;
do:
Code:
spl0 = sign(spl0) * s0 * wet + spl0 * dry;
That would give you the following waveshaper instead (which looks more reasonable to me):
Personally, I would also clip the input to not have the foldback distortion.
Does anyone have access to the original plugin for some tests? Would be interesting to see if the plugin produces even harmonics.
Last edited by sai'ke; 08-10-2021 at 01:09 AM.
|
|
|
08-10-2021, 02:50 AM
|
#11
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by sai'ke
Does anyone have access to the original plugin for some tests? Would be interesting to see if the plugin produces even harmonics.
|
Yes, I have the original plugin and would be happy to do tests. I'm on Linux but can run it via ilok cloud. @sai'ke, just let me know what you need and which tools to use...
Last edited by chmaha; 08-10-2021 at 03:25 AM.
|
|
|
08-10-2021, 03:22 AM
|
#12
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
In direct null test comparison between Sonnox Inflator and RCInflator with identical settings (Effect 100%, curve 0), there is residual signal as high as -25 dBFS:
https://i.imgur.com/Fq6JJzg.png
Compare this to JS Saturation (set at 95%):
https://i.imgur.com/Uf5XdyH.png
And MWaveshaper:
https://i.imgur.com/Htt14v1.png (with input set to -6 dB)
Both of those seem to be a closer with MWaveshaper winning but still not a perfect match (though differences down at -60dBFS would probably be fine).
Best of all though is MWaveshaper (with clip ON) which null tests against Sonnox Inflator around -100dBFS which for all intents and purposes sounds like a perfect match:
https://i.imgur.com/cama5iH.png
Last edited by chmaha; 08-10-2021 at 03:27 AM.
|
|
|
08-10-2021, 03:30 AM
|
#13
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
In direct null test comparison between Sonnox Inflator and RCInflator with identical settings (Effect 100%, curve 0), there is residual signal as high as -25 dBFS
|
Is that with or without the changes I suggested?
Note that you'll have to change spl1 / s1 analogously.
After work I can write a quick JS that can generate some data we can use for analysis.
|
|
|
08-10-2021, 03:50 AM
|
#14
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by sai'ke
Is that with or without the changes I suggested?
Note that you'll have to change spl1 / s1 analogously.
|
With your changes it definitely fares better with residual around -42 dBFS. So it is only marginally worse than JS Saturation.
|
|
|
08-10-2021, 04:11 AM
|
#15
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
With your changes it definitely fares better with residual around -42 dBFS. So it is only marginally worse than JS Saturation.
|
Actually, I just found the forum post that the JSFX referred to and I think there's also a minus sign wrong in the implementation on GH.
If that forum post is to be believed + curveD should be - curveD in the output equation.
So change:
Quote:
s0 = curveA * s0 + curveB * s0_2 + curveC * s0_3 + curveD * (s0_2 - 2 * s0_3 + s0_2 * s0_2);
|
to:
Quote:
s0 = curveA * s0 + curveB * s0_2 + curveC * s0_3 - curveD * (s0_2 - 2 * s0_3 + s0_2 * s0_2);
|
Addendum:
Since supposedly, it's a static waveshaper, we could probably reverse engineer it ourselves.
Put the following JSFX before the plugin and record the output at increments of say 5% effect. Note that the start and end of the cosine should be visible in the wave you export (makes curve fitting _a lot_ easier.
Code:
desc:slow sine test
in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output
@init
t = 0;
@slider
@block
@sample
t += 1.0;
// Start on a full sample around 1/4th sample rate in.
start_sample = floor(0.25*srate);
(t >= start_sample) ? (
spl0 = spl1 = 2 * cos((t - start_sample)/srate);
(t > (10 * srate + start_sample)) ? (
t = 0;
);
);
Be careful that the signal does not clip (this plugin provides input beyond the -1 to 1 range on purpose to see how the inflator handles it).
Last edited by sai'ke; 08-10-2021 at 04:28 AM.
|
|
|
08-10-2021, 05:03 AM
|
#16
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by sai'ke
Actually, I just found the forum post that the JSFX referred to and I think there's also a minus sign wrong in the implementation on GH.
If that forum post is to be believed + curveD should be - curveD in the output equation.
|
Brilliant. The residual max is c. -130 dbFS i.e. even better than the MWaveShaper presets!!!
So, in summary, the updated JSFX should be:
Code:
/*
JSFX Name: RCInflator
Author: RCJacH
Release Date: Aug 2021
Link: https://github.com/RCJacH/ReaScripts
Version: 0.2
Reference:
tviler
Sony Oxford
About:
JSFX implementation of Sony Oxford Inflator algorithm,
found on Gearspace.
*/
desc:RCInflator
slider1:0<-60, 60, 0.1>Input (dB)
slider2:100<0, 100, 0.1>Effect (%)
slider3:curve=0<-50, 50, 0.0001>Curve
slider5:0<-60, 6, 0.1>Output (dB)
@init
@slider
in_db = 2 ^ (slider1 / 6);
wet = slider2 * 0.01;
dry = 1 - wet;
out_db = 2 ^ (slider5 / 6);
curvepct = curve * 0.01;
// 1 + (curve + 50) / 100
curveA = 1.5 + curvepct;
// - curve / 50
curveB = -(curvepct + curvepct);
// (curve - 50) / 100
curveC = curvepct - 0.5;
// 1 / 16 - curve / 400 + curve ^ 2 / (4 * 10 ^ 4)
curveD = 0.0625 - curve * 0.0025 + (curve * curve) * 0.000025;
@sample
s0 = abs(spl0);
s0 *= in_db;
s0_2 = s0 * s0;
s0_3 = s0_2 * s0;
s0 = curveA * s0 + curveB * s0_2 + curveC * s0_3 - curveD * (s0_2 - 2 * s0_3 + s0_2 * s0_2);
s0 *= out_db;
spl0 = sign(spl0) * s0 * wet + spl0 * dry;
s1 = abs(spl1);
s1 *= in_db;
s1_2 = s1 * s1;
s1_3 = s1_2 * s1;
s1 = curveA * s1 + curveB * s1_2 + curveC * s1_3 - curveD * (s1_2 - 2 * s1_3 + s1_2 * s1_2);
s1 *= out_db;
spl1 = sign(spl1) * s1 * wet + spl1 * dry;
|
|
|
08-10-2021, 05:05 AM
|
#17
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by sai'ke
Addendum:
Since supposedly, it's a static waveshaper, we could probably reverse engineer it ourselves.
Put the following JSFX before the plugin and record the output at increments of say 5% effect. Note that the start and end of the cosine should be visible in the wave you export (makes curve fitting _a lot_ easier.
|
I will also record the output of the above after I've had my lunch.
|
|
|
08-10-2021, 05:09 AM
|
#18
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
Brilliant. The residual max is c. -130 dbFS i.e. even better than the MWaveShaper presets!!!
So, in summary, the updated JSFX should be:
|
Coolcool. I'll open a PR on the GitHub repo.
|
|
|
08-10-2021, 05:22 AM
|
#19
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
I will also record the output of the above after I've had my lunch.
|
I don't mind giving it a shot, but if it's -130 dbFS over the entire range of curve values, it's probably good enough already.
|
|
|
08-10-2021, 06:06 AM
|
#20
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by sai'ke
I don't mind giving it a shot, but if it's -130 dbFS over the entire range of curve values, it's probably good enough already.
|
Hmm, maybe your time is better spent doing other things! I'm happy with differences down at -130 dB if you are :P
In a quick test (just for fun), using your slow sine JSFX, here is the difference for official Inflator between 0% and 100% effect with curve at 0: https://i.imgur.com/D0TQQ1v.png
|
|
|
08-10-2021, 06:34 AM
|
#21
|
Human being with feelings
Join Date: Aug 2020
Location: Colombia
Posts: 165
|
To update the GUI version just change code on "line 51" and on "@sample"
Code:
JSFX Name: RCInflator
Author: RCJacH
Release Date: Aug 2021
Link: https://github.com/RCJacH/ReaScripts
Version: 0.2
Reference: tviler, Sony Oxford
-----------------------------------------------------
About:
JSFX implementation of Sony Oxford Inflator algorithm found on Gearspace.
-----------------------------------------------------
GUI by: DAGA
desc:RCInflator
desc:RCInflator GUI GFX
slider1:0<-60,60,0.1>-Input (dB)
slider2:100<0,100,0.1>-Effect (%)
slider3:curve=0<-50,50,0.0001>-Curve
slider5:0<-60,6,0.1>-Output (dB)
slider11:60 <0,120,0.1 >-Input (dB) Dummy
slider12:100<0,100,0.1 >-Effect (%) Dummy
slider13:50 <0,100,0.0001>-Curve Dummy
slider15:6 <0,66 ,0.1 >-Output (dB) Dummy
@init
function button_rect(x,y,w,h)
(
mouse_x >= x && mouse_x <= x+w && mouse_y >= y && mouse_y <= y+h ? this.button = 1:this.button = 0;
);
// Select Color Scheme Function
Function color (scheme)(
scheme == 1 ? (r=r1;g=g1;b=b1;a=a1;);
scheme == 2 ? (r=r2;g=g2;b=b2;a=a2;);
scheme == 3 ? (r=r3;g=g3;b=b3;a=a3;);
scheme == 4 ? (r=r4;g=g4;b=b4;a=a4;);
scheme == 5 ? (r=r5;g=g5;b=b5;a=a5;);
scheme == 6 ? (r=r6;g=g6;b=b6;a=a6;);
scheme == 7 ? (r=r7;g=g7;b=b7;a=a7;);
scheme == 8 ? (r=r8;g=g8;b=b8;a=a8;);
scheme == 9 ? (r=r9;g=g9;b=b9;a=a9;);
scheme == 10? (r=r10;g=g10;b=b10;a=a10;);
scheme == 11? (r=r11;g=g11;b=b11;a=a11;);
gfx_set(r/255,g/255,b/255,a/100);
);
function executeslider()(
in_db = 2 ^ (slider1 / 6);
wet = slider2 * 0.01;
dry = 1 - wet;
out_db = 2 ^ (slider5 / 6);
curvepct = curve * 0.01;
// 1 + (curve + 50) / 100
curveA = 1.5 + curvepct;
// - curve / 50
curveB = -(curvepct + curvepct);
// (curve - 50) / 100
curveC = curvepct - 0.5;
// 1 / 16 - curve / 400 + curve ^ 2 / (4 * 10 ^ 4)
curveD = 0.0625 - curve * 0.0025 + (curve * curve) * 0.000025;
);
@slider
executeslider();
@block
slider1=-1*slider11+60;
slider2=-1*slider12+100;
curve =-1*slider13+50;
slider5=-1*slider15+6;
@sample
s0 = spl0;
s0 *= in_db;
s0_2 = s0 * s0;
s0_3 = s0_2 * s0;
s0 = curveA * s0 + curveB * s0_2 + curveC * s0_3 + curveD * (s0_2 - 2 * s0_3 + s0_2 * s0_2);
s0 *= out_db;
spl0 = s0 * wet + spl0 * dry;
s1 = spl1;
s1 *= in_db;
s1_2 = s1 * s1;
s1_3 = s1_2 * s1;
s1 = curveA * s1 + curveB * s1_2 + curveC * s1_3 + curveD * (s1_2 - 2 * s1_3 + s1_2 * s1_2);
s1 *= out_db;
spl1 = s1 * wet + spl1 * dry;
@gfx 560 330
// Blue darkest
r1=36; g1=51; b1=70; a1=100;
// Blue medium
r2=84; g2=108; b2=176; a2=100;
// Blue light
r3=103; g3=135; b3=190; a3=100;
// Blue lightest
r4=156; g4=176; b4=215; a4=100;
// Text blocks
r5=41; g5=52; b5=73; a5=100;
r6=41/2; g6=52/2; b6=73/2; a6=100;
//Slider LR
r7=90; g7=121; b7=178; a7=100;
//Slider M
r8=141; g8=161; b8=205; a8=100;
//Inside Slider
r9=79; g9=107; b9=154; a9=100;
// White
r10=243; g10=249; b10=254; a10=100;
// Yellow
r11=255; g11=220; b11=0; a11=100;
////////////////////////////////////////////////////////////////
Function color_rect (x,y,w,h,fill,color,shade_color,shade,shade_depth)local(color,shade_color)(
// Shade
color(shade_color);
gfx_rect(x*shade,y*shade,w*shade,h*shade);
// Main Shape
shdh=shade_depth;
color(color);
gfx_rect(x+(shade*shdh),y+(shade*shdh),w-(shade*2*shdh),h-(shade*2*shdh));
);
////////////////////////////////////////////////////////////////
//Texts Function //
Function dotext (x,y,fontype,size,string,color)(
fontype == 0 ? gfx_setfont(1,"Roboto Mono Bold",size,1)
: gfx_setfont(1,"Roboto Mono" ,size,1);
gfx_x=x; gfx_y=y;
color(color);
gfx_drawstr(string);
);
function doCenterText(ctrX, ctrY, val)(
str = sprintf(#, "%.1f", val);
gfx_measurestr(str, str_w, str_h);
gfx_x = ctrX - str_w/2; gfx_y = ctrY - str_h/2;
gfx_drawstr(str);
);
////////////////////////////////////////////////////////////////
// Background
color_rect(0 ,0 ,560,330,1,1,1,0,1);
color_rect(1 ,50 ,173,280,1,3,1,1,2);
color_rect(387,50 ,173,280,1,3,1,1,2);
color_rect(173,50 ,215,280,1,4,1,1,2);
color_rect(90 ,1 ,470,50 ,1,3,1,1,2);
color_rect(1 ,1 ,90 ,50 ,1,3,1,1,2);
// Slider
color_rect(70 ,115,40 ,200,1,7,1,1,1);
color_rect(450,115,40 ,200,1,7,1,1,1);
color_rect(215,115,40 ,200,1,8,1,1,1);
color_rect(305,115,40 ,200,1,8,1,1,1);
// Inside sliders
color_rect(87 ,115,5 ,200,1,9,1,1,1);
color_rect(233,115,5 ,200,1,9,1,1,1);
color_rect(323,115,5 ,200,1,9,1,1,1);
color_rect(468,115,5 ,200,1,9,1,1,1);
// Text box
color_rect(60 ,70 ,60 ,25 ,1,5,6,1,1);
color_rect(205,70 ,60 ,25 ,1,5,6,1,1);
color_rect(295,70 ,60 ,25 ,1,5,6,1,1);
color_rect(440,70 ,60 ,25 ,1,5,6,1,1);
// Strings
version="v.21.08.09";
tittle="RC INFLATOR";
s1t="Input (dB)";
s2t="Effect (%)";
s3t="Curve";
s5t="Output (dB)";
dotext(222,15,1,24,tittle ,10);
dotext(60 ,98,1,13,s1t ,10);
dotext(205,98,1,13,s2t ,6 );
dotext(310,98,1,13,s3t ,6 );
dotext(438,98,1,13,s5t ,10);
dotext(15 ,20,0,13,version,10);
// Numbers
gfx_set(1,1,0,1);
gfx_setfont(1,"Roboto Mono",17,1);
doCenterText(90 ,82,slider1);
doCenterText(235,82,slider2);
doCenterText(325,82,curve);
doCenterText(470,82,slider5);
// Slider 1
s11f.button_rect(70,115,40,200);
s11f.button == 1 ? color11f=9;
s11f.button == 0 ? color11f=0;
s11f.button == 1 ? (
mouse_cap > 0 ? (
slider11 = min(120,max(((mouse_y-115)*0.6),0));
mouse_cap == 2 ? slider11 = 60;
);
);
color_rect(68,115+(slider11*1.5),44,20,1,1+color11f,1,1,1);
// Slider 2 Curve
s12f.button_rect(213,115,40,200);
s12f.button == 1 ? color12f=9;
s12f.button == 0 ? color12f=0;
s12f.button == 1 ? (
mouse_cap > 0 ? (
slider12 = min(100,max(((mouse_y-115)*0.5),0));
mouse_cap == 2 ? slider12 = 100;
);
);
color_rect(213,115+(slider12*1.8),44,20,1,1+color12f,1,1,1);
// Slider 3
s13f.button_rect(305,115,40,200);
s13f.button == 1 ? color13f=9;
s13f.button == 0 ? color13f=0;
s13f.button == 1 ? (
mouse_cap > 0 ? (
slider13 = min(100,max(((mouse_y-115)*0.5),0));
mouse_cap == 2 ? slider13 = 50;
);
);
color_rect(303,115+(slider13*1.82),44,20,1,1+color13f,1,1,1);
// Slider 5
s15f.button_rect(450,115,40,200);
s15f.button == 1 ? color15f=9;
s15f.button == 0 ? color15f=0;
s15f.button == 1 ? (
mouse_cap > 0 ? (
slider15 = min(66,max(((mouse_y-115)*0.33),0));
mouse_cap == 2 ? slider15 = 6;
);
);
color_rect(448,115+(slider15*2.88),44,20,1,1+color15f,1,1,1);
|
|
|
08-10-2021, 06:55 AM
|
#22
|
Human being with feelings
Join Date: Jul 2007
Location: Jazz City
Posts: 5,065
|
Wow, I'll A/B later as well, since I really love the Inflator ‒ but its online iLok authorization and its size are arguable! Thanks everyone!
My impression: STUNNING! The original Inflator still sounds more dense and its resulting perceived loudness is higher while at the same time the peaks are lower (due to the missing clipper in RC, as far as I understand). But for non-essential signals this is definitely great!
__________________
Windows 10x64 | AMD Ryzen 3700X | ATI FirePro 2100 | Marian Seraph AD2, 4.3.8 | Yamaha Steinberg MR816x
"If I can hear well, then everything I do is right" (Allen Sides)
Last edited by beingmf; 08-10-2021 at 08:11 AM.
|
|
|
08-10-2021, 08:23 AM
|
#23
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by dagamusik
To update the GUI version just change code on "line 51" and on "@sample"
|
@dagamusik, I'm a bit confused as the GUI doesn't seem operational i.e. sliders don't do anything.
Quote:
Originally Posted by beingmf
Wow, I'll A/B later as well, since I really love the Inflator ‒ but its online iLok authorization and its size are arguable! Thanks everyone!
My impression: STUNNING! The original Inflator still sounds more dense and its resulting perceived loudness is higher while at the same time the peaks are lower (due to the missing clipper in RC, as far as I understand). But for non-essential signals this is definitely great!
|
Let's hope @sai'ke feels inclined to add a clipper to his squashman version
Last edited by chmaha; 08-10-2021 at 08:29 AM.
|
|
|
08-10-2021, 08:29 AM
|
#24
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
Woah a GUI implemented in a day and a fork by sai'ke with algorithmic bug fixed, I'm in awe.
Regarding clipping, since there's no hint of what Sonnox Inflator clipper was doing algorithmically, would it help if we implement an Airwindows clipping algorithm (like ADClip)? Although it might be easier to just put a clipper/limiter after this JSFX.
|
|
|
08-10-2021, 08:42 AM
|
#25
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by RCJacH
Woah a GUI implemented in a day and a fork by sai'ke with algorithmic bug fixed, I'm in awe.
Regarding clipping, since there's no hint of what Sonnox Inflator clipper was doing algorithmically, would it help if we implement an Airwindows clipping algorithm (like ADClip)? Although it might be easier to just put a clipper/limiter after this JSFX.
|
I was thinking the same thing: an airwindows clipper separately or as part of the JSFX (with option to disable) would be excellent.
I assume others also find that the GUI implementation is not working quite yet? Also, it would need ability to type in numbers and reset individual sliders to starting positions as desired. One more thing, extremes of the sliders are difficult to land on...
|
|
|
08-10-2021, 08:52 AM
|
#26
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
I think you'd want the clipper before the plugin actually. If you do it after, you'd still get the foldback. But uh, since the curve already ends at [-1, -1] and [1, 1], it's easy to add it. Just do:
After:
Add:
Code:
s0 = s0 > 1 ? 1 : s0;
Same for the right channel of course.
You can make the clipping optional by adding a slider named clip with a value of 0 or 1.
Code:
clip ? (
s0 = s0 > 1 ? 1 : s0;
);
Just to be sure, you could run that testing JSFX I sent with the clipper and see. I suspect it will instead of going down again just stay at a fixed value once it reaches its end.
Last edited by sai'ke; 08-10-2021 at 09:09 AM.
|
|
|
08-10-2021, 08:57 AM
|
#27
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by sai'ke
I think you'd want the clipper before the plugin actually. If you do it after, you'd still get the foldback. But uh, since the curve already ends at [-1, -1] and [1, 1], it's easy to add it. Just do:
After:
Add:
Code:
s0 = s0 > 1 ? 1 : s0;
Same for the right channel of course.
You can make the clipping optional by adding a slider named clip with a value of 0 or 1.
Code:
clip ? (
s0 = s0 > 1 ? 1 : s0;
);
Just to be sure, you could run that testing JSFX I sent with the clipper and see. I suspect it will instead of going down again just stay at a fixed value once it reaches its end.
|
I will definitely test that. Also, is there a way to have those lines (I assume it needs to be for s1 too) optional via a checkbox?
|
|
|
08-10-2021, 08:59 AM
|
#28
|
Human being with feelings
Join Date: Aug 2020
Location: Colombia
Posts: 165
|
Quote:
I assume others also find that the GUI implementation is not working quite yet?
|
You are right I uploaded the GUI without checking some stuff, but is working now.
Output slider doesn't work if "Effect [%]" is at o% (trying to figure it out why).
As I know, values cannot be input as numbers, still there's a trick I would add later (if someone knows how to add the ability on type numbers in the GUI would be great)
If you want to go back to initial values use the mouse right click, or if you preffer a special initial value save a preset.
Here I upload a working version!
Hope you enjoy it
|
|
|
08-10-2021, 09:10 AM
|
#29
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
I will definitely test that. Also, is there a way to have those lines (I assume it needs to be for s1 too) optional via a checkbox?
|
Sorry, just for the record, the clipping should be after the gain is applied, so after:
I've edited my post as well
You can add the toggle slider like so:
Code:
slider6:clip=0<0,1,1{No,Yes}>Clip
But for a checkbox, you'd need a custom UI afaik.
Unskinned, the code would become the following:
Code:
/*
JSFX Name: RCInflator
Author: RCJacH
Release Date: Aug 2021
Link: https://github.com/RCJacH/ReaScripts
Version: 0.2
Reference:
tviler
Sony Oxford
About:
JSFX implementation of Sony Oxford Inflator algorithm,
found on Gearspace.
*/
desc:RCInflator
slider1:0<-60, 60, 0.1>Input (dB)
slider2:100<0, 100, 0.1>Effect (%)
slider3:curve=0<-50, 50, 0.0001>Curve
slider5:0<-60, 6, 0.1>Output (dB)
slider6:clip=0<0,1,1{No,Yes}>Clip
@init
@slider
in_db = 2 ^ (slider1 / 6);
wet = slider2 * 0.01;
dry = 1 - wet;
out_db = 2 ^ (slider5 / 6);
curvepct = curve * 0.01;
// 1 + (curve + 50) / 100
curveA = 1.5 + curvepct;
// - curve / 50
curveB = -(curvepct + curvepct);
// (curve - 50) / 100
curveC = curvepct - 0.5;
// 1 / 16 - curve / 400 + curve ^ 2 / (4 * 10 ^ 4)
curveD = 0.0625 - curve * 0.0025 + (curve * curve) * 0.000025;
@sample
s0 = abs(spl0);
s0 *= in_db;
clip ? (
s0 = s0 > 1 ? 1 : s0;
);
s0_2 = s0 * s0;
s0_3 = s0_2 * s0;
s0 = curveA * s0 + curveB * s0_2 + curveC * s0_3 - curveD * (s0_2 - 2 * s0_3 + s0_2 * s0_2);
s0 *= out_db;
spl0 = sign(spl0) * s0 * wet + spl0 * dry;
s1 = abs(spl1);
s1 *= in_db;
clip ? (
s1 = s1 > 1 ? 1 : s1;
);
s1_2 = s1 * s1;
s1_3 = s1_2 * s1;
s1 = curveA * s1 + curveB * s1_2 + curveC * s1_3 - curveD * (s1_2 - 2 * s1_3 + s1_2 * s1_2);
s1 *= out_db;
spl1 = sign(spl1) * s1 * wet + spl1 * dry;
Maybe daga can add a checkbox to the UI
|
|
|
08-10-2021, 09:11 AM
|
#30
|
Human being with feelings
Join Date: Aug 2020
Location: Colombia
Posts: 165
|
Quote:
Maybe daga can add a checkbox to the UI
|
I will
|
|
|
08-10-2021, 09:55 AM
|
#31
|
Human being with feelings
Join Date: Aug 2020
Location: Colombia
Posts: 165
|
How about this?
|
|
|
08-10-2021, 10:08 AM
|
#32
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
I'll add an optional clipping with Airwindows cliponly algorithm (which I use a lot), it clips at -0.2dB true peak (I think).
But I'll have to do it tomorrow, since it's mid night in my timezone, and I have to wake up early tomorrow.
|
|
|
08-10-2021, 10:10 AM
|
#33
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by dagamusik
How about this?
|
Brilliant! This is looking really good. Your "human being with feelings" doesn't seem to fit in the upper left box.
|
|
|
08-10-2021, 10:15 AM
|
#34
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by RCJacH
I'll add an optional clipping with Airwindows cliponly algorithm (which I use a lot), it clips at -0.2dB true peak (I think).
But I'll have to do it tomorrow, since it's mid night in my timezone, and I have to wake up early tomorrow.
|
It's weird but even adding 1dB to both Sonnox and RCInflator inputs gives residual of -70 dBFS i.e. a change of 60dB! Perhaps the dB scales for input/output are not identical?
|
|
|
08-10-2021, 10:27 AM
|
#35
|
Human being with feelings
Join Date: Aug 2020
Location: Colombia
Posts: 165
|
Quote:
Originally Posted by BethHarmon
Brilliant! This is looking really good. Your "human being with feelings" doesn't seem to fit in the upper left box.
|
I suspect it's because you need to have "Roboto Mono" font installed in order to show as I did it. I love monospace fonts.
|
|
|
08-10-2021, 10:47 AM
|
#36
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
It's weird but even adding 1dB to both Sonnox and RCInflator inputs gives residual of -70 dBFS i.e. a change of 60dB! Perhaps the dB scales for input/output are not identical?
|
Correct. It uses an approximation I see a lot in JSFX, namely gain=2^(db/6). More accurate would be to use the exact expression: gain=exp(log(10)/20 * db).
Replace:
Code:
in_db = 2 ^ (slider1 / 6);
out_db = 2 ^ (slider5 / 6);
With:
Code:
in_db = exp(0.11512925464970229 * slider1);
out_db = exp(0.11512925464970229 * slider5);
And I suspect they'll be identical. In practice, I doubt you'd notice this difference in daily use.
|
|
|
08-10-2021, 10:55 AM
|
#37
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Also, here is the new RCInflator clipper in action: https://i.imgur.com/hi6lZ15.png
It seems to be working as expected.
What is interesting is when clip is OFF for both Sonnox and RCInflator and pushed into the red by the same amount, the "magic" in the original seems to create shallower dips and thereby creates more perceived loudness:
https://i.imgur.com/PwDuyTi.png (Sonnox on the left)
Is there a way we can recreate that in RCInflator?
Last edited by chmaha; 08-10-2021 at 11:01 AM.
|
|
|
08-10-2021, 11:09 AM
|
#38
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
Also, here is the clipper in action: https://i.imgur.com/hi6lZ15.png
It seems to be working as expected.
What is interesting is when clip is OFF for both Sonnox and RCInflator and pushed into the red by the same amount, the "magic" in the original seems to create shallower dips and thereby creates more perceived loudness:
https://i.imgur.com/PwDuyTi.png (Sonnox on the left)
Is there a way we can recreate that in RCInflator?
|
I suspect that whoever did this model just calibrated to the 0-1 range. So anything beyond the clipping range is probably not fitted.
We'd need to iterate on datasets if we really want to reverse engineer that. Images are not enough, I'd really need a series of wave files annotated with which settings they were obtained.
My suspicion is that the real thing is just a sine shaper with something added, but no way to be sure.
|
|
|
08-10-2021, 11:15 AM
|
#39
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
OK, I'm up for recording them tomorrow. At this point do we need the 0-1 stuff given it nulls so low down? I could start peaks at 0 and go up in 0.5 dB steps until we hit +6dB when according to the Sonnox documentation hard-ciipping kicks in. Does that work?
|
|
|
08-10-2021, 12:36 PM
|
#40
|
Human being with feelings
Join Date: Aug 2009
Location: NL
Posts: 1,453
|
Quote:
Originally Posted by BethHarmon
OK, I'm up for recording them tomorrow. At this point do we need the 0-1 stuff given it nulls so low down? I could start peaks at 0 and go up in 0.5 dB steps until we hit +6dB when according to the Sonnox documentation hard-ciipping kicks in. Does that work?
|
Hm. If it's really a static waveshaper (which is what is suggested in more than one place), we should only need one wave per "curve" setting. Maybe increments of 25% to begin with, so you don't spend a ton of time exporting a ton of data.
We don't really need to have it at different volume levels. Just one relatively loud one is good (preferably up to the level where you'd want to still use the plugin).
|
|
|
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 05:35 AM.
|