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.
jradio supports high-level generic demodulators. They convert I/Q signal into the stream of soft bits (0-255).
Some generic modulators. They take hard bits and produce I/Q signal.
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
Quite often decoding require some additional tooling. jradio has some.
- Viterbi hard and soft decoders
- CCSDS ReedSolomon
- BCH ReedSolomon
- BCH(15,x,x)
- Repeat Accumulate decoder
- Golay
- PLS
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
- CSP - Full support
- CCSDS - Basic support
- PACSAT - Good support
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
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 |
GRBBETA | 60237 | ru.r2cloud.jradio.grbbeta.GRBBetaBeacon |
CatSat | 60246 | ru.r2cloud.jradio.catsat.CatsatBeacon |
ENSO | 58470 | ru.r2cloud.jradio.enso.EnsoBeacon |
EIRSAT-1 | 58472 | ru.r2cloud.jradio.eirsat.EirsatBeacon |
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.
Configure maven:
<dependency>
<groupId>ru.r2cloud</groupId>
<artifactId>jradio</artifactId>
<version>1.57</version>
</dependency>
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