Math and Programming Help Needed

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

  1. saxman

    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

    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! :colbert:
     
  3. saxman

    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

    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

    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

    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

    saxman

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

    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

    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

    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

    FraGag

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

    "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!

    That's the most important stuff about logarithms. If you need more information, a quick search on the Internet will probably help you.
     
  12. muteKi

    muteKi

    Fuck it Member
    7,587
    6
    18
    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

    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

    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!