jradio
jradio copied to clipboard
Software radio decoding
About
Software radio decoding written in Java. The idea of this project is to get blocks from the gnuradio and implement them in Java. This gives the following:
- No need for tooling. You could use gnuradio-companion to build a working pipeline, then use the same blocks to build the pipeline in Java.
- All Java benefits: run same binaries on multiple platforms without compilation. Single programming language instead of Python and C++. Better tooling like IDE, profilers and memory analyzers.
Demodulators
jradio supports high-level generic demodulators. They convert I/Q signal into the stream of soft bits (0-255).
Modulators
Some generic modulators. They take hard bits and produce I/Q signal.
De-framers
De-framer is a component that converts soft stream of bits into the frames of specific protocol.
- AX.25 - Ax25BeaconSource
- AX.25 with G3ruh scrambler - Ax25G3ruhBeaconSource
- AX100 - Ax100BeaconSource
- cc11xx - Cc11xxReceiver
- NGHam - Support for NGHam radio protocol
- Generic syncword correlator - CorrelateSyncword
- USP - UspDecoder
- Mobitex - MobitexBeaconSource
- TUBiX20 - Generic de-framer for TUB-based satellites. TUBiX20BeaconSource
- CCSDS Concatenated - CCSDS 131.0-B-4 implementation for concatenated framing (Convolutional + Reed-Solomon). CcsdsBeaconSource
Auxiliary tools
Quite often decoding require some additional tooling. jradio has some.
Forward error correction:
- Viterbi hard and soft decoders
- CCSDS ReedSolomon
- BCH ReedSolomon
- BCH(15,x,x)
- Repeat Accumulate decoder
- Golay
- PLS
Randomization
CRC
Most likely the algorithm name can't say you much, so it is better to check corresponding test case. Here is list of supported implementations:
- CRC-8
- CRC-16/XMODEM & CRC-16/X-25
- CRC-16/CCITT-FALSE/CRC-16-IBM
- CRC-16/ARC
- CRC-16-NAIVE. Just sum of bytes.
- CRC-32C
Satellite protocols
- CSP - Full support
- CCSDS - Basic support
- PACSAT - Good support
Low-level blocks
All blocks meant to be binary compatible with gnuradio versions. This will ensure you got the same results when moving from gnuradio-companion to Java.
- Add
- AdditiveScrambler
- AGC
- AX100Decoder. Out-of-tree block. Support ASM + Golay mode.
- BinarySlicer
- Cc11xxReceiver. Out-of-tree block. Decodes frames produced by cc11xx. Based on gr-cc11xx
- ChannelModel
- ChunksToSymbols and ChunksToSymbolsComplex
- ClockRecoveryMM and ClockRecoveryMMComplex
- ComplexConjugate
- ComplexToReal
- ConstellationSoftDecoder
- ConvolutionalDeinterleaver
- CorrelateSynchronizationMarker. Extract data from continuous stream of synchronization markers. Work with soft stream.
- CorrelateSyncword
- CostasLoop
- DcBlocker
- DelayOne. jradio doesn't support split and merge of streams. This block incapsulates delay 1 for imag complex stream
- Descrambler
- DifferentialEncoder/DifferentialDecoder
- DifferentialSoftDecoder. Support qpsk only
- Divide
- FastNoiseSource
- FIRFilterBlock
- File Source (InputStreamSource)
- File Sink (OutputStreamSink)
- FLL Band Edge
- FloatToChar
- FloatToComplex
- FractionalResampler
- FrequencyModulator
- FrequencyXlatingFIRFilter
- GUI Histogram Sink (Spectogram)
- HardToSoft. Convert hard decision stream to soft stream.
- HdlcReceiver. Out-of-tree block. Extracts HDLC frame from the unpacked stream of bytes
- HdlcTransmitter. Take the byte array and create hdlc frame
- InterpFIRFilter
- LowPassFilter and LowPassFilterComplex
- LMSDDEqualizer
- MapBlock
- Multiply
- MultiplyConst
- NrziDecode/NrziEncode. Performs nrzi decoding/encoding over unpacked stream of bytes
- osmocom source (RtlTcp)
- PackedToUnpacked
- PolyphaseArbResamplerComplex
- PolyphaseClockSyncComplex
- PeakDetection. Detect peaks in the FFT. Not a gnuradio block.
- QuadratureDemodulation
- Rail
- Rms
- RmsAgc and RmsAgcComplex. Out-of-tree block. For more details see this blog post
- RootRaisedCosineFilter
- Scrambler
- SigSource
- SequentialSource. Produce time-multiplexed outputs from several sources. Useful in simulations.
- TimeConstraintedSource. Can be used in simulations to time-limit noise source.
- UnpackedToPacked
- WavFileSource
- WavFileSink
Coding:
- NRZI
- Bit stuffing
Supported satellites
jradio has lots of built-in satellite decoders. Some of them have non standard de-framers, some beacon decoders, some both:
Name | NORAD | Sample code |
---|---|---|
DELFI-C3 (DO-64) | 32789 | DelfiC3Test |
1Kuns-Pf | 43466 | KunsPfTest |
AAUSAT-4 | 41460 | Aausat4Test |
Aistechsat3 | 44103 | Aistechsat3Test |
Aistechsat2 | 43768 | Same as Aistechsat3. See Aistechsat3Test |
AO-73 | 39444 | Ao73Test |
Astrocast 0.1 | 43798 | AstrocastTest |
AT03 | 42784 | At03Test |
ATL-1 | 44830 | Atl1Test |
AU02/AU03 | 42723/42731 | Au02Test |
CA03 | 42734 | Ca03Test |
D-Star ONE | 43881 | Dstar1Test |
DELPHINI | 44030 | Delphini1Test |
Entrysat | 44429 | EntrysatTest |
ESEO | 99912 | EseoTest |
Fmn1 | 43192 | Fmn1Test |
FOX-1A, FOX-1B, FOX-1C, FOX-1D | 40967, 43017, 43770, 43137 | FoxTest |
GOMX-1 | 39430 | Gomx1Test |
Itasat1 | 43786 | Itasat1Test |
Jy1sat | 43803 | Nayif1Test |
Lucky-7 | 44406 | Lucky7Test |
Lume-1 / AISTechSat 2 | 43908 / 43768 | Lume1Test |
Meteor-M N2 | 40069 | MeteorImageTest |
Mysat-1 | 44045 | Mysat1Test |
Nayif1 | 42017 | Nayif1Test |
OPS-SAT | 44878 | OpsSatTest |
PwSat2 | 43776 | PwSat2Test |
Reactor Hello World | 43743 | ReaktorHelloWorldTest |
S-NET A,B,C,D | 43186, 43187, 43188, 43189 | SnetTest |
Sat3Cat1 | 99901 | Sat3Cat1Test |
SMOG-P | 44832 | SmogPTest |
Suomi100 | 43804 | Suomi100Test |
SWAMPSAT-2 | 45115 | Swampsat2Test |
Technosat | 42829 | TechnosatTest |
QARMAN | 45263 | QarmanTest |
Quetzal1 | 45598 | FskDemodulator 4800 baud, Ax25G3ruhBeaconSource and Quetzal1Beacon |
Huskysat-1 | 45119 | Huskysat1Test |
Painani-1 | 44365 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and Painani1Beacon |
CHOMPTT | 43855 | ChompttTest |
ALSAT 1N | 41789 | Alsat1nTest |
STRAND-1 | 39090 | Strand1 |
PolyItan1 | 40042 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and PolyItan1Beacon |
Unisat6 | 40012 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and Unisat6Beacon |
Lightsail2 | 44420 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and Lightsail2Beacon |
CubeBel-1 | 43666 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and Bsusat1Beacon |
Salsat | 46495 | AfskDemodulator 1200 baud, -600 deviation, 1500 offset with Salsat decoder |
Armadillo | 44352 | FskDemodulator 19200 baud, Ax25G3ruhBeaconSource and ArmadilloBeacon |
Spooqy1 | 44332 | Spooqy1Test |
NORBI | 46494 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and NorbiBeacon |
MEZNSAT | 46489 | FskDemodulator 2400 baud, Ax25G3ruhBeaconSource and MeznsatBeacon |
FALCONSAT-3 | 30776 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and Falconsat3Beacon |
AMICALSAT | 46287 | AfskDemodulator 1200 baud, Ax25BeaconSource and Amical1Beacon |
BOBCAT-1 | 46922 | FskDemodulator 1200 baud, Ax100BeaconSource and Bobcat1Beacon |
GRIFEX | 40379 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and GrifexBeacon |
BUGSAT-1 (TITA) | 40014 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and BugsatBeacon |
TAUSAT-1 | 47926 | BpskDemodulator 9600 baud, Ax25G3ruhDecoder and Tausat1Beacon |
UVSQ-SAT | 47438 | BpskDemodulator 9600 baud, Ax25G3ruhDecoder and UvsqsatBeacon |
GRBAlpha | 47959 | FskDemodulator 9600 baud, Ax25G3ruhBeaconSource and GRBAlphaBeacon |
SMOG-1 | 47964 | ru.r2cloud.jradio.smog1.Smog1Beacon |
DELFI-PQ | 47964 | ru.r2cloud.jradio.delfipq.DelfiPqBeacon |
GASPACS | 51439 | ru.r2cloud.jradio.gaspacs.Gaspacs |
CUTE | 49263 | ru.r2cloud.jradio.cute.CuteBeacon |
PICSAT | 43132 | ru.r2cloud.jradio.picsat.PicsatBeacon |
INSPIRESAT-1 | 51657 | ru.r2cloud.jradio.is1.InspireSat1Beacon |
CTIM | 52950 | ru.r2cloud.jradio.ctim.CtimBeacon |
CSIM-FD | 43793 | ru.r2cloud.jradio.csim.CsimBeacon |
IRIS-A | 51044 | ru.r2cloud.jradio.iris.IrisABeacon |
FEES | 48082 | ru.r2cloud.jradio.fees.FeesBeacon |
SelfieSat | 53951 | ru.r2cloud.jradio.selfiesat.SelfieSatBeacon |
VZLUSAT-2 | 51085 | ru.r2cloud.jradio.vzlusat.Vzlusat2Beacon |
NETSAT-* | 46507 | ru.r2cloud.jradio.netsat.NetSatBeacon |
MRC-100 | 56993 | ru.r2cloud.jradio.mrc100.Mrc100 |
Dhabisat | 49016 | ru.r2cloud.jradio.dhabi.DhabisatBeacon |
CONNECTA T1.1 | 52739 | ru.r2cloud.jradio.connecta.Connecta11Beacon |
CELESTA and MTCUBE 2 (ROBUSTA 1F) | 53111 and 53109 | ru.r2cloud.jradio.celesta.CelestaBeacon |
StratoSat TK-1 | 57167 | ru.r2cloud.jradio.sstk1.StratosatTk1 and images via ru.r2cloud.jradio.sstk1.StratosatTk1PictureDecoder |
RS52SB, RS52SV, RS52SG, RS52SD, RS52SE | 57323, 57324, 57325, 57326, 57167 | ru.r2cloud.jradio.sstk1.StratosatTk1PicoBeacon |
INSPIRE-SAT 7 | 56211 | SPINO mode - ru.r2cloud.jradio.is7.InspireSat7Spino, AX25 mode using ru.r2cloud.jradio.is7.InspireSat7Beacon |
RS20S (GEOSCAN-EDELVEIS) | 53385 | ru.r2cloud.jradio.geoscan.GeoscanBeacon and images via ru.r2cloud.jradio.geoscan.GeoscanPictureDecoder |
SIREN, UMKA-1, CUBESX-HSE-AIS, CYCLOPS, ISOI, KUZBASS-300, MIET-AIS, MONITOR-1, VIZARD, CUBESX-HSE, CUBESX-SIRIUS-HSE, ORBICRAFT-ZORKIY | 53384, 57172, 53383, 53373, 53381, 53375, 53377, 53374, 57189, 47952, 47951, 47960 | ru.r2cloud.jradio.sputnix.SputnixBeacon |
Sharjahsat-1 | 55104 | ru.r2cloud.jradio.sharjahsat.Sharjahsat1Beacon and images via ru.r2cloud.jradio.sharjahsat.Sharjahsat1PictureDecoder |
Sapling Giganteum | 56214 | ru.r2cloud.jradio.sapling.SaplingGiganteumBeacon |
ROSEYCUBESAT-1 | 56212 | ru.r2cloud.jradio.roseycub.RoseyCubesatBeacon and images via ru.r2cloud.jradio.roseycub.RoseyPictureDecoder |
BDSAT-2 | 55098 | ru.r2cloud.jradio.bdsat.BdSat2Beacon |
KAFASAT | 58317 | ru.r2cloud.jradio.kafasat.KafasatBeacon |
RANDEV | 52898 | ru.r2cloud.jradio.randev.RandevBeacon |
VERONIKA | 58261 | ru.r2cloud.jradio.veronika.VeronikaBeacon |
SUCHAI-3, SUCHAI-2, PLANTSAT | 52191, 52192, 52188 | ru.r2cloud.jradio.suchai2.Suchai2Beacon |
Doppler correction
Doppler correction could be made using SigSource and Multiply blocks. Here is the sample code:
PassPredictor predictor = new PassPredictor(tle, currentLocation);
SigSource source2 = new SigSource(Waveform.COMPLEX, sampleRate, new DopplerValueSource(sampleRate, satelliteFrequency, correctPeriodMillis, startTimeMillis) {
@Override
public long getDopplerFrequency(long satelliteFrequency, long currentTimeMillis) {
return predictor.getDownlinkFreq(satelliteFrequency, new Date(currentTimeMillis));
}
}, 1.0f);
Multiply mul = new Multiply(source, source2, true);
Where "getDopplerFrequency" can be calculated using orekit or predict4java.
Usage
Configure maven:
<dependency>
<groupId>ru.r2cloud</groupId>
<artifactId>jradio</artifactId>
<version>1.57</version>
</dependency>
Contributing
Contributing to the project is super easy:
- Raise an issue with description and use case. Skip this step for small bug fixes or minor features
- Raise pull request
- Make sure pull request contains unit tests for new functionality or bug fix