I'm working on a library to preform frequency demodulation from an SDR signal. I'm using https://github.com/sysrun/rtl-sdr/blob/master/src/rtl_fm.c as a crib for this. The algorithm starts by taking the samples (I & Q data in as 8-bit unsigned values I believe) from the radio and putting them through a 90-degree rotation. From this answer to a related question, I believe I understand why this is needed, but I don't understand how the algorithm achieves this. The algorithm is as follows, where buf holds the (I & Q) samples directly from the radio:

void rotate_90(unsigned char *buf, uint32_t len)
/* 90 rotation is 1+0j, 0+1j, -1+0j, 0-1j
   or [0, 1, -3, 2, -4, -5, 7, -6] */
    uint32_t i;
    unsigned char tmp;
    for (i=0; i<len; i+=8) {
        /* uint8_t negation = 255 - x */
        tmp = 255 - buf[i+3];
        buf[i+3] = buf[i+2];
        buf[i+2] = tmp;

        buf[i+4] = 255 - buf[i+4];
        buf[i+5] = 255 - buf[i+5];

        tmp = 255 - buf[i+6];
        buf[i+6] = buf[i+7];
        buf[i+7] = tmp;

The comment is somewhat confusing, as I don't understand how the complex values match the array. I assume the values in buf correspond to the parts of the complex numbers like such: buf[i] + buf[i+1]j. If that's the case, then why is this a 90-degree rotation? Why does it require 4 complex values?

(buf[i+0] + buf[i+1]j) -> ( buf[i+0] + buf[i+1]j)
(buf[i+2] + buf[i+3]j) -> (-buf[i+3] + buf[i+2]j)
(buf[i+4] + buf[i+5]j) -> (-buf[i+4] - buf[i+5]j)
(buf[i+6] + buf[i+7]j) -> ( buf[i+7] - buf[i+6]j)

Any insight into this algorithm would be greatly appreciated... thanks!


1 Answer 1


I believe this algorithm isn’t a rotation (phase shift) by 90degrees but instead is a frequency shift of fsamp/4. In this algorithm each sample is rotated 90 degrees with respect to the last one causing a frequency shift:

Samp1: no rotation
Samp2: 90 degree rotation
Samp3: 180 degree rotation
Samp4: 270 degree rotation
Samp5: 360 -> 0 degree rotation
Samp6: 90 degree rotation

For a pure 90 degree phase shift all you need to do is:

Ir = -Qi, 
Qr = Ii 

at every sample.

It might be helpful for you to read up on cordic rotation. Although you might not be interested in the cordic algorithm it will provide a good overview of rotations and frequency shifts.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.