Monday, August 14, 2017

Root-Raised Cosine

Yesterday I finally figured out the root-raised cosine. I've been trying to understand it for about a year. It's very necessary for transmitting PSK signals because merely mixing a square wave with a carrier wave makes a wave with sharp transitions that cause lots of spurious signals. The clean, narrow PSK signals you may have seen are all using the root-raised cosine.

Here is the resource that I found yesterday to explain it properly: Pulse Shaping with raised cosine filters.

I found it confusing at first for two reasons. The first is that I didn't know if Wikipedia's formula was for time or frequency domain, and the second is that I had no idea that the RRC is centered on each PSK symbol, meaning that a time of 0 is the center.

Here is the time-domain formula from the University of Stuttgart's Webdemo (linked above):
[REF] Stephan ten Brink, "Pulse Shaping," webdemo, Institute of Telecommunications, University of Stuttgart, Germany, Aug. 2017. [Online] Available:

Why to use it

If I told you to multiply a square wave with a cosine and sine wave to make a QPSK signal, you'd get a result similar to the top stereo track shown below.

Those are some sharp transitions. This is what I got when I first tried to make my own QPSK signals. It seems well and good, right? We have our digital wave mixed with I (cosine) and Q (sine) to make an IQ signal playable in an SDR program. Well, yes, but there's a slight problem...

[Vertical is frequency, horizontal is time]
This isn't what QPSK is supposed to look like. See all the spurious signals splattering everywhere? Satellites like Inmarsat have neat and narrow QPSK, so why does mine look so bad?

It turns out that we've simply placed a square wave (which is full of harmonics) into the RF spectrum by mixing with a carrier.

Now, notice the bottom stereo track. It is the same QPSK signal, but smoothed out using a root-raised cosine filter.

Notice how narrow it becomes:

The signal is also good enough that Signals Analyzer can lock onto the 80 kBit bitrate:

I initially made the mistake of entering 40000 in the BR (bitrate) field because it's 40 kHz QPSK, and with QPSK the bitrate is twice the symbol rate.

(Below) SA can also lock onto the bitrate of the unfiltered QPSK, which means that although it's undesirable for transmitting, it is nonetheless a valid signal (although I did have to zoom out the bottom-left constellation window a bit).

How to use it

The formula generates "taps", which means an array of values to be used on the signal you want to process. In our case, we multiply the taps by our signal.

Here are the variables:

t: time, in fractions of a second, since the center of the symbol.
T: length of half a symbol, in seconds (1 / (2*symbol rate)). (Why not 1/symbol rate? Pitfall explained below)
alpha: roll-off factor, ranges from 0 to 1 (1=wide, 0=brick wall filter)

To maintain the parameters of the signals shown earlier, let's assume we want a QPSK signal with a symbol rate of 40 kHz (80 kbit/sec) and we'll have it in an IQ file sampled at 1 MHz.

Our variables would be:
t: x/sample rate (in our case, x/1000000). x is the FOR loop variable.
T: 0.0000125
alpha: 0.1 (very high roll-off)

40 kHz is a convenient value since we want an odd number of taps. Since 1,000,000/40,000 = 25, it will take 25 samples to make one symbol and so we need 25 taps.

The center value will be 12 (base 0) or 13 if you prefer base 1. We want to start at 0 so we can do our time values properly, so we want a FOR loop to go backwards from 12 to 0.

for (x = 12; x >= 1; x--) {
    taps[12 - x] = [The formula depicted above, substituting (x/1,000,000) for t]

taps[12] = 1

for (x = 1; x <= 12; x++) {
    taps[12 + x] = [The formula depicted above, substituting (x/1,000,000) for t]

This code will give you 25 taps. Think of it as a matrix with just one column; you would use matrix multiplication to multiply each point by a corresponding point in time on an unfiltered QPSK signal. Just make sure to align this so that the taps begin at the beginning of the QPSK symbol, otherwise it won't filter properly. Here's a crude ASCII drawing of what I mean:

|     Taps       |        |   QPSK   |
|   Matrix       |   *   |       IQ       |
|                   |        |   samples |

Note that both matrices are only ONE symbol long; the taps repeat at the start of each symbol.


The pitfall I was referring to is that 0 is the center. This is what my first RRC taps looked like when I calculated starting from 0:

I mistakenly thought that was the whole filter but it's only the right half. Again, here is the right half of another RRC filter:

And finally, here is the output of this mistake. I applied the right half of an RRC filter to the QPSK starting at the beginning of each symbol, which kept the ends from matching properly. When it's done right, the ends meet perfectly. I eventually found out it needed to be mirrored and applied with 0 being the center of the symbol.

This is why we use 1/(2 * bitrate). If you use 1/bitrate, then the right half will span the entire symbol time when you only want it to span half. With 1/(2 * bitrate), each half will cover half the symbol.

I hope this helped if you had no idea how to program the RRC. Use the comment section below if you have any questions or if I left something out.

Tuesday, August 8, 2017

UTSC v1 Packet Specification

After showing the spec to Foxx, wordsun, and Corrosive, only Corrosive had a suggestion and it was to allow embedding a list of ID's in the packets to facilitate pay-per-view. In other words, broadcasters could include a list of ID's of various decoder boxes so only specific paying viewers can see a channel. This is in contrast to my current method of handling encryption like Wi-Fi, using a single password for the channel. I told him his one-key-per-viewer idea most likely wasn't feasible since the packets need to be small.

Here is a link to the document: utsc_finished_release.txt


The UTSC name and specification are Copyright 2017 Designing on a Juicy Cup. The specification may be freely implemented by anyone for any purpose as long as this copyright notice is displayed in the license. The UTSC name may be used in products implementing this standard as long as attribution is made to Designing on a Juicy Cup.

Monday, August 7, 2017

UTSC v1 Standard Finalized

Since 2016, I've been working on a way to transmit digital TV in the 900 MHz Part 15 band. The main focus is on reliability, because ATSC fails miserably in that department. The second focus is on unlicensed operation, because broadcasting is a near-monopoly.

The format officially consists of a 1 Mbit data stream containing VP9 video at about 900 kbits and Opus audio at 48 kbits. Opus is extremely resilient and can withstand high loss, similar to analog TV's sound. It also sounds amazing at that bitrate. Other services, such as audio or data, could be conveyed as well.

My proposed standard is called UTSC. The acronym means nothing, officially. It is designed to be expansible like WAV, meaning that new features can be added without breaking compatibility with the first receivers. My current research suggests that I can fit 32 channels in the band in any given area.

The standard can accommodate any video codec, resolution, and frame rate in theory, but VP9 960x540 @ 30.000 fps is suggested.

I finalized the standard today and I'm documenting it here as proof that I devised this first. If someone else claims to have been first, you can verify with the Wayback Machine that no site before this date carried this info.

The encoder and air interface are proprietary and will not be released yet. However, I'm planning to release the packet format for public review. I'm submitting it privately to Foxx, Corrosive, and wordsun for a pre-review.