Python Type Converter API¶
The doppler.cvt module converts sample streams between float32 and the
fixed-point / integer formats used at the edges of a DSP chain — ADC codes, Q15
fractions, Q15-in-wide-word for CIC — plus an ideal-quantiser ADC model for
characterisation. Every converter is a tiny stateful object with a scale (or
ADC depth) fixed at construction; steps() runs a whole block (optionally
in-place via out=), step() does one sample.
For the F32To* direction, scale is the gain applied before quantising
(code = round(x · scale)); the default scale = 32768 maps the normalised
range [-1, +1) onto full-scale int16 and saturates beyond it. The *ToF32
direction divides by the same scale to recover the float.
Source:
src/doppler/cvt/__init__.py
For the quantisation theory behind the scaling and the UQ15 unsigned format,
see the Quantization gallery page.
Converter map¶
| Class | In → Out | Use |
|---|---|---|
F32ToI16 / I16ToF32 |
float32 ↔ int16 | signed Q15 / 16-bit PCM round-trip |
I32ToF32 |
int32 → float32 | 24/32-bit ADC codes to float |
I8ToF32 |
int8 → float32 | 8-bit codes to float |
F32ToUQ15 / UQ15ToF32 |
float32 ↔ uint16 | unsigned Q15 (offset-binary) round-trip |
F32ToI16U32 / I16U32ToF32 |
float32 ↔ uint32 | one Q15 in the low 16 bits (CIC integer in) |
F32ToI16U64 / I16U64ToF32 |
float32 ↔ uint64 | one Q15 in the low 16 bits (CIC integer in) |
ADC |
float32 → int64 | ideal bits-bit quantiser (codes) |
The F32To* directions expose a clipped flag that latches when an input
exceeded full scale during the last steps().
Examples¶
float32 ↔ int16 round-trip¶
The default scale = 32768 maps [-1, +1) to full-scale int16.
import numpy as np
from doppler.cvt import F32ToI16, I16ToF32
x = np.array([0.0, 0.5, -1.0, 0.999], dtype=np.float32)
enc = F32ToI16() # default scale = 32768
codes = enc.steps(x) # array([0, 16384, -32768, 32735], dtype=int16)
if enc.clipped: # latches when an input exceeded full scale
print("input exceeded full scale")
dec = I16ToF32() # default scale = 32768
back = dec.steps(codes) # ~= x ([0.0, 0.5, -1.0, 0.999])
In-place block conversion¶
Pass a pre-allocated out= to avoid an allocation in a hot loop.
Ideal ADC quantiser (characterisation)¶
ADC(bits, dbfs, dithering) models an ideal converter: a full-scale sine at
dbfs=0.0 spans ±2**(bits-1) codes. Feed its output straight into
ToneMeasure to recover ENOB ≈ bits.
from doppler.cvt import ADC
adc = ADC(12, 0.0, 0) # 12-bit, 0 dBFS, no dither
x = np.array([0.0, 0.5, 0.999, -1.0], dtype=np.float32)
adc.steps(x) # array([0, 1024, 2046, -2048])
Unsigned Q15 (offset binary)¶
F32ToUQ15 maps [-1, 1) onto uint16 centred at 32768 (offset binary), the
convention used by many unsigned ADCs.
from doppler.cvt import F32ToUQ15, UQ15ToF32
enc = F32ToUQ15() # default scale = 32768
u = enc.steps(np.array([-1.0, 0.0, 0.999], dtype=np.float32)) # 0, 32768, 65503
back = UQ15ToF32().steps(u) # ~= input
Signed integer ↔ float¶
F32ToI16
¶
Create a f32_to_i16 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Multiply factor applied before rounding and saturation (default:
32768.0f). Use 32768.0 to convert a normalised |
32768.0
|
Examples:
Create with defaults:
reset
¶
Clear the sticky clip flag, starting a fresh saturation history.
Zeroes clipped so a subsequent clipped query reflects only samples seen after this call; the immutable scale is preserved. Call it at a buffer or segment boundary so a saturation on one block does not leak into the next.
Examples:
step
¶
Scale one float sample by scale, round, and saturate to int16.
Computes round(x * scale), clamps to the int16 range [-32768, 32767],
and latches the sticky clipped flag if the scaled value fell outside
that range before clamping. At the default scale of 32768 a normalised
[-1, +1] input maps to the full Q15 code range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Input sample, normally a normalised float in |
required |
Returns:
| Type | Description |
|---|---|
int
|
Saturated int16 code in |
Examples:
steps
¶
Process a block of float samples to int16.
Applies step() to every element. The clipped flag is updated cumulatively across the block — a single saturating sample raises it for the entire call. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[float32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[int16]
|
Output. |
Examples:
state_bytes
¶
Size in bytes of this object's serialized state.
The exact length get_state returns and set_state requires. It
depends on how the object was constructed (state arrays are sized at
construction), so read it from the instance rather than assuming a
constant.
Raises RuntimeError if the F32ToI16 has already been destroyed.
Returns:
| Type | Description |
|---|---|
int
|
Byte length of one serialized state blob. |
get_state
¶
Serialize this object's mutable state to bytes.
Captures exactly the state that evolves as the object runs, so a blob taken now and restored later resumes from this point. Construction parameters are not included: restore into an object built the same way.
The blob is opaque and always state_bytes() long. Its layout is an
implementation detail of the C core and is not a stable format across
builds.
Raises RuntimeError if the F32ToI16 has already been destroyed.
Returns:
| Type | Description |
|---|---|
bytes
|
Opaque snapshot, |
set_state
¶
Restore mutable state from a get_state() blob.
Overwrites the live state in place; the object keeps the parameters it
was constructed with. Length is validated against state_bytes()
before the blob is handed to the C core, and the core may reject it as
well.
Raises TypeError if blob is not bytes, ValueError if its
length differs from state_bytes() or the core rejects it, and
RuntimeError if the F32ToI16 has already been destroyed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blob
|
bytes
|
A |
required |
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a F32ToI16 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
F32ToI16
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the F32ToI16.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
I16ToF32
¶
Create a i16_to_f32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Denominator scale; 1/scale is applied to each sample (default:
32768.0f). Use 32768.0 to recover normalised |
32768.0
|
Examples:
Create with defaults:
reset
¶
No-op reset, provided only for lifecycle symmetry.
This converter carries no running state beyond the immutable iscale, so there is nothing to clear; the method exists so every converter in the module presents the same create / step / reset / destroy lifecycle.
Examples:
step
¶
Convert one signed int16 sample to a normalised float via 1/scale.
Returns (float)x * iscale, a single multiply on the hot path. No
saturation or clipping is possible — every int16 code maps cleanly to
float32. At the default scale of 32768 the full Q15 range recovers
[-1.0, ~+1.0), the exact inverse of F32ToI16.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
int
|
Signed int16 code, normally a Q15 sample in |
required |
Returns:
| Type | Description |
|---|---|
float
|
Normalised float, |
Examples:
steps
¶
Process a block of int16 samples to float32.
Applies step() to every element. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[int16]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float32]
|
Output. |
Examples:
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a I16ToF32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
I16ToF32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the I16ToF32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
I32ToF32
¶
Create a i32_to_f32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Denominator scale; 1/scale is applied to each sample (default: 2147483648.0f). Use 2^31 to recover normalised floats from a full-range int32 stream. |
2147483648.0
|
Examples:
Create with defaults:
reset
¶
No-op reset, provided only for lifecycle symmetry.
No mutable state exists beyond the immutable iscale, so there is nothing to clear; the method exists so every converter in the module presents the same create / step / reset / destroy lifecycle.
Examples:
step
¶
Convert one signed int32 sample to a normalised float via 1/scale.
Returns (float)x * iscale, a single multiply on the hot path. At the
default scale of 2^31 the full int32 range recovers [-1.0, ~+1.0).
Note that float32 carries only 23 mantissa bits, so int32 magnitudes
beyond 2^24 are rounded to the nearest representable float.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
int
|
Signed int32 code, normally a full-range fixed-point sample. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Normalised float, |
Examples:
steps
¶
Process a block of int32 samples to float32.
Applies step() to every element. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[int32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float32]
|
Output. |
Examples:
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a I32ToF32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
I32ToF32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the I32ToF32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
I8ToF32
¶
Create a i8_to_f32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Denominator scale; 1/scale is applied to each sample (default: 128.0f). Use 128.0 to recover normalised floats from a signed 8-bit stream. |
128.0
|
Examples:
Create with defaults:
reset
¶
No-op reset, provided only for lifecycle symmetry.
No mutable state exists beyond the immutable iscale, so there is nothing to clear; the method exists so every converter in the module presents the same create / step / reset / destroy lifecycle.
Examples:
step
¶
Convert one signed int8 sample to a normalised float via 1/scale.
Returns (float)x * iscale, a single multiply on the hot path. At the
default scale of 128 the full int8 range recovers [-1.0, ~+1.0) — the
front end of an 8-bit IQ path (e.g. a signed-8 RTL-SDR stream) into
normalised floats.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
int
|
Signed int8 code in |
required |
Returns:
| Type | Description |
|---|---|
float
|
Normalised float, |
Examples:
steps
¶
Process a block of int8 samples to float32.
Applies step() to every element. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[int8]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float32]
|
Output. |
Examples:
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a I8ToF32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
I8ToF32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the I8ToF32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
Unsigned Q15 (offset binary)¶
F32ToUQ15
¶
Create a f32_to_uq15 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Multiply factor applied before quantisation and saturation (default:
32768.0f). Use 32768.0 to convert normalised |
32768.0
|
Examples:
Create with defaults:
reset
¶
Clear the sticky clip flag, starting a fresh saturation history.
Zeroes clipped so a subsequent clipped query reflects only samples seen after this call; the immutable scale is preserved. Call it at a buffer or segment boundary so a saturation on one block does not leak into the next.
Examples:
step
¶
Scale one float sample to an offset-binary UQ15 uint16 code.
Computes round(x * scale), clamps to [-32768, 32767], then adds the
32768 offset-binary bias so the signed float domain maps onto the full
unsigned uint16 range. Latches the sticky clipped flag if the scaled
value saturated before clamping. Suits DAC and file formats that store
only unsigned integers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Input sample, normally a normalised float in |
required |
Returns:
| Type | Description |
|---|---|
int
|
Offset-binary uint16 in |
Examples:
steps
¶
Process a block of float samples to UQ15 uint16.
Applies step() to every element. The clipped flag is updated cumulatively across the block. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[float32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[uint16]
|
Output. |
Examples:
state_bytes
¶
Size in bytes of this object's serialized state.
The exact length get_state returns and set_state requires. It
depends on how the object was constructed (state arrays are sized at
construction), so read it from the instance rather than assuming a
constant.
Raises RuntimeError if the F32ToUQ15 has already been destroyed.
Returns:
| Type | Description |
|---|---|
int
|
Byte length of one serialized state blob. |
get_state
¶
Serialize this object's mutable state to bytes.
Captures exactly the state that evolves as the object runs, so a blob taken now and restored later resumes from this point. Construction parameters are not included: restore into an object built the same way.
The blob is opaque and always state_bytes() long. Its layout is an
implementation detail of the C core and is not a stable format across
builds.
Raises RuntimeError if the F32ToUQ15 has already been destroyed.
Returns:
| Type | Description |
|---|---|
bytes
|
Opaque snapshot, |
set_state
¶
Restore mutable state from a get_state() blob.
Overwrites the live state in place; the object keeps the parameters it
was constructed with. Length is validated against state_bytes()
before the blob is handed to the C core, and the core may reject it as
well.
Raises TypeError if blob is not bytes, ValueError if its
length differs from state_bytes() or the core rejects it, and
RuntimeError if the F32ToUQ15 has already been destroyed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blob
|
bytes
|
A |
required |
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a F32ToUQ15 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
F32ToUQ15
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the F32ToUQ15.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
UQ15ToF32
¶
Create a uq15_to_f32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Denominator applied after offset-binary bias removal (default:
32768.0f). Use 32768.0 to recover normalised |
32768.0
|
Examples:
Create with defaults:
reset
¶
No-op reset, provided only for lifecycle symmetry.
No mutable state exists beyond the immutable iscale, so there is nothing to clear; the method exists so every converter in the module presents the same create / step / reset / destroy lifecycle.
Examples:
step
¶
Decode one offset-binary UQ15 uint16 code to a normalised float.
Computes ((int32_t)x - 32768) * iscale — removes the 32768 offset-binary bias and applies 1/scale. The int32_t cast prevents signed overflow when x is 0 (which yields -32768 after bias removal). Exact inverse of F32ToUQ15 at the same scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
int
|
UQ15 offset-binary uint16 code: 0 -> -1.0, 32768 -> 0.0, 65535 -> +32767/32768. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Normalised float in |
Examples:
steps
¶
Process a block of UQ15 samples to float32.
Applies step() to every element. State is not mutated (no clipped flag). Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[uint16]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float32]
|
Output. |
Examples:
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a UQ15ToF32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
UQ15ToF32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the UQ15ToF32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
Q15 in a wide word (CIC integer input)¶
These pack a single saturated Q15 into the low 16 bits of a uint32/uint64
(upper bits zero) — the integer-input wire format the CIC filter expects, where
the headroom absorbs the bit-growth of the integrator cascade.
F32ToI16U32
¶
Create a f32_to_i16u32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Multiply factor applied before quantisation and saturation (default:
32768.0f). Use 32768.0 to convert normalised |
32768.0
|
Examples:
Create with defaults:
reset
¶
Clear the sticky clip flag, starting a fresh saturation history.
Zeroes clipped so a subsequent clipped query reflects only samples seen after this call; the immutable scale is preserved. Call it at a buffer or segment boundary so a saturation on one block does not leak into the next.
Examples:
step
¶
Scale one float sample to a saturated Q15 code packed in a uint32.
Computes round(x * scale), saturates to [-32768, 32767], then
zero-extends the 16-bit two's-complement pattern into the lower 16 bits
of a uint32 (upper 16 bits are always zero — headroom for the CIC
integrator cascade). Latches the sticky clipped flag on saturation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Input sample, normally a normalised float in |
required |
Returns:
| Type | Description |
|---|---|
int
|
Q15 code in the low 16 bits of a uint32; e.g. -32768 -> 0x8000. |
Examples:
steps
¶
Process a block of float samples to Q15-in-uint32.
Applies step() to every element. The clipped flag is updated cumulatively across the block. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[float32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[uint32]
|
Output. |
Examples:
state_bytes
¶
Size in bytes of this object's serialized state.
The exact length get_state returns and set_state requires. It
depends on how the object was constructed (state arrays are sized at
construction), so read it from the instance rather than assuming a
constant.
Raises RuntimeError if the F32ToI16U32 has already been destroyed.
Returns:
| Type | Description |
|---|---|
int
|
Byte length of one serialized state blob. |
get_state
¶
Serialize this object's mutable state to bytes.
Captures exactly the state that evolves as the object runs, so a blob taken now and restored later resumes from this point. Construction parameters are not included: restore into an object built the same way.
The blob is opaque and always state_bytes() long. Its layout is an
implementation detail of the C core and is not a stable format across
builds.
Raises RuntimeError if the F32ToI16U32 has already been destroyed.
Returns:
| Type | Description |
|---|---|
bytes
|
Opaque snapshot, |
set_state
¶
Restore mutable state from a get_state() blob.
Overwrites the live state in place; the object keeps the parameters it
was constructed with. Length is validated against state_bytes()
before the blob is handed to the C core, and the core may reject it as
well.
Raises TypeError if blob is not bytes, ValueError if its
length differs from state_bytes() or the core rejects it, and
RuntimeError if the F32ToI16U32 has already been destroyed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blob
|
bytes
|
A |
required |
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a F32ToI16U32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
F32ToI16U32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the F32ToI16U32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
I16U32ToF32
¶
Create a i16u32_to_f32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Denominator scale; 1/scale is applied after sign-extension (default: 32768.0f). Use 32768.0 to match F32ToI16U32 at its default scale. |
32768.0
|
Examples:
Create with defaults:
reset
¶
No-op reset, provided only for lifecycle symmetry.
No mutable state exists beyond the immutable iscale, so there is nothing to clear; the method exists so every converter in the module presents the same create / step / reset / destroy lifecycle.
Examples:
step
¶
Unpack a Q15 code from a uint32's low 16 bits to a normalised float.
Masks off the lower 16 bits, reinterprets them as a signed int16 (two's complement), then multiplies by iscale — a single multiply after the extraction. The upper 16 bits (which may carry CIC bit-growth headroom) are ignored. Exact inverse of F32ToI16U32 at the same scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
int
|
uint32 carrying a Q15 code in its low 16 bits. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Normalised float recovered from the low-16 Q15 code. |
Examples:
steps
¶
Process a block of Q15-in-uint32 samples to float32.
Applies step() to every element. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[uint32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float32]
|
Output. |
Examples:
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a I16U32ToF32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
I16U32ToF32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the I16U32ToF32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
F32ToI16U64
¶
Create a f32_to_i16u64 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Multiply factor applied before quantisation and saturation (default:
32768.0f). Use 32768.0 to convert normalised |
32768.0
|
Examples:
Create with defaults:
reset
¶
Clear the sticky clip flag, starting a fresh saturation history.
Zeroes clipped so a subsequent clipped query reflects only samples seen after this call; the immutable scale is preserved. Call it at a buffer or segment boundary so a saturation on one block does not leak into the next.
Examples:
step
¶
Scale one float sample to a saturated Q15 code packed in a uint64.
Computes round(x * scale), saturates to [-32768, 32767], then
zero-extends the 16-bit two's-complement pattern into the lower 16 bits
of a uint64 (upper 48 bits are always zero — headroom for the NCO phase
accumulator). Latches the sticky clipped flag on saturation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Input sample, normally a normalised float in |
required |
Returns:
| Type | Description |
|---|---|
int
|
Q15 code in the low 16 bits of a uint64; e.g. -32768 -> 0x8000. |
Examples:
steps
¶
Process a block of float samples to Q15-in-uint64.
Applies step() to every element. The clipped flag is updated cumulatively across the block. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[float32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[uint64]
|
Output. |
Examples:
state_bytes
¶
Size in bytes of this object's serialized state.
The exact length get_state returns and set_state requires. It
depends on how the object was constructed (state arrays are sized at
construction), so read it from the instance rather than assuming a
constant.
Raises RuntimeError if the F32ToI16U64 has already been destroyed.
Returns:
| Type | Description |
|---|---|
int
|
Byte length of one serialized state blob. |
get_state
¶
Serialize this object's mutable state to bytes.
Captures exactly the state that evolves as the object runs, so a blob taken now and restored later resumes from this point. Construction parameters are not included: restore into an object built the same way.
The blob is opaque and always state_bytes() long. Its layout is an
implementation detail of the C core and is not a stable format across
builds.
Raises RuntimeError if the F32ToI16U64 has already been destroyed.
Returns:
| Type | Description |
|---|---|
bytes
|
Opaque snapshot, |
set_state
¶
Restore mutable state from a get_state() blob.
Overwrites the live state in place; the object keeps the parameters it
was constructed with. Length is validated against state_bytes()
before the blob is handed to the C core, and the core may reject it as
well.
Raises TypeError if blob is not bytes, ValueError if its
length differs from state_bytes() or the core rejects it, and
RuntimeError if the F32ToI16U64 has already been destroyed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blob
|
bytes
|
A |
required |
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a F32ToI16U64 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
F32ToI16U64
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the F32ToI16U64.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
I16U64ToF32
¶
Create a i16u64_to_f32 instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scale
|
float
|
Denominator scale; 1/scale is applied after sign-extension (default: 32768.0f). Use 32768.0 to match F32ToI16U64 at its default scale. |
32768.0
|
Examples:
Create with defaults:
reset
¶
No-op reset, provided only for lifecycle symmetry.
No mutable state exists beyond the immutable iscale, so there is nothing to clear; the method exists so every converter in the module presents the same create / step / reset / destroy lifecycle.
Examples:
step
¶
Unpack a Q15 code from a uint64's low 16 bits to a normalised float.
Masks off the lower 16 bits, reinterprets them as a signed int16 (two's complement), then multiplies by iscale — a single multiply after the extraction. The upper 48 bits (which may carry NCO phase-accumulator headroom) are ignored. Exact inverse of F32ToI16U64 at the same scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
int
|
uint64 carrying a Q15 code in its low 16 bits. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Normalised float recovered from the low-16 Q15 code. |
Examples:
steps
¶
Process a block of Q15-in-uint64 samples to float32.
Applies step() to every element. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[uint64]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float32]
|
Output. |
Examples:
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a I16U64ToF32 be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
I16U64ToF32
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the I16U64ToF32.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
Ideal ADC model¶
ADC
¶
Create an ADC instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits
|
int
|
ADC resolution in bits (1..64). |
16
|
dbfs
|
float
|
Full-scale reference level in dBFS (typically negative, e.g. -10.0). A signal with amplitude 10^(dbfs/20) fills the converter's integer range exactly. |
-10.0
|
dithering
|
int
|
0 = no dither; non-zero = TPDF dither before rounding. |
0
|
Examples:
Create with defaults:
reset
¶
Clear the clip flag and re-seed the dither PRNG for a reproducible run.
Zeroes the sticky clipped flag and re-seeds the xorshift32 dither PRNG to its fixed initial value, so a dithered capture restarted after reset() is bit-for-bit reproducible. The immutable configuration (bits, scale, clip bounds) is preserved.
Examples:
step
¶
Quantise one float sample to a signed N-bit ADC code.
Multiplies x by the pre-computed double-precision scale, optionally
adds TPDF dither (when the object was built with dithering enabled),
rounds with llround, and clamps to the signed integer range [clip_min,
clip_max]. Latches the sticky clipped flag if the sample saturated. A
sample at amplitude 10^(dbfs/20) reaches full scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Input sample, normally a normalised float in |
required |
Returns:
| Type | Description |
|---|---|
int
|
Signed ADC code in |
Examples:
steps
¶
Process a block of float samples to int64.
When dithering is disabled the float-to-double multiply can use SIMD widening (jm_simd.h); the int64_t conversion and clamp remain scalar. When dithering is enabled the loop is scalar to preserve sequential PRNG state. Accepts an optional pre-allocated output array; allocates a fresh one when output is NULL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[float32]
|
Input. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[int64]
|
Output. |
Examples:
state_bytes
¶
Size in bytes of this object's serialized state.
The exact length get_state returns and set_state requires. It
depends on how the object was constructed (state arrays are sized at
construction), so read it from the instance rather than assuming a
constant.
Raises RuntimeError if the ADC has already been destroyed.
Returns:
| Type | Description |
|---|---|
int
|
Byte length of one serialized state blob. |
get_state
¶
Serialize this object's mutable state to bytes.
Captures exactly the state that evolves as the object runs, so a blob taken now and restored later resumes from this point. Construction parameters are not included: restore into an object built the same way.
The blob is opaque and always state_bytes() long. Its layout is an
implementation detail of the C core and is not a stable format across
builds.
Raises RuntimeError if the ADC has already been destroyed.
Returns:
| Type | Description |
|---|---|
bytes
|
Opaque snapshot, |
set_state
¶
Restore mutable state from a get_state() blob.
Overwrites the live state in place; the object keeps the parameters it
was constructed with. Length is validated against state_bytes()
before the blob is handed to the C core, and the core may reject it as
well.
Raises TypeError if blob is not bytes, ValueError if its
length differs from state_bytes() or the core rejects it, and
RuntimeError if the ADC has already been destroyed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blob
|
bytes
|
A |
required |
destroy
¶
Release the underlying C resources immediately.
Ordinarily unnecessary: the resources are freed when the object is garbage-collected. Call this to release them at a definite point instead, or use the object as a context manager, which calls it on exit.
Idempotent: calling it again on an already-released object does
nothing. Every other method raises RuntimeError once it has run.
__enter__
¶
Enter a context manager, returning this object.
Lets a ADC be used in a with statement so its C resources are
released deterministically on exit rather than at collection time.
Returns:
| Type | Description |
|---|---|
ADC
|
This same object, not a copy. |
__exit__
¶
__exit__(
exc_type: object | None = ...,
exc: object | None = ...,
tb: object | None = ...,
) -> None
Exit a context manager, releasing the ADC.
Equivalent to calling destroy(). Returns None, so an exception
raised inside the with body propagates normally; this never
suppresses one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
object | None
|
Exception class, or None. Ignored. |
...
|
exc
|
object | None
|
Exception instance, or None. Ignored. |
...
|
tb
|
object | None
|
Traceback object, or None. Ignored. |
...
|
Bits, values and symbols¶
The conversions a frame field is built from. int_to_bin is the one to reach
for first — a literal that fits in 64 bits, expanded exactly, with no failure
mode a typo can reach. hex_to_bin is for what it cannot serve: a literal
wider than 64 bits, or one arriving as text from a CLI flag or a JSON record.
Bit order follows numpy's bitorder (0 big, 1 little; big is "as
written"). It is a different axis from the endian a BLUE file takes,
which selects byte order — the EEEI/IEEE header field. A literal's digit
order already fixes which byte comes first; what is left to choose is the
order of bits inside one.
int_to_bin
¶
Expand the low n_bits of an integer to unpacked bits, one per byte.
The form a frame field literal usually wants: exact, and with no
failure mode a typo can reach, unlike the string form. bitorder is
DP_BITORDER_BIG (0, MSB of each byte first -- as written) or
DP_BITORDER_LITTLE (1), numpy's bitorder convention for this
operation, and NOT the BLUE writer's endian (le/be) which selects a
file's BYTE order. Returns the bits written, or 0 on refusal.
The form a frame field literal usually wants, and the one to reach for first: exact, compiler-checked, with no failure mode a typo can reach. hex_to_bin is for the two cases this cannot serve -- a literal wider than 64 bits, and text arriving from outside.
Bit 0 out is the MOST significant of the n_bits requested under
DP_BITORDER_BIG, which is what makes int_to_bin(0x1A, 8, ...) read
0,0,0,1,1,0,1,0. Only the low n_bits are read, so a caller need not
mask first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
int
|
the value. |
required |
n_bits
|
int
|
1..64. |
required |
out
|
NDArray[uint8]
|
receives n_bits bytes, each 0 or 1. |
required |
bitorder
|
int
|
DP_BITORDER_BIG or DP_BITORDER_LITTLE. |
required |
Returns:
| Type | Description |
|---|---|
int
|
n_bits, or 0 on refusal -- out untouched. |
Examples:
bin_to_int
¶
Read unpacked bits back into an integer -- the inverse of int_to_bin.
Returns the value rather than a status, because that is the shape a binding can carry. 0 is therefore both "the value zero" and "refused", which is acceptable only because every refusal here is a programming error in the WIDTH the caller chose (0, or over 64) or the bit order it named -- never a property of the data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits
|
NDArray[uint8]
|
1..64 unpacked bits; any non-zero byte reads as 1. |
required |
bitorder
|
int
|
DP_BITORDER_BIG or DP_BITORDER_LITTLE. |
required |
Returns:
| Type | Description |
|---|---|
int
|
the value, or 0 on refusal. |
Examples:
hex_to_bin
¶
Expand a hex string to unpacked bits, one per byte. For what int_to_bin cannot serve: a literal wider than 64 bits, or one arriving as TEXT from a CLI flag or a JSON record. An odd number of digits is accepted and yields a 4-bit tail. A bad digit is a REFUSAL, never a silently shortened field -- a marker that shortens syncs to nothing. Returns the bits written, or 0 on refusal.
For what int_to_bin cannot serve: a literal wider than 64 bits, or one arriving as TEXT from a CLI flag or a JSON record. Each digit contributes 4 bits and digits read left to right, so an ODD number of digits is accepted and yields a 4-bit tail.
A bad digit is a REFUSAL, never a skipped one: a typo'd marker that silently shortens is the failure this exists to prevent, and it syncs to nothing rather than failing loudly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hex
|
str
|
NUL-terminated |
required |
out
|
NDArray[uint8]
|
receives |
required |
bitorder
|
int
|
DP_BITORDER_BIG or DP_BITORDER_LITTLE. |
required |
Returns:
| Type | Description |
|---|---|
int
|
bits written, or 0 on refusal -- out untouched. |
Examples:
bin_to_hex
¶
Render unpacked bits back to hex digits -- the exact inverse of hex_to_bin. The digits come back as ASCII BYTES rather than a str: jm has no string out-parameter for a module function (just-buildit/just-makeit#1180), and uint8_t is the same type as the unsigned char a C caller would use. Decode with bytes(out).decode() in Python. n_bits must be a multiple of 4. Returns the digits written, not counting the NUL, or 0 on refusal.
The digits come back as ASCII BYTES rather than a string: jm has no
string out-parameter for a module function
(just-buildit/just-makeit#1180), and uint8_t is the same type as the
unsigned char a C caller would use anyway. A NUL is written after the
digits. The C face is honest; only the Python face pays, with a
bytes(out).decode().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits
|
NDArray[uint8]
|
unpacked bits; any non-zero byte reads as 1. |
required |
out
|
NDArray[uint8]
|
receives the digits plus a NUL. |
required |
bitorder
|
int
|
DP_BITORDER_BIG or DP_BITORDER_LITTLE. |
required |
Returns:
| Type | Description |
|---|---|
int
|
digits written, NOT counting the NUL, or 0 on refusal. |
Examples:
bin_to_nrz maps bits to bipolar symbols as 1 - 2*b — bit 0 to +1, bit 1
to -1. That convention's home is BPSK in
mpsk: M-PSK at m = 2 puts label 0 at +1. The two are
asserted equal in the C tests rather than trusted to stay equal, because a
mapper that disagreed with the receiver's would decode every bit inverted
while looking perfectly locked.
bin_to_nrz
¶
Map unpacked bits to bipolar NRZ symbols: bit 0 -> +1.0, bit 1 ->
-1.0. That is 1 - 2*b, the convention already used across doppler
(qpsk_map.c and the despreader/ber doctests), NOT the opposite sign --
a mapper that disagreed with the receiver's would decode every bit
inverted while looking perfectly locked. Any non-zero byte reads as a
set bit. Returns the symbols written, or 0 on refusal.
That is 1 - 2*b, and the convention's HOME is mpsk_core.h: BPSK is
M-PSK at m = 2, where phi0 is 0, so label 0 lands at +1 and label 1 at
-1. This states the same thing in the form a per-bit loop can afford,
and test_cvt_core asserts the two agree rather than trusting them to.
A mapper that disagreed with the receiver's would decode every bit
INVERTED while looking perfectly locked -- which a round-trip test
cannot see.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits
|
NDArray[uint8]
|
unpacked bits; any non-zero byte reads as 1. |
required |
out
|
NDArray[float32]
|
receives bits_len symbols, each +1.0f or -1.0f. |
required |
Returns:
| Type | Description |
|---|---|
int
|
symbols written, or 0 on refusal. |
Examples:
nrz_to_bin
¶
Hard-decide bipolar NRZ symbols back to unpacked bits -- the inverse
of bin_to_nrz. Negative is a 1, zero and positive are a 0, matching 1
- 2*b. Exactly zero is a 0 rather than a coin toss, so the mapping is
total and a round trip is exact. Returns the bits written, or 0 on
refusal.
Negative is a 1; zero and positive are a 0, matching 1 - 2*b. Exactly
zero decides to 0 rather than a coin toss, so the mapping is TOTAL and
a round trip is exact. A caller that wants an erasure handled as an
erasure wants a soft demapper, not this.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nrz
|
NDArray[float32]
|
symbols. |
required |
out
|
NDArray[uint8]
|
receives nrz_len bytes, each 0 or 1. |
required |
Returns:
| Type | Description |
|---|---|
int
|
bits written, or 0 on refusal. |
Examples:
Related pages¶
Gallery — ADC Quantisation — 3–8 Bits, cvt Quantization Noise, Gallery, Measurement Suite — two-tone IMD/TOI & notched-noise NPR, Q15 vs UQ15 Quantization Guides — Getting Started with Fixed-Point Arithmetic, Power Spectra & Measurements Design — Quantization Design, API taxonomy: the DSP building-block hierarchy and its naming axis, Spectral & Measurement API Map