File dp_format.h¶
FileList > inc > dp_format.h
Go to the source code of this file
Complex sample formats, named by their BLUE/Platinum codes. More...
#include <stddef.h>#include <stdint.h>
Public Types¶
| Type | Name |
|---|---|
| enum | dp_sample_type_t A sample format. The value IS the BLUE code. |
Public Static Functions¶
| Type | Name |
|---|---|
| void | dp_format_chars (dp_sample_type_t type, char out) The two characters BLUE writes for type (HCB bytes 52/53). |
| unsigned | dp_format_components (dp_sample_type_t type) Components per sample of type — 2 for complex, 1 for scalar. |
| double | dp_format_full_scale (dp_sample_type_t type) Full-scale magnitude of one component of type — an I, a Q, or a scalar-mode real sample. |
| int | dp_format_is_valid (dp_sample_type_t type) Non-zero when type is a format doppler can send and decode. |
| size_t | dp_format_size (dp_sample_type_t type) Bytes occupied by one SAMPLE of type , or 0 if the code is not one doppler sends. |
Macros¶
| Type | Name |
|---|---|
| define | DP_FMT (mode, type) /* multi line expression */Pack a BLUE two-character format code into a uint16_t . |
Detailed Description¶
One vocabulary for the five interleaved-I/Q encodings doppler moves, used by both containers that carry them: the streaming wire header (stream/stream.h) and the BLUE file writer (wfm_writer). It lives in neither of those because it belongs to neither — the codes are Midas BLUE 1.1 Table 6's, and a transport that had to be linked in order to name a file's sample format would be the wrong dependency in the wrong direction.
There used to be three enumerations of these five types: the stream's dp_sample_type_t, wfm_writer's stype in "wavegen order", and wfm_sink.c's WT_*, plus a FMTCH[] table mapping one of them to BLUE and a BPS[] table repeating the sizes. They agreed on nothing and were reconciled by hand at every boundary. Naming a format by the code the file format already defines leaves one vocabulary and nothing to translate.
Everything here is a static inline over a switch, so a consumer needs the header and no link edge.
// The wire code and the file's HCB bytes 52/53 are the same two chars.
char code[2];
dp_format_chars (CF64, code); // code = { 'C', 'D' }
size_t n = dp_format_size (CF64); // 16 bytes per complex sample
Public Types Documentation¶
enum dp_sample_type_t¶
A sample format. The value IS the BLUE code.
enum dp_sample_type_t {
CI8 = DP_FMT ('C', 'B'),
CI16 = DP_FMT ('C', 'I'),
CI32 = DP_FMT ('C', 'L'),
CF32 = DP_FMT ('C', 'F'),
CF64 = DP_FMT ('C', 'D'),
SI8 = DP_FMT ('S', 'B'),
SI16 = DP_FMT ('S', 'I'),
SI32 = DP_FMT ('S', 'L'),
SF32 = DP_FMT ('S', 'F'),
SF64 = DP_FMT ('S', 'D')
};
Ten formats: five element types in each of the two modes. The element type is the same in both — only the component COUNT differs, which is the whole of what the mode means.
There is no code for a quad or extended float because BLUE defines none — which is the format agreeing with why doppler retired CF128: its representation differs between x86-64 and aarch64 at identical size, so a frame crossed an architecture boundary and decoded to nonsense.
Public Static Functions Documentation¶
function dp_format_chars¶
The two characters BLUE writes for type (HCB bytes 52/53).
Unpacks rather than translates — the enum value IS the code — so a wire header and a file header cannot disagree about what they carry.
Parameters:
typeSample format.outTwo characters, mode then element type. Not NUL-terminated.
function dp_format_components¶
Components per sample of type — 2 for complex, 1 for scalar.
Read off the MODE character rather than switched per format, so a format added to the enum above needs no edit here. A code this build does not know reports 0, which is the same answer dp_format_size gives and is distinguishable from both valid counts.
Parameters:
typeSample format.
Returns:
2, 1, or 0 for an unknown code.
function dp_format_full_scale¶
Full-scale magnitude of one component of type — an I, a Q, or a scalar-mode real sample.
The divisor that puts an integer format on the same footing as a float one, so a number derived from samples (a power, an RMS, a headroom) means the same thing whatever the wire carried. 1.0 for the float formats, which are already full-scale, and 0 for a code this build does not know.
Parameters:
typeSample format.
Returns:
Full-scale value per component, or 0.
function dp_format_is_valid¶
Non-zero when type is a format doppler can send and decode.
Derived from dp_format_size(): a format with no size is not a format. Ask this rather than range-testing — the codes are two packed characters, so "between the first and the last" means nothing.
function dp_format_size¶
Bytes occupied by one SAMPLE of type , or 0 if the code is not one doppler sends.
A sample is one element: two components in mode 'C' and one in mode 'S'. It was "bytes per complex sample" until doppler#1032, when the scalar half of the mode axis was instantiated — the rename is the point, because every caller multiplying a sample count by this number is already correct under both and would not be if this returned bytes per COMPONENT.
This switch is the single table: validity, element size and the wire layout all derive from it, so a format added here needs no second edit and a code that is not here is not a doppler format anywhere.
Parameters:
typeSample format.
Returns:
Bytes per sample, or 0.
Macro Definition Documentation¶
define DP_FMT¶
Pack a BLUE two-character format code into a uint16_t .
Mode in the low byte, element type in the high byte, so a little-endian hex dump of the wire field reads as the two characters in order.
Mode 'C' is complex — two components per element — and 'S' is scalar, one. Both are real formats a capture can be in; 'S' is what a real-valued waveform is written as, and dropping it was why doppler could READ a scalar BLUE file and not write one (doppler#1032).
The documentation for this class was generated from the following file native/inc/dp_format.h