Sample Streaming API
Note
The Sample Streaming API is provided on TCP port 5308. This API is only available on the GRX3X.
The Sample Streaming API provides continuous raw I/Q sample streaming from a specific radio channel. Unlike the per-detection I/Q samples available through the Receiver API, this API delivers a continuous, uninterrupted stream of samples – similar to an SDR (Software Defined Radio) data source.
This is useful for:
Generic frequency monitoring
Custom signal processing and decoding
Recording raw I/Q data to disk
Feeding external signal processing pipelines
Service Methods
// Query stream properties (center frequency, sample rate, calibration)
rpc GetStreamProperties (GetStreamPropertiesRequest) returns (StreamProperties);
// Start streaming I/Q sample blocks
rpc StartStream (StartStreamRequest) returns (stream StartStreamReply);
Stream Properties
Before starting a stream, call GetStreamProperties to retrieve:
Center frequency (Hz): The frequency the radio is tuned to.
Sample rate (Hz): The I/Q sample rate.
Calibration value (dB): Used to convert raw sample magnitudes to absolute power levels in dBm:
signal_level [dBm] = calibration_value + 10 * log10(I² + Q²)
Note
When channel parameters (e.g. center frequency or hardware gain) are changed
through the Tunable Channel API,
GetStreamProperties should be called again after a few seconds to obtain
updated values. If frequent changes are expected, it is also possible to
poll this method periodically.
Starting a Stream
Call StartStream with a StartStreamRequest specifying:
radio_identification: The radio channel to stream from (band + per-band index). Use
BAND_1090_MHZ,BAND_1030_MHZ,BAND_978_MHZ,BAND_TUNABLE, etc.requested_blocks: Number of sample blocks to receive. Set to
0for indefinite streaming.
Each StartStreamReply in the stream contains:
block_timestamp: Timestamp for this block of samples.
samples: Raw I/Q data as bytes (signed 16-bit interleaved: I0, Q0, I1, Q1, …). Each I/Q pair is 4 bytes.
lost_blocks: Counter for lost blocks. If this value increases between consecutive replies, blocks were dropped.
Warning
Continuous I/Q streaming produces very high data rates. At 12 MHz sample
rate with 16-bit I/Q, the raw data rate is approximately 48 MB/s per
daughterboard.
Ensure your network link and processing pipeline can handle the throughput.
Monitor the lost_blocks counter to detect data loss.
Identifying Radio Channels
The RadioIdentification message (defined in Common.proto) identifies
a radio channel by its frequency band and per-band index:
message RadioIdentification {
Band band = 1; // e.g., BAND_1090_MHZ, BAND_TUNABLE
int32 per_band_index = 2; // 0 for the first radio of that band
}
Use the Tunable Channel API to discover and configure tunable channels before streaming.
Protocol Buffer Definition
syntax = "proto3";
package serosystems.proto.v3.grx.samplestreamingd;
option java_package = "de.serosystems.proto.v3.grx.samplestreamingd";
option java_outer_classname = "SamplestreamingDProto";
import "Common.proto";
/**
* Message describing the properties of a stream.
*/
message StreamProperties {
/* Center Frequency [Hz]. */
uint32 center_frequency = 1;
/* Sample rate [Hz]. */
uint32 sample_rate = 2;
/* Calibration value to convert from sample values to signal level in dBm.
* Use the following formula to convert the squared magnitude (i.e. I^2 + Q^2) to a signal level in dBm:
* signal_level [dBm] = calibration_value + 10 * log10(I^2 + Q^2)
*/
float calibration_value = 3;
}
/* Request type for GetStreamProperties call */
message GetStreamPropertiesRequest {
/* Radio identification of the chosen RX channel */
RadioIdentification radio_identification = 1;
}
/* Request type for StartStream call */
message StartStreamRequest {
/* Radio identification of the chosen RX channel */
RadioIdentification radio_identification = 1;
/* The number of blocks that are requested, set to zero for indefinite streaming */
uint32 requested_blocks = 2;
}
/* Reply type for StartStream call */
message StartStreamReply {
/* data is streamed in blocks, each block has a timestamp */
uint64 block_timestamp = 1;
/* the samples */
bytes samples = 2;
/* counter for lost blocks, can be used to find out a) if blocks have been lost and b) where exactly */
uint32 lost_blocks = 3;
}
/* Sample streaming daemon service definition. Port 5308. */
service Samplestreamingd {
/* Request the stream properties. They usually do not change over time
* (unless the radio front-end allows retuning/changing settings, see TunableChanneld).
* Returns INVALID_ARGUMENT if chosen RX channel is not available.
*/
rpc GetStreamProperties (GetStreamPropertiesRequest) returns (StreamProperties);
/*
* Request a stream of samples.
* Returns INVALID_ARGUMENT if chosen RX channel is not available
*/
rpc StartStream(StartStreamRequest) returns (stream StartStreamReply) {}
}