Skip to content

File f32_to_i32_core.h

File List > doppler > f32_to_i32 > f32_to_i32_core.h

Go to the documentation of this file

#ifndef DP_F32_TO_I32_CORE_H
#define DP_F32_TO_I32_CORE_H

#include "doppler/clib_common.h"
#include "doppler/dp_state.h"
#include "doppler/jm_perf.h"
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    float   scale;   /* multiply factor applied before saturation */
    uint8_t clipped; /* 1 if any sample has been saturated; 0 otherwise */
} dp_f32_to_i32_state_t;

dp_f32_to_i32_state_t *dp_f32_to_i32_create(float scale);

void dp_f32_to_i32_destroy(dp_f32_to_i32_state_t *state);

void dp_f32_to_i32_reset(dp_f32_to_i32_state_t *state);

JM_FORCEINLINE JM_HOT int32_t
dp_f32_to_i32_step(dp_f32_to_i32_state_t *state, float x)
{
    double s = (double)state->scale * (double)x;
    /* Detect saturation before clamping; set sticky flag. */
    state->clipped |= (uint8_t)(s > 2147483647.0 || s < -2147483648.0);
    if (s > 2147483647.0)
        s = 2147483647.0;
    if (s < -2147483648.0)
        s = -2147483648.0;
    return (int32_t)lround(s);
}

void dp_f32_to_i32_steps(
    dp_f32_to_i32_state_t *state,
    const float    *input,
    int32_t          *output,
    size_t               n);

/* ── Serializable state (standard bytes interface; see dp_state.h) ──────────
 * Whole-struct POD snapshot (pointer-free); the sticky clip flag resumes exactly into an
 * identically-built instance. */
#define F32_TO_I32_STATE_MAGIC DP_FOURCC ('F','2','3','2')
#define F32_TO_I32_STATE_VERSION 1u
size_t dp_f32_to_i32_state_bytes (const dp_f32_to_i32_state_t *state);
void dp_f32_to_i32_get_state (const dp_f32_to_i32_state_t *state, void *blob);
int dp_f32_to_i32_set_state (dp_f32_to_i32_state_t *state, const void *blob);

#ifdef __cplusplus
}
#endif

#endif /* F32_TO_I32_CORE_H */