@maruaudio/dsp/math/pcm16 converts between floats and signed 16-bit PCM with libDaisy's exact f32 semantics (f2s16 and s162f). Encoding rounds to f32, clamps to ±PCM16_FLOAT_LIMIT (the f32 nearest 0.999985, not ±1), multiplies by 32767 in f32 and truncates toward zero, so codes lie in [−32766, 32766] and a later int16_t narrowing never wraps. Decoding multiplies by the f32 nearest 1/32767.
Functions
| Name | Input | Output | Domain as coded |
|---|---|---|---|
floatToPcm16 | value | integer in [−32766, 32766] | Clamped; NaN → 0; tiny negatives → +0 |
pcm16ToFloat | sample (any integer) | f32(sample × f32(1/32767)) | Not clamped; 32767 → 1 |
pcm16Quantize | value | pcm16ToFloat(floatToPcm16(value)) | The value an int16_t store returns |
PCM16_FLOAT_LIMIT, PCM16_FROM_FLOAT_SCALE, PCM16_TO_FLOAT_SCALE | constants | f32(0.999985), 32767, f32(1/32767) |
Lifecycle
None. Stateless functions with no preparation or instance state.
When to use it
Store audio the way the CHOMPI firmware does, in int16_t sample buffers, tape and delay lines, so a port matches the hardware. Maru compiler has no Int16Array, so a store keeps pcm16Quantize(x) (exactly representable) in an f32 slot or the integer code in an i32 slot.
Limits
- Decoding then re-encoding can lose one code: truncation toward zero can bring a code back one step smaller in magnitude, as in the firmware's re-encode paths.
- NaN encodes as 0, matching the Cortex-M7
VCVTsaturation; C itself leaves it undefined.