Spin Semiconductor Forum Index Spin Semiconductor
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

tanH soft clipping

 
Post new topic   Reply to topic    Spin Semiconductor Forum Index -> Algorithm development
View previous topic :: View next topic  
Author Message
MacroMachines



Joined: 12 Dec 2014
Posts: 70
Location: Detroit,MI

PostPosted: Sat Aug 20, 2016 2:45 am    Post subject: tanH soft clipping Reply with quote

Im wondering if there is a way to get tanh(x) style function in the FV-1? I use it alot in my algorithm designs for warm clean saturation, but I really have no idea how i would replicate these nice non linearities in assembler with the available opcodes. I am guessing it would have something to do with log/exp?

Hyperbolic tangent
The hyperbolic tangent is the solution to the differential equation
f'=1-f^{2} with f(0)=0 and the nonlinear boundary value problem:
1/2fn=f3-f; f(o)=f1(infinity) = 0

I am not a math pro and I really don't know what this means. I am trying to learn as its becoming useful in this DSP design world but damn its like learning a new language from trying to google the definition of each word hah.

Some music DSP info that is somewhat enlightening :
http://www.musicdsp.org/showone.php?id=178

"tanh(x) = sinh(x)/cosh(x)
= (exp(x) - exp(-x))/(exp(x) + exp(-x))
= (exp(2x) - 1)/(exp(2x) + 1)"

he also explains a taylor series for the exp approximation. but the above equation looks like something that could happen in spinASM relatively easily, but how to account for the /16 aspect of the exp opcode?

in the comments of the thread I found these:
tanh (x) = 1 - 2 / (exp (2*x) + 1)

tanh(x/2)~ x/(abs(x)+3/(2+x*x))

tanh(x/2) ~ x/(abs(x)+2/(2.12-1.44*abs(x)+x*x)) Maximum normalized difference 0.0063 from real tanh (x/2) - good enough now.


Here's the Analog Devices "Sharc" DSP translation of the tanh function (inline processing of register f0):
Code:
f11 = 2.;
f0 = f0 * f11;
f11 = abs f0;
f3 = 3.;   
f12 = f11+f3;
f12 = f11*f2;
f3 = 6.;
f12 = f12+f3;
f0 = f0*f12;
f12 = f11*f12;
f7 = 12.;
f12 = f12+f3;
f11 = 2.;
f0 = recips f12,
f7=f0;
f12=f0*f12;
f7=f0*f7,
f0=f11-f12;
f12=f0*f12;
f7=f0*f7,
f0=f11-f12;
f12=f0*f12;
rts(db);
f7=f0*f7,
f0=f11-f12;
f0=f0*f7;

_________________
http://MacroMachines.net
Digital Control for your Analog Soul.
Back to top
View user's profile Send private message Visit poster's website AIM Address
Iconnu



Joined: 17 Apr 2014
Posts: 10

PostPosted: Sat Aug 20, 2016 7:35 am    Post subject: Reply with quote

from:

https://varietyofsound.wordpress.com/2011/02/14/efficient-tanh-computation-using-lamberts-continued-fraction/


x2 = x * x

a := x(135135 + x2(17325 + x2(378 + x2)))

b := 135135 + x2(62370 + x2(3150 + 28x2))

tanh(x) = a/b


dividing each by 135135

a := x(1 + x2(0.1282051282 + x2(0.002797202797 + x2)))

b := 1 + x2(0.4615384615 + x2(0.02331002331 + 0.0002072002072x2))

Iconnu
Back to top
View user's profile Send private message
MacroMachines



Joined: 12 Dec 2014
Posts: 70
Location: Detroit,MI

PostPosted: Sat Aug 20, 2016 9:09 am    Post subject: Reply with quote

http://www.musicdsp.org/showone.php?id=238:



This is a rational function to approximate a tanh-like soft clipper. It is based on the pade-approximation of the tanh function with tweaked coefficients.

The function is in the range x=-3..3 and outputs the range y=-1..1. Beyond this range the output must be clamped to -1..1.

The first to derivatives of the function vanish at -3 and 3, so the transition to the hard clipped region is C2-continuous.

Code:
Code :
float rational_tanh(x)
{
    if( x < -3 )
        return -1;
    else if( x > 3 )
        return 1;
    else
        return x * ( 27 + x * x ) / ( 27 + 9 * x * x );
}

_________________
http://MacroMachines.net
Digital Control for your Analog Soul.
Back to top
View user's profile Send private message Visit poster's website AIM Address
MacroMachines



Joined: 12 Dec 2014
Posts: 70
Location: Detroit,MI

PostPosted: Sat Aug 20, 2016 10:15 am    Post subject: Reply with quote

Iconnu wrote:
from:

https://varietyofsound.wordpress.com/2011/02/14/efficient-tanh-computation-using-lamberts-continued-fraction/


x2 = x * x

a := x(135135 + x2(17325 + x2(378 + x2)))

b := 135135 + x2(62370 + x2(3150 + 28x2))

tanh(x) = a/b


dividing each by 135135

a := x(1 + x2(0.1282051282 + x2(0.002797202797 + x2)))

b := 1 + x2(0.4615384615 + x2(0.02331002331 + 0.0002072002072x2))

Iconnu



Thank you Iconnu,

I am curious if you know how I might begin to go about boiling this down into FV-1 opcodes, especially with regard to the divide by 16 and multiply by 16 that happen in log/exp.

EDIT: I just read the article and they have an assembler code image : https://varietyofsound.files.wordpress.com/2011/02/lamberts_cf_opt_asm.png
" 13 multiply/adds plus a division " so if I use MAC ops like RDAX and SOF, if I am not mistaken I still need to use exp/log for the division, but I really am not sure if I understand how to do that. The knowledge base sheds a little insight:

__________________
To accomplish this, we will produce a 1/X output from the detector, and divide the result by 4 (multiply by 0.25). To produce 1/X, we do:

EXP( LOG (1) - LOG(X) )
This is simple division, and since LOG(1) is always zero, we can effectively find 1/X by taking the LOG, changing the result's sign, and doing an EXP on the result. Only changing the sign of the LOG result however, will produce an EXP result that is out of range. The LOG2 of 0.25 (our threshold) is -2, and after the LOG scaling of 16, will be numerically represented as -2/16, or -0.125. We will then change the sign of the LOG value by multiplying it by -1, giving us a +0.125 result. We want the output from the EXP function at this point to be 1, which requires a 0 value going into the EXP function. To accomplish this, we will write:

LOG -1.0,-0.125
EXP 1,0

____________________


I also found an asymmetric version that I remembered from the audulus forum:
http://folk.ntnu.no/oyvinbra/gdsp/Lesson4Modtanh.html
http://forum.audulus.com/discussion/comment/6179#Comment_6179

(e^x-e^-x)/(e^x+e^-x)

this asymmetric version a and b are offset values for positive and negative parts of the wave, it sounds good and useful for distortion. G is gain and x is input.
(exp(x*(a+G))-exp(x*(b-G)))/(exp(x*G)+exp(x*-G))
_________________
http://MacroMachines.net
Digital Control for your Analog Soul.
Back to top
View user's profile Send private message Visit poster's website AIM Address
MacroMachines



Joined: 12 Dec 2014
Posts: 70
Location: Detroit,MI

PostPosted: Sat Aug 20, 2016 10:42 am    Post subject: Reply with quote

EXP( LOG(X) - LOG(Y) ) = X/Y.


rereading the knowledge base on log/exp for the 5th time I think Im getting it now that I have an incentive

EXP( LOG(X) + LOG(Y) ) = X*Y.
Further, numbers could be divided:
EXP( LOG(X) - LOG(Y) ) = X/Y.
Finally, any number can be raised to any power with the use of LOG and EXP.

EXP( LOG(X) *2) = X2.
EXP( LOG(X) / 2) = X0.5 (square root)

_________________
http://MacroMachines.net
Digital Control for your Analog Soul.
Back to top
View user's profile Send private message Visit poster's website AIM Address
Iconnu



Joined: 17 Apr 2014
Posts: 10

PostPosted: Sat Aug 20, 2016 1:05 pm    Post subject: Reply with quote

writing this down a little bit quick since I need to go out...

EQU X2 REG0
EQU X REG1
EQU A REG2
EQU B REG3
EQU TANH REG4

; X has been calculated and it resides in the register already...

LDAX X
MULX X
WRAX X2,0

; CALC A

LDAX X2
SOF 1, 0.002797202797
MULX X2
SOF 1, 0.1282051282
MULX X2
MULX X
RDAX X,1
WRAX A,0

;CALC B

LDAX X2
SOF 0.0002072002072, 0
SOF 1, 0.02331002331
MULX X2
SOF 1, 0.4615384615
MULX X2
SOF 1, 0.5
SOF 1, 0.5
WRAX B,0

LDAX B
LOG -1.0,-0.125
EXP 1,0
MULX A
; include a few SOF statements below to compensate level as "needed"
SOF -2,0
SOF -1,0
; etc....
;
WRAX TANH,0 ; your approx tanh value for X
Back to top
View user's profile Send private message
MacroMachines



Joined: 12 Dec 2014
Posts: 70
Location: Detroit,MI

PostPosted: Sun Aug 21, 2016 5:36 pm    Post subject: Reply with quote

Wow! thank you so much Very Happy
so I guess you divided the two by using log -1, -.125 and exp 1, 0 ?

Iconnu wrote:

LDAX B
LOG -1.0,-0.125
EXP 1,0
MULX A


Wow thank you!! Ok, so now I understand the spin knowledge base bit on 1/x.. I am a bit math-tarded so I had forgotten that 1/x was what I need in this workflow for most of my division.

"This is simple division, and since LOG(1) is always zero, we can effectively find 1/X by taking the LOG, changing the result's sign, and doing an EXP on the result. Only changing the sign of the LOG result however, will produce an EXP result that is out of range. The LOG2 of 0.25 (our threshold) is -2, and after the LOG scaling of 16, will be numerically represented as -2/16, or -0.125. We will then change the sign of the LOG value by multiplying it by -1, giving us a +0.125 result. We want the output from the EXP function at this point to be 1, which requires a 0 value going into the EXP function. To accomplish this, we will write:

LOG -1.0,-0.125
EXP 1,0
"



I think I am also beginning to understand that floating point is probably where tanh really shines.. because you can get a great scaled signal that never hard clips. very curious to see how this will work out in fixed point with an approximation like this. I will check it out right now! Very Happy

Again, thank you very much this was tremendously helpful and enlightening!
_________________
http://MacroMachines.net
Digital Control for your Analog Soul.
Back to top
View user's profile Send private message Visit poster's website AIM Address
Display posts from previous:   
Post new topic   Reply to topic    Spin Semiconductor Forum Index -> Algorithm development All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group