Input Sources

This page describes every way to feed samples or frames into gr_satellites: recordings in WAV, raw and SigMF formats, live soundcard and UDP input, and previously decoded KISS files. It also explains the difference between real and IQ input, how FSK and BPSK expect their signals to be tuned, and the options that modify the input (--samp_rate, --input_gain, --throttle, --start_time).

Exactly one input source is required. Giving none, or two, is an argparse error (exit status 2).

On this page:

Summary

Option Source Sample format --samp_rate
--wavfile FILE WAV/OGG/FLAC file (libsndfile) 1 channel real, or 2 channels I/Q with --iq Optional (read from header)
--rawfile FILE Raw file float32 real, or complex64 with --iq Required
--rawint16 FILE Raw file int16 real, or interleaved I/Q int16 with --iq Required
--sigmf FILE SigMF recording ci16_le only Taken from metadata
--audio [DEVICE] Soundcard 1 channel real, or 2 channels I/Q with --iq Required
--udp UDP stream int16 (default) or float32/complex64 with --udp_raw Required
--kiss_in FILE KISS file of decoded frames Frames, no samples Not used

--wavfile

gr_satellites FUNcube-1 --wavfile ao73.wav

Reads any format libsndfile supports (WAV, OGG, FLAC, ...) with GNU Radio's WAV File Source. The sample rate comes from the file header. If you also pass --samp_rate, that value is used instead of the header value. This does not resample the file; it only tells the demodulators a different rate, so use it only when the header is wrong.

  • Without --iq, only the first channel is used as real samples.
  • With --iq, channel 0 is I and channel 1 is Q. The file must have two channels.

--rawfile

gr_satellites NuSat-1 --rawfile capture.c64 --iq --samp_rate 192e3

Reads headerless samples as written by GNU Radio's File Sink:

  • float32 (32-bit IEEE floats) for real input,
  • complex64 (interleaved 32-bit float I and Q) with --iq.

--samp_rate is mandatory. Without it the tool prints Need to specify --samp_rate unless --wavfile or --kiss_in or --sigmf is used and exits with status 1.

--rawint16

gr_satellites AU03 --rawint16 capture.s16 --samp_rate 48e3

Reads 16-bit signed integers in host byte order (GNU Radio File Sink type short). Samples are scaled by 1/32767. With --iq, consecutive values are I and Q. --samp_rate is mandatory.

--sigmf

gr_satellites 39444 --sigmf recording.sigmf-meta

Reads a SigMF recording. You can pass either the .sigmf-meta or the .sigmf-data file; the other one is found by replacing the extension. The tool then:

  1. Loads the metadata JSON and checks that the top-level global, captures and annotations objects exist.
  2. Requires core:datatype and core:sample_rate in global.
  3. Accepts only the ci16_le datatype (complex, 16-bit little-endian integers). It forces IQ input and uses core:sample_rate as the sample rate, overriding --iq and --samp_rate.
  4. Requires core:sample_start in every capture segment.
  5. If there is exactly one capture segment with core:datetime and core:sample_start equal to 0, it uses that datetime as --start_time, replacing any value you passed. If sample_start is not 0, it prints a warning and ignores the datetime.

Errors and their messages:

Problem Message (abridged)
.sigmf archive passed Failed to load SigMF archive (archives are not yet supported).
Other extension Invalid value passed to --sigmf, expected file extension .sigmf-meta or .sigmf-data
Metadata missing Could not open SigMF Metadata in '<file>':
Invalid JSON Failed to parse SigMF Metadata in '<file>', JSON decoder error:
Missing object ERROR: Missing top-level object 'captures' in SigMF metadata.
Missing field SigMF metadata file is malformed: Missing field 'core:sample_rate'
Other datatype Unsupported SigMF Dataset format ('cf32_le'). Supported datatypes are: ci16_le

All of these exit with status 1.

Note: The ci16_le data is read with the same code as --rawint16, which uses host byte order. On little-endian machines (x86, most ARM) this matches the format.

--audio

gr_satellites AU03 --audio --samp_rate 48e3
gr_satellites AU03 --audio hw:1,0 --samp_rate 48e3

Reads from a soundcard with GNU Radio's Audio Source, for example the audio output of a conventional radio or a virtual audio cable from SDR software. The device name is optional and platform-specific (see GNU Radio's Audio Source documentation); without it the default device is used. --samp_rate is mandatory; 48000 is typical. With --iq, the left and right channels are I and Q.

--udp

gr_satellites FUNcube-1 --udp --samp_rate 48e3

Listens for UDP datagrams carrying samples. Defaults and related options:

Option Default Effect
--udp_port PORT 7355 UDP port to listen on.
--udp_ipv4_only off Listen on IPv4 only. By default the socket is opened in IPv6 mode, listening on all addresses (::).
--udp_raw off Expect float32 (real) or complex64 (IQ) samples instead of int16.
--iq off Interpret the stream as I/Q pairs.

The default int16 format and port match GQRX's "UDP audio" output at 48 kHz, which is the simplest way to connect an SDR to gr_satellites. Tools like nc or GNU Radio flowgraphs (for example the ones in the separate gr-frontends project) can also stream samples.

If your system has IPv6 disabled and the tool fails to open the socket, try --udp_ipv4_only.

--kiss_in

gr_satellites AU03 --kiss_in frames.kss

Reads frames that were already decoded and stored in KISS format, either by gr_satellites --kiss_out or by other software. Demodulators, deframers and transmitters are skipped entirely: every frame goes directly to the satellite's data sinks (telemetry parser, file receiver, ...) and to the output options (KISS out, ZMQ, submission).

Details:

  • Only KISS data frames (control byte with low nibble 0) are used. The timestamp frames (control byte 0x09) written by --kiss_out are skipped.
  • --samp_rate, --iq, --input_gain, --throttle and the demodulation options have no effect.
  • Frames are not tagged with a transmitter name, so the telemetry parser does not print the -> Packet from ... line.
  • Data sinks are connected regardless of which transmitter would have produced the frame. For a satellite whose frames normally pass through a transport (for example KISS-in-frames), the KISS file must contain the transport's output, which is what --kiss_out does not store: --kiss_out saves deframer output. See Troubleshooting.

Input Modifiers

Option Default Effect
--samp_rate RATE none Sample rate in Hz (float, so 48e3 works).
--iq off Treat the input as complex I/Q. See below.
--input_gain GAIN 1 Multiply the input by this factor before demodulation. A negative value inverts the signal.
--throttle off Limit file playback to real time (1x speed).
--start_time TIME '' Timestamp of the start of a recording, ISO 8601. Used for timestamps in KISS output and some telemetry submissions.

--input_gain

The main use of --input_gain -1 is fixing FSK polarity. FM receivers often invert the audio, which does not matter for voice but breaks FSK decoding when the protocol is not differentially encoded. The demodulators include AGC, so the magnitude of the gain rarely matters.

--throttle and --start_time

By default a recording is processed as fast as possible. Timestamps attached to frames (in KISS files, KISS server output, SatNOGS and SIDS submissions) are always taken from the computer's clock when the frame is decoded. To get correct timestamps from a recording:

  1. Add --throttle so the recording plays at 1x speed.
  2. Add --start_time with the time the recording started, for example --start_time 2024-03-01T12:34:56.

Each timestamp is then computed as start_time + (time now − time the block was created). The parser accepts the formats of Python's datetime.fromisoformat(), plus a trailing Z. A time without a timezone is taken as UTC; a time with an offset (+02:00) is converted to UTC.

gr_satellites FUNcube-1 --wavfile pass.wav --throttle \
    --start_time 2024-03-01T12:34:56Z --kiss_out pass.kss

Note: --start_time without --throttle produces timestamps that are compressed into the few seconds the file takes to process. The two options are meant to be used together.

Real or IQ Input

gr_satellites assumes real input unless --iq is given.

Source of the signal Use
Audio output of a conventional radio Real
SDR software in SSB or FM mode (audio out, audio recording, GQRX UDP audio) Real
SDR raw sample recording or IQ stream (two-channel WAV, complex64, ci16_le, ...) --iq

FSK and AFSK with Real or IQ Input

For FSK and AFSK, --iq changes what kind of signal is expected, not just the data type:

  • Without --iq, the signal must already be FM-demodulated, which is what a radio or SDR program in FM mode outputs. For FSK this is the baseband NRZ waveform; for AFSK it is the audio tones.
  • With --iq, the signal must not be FM-demodulated. The FSK and AFSK demodulators then perform FM demodulation themselves (after a low-pass filter sized with Carson's rule). The signal must be centred at 0 Hz.

A consequence is that a real signal containing raw FSK at an intermediate frequency cannot be decoded directly.

With real input, the FSK demodulator always uses AGC. With IQ input, AGC is off unless you pass --use_agc.

BPSK Frequency Offsets

BPSK is usually received in SSB (USB) mode with the signal placed in the audio passband. The BPSK demodulator must know where:

Input Baud rate Default --f_offset
Real ≤ 2400 1500 Hz (middle of a normal 3 kHz SSB passband)
Real > 2400 12000 Hz ("wide SSB": middle of a 24 kHz passband in 48 kHz audio)
IQ any 0 Hz (signal at baseband)

Override it with --f_offset in Hz. A conventional SSB radio's roughly 3 kHz filter limits real-input BPSK to about 2400 baud; faster signals need an SDR.

Note: For Manchester-coded BPSK the demodulator doubles the baud rate before choosing the default, so a 1250 baud BPSK Manchester transmitter (2500 after doubling) defaults to 12000 Hz, not 1500 Hz.

See Also