Author |
Message |
emoc
Joined: Aug 24, 2006 Posts: 12 Location: France
|
Posted: Tue Jul 10, 2007 1:45 am Post subject:
distorsion |
|
|
Hi all,
This is my first post here! I'm beginning with chuck and would like to add some distorsion to sounds, what's the best way to do it? I've seen GenX functions in the last version, but there's much hardcore math in it... any example or advice ?
all the best, chuckers! |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Tue Jul 10, 2007 3:19 am Post subject:
|
|
|
Some quite-easy way I apply distortion is by a Transfer Function..
(try reading about Waveshaping technique)
But I might wanna introduce some very easy-to-apply
(and gives very short and understandable code also) ...
It's one of the waveshaping technique also.
It's by using the general oscillators we have here..
(Let's try SinOsc, TriOsc, SqrOsc)
They can be used as a transfer function:
it's like using a math function with a signal.
For SinOsc..
if you have signal with the output value of s
the result signal will be sin(s)
it's by setting the SinOsc's sync option to 1 (.. that's phase modulation mode)
So This means we're going to apply the signal you have to the phase of the Sine Wave Oscillator.
- - -
My Example with use a Sine Wave the source.
Code: | SinOsc signal => SinOsc overdrive => dac;
1 => overdrive.sync; // set sync option to Phase Mod.
4::second => now; |
after this, try changing signal's gain and freq.
gain from around 0.4 up will definitely show off some warm overdrive.
the more gain, the more distortion it gets.
With lots of gain, you'll get lots of harmonics out of a simple input signal.
You can replace the overdrive with TriOsc, SqrOsc (or even a SawOsc!)
and hear different kinds of overdrive / clipping..
(but most'd not sound as smooth as SinOsc..
TriOsc is interesting, it can produce a trianglish harmonics heheh)
This is one fast idea I want you to try out.
There are a number of methods left.
I still haven't implemented a lot. |
|
Back to top
|
|
|
emoc
Joined: Aug 24, 2006 Posts: 12 Location: France
|
Posted: Tue Jul 10, 2007 6:58 am Post subject:
|
|
|
Thanks Kijjaz for this crystal clear answer, i'll play with it, try to find some french explanations on waveshaping and come back |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Tue Jul 10, 2007 9:17 am Post subject:
|
|
|
Glad you enjoy one of my simple method.
That sine waveshaper is one of my favourite warm overdrive sound,
but it can sound too complex sometimes..
especially with high gains..
There is also another method,
but require longer code:
Using a shred to continuously calculating value of the waveshaping transfer function.
This can burn a lot more CPU power,
but you have more freedom to choose the function you'd like to use.
Code: | SinOsc signal => blackhole;
// define transfer function
fun float SineDrive(UGen input, UGen output)
{
Step result => output;
do Math.sin(2 * pi * input.last()) => result.next;
while (samp => now);
}
spork ~ SineDrive(signal, dac);
.7 => dac.gain; // keep the level down
// test various sinosc gain and freq
do
{
Std.rand2f(50, 1000) => signal.freq;
Std.rand2f(0.4, 20) => signal.gain;
.5::second => now;
}
while (true); |
Code: | SinOsc signal => blackhole;
// define transfer function
fun float AtanDrive(UGen input, UGen output)
{
Step result => output;
do Math.atan(input.last()) / pi => result.next;
while (samp => now);
}
spork ~ AtanDrive(signal, dac);
.7 => dac.gain; // keep the level down
// test various sinosc gain and freq
do
{
Std.rand2f(50, 1000) => signal.freq;
Std.rand2f(0.4, 50) => signal.gain;
.5::second => now;
}
while (true); |
These are two quite-short code for applying Sine waveshaping and Atan waveshaping.
These two are my favourites.
It has a warm kinda character..
it reminds me of Tube drive or something
but I don't know about theory.
Let's try a drive by using power of 3..
Code: | SinOsc signal => blackhole;
// define transfer function
fun float CubicDrive(UGen input, UGen output)
{
Step result => output;
do input.last() * input.last() * input.last() => result.next;
while (samp => now);
}
spork ~ CubicDrive(signal, dac);
.7 => dac.gain; // keep the level down
// test various sinosc gain and freq
do
{
Std.rand2f(50, 1000) => signal.freq;
Std.rand2f(0.4, 3) => signal.gain;
.5::second => now;
}
while (true); |
wow! .. nasty! ..
This is the way to directly apply "waveshaper transfer function"
you can check out more about distortion synthesis and waveshaping synthesis.
or check out waveshaper.
These I applied are only the basics of it
(I don't know any further hahahah) Last edited by kijjaz on Tue Jul 10, 2007 11:36 pm; edited 1 time in total |
|
Back to top
|
|
|
dewdrop_world
Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Jul 10, 2007 6:26 pm Post subject:
|
|
|
Like in trigonometry? sin, cos and tan? ChucK has one but it's expensive on the cpu to calculate that every sample. I seem to remember that tan(x) = sin(x) / cos(x) and that would be doable using Kijjaz's trick of using a oscilator as a lookup table and with a "gain" sety to devide.... I'll look into that, thanks! _________________ Kassen |
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24211 Location: The Netherlands, Enschede
Audio files: 281
G2 patch files: 320
|
Posted: Tue Jul 10, 2007 6:35 pm Post subject:
|
|
|
Kassen wrote: | Like in trigonometry? |
More like this maybe, although tan I've seen used for distortion before, not tanh. _________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Tue Jul 10, 2007 11:35 pm Post subject:
|
|
|
This (on Wikipedia) seems quite an interesting optimization.
But never tried Tanh myself.
I like the soft clipping sound of atan.
- - -
Blue Hell:
Yes.
I've used Tan for distortion.
but we can noticed that Tan can yeild very big values..
so it's not usually appropriate for straight connect to dac.
Waveshaping it in someway, or using it to modulate other signals seems to be safer.
(But I still insist you all hear out that destructive clipping created by sending Tan waveshaped signal to DAC hahahahah!)
- - -
There's an easy way to achive tan with ChucK's UGens
It's by dividing a sin with a cos of the same input.
Code: | SinOsc s1 => Gain divider => blackhole;
Step phaseshifter => SinOsc s2 => divider;
// make s1 and s2 phase syncable
1 => s1.sync => s2.sync;
// make s2 phase's 90 degree ahead of s1
0.25 => phaseshifter.next;
// disable s1 and s2's frequency
0 => s1.freq => s2.freq;
// set divider gain .op mode to division
4 => divider.op;
// connect the signal to you want to feed into tan function
Step test => s1;
test => s2;
// TESTING..
for(float i; i < 1; 0.05 +=> i)
{
i => test.next;
10::ms => now;
<<< i, divider.last() >>>;
}
// now the signal feeded into both s1, s2
// will produce tan() result out of "divider"
// that's all folks! |
|
|
Back to top
|
|
|
dewdrop_world
Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Wed Jul 11, 2007 4:42 am Post subject:
|
|
|
No, not tan, tanh - hyperbolic tangent - http://mathworld.wolfram.com/HyperbolicTangent.html
In distortion you want low-level input to be basically unchanged, but higher amplitude values should be "squished" lower. So the transfer function should have an s-curve, with a higher slope in the center and lower at the edges.
The normal trigonometric tangent has an infinite slope at pi * x where x is 2*i + 0.5, so it's not a good candidate for classic distortion (though it may be good for other outrageous sounds).
Graphed in SuperCollider, tanh looks like this, ranging from -1.0 to +1.0.
SC also implements y / (1.0 + abs(y)) as a primitive for distortion. Nice sound, actually.
James
Description: |
tanh graphed -1.0 .. +1.0 |
|
Filesize: |
29.04 KB |
Viewed: |
35247 Time(s) |
|
_________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net Last edited by dewdrop_world on Sun Aug 26, 2007 1:20 pm; edited 1 time in total |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Wed Jul 11, 2007 2:38 pm Post subject:
|
|
|
Wow.. dewdrop_world ,
y / (1 + abs(y)) ! .. that's one idea i never tried for distortion!
It looks so simple.. I'm gonna hear and see it distorting a sine wave right away...
That's a lovely function.. The result won't go outside -1 to 1 range also..
The slope at the origin is also equal to 1
note:
dy/dx of x/(a+abs(x)) = 1/(abs(x)+1)-x^2/(abs(x)*(abs(x)+1)^2)
That makes me wanna tryout with this one also..
y / (1 + y^2)
From looking at the graph, i suspect it'll produce an interesting modern distortion sound if y's amplitube's going over 1.
- - -
Me trying out x/(1+|x|) drive with SinOsc
hmm.. sounds Tube-warm.
Code: | // use SinOsc as the source
// calculate abs()
SinOsc s => FullRect abs_s;
// calculate 1 + abs(source) to use as the divisor
abs_s => Gain divisor;
Step one => divisor;
1 => one.next;
// divide source by the divisor
s => Gain division;
divisor => division;
4 => division.op;
// hear out. (try different gain)
2.5 => s.gain;
division => dac;
5::second => now; |
and also with the x/(1+x^2)
.. wow! I hear them odd harmonics coming out!
Code: | // use SinOsc as the source
// calculate source ^ 2
SinOsc s => Gain s_power2;
s => Gain s_dummy => s_power2;
3 => s_power2.op;
// calculate 1 + source ^ 2 to use as the divisor
s_power2 => Gain divisor;
Step one => divisor;
1 => one.next;
// divide source by the divisor
s => Gain division;
divisor => division;
4 => division.op;
// hear out. (try different gain)
10 => s.gain;
division => dac;
5::second => now; |
- - -
plots of the functions in our interest:
atan(x), x / (1 + |x|), x / (1 + x^2)
http://electro-music.com/forum/gallery2.php/v/kijjaz/plot2d+-+atan+x.png.html
http://electro-music.com/forum/gallery2.php/v/kijjaz/plot2d+-+x+over+1+_+abs+x.png.html
http://electro-music.com/forum/gallery2.php/v/kijjaz/plot2d+-+x+over+1+_+x+pow+2.png.html
note, atan has output value in the range (-pi/2, pi/2)
and x / (1 + |x|), x / (1 + x^2) both have output value in the range [-1, 1]
so when I use atan waveshaping to connect directly to dac,
I usually divide it with pi/2 to make it limit to the range (-1, 1)
so no digital clipping can occur. |
|
Back to top
|
|
|
dewdrop_world
Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Wed Jul 11, 2007 7:31 pm Post subject:
|
|
|
kijjaz wrote: | Wow.. dewdrop_world ,
y / (1 + abs(y)) ! .. that's one idea i never tried for distortion! |
I can't claim credit, of course -- I just looked at the source code for the .distort primitive. But I agree, it's simple and elegant and sounds good. I use it routinely when I need a little grit in the sound.
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Thu Aug 02, 2007 5:49 am Post subject:
|
|
|
Are there already names for these particular distortions?
I'd like to define them in some way in my code library..
(possibly, these are being added to my include-chuck-code) |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Thu Aug 23, 2007 1:14 am Post subject:
|
|
|
I've tried another distortion waveshaping:
f(x) = x^3 / (1 + |x^3|)
it sounds so chubby and warm.
just to let you all know & try it also. |
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Thu Aug 23, 2007 4:43 am Post subject:
|
|
|
Cool! Have you tried rewriting that as a set of Gain's, a Step and a wave rectifier yet? That won't look as clean or read as easily but it should save a handsome amount of CPU. _________________ Kassen |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Thu Aug 23, 2007 10:03 pm Post subject:
|
|
|
This is one of my implementation for the function:
Code: | class overdrive03_01
{
// this overdrive UGen applies f(x) = x^3 / (1 + abs(x^3)) waveshaping function
// to the "in"put signal and output to "out".
Gain in; Gain out; // chuck or unchuck this to the outside world to connect;
// prepare input ^ 3
in => Gain CubeOfInput;
in => Gain inDummy1 => CubeOfInput;
in => Gain inDummy2 => CubeOfInput;
3 => CubeOfInput.op;
// prepare abs(input ^ 3)
CubeOfInput => FullRect Abs;
// prepare 1 + abs(input ^ 3) .. to be used as the "divisor"
Step one => Gain divisor;
1.0 => one.next;
Abs => divisor;
// calculate input^3 / (1 + abs(input ^ 3)) and send to "out"
CubeOfInput => out;
divisor => out;
4 => out.op; // <-- make out do a division of the inputs
}
// Testing by feeding Sine Wave at 110hz into the drive unit.
overdrive03_01 drive;
SinOsc s => drive.in;
drive.out => dac;
110.0 => s.freq;
for(int i; i < 10; i++)
{
i * .5 => s.gain;
second => now;
} |
Like the other calculations, main mechanism is only using Gains and a FullRect
Gains for summing, division, multiplication .. and FullRect for absolute
I guess this is not too CPU consuming
Hmm.. How can I test the exact consumption rate of CPU that
chuck is consuming? hopefully for comparing between shreds?
I'd like to try that sometimes to compare between various methods. ^_^ |
|
Back to top
|
|
|
Consul
Joined: May 05, 2007 Posts: 59 Location: Port Huron, Michigan, USA
|
Posted: Wed Aug 29, 2007 1:34 pm Post subject:
|
|
|
Kijjaz,
I had sent you an email about this through the board a couple of days ago, but I have no way of knowing whether you received it, so I thought I'd ask here.
I implemented your distortion algorithms, as well as the SC one, in a system called Jesusonic, which is part of the Reaper DAW. However, before releasing my little JS plug-in on the world (under the GPL), I wanted to get your permission to use your derived functions, as well as find out how you want to be credited.
I look forward to hearing back from you. Thanks!
Here's what the Jesusonic script looks like, if you're curious:
Code: | // Tristortion
//
// This is an implementation of f(x) = x/(1+|x|), f(x) = x^3 / (1 + |x^3|),
// and f(x) = x/(1+x^2) as distortion algorithms. The first is courtesy of
// SuperCollider. The second and third are courtesy of Kijjaz from the ChucK
// forums on electromusic.com.
//
// (C) 2007 Darren Landrum
// Licensed under the GNU General Public License, Version 2.
// Uses algos from Kijjaz of the ChucK forums, and Supercollider.
desc: Tristortion - Three Flavors in One
slider1:0<0,1,1{Mono,Stereo}>Input Type
slider2:0<0,2,1{Warm,Harsh,Crunchy}>Flavor
slider3:1<.5,30,.1>Drive
@slider
input_type = slider1;
dist_type = slider2;
drive = slider3;
@sample
input_type == 0 ? (
in0 = spl0 + spl1; // sum to mono
in1 = in0;
) : input_type == 1 ? (
in0 = spl0;
in1 = spl1;
) : 0;
// The drive is simply a multiplier for the input.
// Eventually, I'll change how this works, I'm sure.
in0 = drive * in0;
in1 = drive * in1;
dist_type == 0 ? (
out0 = in0 / (1 + abs(in0));
out1 = in1 / (1 + abs(in1));
) : dist_type == 1 ? (
in0 = in0 ^ 3;
in1 = in1 ^ 3;
out0 = in0 / (1 + abs(in0));
out1 = in1 / (1 + abs(in1));
) : dist_type == 2 ? (
insq0 = in0 ^ 2;
insq1 = in1 ^ 2;
out0 = in0 / (1 + insq0);
out1 = in1 / (1 + insq1);
) : 0;
// Output
spl0 = out0;
spl1 = out1; |
_________________ Darren Landrum
"Never be afraid to try something new. Remember that a lone amateur built the Ark. A large group of professionals built the Titanic." - Dave Barry Last edited by Consul on Thu Aug 30, 2007 5:54 am; edited 2 times in total |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Thu Aug 30, 2007 4:40 am Post subject:
|
|
|
Consul,
Thanks for giving me credits for the distortion ideas..
but actually I myself still can't find places that might give these kinds of waveshaping function,
so let's check out more..
If it's really unique, I'd be glad to share the idea with you.
But I guess it's quite easy and it may have names already ^_^"
Maybe an electrical engineering person can explain this more,
I guess I'll read more about analog circuits and its analysis.
Hmm.. sounds like electrical engineering calculus.. |
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Thu Aug 30, 2007 5:51 am Post subject:
|
|
|
Consul wrote: |
NOTE: This is NOT what the code looks like! For some reason, this board is parsing out and removing pieces of the code, which means copying and pasting this into Jesusonic would NOT WORK! However, the algorithms did survive just fine, so you can at least see how I did it.
|
Most likely you accidentally didn't tick the box to disable HTML. If you don't the board will think it's HTML as soon as it sees triangular brackets, even within the CODE tag. This is a known bug. _________________ Kassen |
|
Back to top
|
|
|
Consul
Joined: May 05, 2007 Posts: 59 Location: Port Huron, Michigan, USA
|
Posted: Thu Aug 30, 2007 5:59 am Post subject:
|
|
|
Kassen, thank for the tip. I'm not used to phpBB ever being configured to allow HTML, so I never thought of this one. It's fixed now. I also fixed the misspelling of Kijjaz's name.
Kijjaz,
I don't understand completely, but it sounds like you're asking me NOT to release this. If that's the case, I'll remove the second two algos and just go with the SC one, since that's GPL IIRC. Really, I just did this for the learning experience, and to get my feet wet with Jesusonic. It's also still quite beta, and has some behaviors I'd like to fix, but don't quite know how.
There are some really talented DSP guys on the Reaper boards. If I release this over there, they can comment further on things, including maybe how I can do better scaling of the input slider. _________________ Darren Landrum
"Never be afraid to try something new. Remember that a lone amateur built the Ark. A large group of professionals built the Titanic." - Dave Barry |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Thu Aug 30, 2007 7:31 am Post subject:
|
|
|
Oh sorry,
what I mean is that I'm not sure if anybody already owns the methods..
they are actually my ideas,
but I'm not sure if it's already there in text books or programs.
And I'm still not sure where I should check because from googling,
I still find equation not identical to those two I introduced to you.
hmm.. If there's no statement of the formulas anywhere,
i'd feel sure to claim that it's my idea.
Anyone knows where I should check more?
I'd love to share these formulas, but I'm just not sure if anyone has released them in their names. |
|
Back to top
|
|
|
Consul
Joined: May 05, 2007 Posts: 59 Location: Port Huron, Michigan, USA
|
Posted: Thu Aug 30, 2007 10:07 am Post subject:
|
|
|
Well, you derived them yourself, so as far as I'm concerned, you came up with it independently of whoever else may have, so unless they're patented, I think you're good with claiming them.
That's just my opinion, though. _________________ Darren Landrum
"Never be afraid to try something new. Remember that a lone amateur built the Ark. A large group of professionals built the Titanic." - Dave Barry |
|
Back to top
|
|
|
kijjaz
Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Thu Aug 30, 2007 1:59 pm Post subject:
|
|
|
And as far as I searched, I see no such identical formulas..
Consul: Please use them in your code. Thanks for the credit.
I'll wait to hear some feedback also.
They're not sounding very classic,
but they sound good for such a simple formula. |
|
Back to top
|
|
|
Consul
Joined: May 05, 2007 Posts: 59 Location: Port Huron, Michigan, USA
|
Posted: Thu Aug 30, 2007 4:15 pm Post subject:
|
|
|
Thank you! I'll unleash this on the Reaper folks and see what they think. No doubt improvements will be forthcoming. _________________ Darren Landrum
"Never be afraid to try something new. Remember that a lone amateur built the Ark. A large group of professionals built the Titanic." - Dave Barry |
|
Back to top
|
|
|
Consul
Joined: May 05, 2007 Posts: 59 Location: Port Huron, Michigan, USA
|
Posted: Thu Aug 30, 2007 4:56 pm Post subject:
|
|
|
Here's a link to the Reaper forum post:
http://www.cockos.com/forum/showthread.php?t=12296 _________________ Darren Landrum
"Never be afraid to try something new. Remember that a lone amateur built the Ark. A large group of professionals built the Titanic." - Dave Barry |
|
Back to top
|
|
|
Consul
Joined: May 05, 2007 Posts: 59 Location: Port Huron, Michigan, USA
|
Posted: Thu Aug 30, 2007 10:57 pm Post subject:
|
|
|
Sorry for the triple-in-a-row post, but I'm afraid the Kijjaz algorithms didn't work out for now. They were soaking up about 28% of mine and others' CPU, which is outrageously high. Until I can sort that out, I'm back to the good old SC one, which maxes out at 2%. It's now called Compstortion.
I still give you credit for the inspiration. _________________ Darren Landrum
"Never be afraid to try something new. Remember that a lone amateur built the Ark. A large group of professionals built the Titanic." - Dave Barry |
|
Back to top
|
|
|
|