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.
Here is how I'd translate that to C: Code (Text): #include <stdio.h> #include <math.h> int main() { double v; printf("Type a number: "); scanf("%lf", &v); v = pow(10, (log10(v / 32768) * 0.866667)) * 32768; printf("Result: %lf\n", v); return 0; } Quite straightforward when you know the necessary functions!
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): in = 25801.000000 in / 32768 = 0.787384 log10(in / 32768) = -0.005039 log10(in / 32768) * 0.466667 = -0.061605 pow(10, (log10(in / 32768) * 0.466667)) = 0.844949 pow(10, (log10(in / 32768) * 0.466667)) * 32768 = 29078.600561 out 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...
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).
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!
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) ?
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.
I could not really understand logarithms at school... but I do know that in sound stuff 6db attenuation means 50% lower volume :P
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!) =)
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, 6x = 1296 If you want to find x: x = log6(1296) Here, x is 4. If you want to do that on your calculator, you can use this: logn(1296) ÷ logn(6) where n is any strictly positive real number. Usually, log10 and loge (also called ln) are available on scientific calculators. Make sure you use the same base for both logarithms! That's the most important stuff about logarithms. If you need more information, a quick search on the Internet will probably help you.
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 logn(x)=logn(y) [keep the bases the same!] ln(e)=1 [ln is loge; 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] eI*x=cos(x)+Isin(x) [the I should be lowercase as it's supposed to be sqrt(-1)] WOO MATH
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...
I know this has been calculated before, but just try my code... Just copy, paste and compile: Code (Text): #include <stdio.h> #include <math.h> int main (int argc, const char * argv[]) { double v; printf("Type a number: "); //scanf("%lf", &v); v=25801.000000; printf("in = %lf\n", v); v/=32768; printf("in / 32768 = %lf\n", v); v=log10(v); printf("log(in / v) = %lf\n", v); v*= 0.466667; printf("log(in / v) * 0.466667 = %lf\n", v); v=pow(10.0,v); printf("v = pow(10, (log10(v / 32768) * 0.466667)) = %lf\n", v); v*=32768; printf("Result: %lf\n", v); return 0; } 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!