This code uses libhackrf for a basis, and I have created an AM/FM/WBFM/SSB demodulator with this stuff. Additionally, AM/FM/WBFM/SSB transmit functionality has been provided. The goal here was to keep it light weight so that it can run on a BeagleBone Black board. There is no GUI, but instead, I have created a command interpreter that you access via netcat or telnet to port 20300. You can change modulation and demodulaton modes on the fly, and you can change various radio parameters. Let me mention a few things. First of all, I did *not* write the libhackrf code. I've merely incorporated a snapshot of it into my code since it provides the foundation for my system, and I want people to be able to build the code in a standalone fashion. Next up, I wrote my own message queue code since I needed something that could survive newer versions of compilers. Finally, I didn't use makefiles, although, I don't really have anything against using make. This occurred because I wanted to whip something up quick and dirty. The system grew though, but I still don't really have any regrets as to my decision. The result is that the user need only have g++, and bash to build my code (and the other people's code which I have included in the system). Here's how you build this stuff. 1. Clone the repository. 2. Navigate to the radioDiags directory. 3. Type "sh buildLibs.sh". 4. Type "buildRadioDiags.sh. The executable will be in radioDiags/bin/radioDiags. Let's talk about receiver functionality first. The demodulated output is presented to stdout, and the format is 8000Samples/s, 16-bit, Little Endian PCM. You could run the program in the following manner. bin/radioDiags | aplay -f S16_LE -r 8000 Now that the program is running, you need to connect to the command and control link to port 20300 via netcat or telnet (I prefer netcat). A welcome message will appear, and if you type help, you will be presented with a help menu. Okay, let's say that you want to listen to a local station on the FM broadcast band. At my location, I would type the following: 1. "start receiver" 2. "set frequency 91500000" 3. "set demodmode 3" This starts the receiver up, sets the frequency to 91.5MHz, and the demodulation mode to wideband FM. If you type help, you'll see how to set the other demodulator modes. You can do other things also such as setting the demodulator gains. What if you don't have a sound card on the computer for which the software is executing on? For example, I use a BeagleBone Black to run the SDR code (it's fast enough to do all the signal processing), and I use a 200MHz Pentium 2 computer to play the sound? Here's what I do. On the BeagleBone Black, type the following (note that the -u argument to netcat forces UDP usage. If you don't have UDP support, don't use the -u argument): 1. "bin/radioDiags | netcat -u <IP address of host computer> 8000" 2. Perform steps t to 3 above to listen to your local FM station on 91.5MHz. On the host computer (the one with the sound card), type the following: 1. "netcat -l -u -p 8000 | aplay -f S16_LE -r 8000" 2. On a separate shell, type "netcat <IP address of BeagleBone Black> 20300" 3. Peform steps 1 to 3 above to listen to your local FM station on 91.5Mhz. Let it be noted that all demodulated output is 8000Samples/s PCM (for all demodulation modes). I made this decision because I wanted to be able to change demodulation modes on the fly. Also note that steps 1 to 3 can be performed in any order. You can change any of the receiver parameters without having to stop and restart the receiver. Yes, there is a "stop receiver" command. Okay, let's talk about transmit functionality. The scenario that I describe here is to run the HackRf code on the BeagleBone Black and to use the host computer to send a PCM stream to the HackRF via a netcat connection. Here are the steps: 1. From a shell on the BeagleBone Black, type "netcat -l -p 8000 | bin/radioDiags" 2. On the host computer, type "arecord -t raw -f S16_LE -r 8000 | netcat <IP address of BeagleBone Black> 8000" 3. From a shell on the host computer, type "netcat <IP address of BeagleBone Black> 20300" 4. Now that there exists a command and control link (via netcat) to the BeagleBone Black, type the following: 4.1 "set frequency <desired frequency in Hz>" 4.2 "select livesource" 4.3 "set modmode [1|2|4|5]" 4.4 "start livestream" 4.5 "start transmitter" For example, if you want to transmit on 27.125MHz using amplitude x modulation, you'd type: 1. "set frequency 27125000" 2. "set modmode 1". After carrying out the above steps, one could speak into a microphone (connected to the sound card of the host computer) and hear themselves on an HF receiver tune to 27.125MHz using AM demodulation. Now, let's discuss transmission of a file of IQ data that is loaded into mamory, In this case, on the host computer type, 1. "load iqfile <someiqfile>" 2. "select filesource" 3. "start transmitter" After carrying out the above steps, the file data (that was loaded into memory) will be transmitted over and over in a cyclic manner. Now where do you get these IQ data files? I'm glad you asked that question. In each of the modulator directories there exist test applications that accept an input file (through stdin) that contains data to be modulated. The format of the input data is 16-bit signed little endian integers sampled at 8000S/s. I use PCM audio for my use case. Each of the modulator utilities (am, fm, wbfm, and ssb) accept the input data and output modulated data to stdout. The format of the output data is 8-bit signed integers sampled at 2048000S/s. It follows that a 5 seconds of captured PCM data will result into a file size of 2048000 bytes. This means that 2048000 bytes of memory must be available for the data buffer that is used for transmission. Now how do you build these modulator test apps? In each of the modulator directories (AmModulator, FmModulator, WbFmModulator, SsbModulator), there exist shell scripts: buildAm.sh, buildFm.sh, buildWbFm.sh, and buildSsb.sh. You merely run these scripts to create the appropriate apps: am, fm, wbfm, and ssb. I generally build these apps on X86 since the output files serve as nice test vectors (for transmission) for my demodulator testing at work. The hackRF serves as a nice signal generator when I want to test demodulators for reception of voice transmission. Okay, it's time to discuss interaction with the command line interpretor. When the user types "help", the output appears as illustrated below. ******************** Begin Help Output ******************************** select filesource select livesource set demodmode <mode: [0 (None) | 1 (AM) | 2 (FM) | 3 (WBFM)] | 4 (LSB) | 5 (USB)>] set modmode <mode: [0 (None) | 1 (AM) | 2 (FM) | 3 (WBFM) | 4 (LSB) | 5 (USB)>] set amdemodgain <gain> set fmdemodgain <gain> set wbfmdemodgain <gain> set ssbdemodgain <gain> set ammodindex <modulation index> set fmmoddeviation <deviation in Hz> set wbfmmoddeviation <deviation in Hz> enable rxfrontendamp disable rxfrontendamp enable agc disable agc set agctype <type: [0 (Lowpass) | 1 (Harris)]> set agcdeadband <deadband in dB: (0 < deadband < 10)> set agcblank <blankinglimit in ticks: (0 =< blankinglimit <= 10)> set set agcalpha <alpha: (0.001 <= alpha < 0.999)> set agclevel <level in dBFs> enable txfrontendamp disable txfrontendamp set txifgain <gain in dB> set rxifgain <gain in dB> set rxbasebandgain <gain> set frequency <frequency in Hertz> set bandwidth <bandwidth in Hertz> set samplerate <samplerate in S/s> set warp <warp in ppm> set squelch <threshold> enable iqdump disable iqdump start transmitter stop transmitter start receiver stop receiver start livestream stop livestream set fscanvalues <startfrequency> <endfrequency> <stepsize> start fscan stop fscan start frequencysweep <startfrequency> <stepsize> <count> <dwelltime> stop frequencysweep load iqfile <filename> get radioinfo get fscaninfo get sweeperinfo get agcinfo exit system help Type <^B><enter> key sequence to repeat last command ******************** End Help Output ********************************** When the user types "get radioinfo", the output appears as illustrated below. ******************** Begin Get Radio Info Output ********************** ------------------------------------------------------ Radio Internal Information ------------------------------------------------------ Information Source : File Frequency Warp: : -28 ppm Receive Enabled : No Receive Front End Amp Enabled : Yes Receive IF Gain: : 0 dB Receive Baseband Gain: : 0 dB Receive Frequency : 89100000 Hz Receive Bandwidth : 1750000 Hz Receive Sample Rate: : 2048000 S/s Receive Timestamp : 376176640 Receive Block Count : 2870 Transmit Enabled : No Transmit Front End Amp Enabled : No Transmit IF Gain: : 35 dB Transmit Frequency : 89100000 Hz Transmit Bandwidth : 1750000 Hz Transmit Sample Rate : 2048000 S/s Transmit Block Count : 8789 -------------------------------------------- Data Consumer Internal Information -------------------------------------------- Last Timestamp : 376176640 Short Block Count : 0 -------------------------------------------- Data Provider Internal Information -------------------------------------------- IQ File Name : /home/gianakop/HackRfModulators/wbfm.iq IQ Sample Buffer Length : 20480000 IQ Sample Buffer Index : 1245184 -------------------------------------------- IQ Data Processor Internal Information -------------------------------------------- Demodulator Mode : AM Signal Detect Threhold : -20 dBFs -------------------------------------------- Baseband Data Processor Internal Information -------------------------------------------- Stream State : Idle Synchronization State : Unsynchronized PCM Writer Index : 14 PCM Reader Index : 6 Buffers Produced : 258831 Buffers Consumed : 3549 PCM Blocks Dropped : 109 PCM Blocks Added : 122 Modulator Mode : WBFM -------------------------------------------- AM Demodulator Internal Information -------------------------------------------- Demodulator Gain : 300.000000 -------------------------------------------- FM Demodulator Internal Information -------------------------------------------- Demodulator Gain : 10185.916016 -------------------------------------------- Wideband FM Demodulator Internal Information -------------------------------------------- Demodulator Gain : 10185.916016 -------------------------------------------- SSB Demodulator Internal Information -------------------------------------------- Demodulation Mode : LSB Demodulator Gain : 300.000000 -------------------------------------------- AM Modulator Internal Information -------------------------------------------- Modulator Index : 0.800000 -------------------------------------------- FM Modulator Internal Information -------------------------------------------- Frequency Deviation: : 3500.000000Hz Phase Accumulator : -1.731567rad -------------------------------------------- Wideband FM Modulator Internal Information -------------------------------------------- Frequency Deviation: : 70000.000000Hz Phase Accumulator : -1.104594rad -------------------------------------------- SSB Modulator Internal Information -------------------------------------------- Modulation Mode : USB ******************** End Get Radio Info Output ************************* The new features I have added are listed below: 1. A signal squelch that works directly with the average magnitude of a received IQ data block. 2. A frequency scanner that lets you specify a start frequency, an end frequency, and a frequency step. This collaborates with the squelch such that, when scanning, if a signal exceeds the squelch threshold, the scan will stop so that you can hear the demodulated audio of the signal. When the signal goes away, frequency scan will continue. 3. An automatic gain control (AGC) for the receiver. For my purposes, this was a much-needed feature since the HackRF doesn't provide AGC functionality. I wasn't a fan of always changing the system gain parameters manually as I listened to different frequencies. For example, I might tune to a local weather station at one time, and tune to a strong local FM radio station (FM broadcast band) at another time. There can be a significant variation in signal level between these two scenarios. This is handled automatically by the AGC. When the user types "get fscaninfo" (for the frequency scanner), the output appears as illustrated below. Not that the start frequency, the end frequency, and the frequency increment are configurable. See the help command output for the syntax of the commands related to the frequency scanner (fscan). ******************** Begin GetFscainfo Info Output ********************** -------------------------------------------- Frequency Scanner Internal Information -------------------------------------------- Scanner State : Scanning Start Frequency : 120350000 Hz End Frequency : 120550000 Hz Frequency Increment : 25000 Hz Current Frequency : 120475000 Hz ******************** End Get Fscainfo Output **** ********************** When the user types "get agcinfo" (for the AGC), the output appears as illustrated below. Note that the algorithm type, lowpass filter coefficient, and the operating point are user configurable. See the help command output for the syntax of the commands related to the AGC. ******************** Begin Getagcinfo Info Output ********************** -------------------------------------------- AGC Internal Information -------------------------------------------- AGC Emabled : Yes AGC Type : Harris Blanking Counter : 0 ticks Blanking Limit : 1 ticks Lowpass Filter Coefficient: 0.800 Deadband : 1 dB Operating Point : -6 dBFs Baseband Gain : 50 dB /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Signal Magnitude : 59 RSSI (After Mixer) : -56 dBFs /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ******************** End Get Agcinfo Output **** ********************** Anyway, if you have any questions, you can always catch me on libera IRC. I use the nick wizardyesterday. I can also be reached on Facebook as Chris Gianakopoulos. Oh one last thing. Anybody can use my software without grief. I guess I'll have to put the GNU open source stuff at the beginning of my files, and that will happen later. Either way, feel free to use my software, sell it, or give it away. I believe in sharing what I create to benefit the Open Source Community.
wizardyesterday/HackRfDiags
This code uses libhackrf for a basis, and I have created an AM/FM/WBFM/SSB transmitter/receiver application with this stuff. I call the application radioDiags. The application accepts raw PCM data from stdin for transmit functionality, and sends demodulated data (also raw PCM) to stdout. The raw PCM data is sampled at 8000S/s and is represented by 16-bit signed little endian integers. The user connects to the user interface by using telnet (or netcat) to connect to port 20300.
C++