I have been trying to learn about Q31 format (as well as Q15), but I am having trouble understanding how it works.

So my CODEC is giving me 24-bit two's complement data. I have converted this data successfully to 32-bit two's complement data and back. I would like to so some math on this data using Q31 format. For starters, hopefully something like attenuation. I am using a PIC32MZ series processor. Here is some of the code I am working with.

#define Q31 int
#define Q63 long long

Q31 Q31multQ31 (Q31 a, Q31 b){
    Q63 y;
    y = (Q63) a * (Q63) b;
    y >> 31;
    return ((Q31) y);

// Super basic attenuation (hopefully)
left_output =  Q31multQ31(left_input,0b00000000001111111111111111111111);

This seems to give me awful noise. left_input and left_output are int (signed 32-bit). Is there some sort of conversion I am missing to use these as Q31?

  • $\begingroup$ Does Q31 mean that that there are 32 bits in total and that the number is between $-1$ (represented by 0x80000000) inclusive and $1-2^{-31}$ (represented by 0x7fffffff) inclusive? $\endgroup$ – Olli Niemitalo Nov 9 '16 at 7:38
  • $\begingroup$ @OlliNiemitalo yes, thats the goal. Is the data I have already usable in that way? or do I have to do some form of conversion? $\endgroup$ – BBales Nov 9 '16 at 15:42
  • $\begingroup$ Your code seems fine. There could be an unhandled overflow in Q31multQ31 if you multiplied 0x8000000 by itself, but that's not your problem here. How do you do the conversions? $\endgroup$ – Olli Niemitalo Nov 9 '16 at 16:44
  • 2
    $\begingroup$ Looks like a bug: you want y >>= 31; You are missing the "=" sign.The line as written doesn't do anything. $\endgroup$ – Hilmar Nov 9 '16 at 19:27
  • 1
    $\begingroup$ @Hilmar Yes! Missed that. You could write it as an answer so that BBales can accept it. $\endgroup$ – Olli Niemitalo Nov 12 '16 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.