ZigRadio Reference Manual
Generated from ZigRadio v0.8.0
.
Example
Coming soon...
Building
Coming soon...
Running
Coming soon...
Blocks
Sources
AirspyHFSource
Source a complex-valued signal from an Airspy HF+. This source requires the libairspyhf library.
radio.blocks.AirspyHFSource.init(frequency: f64, rate: f64, options: Options)
Arguments
-
frequency
(f64): Tuning frequency in Hz -
rate
(f64): Sample rate in Hz (e.g. 192 kHz, 256 kHz, 384 kHz, 768 kHz) -
options
(Options): Additional options:hf_agc
(bool
, default true)hf_agc_threshold
(enum { Low, High}
, default .Low)hf_att
(u8
, default 0 dB, for manual attenuation when HF AGC is disabled, range of 0 to 48 dB, 6 dB step)hf_lna
(bool
, default false)debug
(bool
, default false)
Type Signature
- ❑➔
out
Complex(f32)
Example
var src = radio.blocks.AirspyHFSource.init(7.150e6, 192e3, .{ .hf_lna = true });
try top.connect(&src.block, &snk.block);
ApplicationSource
Source a signal from a host application.
Provides an interface for applications to push samples into the flowgraph.
radio.blocks.ApplicationSource(comptime T: type).init(rate: f64)
Comptime Arguments
T
(type): Complex(f32), f32, u1, etc.
Arguments
rate
(f64): Sample rate in Hz
Type Signature
- ❑➔
out
T
Example
var src = radio.blocks.ApplicationSource(std.math.Complex(f32)).init(1e6);
try top.connect(&src.block, &snk.block);
...
try src.push(std.math.Complex(f32).init(2, 3));
IQStreamSource
Source a complex-valued signal from a binary stream, using the specified sample format.
radio.blocks.IQStreamSource.init(reader: std.io.AnyReader, format: SampleFormat, rate: f64, options: Options)
Arguments
-
reader
(std.io.AnyReader): Reader -
format
(SampleFormat): Choice of s8, u8, u16le, u16be, s16le, s16be, u32le, u32be, s32le, s32be, f32le, f32be, f64le, f64be -
rate
(f64): Sample rate in Hz -
options
(Options): Additional options
Type Signature
- ❑➔
out
Complex(f32)
Example
var input_file = try std.fs.cwd().openFile("samples.iq", .{});
defer input_file.close();
...
var src = radio.blocks.IQStreamSource.init(input_file.reader().any(), .s16le, 1e6, .{});
try top.connect(&src.block, &snk.block);
RealStreamSource
Source a real-valued signal from a binary stream, using the specified sample format.
radio.blocks.RealStreamSource.init(reader: std.io.AnyReader, format: SampleFormat, rate: f64, options: Options)
Arguments
-
reader
(std.io.AnyReader): Reader -
format
(SampleFormat): Choice of s8, u8, u16le, u16be, s16le, s16be, u32le, u32be, s32le, s32be, f32le, f32be, f64le, f64be -
rate
(f64): Sample rate in Hz -
options
(Options): Additional options
Type Signature
- ❑➔
out
f32
Example
var input_file = try std.fs.cwd().openFile("samples.real", .{});
defer input_file.close();
...
var src = radio.blocks.RealStreamSource.init(input_file.reader().any(), .s16le, 1e6, .{});
try top.connect(&src.block, &snk.block);
RtlSdrSource
Source a complex-valued signal from an RTL-SDR dongle. This source requires the librtlsdr library.
radio.blocks.RtlSdrSource.init(frequency: f64, rate: f64, options: Options)
Arguments
-
frequency
(f64): Tuning frequency in Hz -
rate
(f64): Sample rate in Hz -
options
(Options): Additional options: struct (bias_tee, direct_sampling, bandwidth, rf_gain, freq_correction, device_index, debug)biastee
(bool
, default false)direct_sampling
(?DirectSamplingMode
, default null, choice of .I, .Q)bandwidth
(?f32
, default null for sample rate)rf_gain
(?f32
, number in dB for manual gain, default null for auto-gain)freq_correction
(isize
, in PPM, default 0)device_index
(isize
, default 0)debug
(bool
, default false)
Type Signature
- ❑➔
out
Complex(f32)
Example
var src = radio.blocks.RtlSdrSource.init(162.400e6, 1e6, .{ .autogain = true });
try top.connect(&src.block, &snk.block);
SignalSource
Sources a real-valued signal with configurable waveform, frequency, amplitude, and phase.
radio.blocks.SignalSource.init(waveform: WaveformFunction, frequency: f32, rate: f64, options: Options)
Arguments
-
waveform
(WaveformFunction): Choice of .Cosine, .Sine, .Square, .Triangle, .Sawtooth, .Constant -
frequency
(f32): Frequency in Hz -
rate
(f64): Sample rate in Hz -
options
(Options): Additional options:amplitude
(f32
, default 1.0)offset
(f32
, default 0.0)phase
(f32
, in radians, default 0.0)
Type Signature
- ❑➔
out
f32
Example
var src = radio.blocks.SignalSource.init(.Sine, 1000, 48000, .{ .amplitude = 0.5 });
try top.connect(&src.block, &snk.block);
ZeroSource
Source a zero-valued signal of the specified type.
radio.blocks.ZeroSource(comptime T: type).init(rate: f64)
Comptime Arguments
T
(type): Complex(f32), f32, u1, etc.
Arguments
rate
(f64): Sample rate in Hz
Type Signature
- ❑➔
out
T
Example
var src = radio.blocks.ZeroSource(std.math.Complex(f32)).init(1e6);
try top.connect(&src.block, &snk.block);
Sinks
ApplicationSink
Sink a signal to a host application.
Provides an interface for applications to consume samples from the flowgraph.
radio.blocks.ApplicationSink(comptime T: type).init()
Comptime Arguments
T
(type): Complex(f32), f32, u1, etc.
Type Signature
in
T ➔❑
Example
var snk = radio.blocks.ApplicationSink(std.math.Complex(f32)).init();
try top.connect(&src.block, &snk.block);
...
const sample = snk.pop();
BenchmarkSink
Benchmark throughput.
Consumes samples and periodically reports the sample rate and byte rate.
radio.blocks.BenchmarkSink(comptime T: type).init(options: Options)
Comptime Arguments
T
(type): Complex(f32), f32, u1, etc.
Arguments
options
(Options): Additional options:title
([]const u8
, default "BenchmarkSink")report_period_ms
(usize
, reporting period in milliseconds, default 3000)
Type Signature
in
T ➔❑
Example
var snk = radio.blocks.BenchmarkSink(std.math.Complex(f32)).init(.{});
try top.connect(&src.block, &snk.block);
IQStreamSink
Sink a complex-valued signal to a binary stream, using the specified sample format.
radio.blocks.IQStreamSink.init(writer: std.io.AnyWriter, format: SampleFormat, options: Options)
Arguments
-
writer
(std.io.AnyWriter): Writer -
format
(SampleFormat): Choice of s8, u8, u16le, u16be, s16le, s16be, u32le, u32be, s32le, s32be, f32le, f32be, f64le, f64be -
options
(Options): Additional options
Type Signature
in
Complex(f32) ➔❑
Example
var output_file = try std.fs.cwd().createFile("samples.iq", .{});
defer output_file.close();
...
var snk = radio.blocks.IQStreamSink.init(output_file.writer().any(), .s16le, .{});
try top.connect(&src.block, &snk.block);
JSONStreamSink
Sink a signal to a binary stream, serialized with JSON. Samples are serialized individually and newline delimited.
radio.blocks.JSONStreamSink(comptime T: type).init(writer: std.io.AnyWriter, options: Options)
Comptime Arguments
T
(type): Any type serializable bystd.json.stringify()
Arguments
-
writer
(std.io.AnyWriter): Writer -
options
(Options): Additional options
Type Signature
in
T ➔❑
Example
var output_file = try std.fs.cwd().createFile("samples.json", .{});
defer output_file.close();
...
var snk = radio.blocks.JSONStreamSink(Foo).init(output_file.writer().any(), .{});
try top.connect(&src.block, &snk.block);
PrintSink
Sink a signal to standard out.
radio.blocks.PrintSink(comptime T: type).init()
Comptime Arguments
T
(type): Any type formattable bystd.debug.print()
Type Signature
in
T ➔❑
Example
var snk = radio.blocks.PrintSink(f32).init();
try top.connect(&src.block, &snk.block);
PulseAudioSink
Sink a mono or stereo real-valued signal to the PulseAudio sound server. This sink requires the libpulse-simple library.
radio.blocks.PulseAudioSink.init()
Type Signature
in1
f32,in2
f32 ➔❑
Example
var snk = radio.blocks.PulseAudioSink(2).init();
try top.connectPort(&src_left.block, "out", &snk.block, "in1");
try top.connectPort(&src_right.block, "out", &snk.block, "in2");
RealStreamSink
Sink a real-valued signal to a binary stream, using the specified sample format.
radio.blocks.RealStreamSink.init(writer: std.io.AnyWriter, format: SampleFormat, options: Options)
Arguments
-
writer
(std.io.AnyWriter): Writer -
format
(SampleFormat): Choice of s8, u8, u16le, u16be, s16le, s16be, u32le, u32be, s32le, s32be, f32le, f32be, f64le, f64be -
options
(Options): Additional options
Type Signature
in
f32 ➔❑
Example
var output_file = try std.fs.cwd().createFile("samples.real", .{});
defer output_file.close();
...
var snk = radio.blocks.RealStreamSink.init(output_file.writer().any(), .u16be, .{});
try top.connect(&src.block, &snk.block);
Filtering
BandpassFilterBlock
Filter a complex or real valued signal with a real-valued FIR band-pass filter generated by the window design method.
$$ y[n] = (x * h_{bpf})[n] $$
radio.blocks.BandpassFilterBlock(comptime T: type, comptime N: comptime_int).init(cutoffs: struct{f32,f32}, options: Options)
Comptime Arguments
-
T
(type): Complex(f32), f32 -
N
(comptime_int): Number of taps
Arguments
-
cutoffs
(struct{f32,f32}): Lower and upper cutoff frequencies in Hz -
options
(Options): Additional options:nyquist
(?f32
, alternate Nyquist frequency in Hz)window
(WindowFunction
, window function, default Hamming)
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.BandpassFilterBlock(std.math.Complex(f32), 129).init(.{ 10e3, 20e3 }, .{});
BandstopFilterBlock
Filter a complex or real valued signal with a real-valued FIR band-stop filter generated by the window design method.
$$ y[n] = (x * h_{bsf})[n] $$
radio.blocks.BandstopFilterBlock(comptime T: type, comptime N: comptime_int).init(cutoffs: struct{f32,f32}, options: Options)
Comptime Arguments
-
T
(type): Complex(f32), f32 -
N
(comptime_int): Number of taps
Arguments
-
cutoffs
(struct{f32,f32}): Lower and upper cutoff frequencies in Hz -
options
(Options): Additional options:nyquist
(?f32
, alternate Nyquist frequency in Hz)window
(WindowFunction
, window function, default Hamming)
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.BandstopFilterBlock(std.math.Complex(f32), 129).init(.{ 10e3, 20e3 }, .{});
ComplexBandpassFilterBlock
Filter a complex-valued signal with a complex-valued FIR band-pass filter generated by the window design method. This filter is asymmetric in the frequency domain.
$$ y[n] = (x * h_{bpf})[n] $$
radio.blocks.ComplexBandpassFilterBlock(comptime N: comptime_int).init(cutoffs: struct{f32,f32}, options: Options)
Comptime Arguments
N
(comptime_int): Number of taps
Arguments
-
cutoffs
(struct{f32,f32}): Lower and upper cutoff frequencies in Hz -
options
(Options): Additional options:nyquist
(?f32
, alternate Nyquist frequency in Hz)window
(WindowFunction
, window function, default Hamming)
Type Signature
in
Complex(f32) ➔❑➔out
Complex(f32)
Example
var filter = radio.blocks.ComplexBandpassFilterBlock(129).init(.{ 10e3, 20e3 }, .{});
ComplexBandstopFilterBlock
Filter a complex-valued signal with a complex-valued FIR band-stop filter generated by the window design method. This filter is asymmetric in the frequency domain.
$$ y[n] = (x * h_{bsf})[n] $$
radio.blocks.ComplexBandstopFilterBlock(comptime N: comptime_int).init(cutoffs: struct{f32,f32}, options: Options)
Comptime Arguments
N
(comptime_int): Number of taps
Arguments
-
cutoffs
(struct{f32,f32}): Lower and upper cutoff frequencies in Hz -
options
(Options): Additional options:nyquist
(?f32
, alternate Nyquist frequency in Hz)window
(WindowFunction
, window function, default Hamming)
Type Signature
in
Complex(f32) ➔❑➔out
Complex(f32)
Example
var filter = radio.blocks.ComplexBandstopFilterBlock(129).init(.{ 10e3, 20e3 }, .{});
FIRFilterBlock
Filter a complex or real valued signal with an FIR filter.
$$ y[n] = (x * h)[n] $$
$$ y[n] = b_0 x[n] + b_1 x[n-1] + ... + b_N x[n-N] $$
radio.blocks.FIRFilterBlock(comptime T: type, comptime U: type, comptime N: comptime_int).init(taps: [N]U)
Comptime Arguments
-
T
(type): Complex(f32), f32 -
U
(type): Tap data type (e.g. Complex(f32), f32) -
N
(comptime_int): Number of taps
Arguments
taps
([N]U): Taps
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.FIRFilterBlock(std.math.Complex(f32), f32, 64).init(taps);
FMDeemphasisFilterBlock
Filter a complex or real valued signal with an FM De-emphasis filter, a single-pole low-pass IIR filter.
$$ y[n] = (x * h_{fmdeemph})[n] $$
radio.blocks.FMDeemphasisFilterBlock.init(tau: De-emphasis)
Arguments
tau
(De-emphasis): time constant
Type Signature
in
f32 ➔❑➔out
f32
Example
var deemphasis = radio.blocks.FMDeemphasisFilterBlock.init(75e-6);
HighpassFilterBlock
Filter a complex or real valued signal with a real-valued FIR high-pass filter generated by the window design method.
$$ y[n] = (x * h_{hpf})[n] $$
radio.blocks.HighpassFilterBlock(comptime T: type, comptime N: comptime_int).init(cutoff: f32, options: Options)
Comptime Arguments
-
T
(type): Complex(f32), f32 -
N
(comptime_int): Number of taps (filter length)
Arguments
-
cutoff
(f32): Cutoff frequency in Hz -
options
(Options): Additional options:nyquist
(?f32
, alternate Nyquist frequency in Hz)window
(WindowFunction
, window function, default Hamming)
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.HighpassFilterBlock(std.math.Complex(f32), 129).init(100, .{});
IIRFilterBlock
Filter a complex or real valued signal with an IIR filter.
$$ y[n] = (x * h)[n] $$
$$ \begin{align} y[n] = &\frac{1}{a_0}(b_0 x[n] + b_1 x[n-1] + ... + b_N x[n-N] \\ - &a_1 y[n-1] - a_2 y[n-2] - ... - a_M x[n-M])\end{align} $$
radio.blocks.IIRFilterBlock(comptime T: type, comptime N: comptime_int, comptime M: comptime_int).init(b_taps: [N]f32, a_taps: [M]f32)
Comptime Arguments
-
T
(type): Complex(f32), f32 -
N
(comptime_int): Number of feedforward taps -
M
(comptime_int): Number of feedback taps
Arguments
-
b_taps
([N]f32): Feedforward taps -
a_taps
([M]f32): Feedback taps
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.IIRFilterBlock(std.math.Complex(f32), 3, 3).init(b_taps, a_taps);
LowpassFilterBlock
Filter a complex or real valued signal with a real-valued FIR low-pass filter generated by the window design method.
$$ y[n] = (x * h_{lpf})[n] $$
radio.blocks.LowpassFilterBlock(comptime T: type, comptime N: comptime_int).init(cutoff: f32, options: Options)
Comptime Arguments
-
T
(type): Complex(f32), f32 -
N
(comptime_int): Number of taps (filter length)
Arguments
-
cutoff
(f32): Cutoff frequency in Hz -
options
(Options): Additional options:nyquist
(?f32
, alternate Nyquist frequency in Hz)window
(WindowFunction
, window function, default Hamming)
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.LowpassFilterBlock(std.math.Complex(f32), 128).init(10e3, .{});
RectangularMatchedFilterBlock
Correlate a real-valued signal with a rectangular matched filter.
radio.blocks.RectangularMatchedFilterBlock.init(baudrate: Baudrate)
Arguments
baudrate
(Baudrate):
Type Signature
in
f32 ➔❑➔out
f32
Example
var matched_filter = radio.blocks.RectangularMatchedFilterBlock.init(2400);
SinglepoleHighpassFilterBlock
Filter a complex or real valued signal with a single-pole high-pass IIR filter.
$$ H(s) = \frac{\tau s}{\tau s + 1} $$
$$ H(z) = \frac{2\tau f_s}{1 + 2\tau f_s} \frac{1 - z^{-1}}{1 + (\frac{1 - 2\tau f_s}{1 + 2\tau f_s}) z^{-1}} $$
$$ y[n] = \frac{2\tau f_s}{1 + 2\tau f_s} \; x[n] + \frac{2\tau f_s}{1 + 2\tau f_s} \; x[n-1] - \frac{1 - 2\tau f_s}{1 + 2\tau f_s} \; y[n-1] $$
radio.blocks.SinglepoleHighpassFilterBlock(comptime T: type).init(cutoff: f32)
Comptime Arguments
T
(type): Complex(f32), f32
Arguments
cutoff
(f32): Cutoff frequency in Hz
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.SinglepoleHighpassFilterBlock(f32).init(100);
SinglepoleLowpassFilterBlock
Filter a complex or real valued signal with a single-pole low-pass IIR filter.
$$ H(s) = \frac{1}{\tau s + 1} $$
$$ H(z) = \frac{1}{1 + 2\tau f_s} \frac{1 + z^{-1}}{1 + (\frac{1 - 2\tau f_s}{1 + 2\tau f_s}) z^{-1}} $$
$$ y[n] = \frac{1}{1 + 2\tau f_s} \; x[n] + \frac{1}{1 + 2\tau f_s} \; x[n-1] - \frac{1 - 2\tau f_s}{1 + 2\tau f_s} \; y[n-1] $$
radio.blocks.SinglepoleLowpassFilterBlock(comptime T: type).init(cutoff: f32)
Comptime Arguments
T
(type): Complex(f32), f32
Arguments
cutoff
(f32): Cutoff frequency in Hz
Type Signature
in
T ➔❑➔out
T
Example
var filter = radio.blocks.SinglepoleLowpassFilterBlock(f32).init(1e3);
Math Operations
AddBlock
Add two signals.
$$ y[n] = x_{1}[n] + x_{2}[n] $$
radio.blocks.AddBlock(comptime T: type).init()
Comptime Arguments
T
(type): Complex(f32), f32, etc.
Type Signature
in1
T,in2
T ➔❑➔out
T
Example
var summer = radio.blocks.AddBlock(std.math.Complex(f32)).init();
try top.connectPort(&src1.block, "out1", &summer.block, "in1");
try top.connectPort(&src2.block, "out1", &summer.block, "in2");
try top.connect(&summer.block, &sink.block);
ComplexMagnitudeBlock
Compute the magnitude of a complex-valued signal.
$$ y[n] = |x[n]| $$
$$ y[n] = \sqrt{\text{Re}(x[n])^2 + \text{Im}(x[n])^2} $$
radio.blocks.ComplexMagnitudeBlock.init()
Type Signature
in
Complex(f32) ➔❑➔out
f32
Example
var mag = radio.blocks.ComplexMagnitudeBlock.init();
MultiplyBlock
Multiply two signals.
$$ y[n] = x_{1}[n] \; x_{2}[n] $$
radio.blocks.MultiplyBlock(comptime T: type).init()
Comptime Arguments
T
(type): Complex(f32), f32, etc.
Type Signature
in1
T,in2
T ➔❑➔out
T
Example
var multiplier = radio.blocks.MultiplyBlock(std.math.Complex(f32)).init();
try top.connectPort(&src1.block, "out1", &multiplier.block, "in1");
try top.connectPort(&src2.block, "out1", &multiplier.block, "in2");
try top.connect(&multiplier.block, &snk.block);
MultiplyConjugateBlock
Multiply a complex-valued signal by the complex conjugate of another complex-valued signal.
$$ y[n] = x_{1}[n] \; x_{2}^*[n] $$
radio.blocks.MultiplyConjugateBlock.init()
Type Signature
in1
Complex(f32),in2
Complex(f32) ➔❑➔out
Complex(f32)
Example
var mixer = radio.blocks.MultiplyConjugateBlock.init();
try top.connectPort(&src1.block, "out1", &mixer.block, "in1");
try top.connectPort(&src2.block, "out1", &mixer.block, "in2");
try top.connect(&mixer.block, &snk.block);
SubtractBlock
Subtract two signals.
$$ y[n] = x_{1}[n] - x_{2}[n] $$
radio.blocks.SubtractBlock(comptime T: type).init()
Comptime Arguments
T
(type): Complex(f32), f32, etc.
Type Signature
in1
T,in2
T ➔❑➔out
T
Example
var subtractor = radio.blocks.SubtractBlock(std.math.Complex(f32)).init();
try top.connectPort(&src1.block, "out1", &subtractor.block, "in1");
try top.connectPort(&src1.block, "out1", &subtractor.block, "in2");
try top.connect(&subtractor.block, &snk.block);
Level Control
AGCBlock
Apply automatic gain to a real or complex valued signal to maintain an average target power.
$$ y[n] = \text{AGC}(x[n], \text{mode}, \text{target}, \text{threshold}) $$
Implementation note: this is a feedforward AGC. The power_tau
time
constant controls the moving average of the power estimator. The gain_tau
time constant controls the speed of the gain adjustment. The gain has
symmetric attack and decay dynamics.
radio.blocks.AGCBlock(comptime T: type).init(mode: Mode, options: Options)
Comptime Arguments
T
(type): Complex(f32), f32
Arguments
-
mode
(Mode): AGC mode, either preset of .Slow, .Medium, .Fast or a custom time constant -
options
(Options): Additional options:target_dbfs
(f32
, target level in dBFS, default -20)threshold_dbfs
(f32
, threshold level in dBFS, default -75)power_tau
(f32
, power estimator time constant, default 1.0)
Type Signature
in
T ➔❑➔out
T
Example
var agc = radio.blocks.AGCBlock(std.math.Complex(f32)).init(.{ .preset = .Fast }, .{ .target_dbfs = -30, .threshold_dbfs = -75 });
Sample Rate Manipulation
DownsamplerBlock
Downsample a complex or real valued signal. This block reduces the sample rate for downstream blocks in the flow graph by a factor of M.
$$ y[n] = x[nM] $$
Note: this block performs no anti-alias filtering.
radio.blocks.DownsamplerBlock(comptime T: type).init(factor: usize)
Comptime Arguments
T
(type): Complex(f32), f32, etc.
Arguments
factor
(usize): Downsampling factor
Type Signature
in
T ➔❑➔out
T
Example
var downsampler = radio.blocks.DownsamplerBlock(std.math.Complex(f32)).init(4);
Spectrum Manipulation
TunerBlock
Frequency translate, low-pass filter, and downsample a complex-valued signal.
$$ y[n] = (\text{FrequencyTranslate}(x[n], f_{offset}) * h_{lpf})[nM] $$
This block is convenient for translating signals to baseband.
radio.blocks.TunerBlock.init(offset: f32, bandwidth: f32, factor: usize)
Arguments
-
offset
(f32): Translation offset in Hz -
bandwidth
(f32): Signal bandwidth in Hz -
factor
(usize): Downsampling factor M
Type Signature
in1
Complex(f32) ➔❑➔out1
Complex(f32)
Example
var tuner = radio.blocks.TunerBlock.init(50e3, 10e3, 5);
try top.connect(&src.block, &tuner.block);
try top.connect(&tuner.block, &snk.block);
FrequencyTranslatorBlock
Frequency translate a complex-valued signal by mixing it with \( e^{j \omega_0 n} \), where \( \omega_0 = 2 \pi f_o / f_s \).
$$ y[n] = x[n] \; e^{j\omega_0 n} $$
radio.blocks.FrequencyTranslatorBlock.init(offset: Translation)
Arguments
offset
(Translation): offset in Hz
Type Signature
in
Complex(f32) ➔❑➔out
Complex(f32)
Example
var translator = radio.blocks.FrequencyTranslatorBlock.init(-50e3);
Carrier and Clock Recovery
ComplexPLLBlock
Generate a phase-locked complex sinusoid to a complex-valued reference signal.
$$ y[n] = \text{PLL}(x[n], f_{BW}, f_{min}, f_{max}, M) $$
radio.blocks.ComplexPLLBlock.init(loop_bandwidth: f32, frequency_range: struct{f32,f32}, options: Options)
Arguments
-
loop_bandwidth
(f32): Loop bandwidth in Hz -
frequency_range
(struct{f32,f32}): Minimum and maximum frequency range in Hz -
options
(Options): Additional options:multiplier
(f32
, frequency multiplier, default 1.0)
Type Signature
in
Complex(f32) ➔❑➔out
Complex(f32),err
f32
Example
var pll = radio.blocks.ComplexPLLBlock.init(500, .{ 8e3, 12e3 }, .{});
try top.connect(&src.block, &pll.block);
try top.connectPort(&pll.block, "out1", &snk.block);
try top.connectPort(&pll.block, "out2", &err_snk.block);
Digital
DifferentialDecoderBlock
Decode a differentially encoded bit stream.
radio.blocks.DifferentialDecoderBlock.init()
Type Signature
in
u1 ➔❑➔out
u1
Example
var diffdecoder = radio.blocks.DifferentialDecoderBlock(false).init();
SlicerBlock
Slice a signal into symbols using the specified slicer.
radio.blocks.SlicerBlock.init()
Type Signature
in
T ➔❑➔out
U
Example
var slicer = radio.blocks.SlicerBlock(radio.blocks.BinarySlicer).init();
Type Conversion
ComplexToImagBlock
Decompose the imaginary part of a complex-valued signal.
$$ y[n] = \text{Im}(x[n]) $$
radio.blocks.ComplexToImagBlock.init()
Type Signature
in
Complex(f32) ➔❑➔out
f32
Example
var complextoimag = radio.blocks.ComplexToImagBlock.init();
ComplexToRealBlock
Decompose the real part of a complex-valued signal.
$$ y[n] = \text{Re}(x[n]) $$
radio.blocks.ComplexToRealBlock.init()
Type Signature
in
Complex(f32) ➔❑➔out
f32
Example
var complextoreal = radio.blocks.ComplexToRealBlock.init();
RealToComplexBlock
Compose a complex-valued signal from a real-valued signal and a zero-valued imaginary part.
$$ y[n] = x[n] + 0 \, j $$
radio.blocks.RealToComplexBlock.init()
Type Signature
in
f32 ➔❑➔out
Complex(f32)
Example
var realtocomplex = radio.blocks.RealToComplexBlock.init();
Miscellaneous
DelayBlock
Delay a signal by a fixed number of samples.
$$ y[n] = x[n - D] $$
radio.blocks.DelayBlock(comptime T: type).init(delay: usize)
Comptime Arguments
T
(type): Complex(f32), f32, etc.
Arguments
delay
(usize): Number of samples to delay
Type Signature
in
T ➔❑➔out
T
Example
var delay = radio.blocks.DelayBlock(std.math.Complex(f32)).init(7);
Demodulation
AMEnvelopeDemodulatorBlock
Demodulate a baseband, double-sideband amplitude modulated
$$ y[n] = \text{AMDemodulate}(x[n], \text{bandwidth}) $$
complex-valued signal with an envelope detector.
radio.blocks.AMEnvelopeDemodulatorBlock.init(options: Options)
Arguments
options
(Options): Additional options:bandwidth
(f32
, bandwidth in Hz, default 5e3)
Type Signature
in1
Complex(f32) ➔❑➔out1
f32
Example
var demod = radio.blocks.AMEnvelopeDemodulatorBlock.init(.{});
try top.connect(&src.block, &demod.block);
try top.connect(&demod.block, &snk.block);
AMSynchronousDemodulatorBlock
Demodulate a baseband, double-sideband amplitude modulated complex-valued signal with a synchronous detector.
$$ y[n] = \text{AMDemodulate}(x[n], \text{bandwidth}) $$
radio.blocks.AMSynchronousDemodulatorBlock.init(options: Options)
Arguments
options
(Options): Additional options:bandwidth
(f32
, bandwidth in Hz, default 5e3)
Type Signature
in1
Complex(f32) ➔❑➔out1
f32
Example
var demod = radio.blocks.AMSynchronousDemodulatorBlock.init(.{});
try top.connect(&src.block, &demod.block);
try top.connect(&demod.block, &snk.block);
NBFMDemodulatorBlock
Demodulate a baseband, narrowband FM modulated complex-valued signal.
$$ y[n] = \text{NBFMDemodulate}(x[n], \text{deviation}, \text{bandwidth}) $$
radio.blocks.NBFMDemodulatorBlock.init(options: Options)
Arguments
options
(Options): Additional options:bandwidth
(f32
, bandwidth in Hz, default 5e3)deviation
(f32
, deviation in Hz, default 4e3)
Type Signature
in1
Complex(f32) ➔❑➔out1
f32
Example
var demod = radio.blocks.NBFMDemodulatorBlock.init(.{});
try top.connect(&src.block, &demod.block);
try top.connect(&demod.block, &snk.block);
WBFMMonoDemodulatorBlock
Demodulate a baseband, broadcast radio wideband FM modulated complex-valued signal into the real-valued mono channel (L+R) signal.
$$ y[n] = \text{WBFMMonoDemodulate}(x[n], \text{deviation}, \text{bandwidth}, \tau) $$
radio.blocks.WBFMMonoDemodulatorBlock.init(options: Options)
Arguments
options
(Options): Additional options:deviation
(f32
, deviation in Hz, default 75e3)af_bandwidth
(f32
, audio bandwidth in Hz, default 15e3)af_deemphasis_tau
(f32
, audio de-emphasis time constant, default 75e-6)
Type Signature
in1
Complex(f32) ➔❑➔out1
f32
Example
var demod = radio.blocks.WBFMMonoDemodulatorBlock.init(.{});
try top.connect(&src.block, &demod.block);
try top.connect(&demod.block, &snk.block);
WBFMStereoDemodulatorBlock
Demodulate a baseband, broadcast radio wideband FM modulated complex-valued signal into the real-valued stereo channel (L and R) signals.
$$ y_{left}[n], y_{right}[n] = \text{WBFMStereoDemodulate}(x[n], \text{deviation}, \text{bandwidth}, \tau) $$
radio.blocks.WBFMStereoDemodulatorBlock.init(options: Options)
Arguments
options
(Options): Additional options:deviation
(f32
, deviation in Hz, default 75e3)af_bandwidth
(f32
, audio bandwidth in Hz, default 15e3)af_deemphasis_tau
(f32
, audio de-emphasis time constant, default 75e-6)
Type Signature
in1
Complex(f32) ➔❑➔out1
f32,out2
f32
Example
var demod = radio.blocks.WBFMStereoDemodulatorBlock.init(.{});
try top.connect(&src.block, &demod.block);
try top.connectPort(&demod.block, "out1", &left_snk.block, "in1");
try top.connectPort(&demod.block, "out2", &right_snk.block, "in1");
FrequencyDiscriminatorBlock
Compute the instantaneous frequency of a complex-valued input signal. This is a method of frequency demodulation.
$$ y[n] = \frac{\text{arg}(x[n] \; x^*[n-1])}{2 \pi k} $$
radio.blocks.FrequencyDiscriminatorBlock.init(deviation: f32)
Arguments
deviation
(f32): Frequency deviation in Hz
Type Signature
in
Complex(f32) ➔❑➔out
f32
Example
var demod = radio.blocks.FrequencyDiscriminatorBlock.init(5e3);