IQ file formats
The receiver works on complex baseband IQ. Two helpers load recordings:
load_iq— loads the whole file into memory ascomplex64.iter_iq_chunks— streams the same formats ascomplex64chunks without loading the file; used internally bydecode_file.
Both auto-detect the format.
Raw interleaved IQ
Extensions: .cfile, .cf32, .dat, .bin, .iq.
Samples are stored as interleaved I/Q pairs:
| Encoding | Byte layout | Notes |
|---|---|---|
| float32 | I Q I Q ... |
GNU Radio File Sink default (.cfile) |
| int16 | I Q I Q ... |
common SDR format |
Detection: the first ~1000 samples are read as float32; if their mean power is
effectively zero, the file is reinterpreted as int16 (and scaled to [-1, 1)).
fs is not stored in the file — pass it to the LoRaDecoder constructor.
WAV
Extensions: .wav, .wave.
Stereo WAVs are treated as IQ: channel 0 = I, channel 1 = Q. Supported encodings:
- int16 PCM (most common)
- float32 IEEE
Mono WAVs raise an error (no I/Q channels). For WAV files the sample rate is
stored in the header — read it with
sample_rate:
from softlora import LoRaDecoder, sample_rate
fs = sample_rate("recording.wav")
decoder = LoRaDecoder(sf=10, bw=125_000, fs=fs, fc=437e6)
Sample-rate and bandwidth
LoRaDecoder needs:
fs— the rate of your IQ (or WAV header rate).bw— the LoRa channel bandwidth. The decoder resamplesfs → bwso that each LoRa symbol is exactlyN = 2**sfsamples.
The three are linked: a standard LoRa uplink is sf=7..12 at bw=125 kHz,
often captured at fs = 250 kHz (factor-2 oversampling).
Persistence
save_packets writes each packet's
raw payload to packet_XXXX.bin, appends one machine-readable
metadata.jsonl line with the full
Packet.to_dict
serialization, and renders a human-readable packets.txt summary (each
packet's Packet.__str__ detail table) — a convenient ground-station log.