Modulus question!

This is a discussion on Modulus question! within the C Programming forums, part of the General Programming Boards category; Hi ppl! ...I have a quick question! ...I am designing an audio effect algorithm; flanger. I am currently working on ...

  1. #1
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    121

    Unhappy Modulus question!

    Hi ppl! ...I have a quick question! ...I am designing an audio effect algorithm; flanger. I am currently working on the problem of interpolation. Now my problem lies here:

    If sample rate is 22.4 kHz, I can work out that the current delay will map exactly to any one sample in a 1second buffer by:

    SAMPLE_RATE / 1000 - to give number of samples per second.

    So: every ms, 22.4 samples are saved. If my delay time is [for example] 5ms, I have:

    5 * 22.4 = 112 - this is a whole number! - can take the 112th sample and return!

    BUT! If my delay time is 4ms:

    4 * 22.4 = 89.6 - not a whole number!

    SO, in this case, i need to take an average of the 89th sample and the 90th sample in the buffer!


    My problem is this! how can I check to see if the number calculated is a whole number?

    Code:
    tmp = currentDelay * (SAMPLE_RATE / 1000);
    if (tmp = whole number) {
      /* can simply return the sample at point currentDelay time from current sample! */
      /* find where this sample is in the buffer - currentDelay samples from writePtr */ 
      return audioBuffer[pointer - tmp];
    }
    else {
      /* Have to return the average of the two nearest neighbours - get whole number part */
      return(average(audioBuffer[pointer - tmp], audioBuffer[pointer-(tmp+1)]));
    }
    
    /* NOTE: Please - don't say my return statements are false because I am using array wrap around checks in my code! i.e:
      if (tmp < pointer){ 
        sample is at other end of array! calculate its position!
      }
    I just haven't put it here because it would be about 10 lines longer!!! */
    Thanks for any help!!! Matt.
    Many junglists take pride in their belongin to what may be referred to as a globalised drum & bass subculture, as a subculture though, it is not nearly as distinct at gothic or punk!

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    I would do something like:

    Code:
    if((float)((int)tmp + 1) - tmp >= 0.1f)
    {
        ...
    }
    The int cast drops the decimals if there are any, then you add one, convert back to float and substract the original number from it. If you had for example 89.6f, converting to an int would give you 89, adding one would get 90 and converting back to float would get 90f. Then you substract the original number (89.6f) to 90f which gives you 0.4f and compare that with your degree of acceptability which I set to 0.1f. If you want more precision, just make it smaller.
    Last edited by Desolation; 01-05-2007 at 07:29 AM.

  3. #3
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    121
    Quote Originally Posted by Desolation
    I would do something like:

    Code:
    if((float)((int)tmp + 1) - tmp >= 0.1f)
    {
        ...
    }
    AH!!! Very clever!!! I like what you have done there!!! would never have thought of that!!!! many thanks!!!!!

    so your doing:

    tmp + 1

    casting to a float

    then subtracting tmp

    which would give a value between 0-1 if it was not a whole number!

    I guess it could be better to do:

    Code:
    if((float)((int)tmp + 1) - tmp != 1)
    would this work better? Thanks!
    Many junglists take pride in their belongin to what may be referred to as a globalised drum & bass subculture, as a subculture though, it is not nearly as distinct at gothic or punk!

  4. #4
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    121
    Quote Originally Posted by peterchen
    this all so works

    Code:
    if(tmp>(int)tmp) {
      /* your code here */
    }
    ah! I like that better! far more effiecient!!! especially when doing Real Time DSP! I need as much efficiency as i can get!!! thanks a lot!!!!
    Many junglists take pride in their belongin to what may be referred to as a globalised drum & bass subculture, as a subculture though, it is not nearly as distinct at gothic or punk!

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    903
    I don't think so because of the way floating integers are represented by the computer (or whatever). You can do the following and never get the first message:

    Code:
    float a = 0.7f;
    if(a == 0.7f)
        printf("First");
    else
        printf("Second");
    This is because floating point numbers are represented as very close approximations, if I recall. Like I said, you can still make your "degree of acceptability" way smaller like 0.001f which is more than acceptable I think. I doubt the difference could be heard.

    Edit: Yep, definitely better, peterchen. =)

  6. #6
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    121
    Cheers Guys For Your Help!!!!
    Many junglists take pride in their belongin to what may be referred to as a globalised drum & bass subculture, as a subculture though, it is not nearly as distinct at gothic or punk!

  7. #7
    Registered User
    Join Date
    Dec 2005
    Location
    Australia - Melbourne
    Posts
    63
    note just realized it doesn't work for negative nums

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    903
    Time can't be negative anyway ;-)

    Edit: My flanger (on my multi-fx pedal for my guitar) ranges from 0 to 100.
    Last edited by Desolation; 01-05-2007 at 07:42 AM.

  9. #9
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    121
    HAHA!!! Yes... of course!!! ...I guess I'm lucky in this case that I will never have a negative delay time! ...this would be impossible as it would mean going into the future! and those samples have not even been taken!!!!

    Thanks again!
    Many junglists take pride in their belongin to what may be referred to as a globalised drum & bass subculture, as a subculture though, it is not nearly as distinct at gothic or punk!

  10. #10
    Registered User
    Join Date
    Dec 2005
    Location
    Australia - Melbourne
    Posts
    63
    regarding
    Code:
    float a = 0.7f;
    if(a == 0.7f)
        printf("First");
    else
        printf("Second");
    i did get first message

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    903
    Ha ! I tried to reproduce the behavior I told you guys and the following code did it:
    Code:
    	float a = 0.5415;
    	if(a == 0.5415)
    		std::cout << 1;
    It doesn't output anything. (0.5415 is just some random number by the way)

  12. #12
    ZuK
    ZuK is offline
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    	float a = 0.5415;
    	if(a == 0.5415f)
    		std::cout << 1;
    Now try this.
    Kurt
    EDIT:
    Reason 0.5415 is not a float ( its a double literal ).

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    903
    Oops. My mistake. I swear I'd seen something like that and the equation wasn't true. Mmm.. Oh well, let's just forget it =P

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  2. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  3. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  4. using modulus & weighting factors
    By task in forum C Programming
    Replies: 4
    Last Post: 09-11-2002, 05:52 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 12:47 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21