# Math and Programming Help Needed

Discussion in 'Technical Discussion' started by saxman, Feb 1, 2009.

1. ### saxman

Oldbie Tech Member
I know what I want to do on paper, but I can't seem to translate it into working C code. Here's what I want:

V = AntiLog10(Log10(V / 32768) * 0.866667) * 32768

I'm trying to use a bell curve to make small numbers bigger, and the higher V is initially, the less it gets increased. I'm fairly certain the top formula is correct. So he's what I've translated into code:

Okay, now if someone could show me how to turn that into working C code, that'd be very helpful!

EDIT: For anyone curious, it's sound compression I'm attempting here. The 'V' is a binary number representing the amplitude of the sound. I'm raising the very bottom by 12dB, and raising higher amplitudes by less, and the very tip-top by nothing. That's the idea anyhow.

2. ### FraGag

Tech Member
Here is how I'd translate that to C:
Code (Text):
1. #include <stdio.h>
2. #include <math.h>
3.
4. int main()
5. {
6.     double v;
7.     printf("Type a number: ");
8.     scanf("%lf", &v);
9.     v = pow(10, (log10(v / 32768) * 0.866667)) * 32768;
10.     printf("Result: %lf\n", v);
11.     return 0;
12. }
Quite straightforward when you know the necessary functions!

3. ### saxman

Oldbie Tech Member
You're a life saver! Except... now I'm having another issue... my volume level is lower that I expected. After analyzing some results, I came across this:

I wrote a string to the screen to display the values at each stage of the calculation, and something is seriously wrong here:
Code (Text):
1. in =
2. 25801.000000
3.
4. in / 32768 =
5. 0.787384
6.
7. log10(in / 32768) =
8. -0.005039
9.
10. log10(in / 32768) * 0.466667 =
11. -0.061605
12.
13. pow(10, (log10(in / 32768) * 0.466667)) =
14. 0.844949
15.
16. pow(10, (log10(in / 32768) * 0.466667)) * 32768 =
17. 29078.600561
18.
19. out
20. 32591.054014
The in and out values are determined before this screen write. I'm simply comparing different stages of the in, but it amazes me the final result for in doesn't even match that of the out. Both in and out are doubles. Still, neither the final in result or the out are correct. The final result is "supposed" to be 29309.178697. Can someone explain this to me?

EDIT: Crap, I just realized I created a limiter, not a compressor *palms*
Well, still doesn't quite explain the numbers, but it sounds alright...

4. ### FraGag

Tech Member
This result is wrong. I don't know why, because I get the correct result (-0.103813).
This is what I get. I'm using GCC 4.2.1-dw2 (mingw32-2).

5. ### saxman

Oldbie Tech Member
I didn't figure out the problem, but the audio sounds fine. So I'll leave it. My compressor/limiter is working, woohoo! I have a variable controlling the compression ratio, and I can change it and hear the difference. I have my volume down lower than normal, but compressing at 3:1, you can't even tell the volume was ever lowered! This is neat stuff.

Anyway, thanks FraGag, I appreciate it very much!

6. ### Sith

The molotov bitch Member
I just finished studying basic log math at school.
Stupid noobish question: do you mean 10log(in/32768) like in the standard Briggs logarithm or is the 10 not the ground number but something else?
10log10*(in/32768) ?

7. ### saxman

Oldbie Tech Member
If you mean "is 10 the base", then yes it is. Otherwise, you went over my head!

8. ### Sith

The molotov bitch Member
Yes Sax, that's what I meant.
Where I learned this stuff they write the base in front of log and you guys write it after. Must be a US and Europe difference thing again.
Also they said, if the base number is the standard number 10 it isn't displayed at all: eg log(500) = base 10 with result 500.
I'm sure you know this since ages lol.

Thx for clearing it up for me.

9. ### TmEE

Master of OPL3-SA2/3 Tech Member
1,726
0
16
Estonia, Rapla City
T-04YBSC-A !
I could not really understand logarithms at school... but I do know that in sound stuff 6db attenuation means 50% lower volume :P

10. ### saxman

Oldbie Tech Member
That's right, and if you double or half your distance from a microphone or loud speaker, that's a difference of 6dB too! I have a sound book that is full of interesting facts like this. It's really fun stuff (for me at least!) =)

11. ### FraGag

Tech Member
Some people say I'd make a good teacher, so here's a quick course on logarithms!

"Logarithm" is a synonym of "exponent." If you have an expression where the exponent is unknown, you use the logarithm function to find it. For example,

6[sup]x[/sup] = 1296

If you want to find x:

x = log[sub]6[/sub](1296)

Here, x is 4. If you want to do that on your calculator, you can use this:

log[sub]n[/sub](1296) ÷ log[sub]n[/sub](6)

where n is any strictly positive real number. Usually, log[sub]10[/sub] and log[sub]e[/sub] (also called ln) are available on scientific calculators. Make sure you use the same base for both logarithms!

12. ### muteKi

Fuck it Member
more log rolling:

log(x)+log(y)=log(x*y)
log(x)-log(y)=log(x/y)

d/dx ln(x) = 1/x

let x=y then log[sub]n[/sub](x)=log[sub]n[/sub](y) [keep the bases the same!]

ln(e)=1 [ln is log[sub]e[/sub]; really, any time the base and the number being log'd are the same, it's 1]

log(0)=undefined
log(x)=undefined where x<0 [the less than or equal to sign isn't on this keyboard so it's easier to type this]

e[sup]I*x[/sup]=cos(x)+Isin(x) [the I should be lowercase as it's supposed to be sqrt(-1)]

WOO MATH

13. ### TmEE

Master of OPL3-SA2/3 Tech Member
1,726
0
16
Estonia, Rapla City
T-04YBSC-A !
I'm slowly remembering some stuff from school.... I threw a BIG BIG pile of math papers away some weeks ago... over 300 A4 sheets of math stuff I barely understood, and without teacher they're worthless anyway...

14. ### Pablo

Member
I know this has been calculated before, but just try my code... Just copy, paste and compile:

Code (Text):
1. #include <stdio.h>
2. #include <math.h>
3.
4. int main (int argc, const char * argv[]) {
5.     double v;
6.     printf("Type a number: ");
7.     //scanf("%lf", &v);
8.     v=25801.000000;
9.     printf("in = %lf\n", v);
10.     v/=32768;
11.     printf("in / 32768 = %lf\n", v);
12.     v=log10(v);
13.     printf("log(in / v) = %lf\n", v);
14.     v*= 0.466667;
15.     printf("log(in / v) * 0.466667 = %lf\n", v);
16.     v=pow(10.0,v);
17.     printf("v = pow(10, (log10(v / 32768) * 0.466667)) = %lf\n", v);
18.     v*=32768;
19.     printf("Result: %lf\n", v);
20.     return 0;
21. }
May I ask what compiler you are using? Works fine here on GCC 4.0.1

What I reccommend doing is playing around with the constants. try 32768.0 and 10.0 instead of 32768 or 10

Why? Some overloaded function might do funky stuff and it might vary a bit from compiler to compiler even though it shouldn't... You never know these days. Coercion can screw you around pretty badly!