|
|||||||
![]() |
|
|
Thread Tools |
|
|
#1 |
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
Transfer function?
Hi there.
My experience with kX DSP involves pasting code snippets from this forum into the Dane editor and saving it and using it. I really know nothing about DSP coding myself. But, I want to know if something can be done. (And, of course, can someone code it for me! )If my sound were normalized to within (-1, 1), I'd like a function that, when given a sample, returns sin(sample * pi/2). I believe this would give a specific soft clip and limit sound, and could be useful. Anyone help? :-) Thanks. |
|
|
|
|
|
#2 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
This gives you virtually the same result((the function graph is identical):
2*x*(1-abs(x)*0.5) If you want further compression remove the 2.
__________________
Miss you, Steve... |
|
|
|
|
|
|
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
Are you sure about that?
(maybe abs means something different to you... abs to me means absolute value.) Edit: I plugged it into my graphing calculator... by golly, it is the same! So... How do I code this into a kX DSP plugin? Assuming I know nothing about DSP programming? |
|
|
|
|
|
#4 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
You should trust me in the future
![]() Code:
input in output out control level=1, compress=0.5 temp tmp, tmp2 ;level macs tmp, 0, in, level ;abs(in) tstneg tmp2, tmp, tmp, 0 ;compress should be from 0 to 0.5, should not exceed 0.5 macs tmp2, 0, tmp2, compress interp out, tmp, tmp2, 0 end Code:
input in output out control level=1 temp tmp, tmp2 ;level macs tmp, 0, in, level ;abs(in) tstneg tmp2, tmp, tmp, 0 macs tmp2, 0, tmp2, 0.5 interp tmp, tmp, tmp2, 0 macints out, 0, tmp, 2 end
__________________
Miss you, Steve... |
|
|
|
|
|
|
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
I pasted that code into a new kX plugin and saved it, and when I tried to register it, I got an error that it's an "invalid plugin library". What now?
|
|
|
|
|
|
#6 |
|
HardwareHeaven Extreme Member
Join Date: Jan 2005
Posts: 5,561
Rep Power: 62 ![]() ![]() ![]() ![]() ![]() ![]() |
Make sure there is a new line after 'end'.
|
|
|
|
|
|
#7 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
It works, try again.
__________________
Miss you, Steve... |
|
|
|
|
|
#8 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... i tried it... awesome... there is so much to learn from you Martin!
![]() Why do you say to set compress not higher than 0.5, what should happen? ... maybe i got: if compress>0.5 the approximation of the sin.. function is not good anymore? Last edited by radiocolonel.it; May 20, 2005 at 01:47 PM. |
|
|
|
|
|
|
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
Okay, I got it to work, and yes, it was because there wasn't a blank line after end.
I tried it, and by my tests, it adds 6dB to the output, but the transfer function is still linear. If you take the 2 from the macints instruction and replace it with a 1, the output of the function is identical to the input. I trace through your instructions, and if there's a problem, it seems like it would be with interp. I read your beginners' guide to DSP programming for kX, and by what you have written there, your code is correct... but it still isn't doing what it should be doing. Any ideas? |
|
|
|
|
|
#10 | ||
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Quote:
Quote:
__________________
Miss you, Steve... Last edited by Tiger M; May 20, 2005 at 04:41 PM. |
||
|
|
|
|
|
#11 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... yeah, Martin is right! The formula is well implemented, i tried different setting and i drawed yhe function to understand it better, anyway i have that 6dB increase (exactly i get 4.5dB increase). We'll see, i'll make some tries, if i get some nice result i'll post the code here.
|
|
|
|
|
|
|
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
http://www.naptastic.com/function.jpg
This image shows direct recording, by Goldwave, of our expander plugin. On the left is the original sound I played. This played out in stereo from FXbus into (on the left) the expander plugin, with the volume at 50%, then into WinMM recording, and (on the right) straight into WinMM recording. The result was recorded and shown on the right-hand side of this picture; the left (wet) channel on top in green, and right (dry) channel on the bottom in red. You can see that, because of the lowered volume setting, the wet signal is a little bit quieter than the right signal, but other than that, it is unchanged. (If the volume is set at 100%, then the signal clips heavily. I have not made a screenshot of that.) I read your code, and did the math, and you are right--it *should* do the exact thing I predicted. But it isn't. The transfer function is linear. It seems like the interp function is not being processed correctly. I don't know why. I don't know anything about DSP programming except what I read on your website. (I think it was your website anyway.) If interp works the way your website says it does, then this program will work the way it's supposed to... but it isn't. Any ideas? |
|
|
|
|
|
#13 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Again, the implementation is correct. I don't know which version are you using the first I posted (pseudo compressor) or the second (pseudo expander). I have tested both just to make shure and they both work. Do not make any modifications if you don't know nothing about dsp.
To test them, pass a 1 constant trough the input of the "compressor" (leave the 'cpmressor' value to 0.5) the output will be 0.5, meaning that the value of 1 is comressed to 0.5 and it is working. Pass a 0.5 constant to the input of the "expander". The output value will be 0.75, meaning that the value of 0.5 has expanded to 0.75 and it works. It works dude, perhaps you should start learning dsp.
__________________
Miss you, Steve... |
|
|
|
|
|
#14 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... Hi, guys! I made some tries and everything works! Nappylady, here there the two plots:
---> compressor ---> expander actually i'm using this: 2*x*(1-abs(x)*0.5) i set the values that Martin suggested not to touch as static registers, so there are no controls, there is no need. Thanks again Martin! Last edited by radiocolonel.it; May 21, 2005 at 12:44 PM. |
|
|
|
|
|
#15 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... hi, Martin, may i ask u some? Is there any way to improve- develop this plugin?
It would be cool making it more effective and flexible! Let me know! |
|
|
|
|
|
|
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
Okay, I fixed it!
http://www.naptastic.com/function2.jpg On the left is the sound I played. On the bottom-right is the sound recorded straight from FXbus -> WinMM recording. On the top-right is the same signal, passed through my expander before being recorded. You can see that the transfer function actually looks like I intended it to. Here is the code for the stereo version of the plugin: Code:
; Registers input lin, rin; output lout, rout; temp tmp, tmp2 ; Code macs tmp, 0x0, lin, 0x7fffffff; tstneg tmp2, tmp, tmp, 0x0; macsn tmp2, 0x20000000, tmp2, 0x40000000; macs tmp2, 0x0, tmp2, tmp; macints lout, 0x0, tmp2, 0x10; macs tmp, 0x0, rin, 0x7fffffff; tstneg tmp2, tmp, tmp, 0x0; macsn tmp2, 0x20000000, tmp2, 0x40000000; macs tmp2, 0x0, tmp2, tmp; macints rout, 0x0, tmp2, 0x10; end The gain is +12dB, and the plugin allows its output to reach +6dB on the peak meter... so perhaps a gain control would be a good idea, if you are using ProFX sources, or something really hot like that. Overall, it removes 6dB of dynamic range from the signal, which is nice if you are working with a vocalist who is inconsistent with her microphone. Coupling this plugin with a slower compressor is highly recommended. Thanks, everyone, for your help, and enjoy the plugin! |
|
|
|
|
|
#17 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Btw, this implementation is very clumsy, but if it works for you it's OK
![]() I now figured out why the implementation I proposed does not work for you. I always forget that when the signal gets into the dsp it is divided by 4 and when it leaves it it is multiplied by 4 (open the code of k2lt and you'll see what I mean). I always use dsp internal signals to test stuff. You use an external signal and when it enters the dsp it ends up being not from -1 to 1, but from -0.25 to 0.25 and the above formula starts to compress or expand somewhere above 0.5, so your signal never gets to that point and remains unchainged. Here's what you can do to test: compile my implementation, before the signal enters the plugin add a 'x4' plugin and after it leaves add a 'div4', then test. radiocolonel.it: you could easily add threshold control with 'limit' and 'limitn' instructions. Subsequently you could add attack and release times. |
|
|
|
|
|
#18 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
Thanks a lot Martin! i knew there was something strange...
i'll try to follow your tips, so i hope to come up with some useful stuff! Your help is always essential, Martin, thanks again!
|
|
|
|
|
|
#19 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... Hi Martin! This is the new code with the improvements u told me!
This time it seems to work properly as u described it. This is the code, please check if there is some wrong and test it! Martin please help me with adding a threshold, i tried but i came up with crop, what i was doing was too much incorrect i guess, can you make me an example? As always.. THANKS a LOT! code: input inl, inr output outl, outr static tmpl, tmpr, tl, tr, out_tl, out_tr ;in level macints tmpl, 0, inl, 0x4 macints tmpr, 0, inr, 0x4 ;abs(in) tstneg tl, tmpl, tmpl, 0 tstneg tr, tmpr, tmpr, 0 ;abs(in)*0.5 macs tl, 0, tl, 0.5 macs tr, 0, tr, 0.5 ;(in)*(1-abs(in)*0.5) interp tmpl, tmpl, tl, 0 interp tmpr, tmpr, tr, 0 ; 2* macints out_tl, 0, tmpl, 0x2 macints out_tr, 0, tmpr, 0x2 ;out level macs outl, 0, out_tl, 0.25 macs outr, 0, out_tr, 0.25 end Last edited by radiocolonel.it; May 25, 2005 at 03:35 PM. |
|
|
|
|
|
#20 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
As I understand this should be the expander version, right? If it works than everything is OK, it is far from optimized but 2-3 registers don't matter. I made a few tests and found that this thing compresses/expands much better and smoother than the available kX compressors/expanders, it's only problem is that it could not be tweaked like a standart compressor, but who cares
.You could add a kind of threshold with the 'limitn' instruction, something like this: EDIT:code removed You should adapt this to your code. Last edited by Tiger M; May 26, 2005 at 03:56 PM. |
|
|
|
|
|
#21 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... Yeah, this is made with the formula: 2*x*(1-abs(x)*0.5), so i named it Compander!
.. about the threshold can i set it as control? i mean i have to set a static register with a fixed value or is possible have it user controllable?[img]images/blue_heaven/smilies/rolleyes.gif[/img] ... i was making some rough tries and i came up with this weird code, this has nothing to do with the compander, it was just a try to understand how threshold things works, so please don't laugh at me! code: input in output out control thres=0, ratio=0.5 static tmp, tmp2, t, t2 tstneg tmp, in, in, 0 macs t, 0, in, thres macsn tmp2, in, t, 1 macs t2, t, tmp2, ratio limitn out, t, t2, tmp end
Last edited by radiocolonel.it; May 26, 2005 at 01:07 AM. |
|
|
|
|
|
#22 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
You should set it as a control register. The idea here is that when the uncompressed input value (absolute) gets higher than the threshold value the compressor steps in, if it is lower then the uncompressed value is passed to the output.
|
|
|
|
|
|
#23 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... Hi, Martin... please help me!!! The code i wrote above, with the threshold experiment (did u give a look at it?), works fine, i mean the threshold does what it should do: i tried to do the same with the compander code but it doesn't work! I don't undertstand why it doesn't work i did the same thing...
![]() ![]()
Last edited by radiocolonel.it; May 26, 2005 at 02:01 PM. |
|
|
|
|
|
#24 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
I tested my threshold idea and it doesn't work the way it should, since there is no relation between threshold and compression level, so you should forget about it, here is an optimized version of the above code (not tested):
Code:
input inl, inr output outl, outr temp tmp, tmp2, tmp3, tmp4 control expand=1 interp tmp3, 0, expand, 0.5 interp tmp4, 0.25, expand, 0.5 macints tmp, 0, inl, 0x4 tstneg tmp2, tmp, tmp, 0 macs tmp2, 0, tmp2, tmp3 interp tmp, tmp, tmp2, 0 macs outl, 0, tmp, tmp4 macints tmp, 0, inr, 0x4 tstneg tmp2, tmp, tmp, 0 macs tmp2, 0, tmp2, tmp3 interp tmp, tmp, tmp2, 0 macs outr, 0, tmp, tmp4 end Last edited by Tiger M; May 26, 2005 at 04:43 PM. |
|
|
|
|
|
|
|
DriverHeaven Addict
Join Date: Jun 2003
Posts: 257
Rep Power: 0 ![]() |
Okay, let me tell you the story behind this plugin
I play dances for local high schools, with my custom-made sound system. It plays as loud as 110 dB SPL without noticeable distortion. I can have my amplifiers (it's biamped) turned to 11 and the sound will still be totally clean. The kids are always asking me to turn it up, but there is only so much amp power available, and there's no way for me to drive the speakers to distortion. So, I thought, maybe it's because the sound is so clean, that the kids always want it louder. They want it to sound slightly distorted so they know it's "all the way up". That's where the idea for this plugin comes from: the transfer function looks about the same as if it were a speaker being driven past its limits. The curve itself comes from my lousy approximation of a Bl curve falling off above and below the voice coil gap. I like the name "Compander". It really gives a good description of what the plugin does. A threshhold control wouldn't really be the right solution for this plugin, since any signal going in that stays below -6dB (as read on "peak"; actually -12dBFS, I think ) will pass through with less than .5% distortion.There is one control that should be added, and that's an attenuator slider at the front, ranging from 0 (full strength) to -12dB. I don't know how to code this, I'm too lazy to figure it out myself, and besides, I have a fader on my mixer that does that task already! ![]() Max, I haven't tried this plugin on your FM synth yet, but I think it might sound really cool. One thing that does sound really cool: DRUMS. You have *GOT* to hear some good, clean drum solos dirtied up by this plugin. The amount of energy it adds is just unreal. |
|
|
|
|
|
#26 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Nappylady, check the above optimized code. Adding an attenuator slider would be easy, I'll see what I can do.
Oh, don't call me Max
|
|
|
|
|
|
#27 | |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
Quote:
Yap, it works! i just added at the static registers "tmp" that was missing. Thanks so much for your kind helping here! About the threshold... who cares as u said! This thing is simple but so much effective! |
|
|
|
|
|
|
#28 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
LAST REVISION:
Added an 'expand' slider. 0=unaltered signal; 1=max expanded signal. The amplitude remains the same, only the curve shape is changed. 'Compander' is a good name Code:
name "Compander"; copyright "Copyright (c) Nappylady, radiocolonel.it, Tiger M 2004."; created "05/26/2005"; engine "kX any"; comment "Simple, yet effective"; guid "f404199a-9f93-4db4-9c11-845a74743e79"; input inl, inr output outl, outr temp tmp, tmp2, tmp3, tmp4 control expand=1 interp tmp3, 0, expand, 0.5 interp tmp4, 0.25, expand, 0.5 macints tmp, 0, inl, 0x4 tstneg tmp2, tmp, tmp, 0 macs tmp2, 0, tmp2, tmp3 interp tmp, tmp, tmp2, 0 macs outl, 0, tmp, tmp4 macints tmp, 0, inr, 0x4 tstneg tmp2, tmp, tmp, 0 macs tmp2, 0, tmp2, tmp3 interp tmp, tmp, tmp2, 0 macs outr, 0, tmp, tmp4 end |
|
|
|
|
|
#29 |
|
DriverHeaven Lover
Join Date: Jan 2005
Location: Italy
Posts: 192
Rep Power: 0 ![]()
|
... i'm just trying it... what seems strange is that when expand slider is set at 50% the output exceeds 0 dB. This doesn't happen if i set it to 0 or 100%
|
|
|
|
|
|
#30 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Hmm, then the interpolation relation is not absolutely linear, I have to test and will probably have to make a c++ compile. Ok, to achieve the smae effect as before you should keep it at 100%.
Btw, nice songs last night , is there a way to learn the name of the song that is being played?
|
|
|
|
![]() |
| Thread Tools | |
|
|