Signal Conditioner
A Signal Conditioner block is in charge of adapting the sample bit depth to a data type tractable at the host computer running the software receiver, and optionally intermediate frequency to baseband conversion, resampling, and filtering.
Regardless of the selected signal source features, the Signal Conditioner interface delivers in a unified format a sample data stream to the receiver downstream processing channels, acting as a facade between the signal source and the synchronization channels, providing a simplified interface to the input signal at a reference, internal sample rate \(f_{IN}\). We denote the complex samples at the Signal Conditioner output as \(x_{\text{IN}}[n]\). This signal stream feeds a set of parallel Channels.
Implementation: Signal_Conditioner
This implementation is in fact a wrapper for other three processing blocks.

Those inner blocks are in charge of:
-
The role of the Data Type Adapter block is to perform a conversion of the data type in the incoming sample stream.
-
The role of the Input Filter block is to filter the incoming signal.
-
The role of the Resampler block is to resample the signal and to deliver it to the \(N\) parallel processing channels.
Any of them can be bypassed by using a Pass_Through implementation. Such
identity stages can be removed from the flowgraph when the receiver batches the
conditioned stream, see Batching and buffering below.
The Signal_Conditioner implementation accepts the following parameters:
| Parameter | Description | Required |
|---|---|---|
implementation |
Signal_Conditioner |
Mandatory |
| DataTypeAdapter | This implementation requires the configuration of a Data Type Adapter block. | Mandatory |
| InputFilter | This implementation requires the configuration of an Input Filter block. | Mandatory |
| Resampler | This implementation requires the configuration of a Resampler block. | Mandatory |
Signal Conditioner implementation: Signal_Conditioner.
Example:
;######### SIGNAL_CONDITIONER CONFIG ############
;## It holds blocks to change data type, filter and resample input data.
SignalConditioner.implementation=Signal_Conditioner
;######### DATA_TYPE_ADAPTER CONFIG ############
;## Changes the type of input data.
;#implementation: [Pass_Through] disables this block
DataTypeAdapter.implementation=Ishort_To_Complex
;######### INPUT_FILTER CONFIG ############
;## Filter the input data.
InputFilter.implementation=Fir_Filter
InputFilter.input_item_type=gr_complex
InputFilter.output_item_type=gr_complex
; ... other InputFilter parameters
;######### RESAMPLER CONFIG ############
;## Resamples the input data.
Resampler.implementation=Pass_Through
Implementation: Pass_Through
This implementation copies samples from its input to its output.
It accepts the following parameters:
| Parameter | Description | Required |
|---|---|---|
implementation |
Pass_Through |
Mandatory |
item_type |
[gr_complex, cshort]: Format of data samples. It defaults to gr_complex. |
Optional |
Signal Conditioner implementation: Pass_Through.
Examples:
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Pass_Through
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Pass_Through
SignalConditioner.item_type=cshort
Implementation: Bypass
This implementation connects the channels directly to the output of the
Signal Source, with no
conditioning block in between. It is intended for sources that already deliver
samples in the data type, spectrum orientation, and sample rate (set by
GNSS-SDR.internal_fs_sps) expected by the channels: Bypass does not convert,
filter, or resample samples, and it does not correct an inverted spectrum.
This implementation is only present in the next
branch of the upstream repository, and will be included in the next GNSS-SDR
stable release.
It accepts the following parameters:
| Parameter | Description | Required |
|---|---|---|
implementation |
Bypass |
Mandatory |
Signal Conditioner implementation: Bypass.
The receiver refuses to start if the DataTypeAdapter, InputFilter, or
Resampler of a bypassed Signal Conditioner set an implementation other than
Pass_Through, or if inverted_spectrum=true is set on any of them or on the
Signal Conditioner itself, since those settings would be silently ignored. It
also reports any mismatch between the item size of the source output and the
one expected by the channels.
In multi-band receivers, each SignalConditioner0, SignalConditioner1, …
can be bypassed independently.
Example:
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Bypass
Batching and buffering
Every time the block that feeds the channels delivers new samples, GNU Radio wakes up all its readers: the tracking and acquisition blocks of each channel connected to that stream, plus the receiver clock on the first stream. When samples are delivered in many small chunks, this cost can exceed the cost of the signal processing itself. GNSS-SDR controls two things at that point:
- Batching: when the last stage of the Signal Conditioner is a
Pass_Throughwith no spectrum inversion, or the whole Signal Conditioner isPass_Through, the receiver removes every such identity stage from the flowgraph, wherever it is in the chain, keeps the stages that do real work, and inserts a batching block after the last of them (or right after the source, if none is left). For instance, with aPass_ThroughData Type Adapter, aFreq_Xlating_Fir_FilterInput Filter, and aPass_ThroughResampler, the channels are fed by source → Input Filter → batching block. The batching block delivers samples to the channels in batches of \(\min(10, T_{obs})\) ms of signal, where \(T_{obs}\) isGNSS-SDR.observable_interval_ms, with at most 512 KiB per batch. A batch that is not complete within that time is delivered anyway, and the last samples of a file are always delivered. No sample or stream tag is lost. If the last stage does real work, nothing is removed and no batching block is inserted, even if an earlier stage is aPass_Through.Bypassis also kept as configured. - Buffer depth: with real-time sources (radio frequency front-ends, and file
sources with
enable_throttle_control=true), the buffer that feeds the channels holds as much signal as the observables allow (up to about 200 ms with the default settings, at most 8 MiB), so that a channel that falls temporarily behind, for instance during a blocking acquisition, does not stop the others. Unthrottled file replays keep a minimal buffer, as before.
No configuration change is required. The following parameters, with the same
prefix as the Signal Conditioner (SignalConditioner, or SignalConditioner0,
SignalConditioner1, … for multiple radio frequency chains), override these
choices:
| Parameter | Description | Required |
|---|---|---|
batch_size_ms |
[auto, 0, a positive number]: Duration, in ms, of the batches delivered to the channels. auto lets the receiver decide as described above. 0 disables batching. A positive number inserts a batching block, also for Bypass, and is limited as explained below. It defaults to auto. |
Optional |
max_batch_latency_ms |
Longest time, in ms, that a sample waits for its batch to be completed. It defaults to the largest of batch_size_ms and \(\min(10, T_{obs})\), and must not be smaller than batch_size_ms. With batch_size_ms=auto, it also sets the length of the automatic batch, which is then limited as explained below. |
Optional |
remove_pass_through |
[true, false]: If set to true, identity Pass_Through stages are removed from the flowgraph. It defaults to true when batching is applied and to false otherwise. Setting it with batch_size_ms=auto disables automatic batching. |
Optional |
output_buffer_ms |
[auto, 0, a positive number]: Signal time, in ms, held by the buffer that feeds the channels. auto applies the buffer depth described above to real-time sources only. 0 requests no extra depth. A positive number must not exceed the observables delay (280 ms with \(T_{obs} = 20\) ms), and a warning is logged if it exceeds the budget described below. It has no effect on a Bypass Signal Conditioner without batching, since the source keeps its own buffer. It defaults to auto. |
Optional |
Signal Conditioner parameters for batching and buffering.
These parameters are only present in the next
branch of the upstream repository, and will be included in the next GNSS-SDR
stable release.
Limits. The observables block computes the observables of an epoch when the
receiver clock is a fixed time past it. This observables delay is 280 ms with
the default \(T_{obs} = 20\) ms, 190 ms with \(T_{obs} = 10\) ms, and
200 ms with \(T_{obs} = 100\) ms. A channel can lag the
receiver clock by up to the buffer that feeds it, and it needs its own input
window (usually two code periods) and one 20 ms telemetry symbol beyond an epoch
to report it. What remains of the observables delay after that window, the
symbol and a 60 ms guard is the time a channel can lag and still deliver its
observables: 198 ms for GPS L1 C/A with the default settings. A batch is always
accepted up to the automatic length. A longer batch is accepted only if the
buffer it needs (two batches, or one batch on top of the largest reader input
window) fits in that time, and if the batch takes no more than 4 MiB. With GPS
L1 C/A, \(T_{obs} = 20\) ms and gr_complex samples at 4 Msps, this allows
batches of up to about 99 ms. Otherwise, the receiver refuses to start and
explains why.
Longer batches reduce the scheduling cost, but they add up to one batch of
latency, and channels searching for satellites wait for each new batch before
starting a new acquisition attempt, so they search less often. If
GNSS-SDR.max_source_buffer_samples is set, a batch takes at most half of it,
and the batch plus the largest reader input window must fit in it.
The receiver logs its decision for each Signal Conditioner. For example, with
twelve GPS L1 C/A channels, SignalConditioner.batch_size_ms=90, and an
unthrottled file at 4 Msps:
SignalConditioner: explicit batch target; readers=25, batch=360000 samples, batch deadline=90 ms, largest reader window=80000 samples, output buffer=720000 samples (180 ms), alignment budget=198 ms, unthrottled replay
Examples:
;######### SIGNAL_CONDITIONER CONFIG ############
;## Keep the configured topology, with no batching and no extra buffer depth
SignalConditioner.implementation=Signal_Conditioner
SignalConditioner.batch_size_ms=0
SignalConditioner.remove_pass_through=false
SignalConditioner.output_buffer_ms=0
;######### SIGNAL_CONDITIONER CONFIG ############
;## Feed the channels from the source, in batches of 40 ms
SignalConditioner.implementation=Bypass
SignalConditioner.batch_size_ms=40