Overview of the RFCAP format 📸
Paul Tagliamonte 2020-11-03 formatrfcap is a file format with extremely small ambitions. rfcap files
contain a fixed size header, and then a stream of raw IQ data. The
rfcap header contains information about the IQ format type, and
capture metadata. The header is aligned to a 128 bit boundary, so
most iq formats can choose to ignore the header and throw out the
first window, meaning existing tools like gqrx
can read a subset
of rfcap files in the right IQ sample format.
The biggest advantage of the rfcap scheme is that IQ data can be piped around without additional sample information such as IQ format, or sample rate, and the metadata remains attached to the stream.
Reference implementation
The hz.tools/rfcap
package contains the reference
implementation of the rfcap spec, and will be maintained as the
spec evolves. Go programmers are strongly advised to use this
package as a dependency for reading and writing SDR captures
in Go.
Format Description
Each rfcap file is comprised of a single 48 byte header, followed by a stream of IQ data, as described by the header.
Implementations are advised to store the header, in case samples need to be written to disk, or piped to another application outside of the current process.
Header
The Header is split up into fields containing metadata describing
the format and rate of the IQ samples to follow. At minimum,
implementations must be able to understand the
SampleRate
field, the SampleFormat
field, and if not only using uint8, the Endianness
field.
The header itself is always encoded little endian. This may make things a little confusing when operating over the network, since you may be expecting network order – but it does make it significantly easier to consume on little endian systems (which make up most of the target platforms), and makes things a little easier when the encoded data is also little endian floating point numbers (which is also usually the case on little endian systems).
Field Name | Type | Description |
Magic | [6]byte | Currently always `RFCAP1` for rfcap v1 |
Capture Time | int64 | Number of nanoseconds since the Unix Epoch. Divide by `1e+9` to get a Unix Epoch in seconds, and preform a modulus to get the nanoseconds. |
Center Frequency | float64 | Center Frequency of the capture, in Hz, as a floating point 64 bit number. |
Sample Rate | uint32 | Number of IQ samples per second this capture was taken at. Each IQ sample is comprised of the real and imaginary sample. |
Sample Format | uint8 | Sample Format defined by the
`hz.tools/sdr.SampleFormat` enum.
|
Endianness | uint8 | In order to retain compatability with an earlier rfcap
version, Little Endian files are denoted with a 0, rather
than a 1.
|
Reserved | [20]byte | Currently unused. Implementations must not rely on any information in this range, and when writing headers, the data in these bytes must be all zeros. |