# 90 Degree Phase Shift / Rotation Algorithm for SDR

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

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.