Sunday, February 21, 2016

Understanding Spread Spectrum (Direct Sequence)

I've recently been working on some spread-spectrum DSP software for an experiment I'm conducting. I'm very familiar with frequency-hopping spread spectrum (FHSS). In fact, I own a pair of the discontinued TriSquare walkie-talkies. However, it took me a while to wrap my mind around direct-sequence spread spectrum, and now that I understand it I'm providing a simplified explanation for the benefit of others like me.

Background

Spread spectrum involves spreading a signal's bandwidth to enable many users to share a frequency band. It has the added benefit of providing decent privacy as it's very difficult to de-spread a signal unless you know the unique code used to spread it.

Before I got an SDRplay, I tuned my RTL-SDR to 900 MHz and spoke into a TriSquare walkie-talkie. On the waterfall I could see very short bursts of relatively wide FM. When a burst happened to land on my passband I could hear my voice momentarily. This came as a surprise since I had thought these walkie-talkies used encrypted digital voice. Even when not using my TriSquare I have seen similar bursts in the same band, and they are quite strong. These walkie-talkies are extremely rare so I knew it had to be another device. My research makes me think these are electric and gas meters.

I am particularly interested in creating a DSSS transmitter, but I didn't understand how to spread a signal evenly over a band, as opposed to hopping. This YouTube video was extremely helpful.

What doesn't work:

I misunderstood the video the first time around. Here's what I thought it meant:

Let's say I want to spread the string "SaaS" with a 20-byte spreading code of

"356A192B7913B04C54574D18C28D46E6395428AB".
(By the way, that's the SHA-1 hash of "1")

I thought spreading worked by literally spreading the whole message (or at least a chunk) over the spreading code. Here's what I imagined:

You repeat each letter of the string 5 times, and since the string is 4 bytes this becomes 20 bytes:

SSSSSaaaaaaaaaaSSSSS
In hex that is 5353535353616161616161616161615353535353

Then you XOR it with your 20-byte spreading code:
              5353535353616161616161616161615353535353
XOR     356A192B7913B04C54574D18C28D46E6395428AB
------------------------------------------------------------------------------
             6066651262585323565850522351551066676664

All seemed well and good until I wanted to despread it. I was completely at a loss as to how that would be done and, looking over the video again, saw that it would be a mess, if it was possible at all.
(On a side note, I know I could just XOR it again like a one-time pad and thereby recover the data, but if I had combined it with other signals then it likely would have been unrecoverable.)

What does work:

I found that in fact each bit of the message must be spread with the entire spreading code. So let's say I have a spreading code of 10010101. Just XOR each message bit by the entire spreading code. If I want to transmit a 1, then it would look like this:

            10010101 (entire spreading code)
XOR    11111111 (just one message bit)
----------------------
             01101010 (spreaded bits, chip rate 8x)

Now here's where it gets interesting. The signal must be transmitted as a waveform, so these bits are converted to voltages. The standard convention is 0 = +1 volt while 1 = -1 volt. However, when I was writing my modulator and demodulator I found it easier to think of it as 1 = +1 and 0 = -1. Using my convention, the message wave voltages would be:

-1 +1 +1 -1 +1 -1 +1 -1

Repeat the process with all the transmitters that must share the band. Then add their values together to get a composite waveform.

How do you recover just one stream? Assuming you tune in at the beginning of a bit's spreading cycle (which you can assume since you're working with samples in a file), simply multiply the +1/-1 values of the desired spreading code by the corresponding values of the composite waveform. This will yield a lot of crazy, fluctuating values. Average them. Unlike the YouTube tutorial, the average you get will not be clean-cut or precisely 1 or 0. You will have to depend on the sign to determine the actual bit. The software provided below takes this into account.

If you want to try this concept, I have written a program that generates *.CSV files of the waveforms of whatever text you like. It uses the 0=-1/1=+1 convention and uses just the sign of the average to determine the bits. Just save several different CSV files with different spreading codes and copy-paste them into their own Excel columns in one document. Then apply Excel's Average Add function to the final column. Copy-paste that column into its own file called "compositewaveform.csv" or whatever you like. The demodulator will read this file, accept the spreading code in a variable, despread the message, and show it on screen.

Here are download links for my program:
Written in Liberty BASIC v4.50

Spreader (proper_adjustable_spreader.bas)

Despreader (dsss_demod.bas)

Note that if you don't feel like combining several waveforms in Excel, you can still tell the demodulator to open just one waveform file and it will still despread it, provided you have given it the right spreading code.

You can experiment with spreading codes to see which ones coexist well. I have experimented with using the first 16 bits of SHA-512 hashes of consecutive numbers. My favorite hashing tool is a hex editor called HxD Hex Editor. It also has a great disk editor. However, I don't think it can copy-paste excessively large chunks. For that, use HHD Hex Editor Neo.

I have found that some of the data is corrupted when too many signals are together in the composite waveform. Also, some spreading codes do not coexist well at all, losing all the data in their streams. But higher chip rates, while reducing throughput, also reduce errors.

New recorder for SDRsharp breaks 2GiB limit

In my post ATSC now possible on magnetic drives I said that SDRsharp was the perfect solution for TV recording but lamented its 2 GiB limitation.

In my opinion, HDSDR and SDRsharp are the two best SDR applications. HDSDR has minuscule computing requirements (low CPU usage) and more reliable recording while SDRsharp draws a slightly better waterfall and (at least for older versions) is more fun to use overall.

I especially like that HDSDR is written (AFAIK) in rock-solid, no-frills Win32 C++ instead of SDRsharp which was done in C# .NET. Pure C++ produces smaller and lighter programs that don't crash or bog down the CPU quite as easily.

Since the recording function is so reliable and well-written in HDSDR, not to mention the support it has for files of unlimited size, I have written 2 emails to the author of HDSDR asking him to add 8-bit recording. However, he has not gotten back to me. On the HDSDR website it says the latest version is from 2013, implying that he has halted development. That fine by me, though. Apart from the lack of 8-bit recording, HDSDR is perfect and I hate when software developers mess with perfection.

Last week I emailed Youssef Touil, the author of SDRsharp, requesting that he update SDRsharp to support larger files. After I explained that it wasn't specifically for the SDRplay he kindly sent me links to plugins that will unlock >2GiB recording. Here they are:

Baseband Recorder (http://rtl-sdr.ru/uploads/download/basebandrecorder.zip)
WavPlayer (http://rtl-sdr.ru/uploads/download/wavplayer.zip)

Today I had a chance to test the Baseband Recorder. To use it yourself, open the zip file after downloading and go into the basebandrecorder folder:
I only needed the Baseband Recorder because my goal is to convert the files in Audacity, not play them back. Just select the 4 files you see and do Ctrl+C. Then go into your SDRsharp folder and paste.

Then you will need to open MagicLine.txt and do Ctrl+A and Ctrl+C. Close MagicLine.txt and open Plugins.xml in your SDRsharp folder. Paste the line in where indicated:
You may have more or fewer plugins than I do, but you get the general idea. Also, as you can see, it needn't be tabbed over.

Save Plugins.xml and open SDRsharp. You should see the new recorder at the bottom of the sidebar.
Click the arrow to expand it.
And there you have it: a flexible new recorder that even supports choosing an output directory. To show just how flexible it is, here is the Configure dialog:


What... did that just say WAV RF64?!? Yes it did!


With this plugin we are very close to being able to do some awesome stuff with ATSC decoding. Now the last step is to figure out how to capture the necessary 7 MHz bandwidth as opposed to SDRsharp's baseband which is limited to 250 KHz. I was really hoping I could capture the whole bandwidth with this plugin.

(Update 03/01/2016)

I made a mistake above. I had confused Baseband with passband. Baseband in SDR# is the same as RF in HDSDR, which means that this plugin will record your full RF bandwidth. I had my SDRplay set to about 200 kHz during the first test, and so the WAV file's properties said 200 kHz sampling, reinforcing my false assumption that this plugin only records passband.

I am very pleased to see that progress bar underneath "Dropped buffers: 0". In case you didn't know, the progress bar represents the recording buffer. In a previous post I suggested that a buffer be used to smooth out the latency inherent in magnetic hard drives. It seems that the author of this plugin has taken that into account. I don't think the buffer is very big, but it's certainly better than nothing (ever notice how the native SDR# recorder seems so prone to dropping samples? I suspect the native recorder has no buffer.)

Today I made some TV recordings on 8-bit with this plugin, converting them to 16 bits in Audacity and decoding them. Sure enough, the plugin works as I had hoped. I was able to take recordings of unlimited length and I chose to stop them at 8 GB because I didn't want Audacity to take too long to convert them. Both final decodes were rife with errors, although WACH had some perfect spots. I only used the two blowtorches in my area, WJBF and WACH. These two have always been the most reliable, so it is obviously something wrong with the new method. I think it has something to do with 8-bit and the reduced dynamic range because no buffers were dropped.

In conclusion, if you can get around the reliability problem then it is now possible to take TV recordings of virtually unlimited length using magnetic hard drives.

Special thanks to Youssef Touil for showing me the final piece of the puzzle that made this possible.

Monday, February 1, 2016

Why I still prefer Windows XP

A few days ago I restored my laptop to Windows XP from a hard drive image I made before upgrading to Windows 10. As you know, I only upgraded so I could use Visual Studio and Office 2013. I prefer XP and here's a major reason why:


Above you can see I've set my SDRplay to the full 8 MHz of bandwidth. It's tuned to a Volmet upper-sideband weather report and there is no stutter. HDSDR reports only about 50% CPU usage. (Notice how overall usage is not ~100%, like Windows 10 would be?)

Fortunately, I also imaged the drive before going back to XP, so I have a Windows 10 drive image. After a nice break from Windows 10, I have to restore it so I can finish an app I'm working on in Visual Studio.

I restored my Windows 10 backup. Here in Windows 10 I've got HDSDR tuned to some RTTY on lower-sideband and it stutters incessantly. CPU usage is almost 100%. (If you click to zoom in, you can even see a strip of waterfall smear at the top where HDSDR froze.)

But maybe Windows 10 isn't really to blame. Maybe my laptop is just too old to hardware-accelerate all the visual styles, so it has to be done by the CPU. I would like to blame it on the background processes, but HDSDR itself is at nearly 100% CPU, and the overall CPU reading is only marginally higher. A newer computer should be able to run HDSDR with 8 MHz bandwidth without breaking a sweat, but there's no denying XP was a much leaner OS.