Skip to content

File f32_to_uq15_core.h

FileList > f32_to_uq15 > f32_to_uq15_core.h

Go to the source code of this file

Scale-and-saturate float-to-UQ15 (offset-binary uint16) converter. More...

  • #include "clib_common.h"
  • #include "dp_state.h"
  • #include "jm_perf.h"
  • #include <math.h>

Classes

Type Name
struct f32_to_uq15_state_t
F32ToUQ15 state.

Public Functions

Type Name
f32_to_uq15_state_t * f32_to_uq15_create (float scale)
Create a f32_to_uq15 instance.
void f32_to_uq15_destroy (f32_to_uq15_state_t * state)
Destroy a f32_to_uq15 instance and release all memory.
void f32_to_uq15_get_state (const f32_to_uq15_state_t * state, void * blob)
void f32_to_uq15_reset (f32_to_uq15_state_t * state)
Clear the sticky clip flag, starting a fresh saturation history.
int f32_to_uq15_set_state (f32_to_uq15_state_t * state, const void * blob)
size_t f32_to_uq15_state_bytes (const f32_to_uq15_state_t * state)
JM_FORCEINLINE JM_HOT uint16_t f32_to_uq15_step (f32_to_uq15_state_t * state, float x)
Scale one float sample to an offset-binary UQ15 uint16 code.
void f32_to_uq15_steps (f32_to_uq15_state_t * state, const float * input, uint16_t * output, size_t n)
Process a block of float samples to UQ15 uint16.

Macros

Type Name
define F32_TO_UQ15_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('F','U','1','5')
define F32_TO_UQ15_STATE_VERSION 1u

Detailed Description

Converts a normalised float sample to offset-binary uint16 (UQ15 format). The Q15 quantised value is biased by +32768 so that the full unsigned range maps to the signed float domain: -1.0 → uint16 0 (0x0000) 0.0 → uint16 32768 (0x8000) +1.0 → uint16 65535 (0xFFFF)

Encoding:

v_Q15 = clamp(round(x * scale), -32768, 32767)
u     = (uint16_t)((int32_t)v_Q15 + 32768)

This is the unsigned wire format used by some DAC and file-format conventions that cannot represent negative integer values. UQ15ToF32 performs the exact inverse. A sticky clipped flag is raised on saturation and cleared only by reset().

Lifecycle: create -> (step / steps / reset)* -> destroy

>>> from doppler.cvt import F32ToUQ15
>>> import numpy as np
>>> obj = F32ToUQ15(scale=32768.0)
>>> obj.step(0.0)
32768
>>> obj.step(-1.0)
0
>>> obj.clipped
False
>>> obj.step(1.0)
65535
>>> obj.clipped
True
>>> obj.reset()
>>> x = np.array([-1.0, 0.0, 1.0], dtype=np.float32)
>>> obj.steps(x).tolist()
[0, 32768, 65535]

Public Functions Documentation

function f32_to_uq15_create

Create a f32_to_uq15 instance.

f32_to_uq15_state_t * f32_to_uq15_create (
    float scale
) 

Stores scale and initialises the sticky clipped flag to 0.

Parameters:

  • scale Multiply factor applied before quantisation and saturation (default: 32768.0f). Use 32768.0 to convert normalised [-1, +1] floats to the full UQ15 range [0, 65535]. Must be > 0; returns NULL otherwise.

Returns:

Heap-allocated state, or NULL on invalid args or allocation failure.

Note:

Caller must call f32_to_uq15_destroy() when done.


function f32_to_uq15_destroy

Destroy a f32_to_uq15 instance and release all memory.

void f32_to_uq15_destroy (
    f32_to_uq15_state_t * state
) 

Parameters:

  • state May be NULL.

function f32_to_uq15_get_state

void f32_to_uq15_get_state (
    const f32_to_uq15_state_t * state,
    void * blob
) 

function f32_to_uq15_reset

Clear the sticky clip flag, starting a fresh saturation history.

void f32_to_uq15_reset (
    f32_to_uq15_state_t * state
) 

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.

Parameters:

  • state Must be non-NULL.
>>> from doppler.cvt import F32ToUQ15
>>> c = F32ToUQ15()
>>> c.step(2.0)       # out of range -> saturates 0xFFFF, latches
65535
>>> c.reset()            # forget the clip history
>>> c.clipped
False

function f32_to_uq15_set_state

int f32_to_uq15_set_state (
    f32_to_uq15_state_t * state,
    const void * blob
) 

function f32_to_uq15_state_bytes

size_t f32_to_uq15_state_bytes (
    const f32_to_uq15_state_t * state
) 

function f32_to_uq15_step

Scale one float sample to an offset-binary UQ15 uint16 code.

JM_FORCEINLINE  JM_HOT uint16_t f32_to_uq15_step (
    f32_to_uq15_state_t * state,
    float x
) 

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:

  • state Must be non-NULL.
  • x Input sample, normally a normalised float in [-1, +1].

Returns:

Offset-binary uint16 in [0, 65535]: -1.0 -> 0, 0.0 -> 32768, +1.0 -> 65535.

>>> from doppler.cvt import F32ToUQ15
>>> c = F32ToUQ15(scale=32768.0)
>>> c.step(0.0)          # midscale maps to the offset-binary bias
32768
>>> c.step(-1.0)         # full-negative maps to code 0
0

function f32_to_uq15_steps

Process a block of float samples to UQ15 uint16.

void f32_to_uq15_steps (
    f32_to_uq15_state_t * state,
    const float * input,
    uint16_t * output,
    size_t n
) 

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:

  • state Must be non-NULL.
  • input Input float32 array; must contain at least n elements.
  • output Output uint16 offset-binary array; must contain at least n elements.
  • n Number of samples to process.
>>> from doppler.cvt import F32ToUQ15
>>> import numpy as np
>>> F32ToUQ15().steps(
...     np.array([-1.0, 0.0, 0.999], dtype=np.float32)).tolist()
[0, 32768, 65503]

Macro Definition Documentation

define F32_TO_UQ15_STATE_MAGIC

#define F32_TO_UQ15_STATE_MAGIC `DP_FOURCC ('F','U','1','5')`

define F32_TO_UQ15_STATE_VERSION

#define F32_TO_UQ15_STATE_VERSION `1u`


The documentation for this class was generated from the following file native/inc/f32_to_uq15/f32_to_uq15_core.h