Two fixes to the Rabi tune-up: - Replace the noise-sensitive argmax peak-finder with a WHOLE-CURVE model fit (search the candidate pi-amplitude minimizing Sigma|measured - sin2(pi*a/2a_pi)|, coarse then fine) — what real tune-ups do, and robust where argmax fails: near a flat maximum shot noise moves the peak sample, but the model fit uses every point. Browser check: recovered pi-amp 1.428 vs hidden truth 1.426 (was ~0.11 off). - Add TuneResult::artifacts() so all four routines seal uniformly via seal_artifacts. - Rename the module's public FRAC/ONE to CAL_FRAC/CAL_ONE: cbindgen exports pub consts into wai.h, and the bare names collided with quantum.rs's FRAC=30/ONE (duplicate #define). Now namespaced; header clean (FRAC 30 + CAL_FRAC 20 distinct). 9 lib tests green. Co-Authored-By: Claude Opus 4.8 <[email protected]>
601 lines
16 KiB
C
601 lines
16 KiB
C
/*
|
||
* WAI — Web AI media transport + execution.
|
||
*
|
||
* Auto-generated by cbindgen from src/ffi.rs. DO NOT EDIT — regenerate
|
||
* by rebuilding `wai-rs` (the build.rs runs cbindgen) or by running
|
||
* cbindgen --config cbindgen.toml --crate wai --output include/wai.h
|
||
*
|
||
* SDK contract:
|
||
* - Every `wai_*` function returns a `wai_status_t` (typedef int).
|
||
* 0 = ok; non-zero = see WAI_ERR_* below + wai_last_error().
|
||
* - Any `WaiBuffer` written into an out parameter MUST be freed via
|
||
* `wai_buffer_free`. Passing a zero-cap buffer to free is safe.
|
||
* - `wai_last_error()` returns a NUL-terminated UTF-8 string that is
|
||
* valid until the next wai_* call on the same thread.
|
||
*
|
||
* Build the library:
|
||
* cargo build --release # produces libwai.{so,dylib,a}
|
||
* Link with:
|
||
* gcc your.c -lwai # static or dynamic per linker
|
||
*/
|
||
|
||
|
||
#ifndef WAI_H
|
||
#define WAI_H
|
||
|
||
#pragma once
|
||
|
||
#include <stdarg.h>
|
||
#include <stdbool.h>
|
||
#include <stdint.h>
|
||
#include <stdlib.h>
|
||
|
||
#define WAI_OK 0
|
||
|
||
#define WAI_ERR_INVALID_ARG 1
|
||
|
||
#define WAI_ERR_CODEC 2
|
||
|
||
#define WAI_ERR_CONTAINER 3
|
||
|
||
#define WAI_ERR_PANIC 4
|
||
|
||
/**
|
||
* Probability output scale of [`softmax`]: results are at `2^PROB_FRAC`
|
||
* (they sum to ~`2^PROB_FRAC`).
|
||
*/
|
||
#define PROB_FRAC 16
|
||
|
||
/**
|
||
* Fractional bits of the Q16 fixed-point format.
|
||
*/
|
||
#define F 16
|
||
|
||
/**
|
||
* 1.0 in Q16.
|
||
*/
|
||
#define S (1 << F)
|
||
|
||
/**
|
||
* Number of action planes appended to the latent for the transition (dx, dy, btn).
|
||
*/
|
||
#define A 3
|
||
|
||
#define MARKER_SOC 65408
|
||
|
||
#define MARKER_EOC 65409
|
||
|
||
#define MARKER_PIH 65410
|
||
|
||
#define MARKER_TON 65411
|
||
|
||
#define MARKER_RDI 65412
|
||
|
||
#define MARKER_SOZ 65416
|
||
|
||
#define MARKER_SORP 65417
|
||
|
||
#define MARKER_SORS 65418
|
||
|
||
#define MARKER_SOQ 65419
|
||
|
||
#define MARKER_UDI 65420
|
||
|
||
#define SECTION_CONTRACT 1
|
||
|
||
#define SECTION_GRAPH 2
|
||
|
||
#define SECTION_ASSETS 3
|
||
|
||
#define SECTION_OPLOG 4
|
||
|
||
#define SECTION_SEAL 5
|
||
|
||
/**
|
||
* Payload = a record body (`n_cells u16 | cells…`). Target MUST
|
||
* equal `mint_node_id(actor, lamport)`. Resolution: LWW.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* `pos[3] | vel[3] | scalar` (7 × i64). Target MUST equal
|
||
* `mint_node_id(actor, lamport)`. Resolution: LWW.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* `pos[3] | vel[3] | radius | restitution` (8 × i64). Target MUST
|
||
* equal `mint_node_id(actor, lamport)`. Resolution: LWW.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* `parent[16] | translation[3] | rotation[4] | scale[3]`
|
||
* (16 + 10×`i64` Fx = 96 bytes). Target MUST equal
|
||
* `mint_node_id(actor, lamport)`. `parent` is another bone's node
|
||
* id, or all-zero for a root.
|
||
*/
|
||
#define CREATE 1
|
||
|
||
/**
|
||
* Empty payload. Resolution: LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload. Resolution: LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload. Resolution: LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload — remove the bone.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* Empty payload; removes a particle or member. LWW.
|
||
*/
|
||
#define DELETE 2
|
||
|
||
/**
|
||
* `field_idx u16 | cell(tag u8 | value)` — replace one cell.
|
||
* Resolution: LWW.
|
||
*/
|
||
#define SET_CELL 16
|
||
|
||
/**
|
||
* `field_idx u16 | i64` — add to an `Int` cell (saturating).
|
||
* Resolution: SUM.
|
||
*/
|
||
#define ADD_INT 17
|
||
|
||
/**
|
||
* `field_idx u16 | i64` (Fx bits) — add to a `Fixed` cell
|
||
* (saturating). Resolution: SUM.
|
||
*/
|
||
#define ADD_FIXED 18
|
||
|
||
#define Fx_FRAC_BITS 32
|
||
|
||
/**
|
||
* `scalar` (1 × i64). Resolution: LWW.
|
||
*/
|
||
#define SET_SCALAR 3
|
||
|
||
/**
|
||
* `dv[3]` (3 × i64) added to velocity. Resolution: SUM — two
|
||
* actors shoving the same node both act; neither is discarded.
|
||
*/
|
||
#define IMPULSE 4
|
||
|
||
/**
|
||
* `dv[3]` (3 × i64) added to velocity. Resolution: SUM.
|
||
*/
|
||
#define IMPULSE 4
|
||
|
||
/**
|
||
* `dv[3]` (3 × i64) added to a particle's velocity. SUM.
|
||
*/
|
||
#define IMPULSE 4
|
||
|
||
/**
|
||
* `pos[3]` (3 × i64). Resolution: LWW.
|
||
*/
|
||
#define SET_POS 5
|
||
|
||
/**
|
||
* `pos[3]` (3 × i64). Resolution: LWW.
|
||
*/
|
||
#define SET_POS 5
|
||
|
||
/**
|
||
* `pos[3]` (3 × i64) on a particle. LWW.
|
||
*/
|
||
#define SET_POS 5
|
||
|
||
/**
|
||
* `rotation[4]` (4×`i64` Fx quaternion x,y,z,w) — the animation
|
||
* driver: set a joint's local rotation.
|
||
*/
|
||
#define SET_ROTATION 16
|
||
|
||
/**
|
||
* `translation[3]` (3×`i64` Fx).
|
||
*/
|
||
#define SET_TRANSLATION 17
|
||
|
||
/**
|
||
* `scale[3]` (3×`i64` Fx).
|
||
*/
|
||
#define SET_SCALE 18
|
||
|
||
/**
|
||
* Create a particle: `pos[3] | vel[3] | inv_mass` (7 × i64).
|
||
* `inv_mass == 0` is an anchor (infinite mass — foundations).
|
||
* Target MUST equal `mint_node_id(actor, lamport)`. LWW.
|
||
*/
|
||
#define CREATE_PARTICLE 1
|
||
|
||
/**
|
||
* Create a member between two particles:
|
||
* `node_a (16 B) | node_b (16 B) | yield_strain (i64)`.
|
||
* Rest length is measured from the endpoints' current positions
|
||
* at apply time (weld what's there — deterministic, since apply
|
||
* order is canonical). Target MUST be minted; endpoints missing
|
||
* or coincident → deterministic no-op. LWW.
|
||
*/
|
||
#define CREATE_MEMBER 16
|
||
|
||
/**
|
||
* Fixed PCM window per reconstruction block (samples). The final block may
|
||
* be short; every block carries its index, so the partition is canonical.
|
||
*/
|
||
#define SEGMENT_SAMPLES 4096
|
||
|
||
#define SAW 0
|
||
|
||
#define SQUARE 1
|
||
|
||
#define TRIANGLE 2
|
||
|
||
#define PULSE25 3
|
||
|
||
/**
|
||
* `CausalOp::mutation_kind` for an action input (move/look/buttons + free payload).
|
||
*/
|
||
#define MUT_ACTION 1
|
||
|
||
/**
|
||
* Fractional bits of the fixed-point amplitude floor. Amplitudes live in
|
||
* `[-1, 1]`, so `2^FRAC` (≈ `1.07e9` at 30) is the unit and the i128 products in
|
||
* [`Amp::mul`] stay far inside range.
|
||
*/
|
||
#define FRAC 30
|
||
|
||
/**
|
||
* The fixed-point unit `1.0`.
|
||
*/
|
||
#define ONE (1 << FRAC)
|
||
|
||
/**
|
||
* Largest `k` for which `P(k) = e^{2πi/2^k}` is tabulated — the QFT reaches this
|
||
* many qubits. The table is built by an integer half-angle recurrence (no float).
|
||
*/
|
||
#define DYADIC_MAX 32
|
||
|
||
/**
|
||
* The largest circuit this build will simulate (a state vector is `2^n`
|
||
* amplitudes × 16 bytes; 26 qubits ≈ 1 GiB). The *format* supports more — this
|
||
* is a materialization guard, not a spec limit.
|
||
*/
|
||
#define MAX_QUBITS 26
|
||
|
||
/**
|
||
* Fixed-point fractional bits for core scales and the reconstruction
|
||
* accumulator. Scales live at `2^SCALE_FRAC`; the i128 contraction rescales by
|
||
* `>> SCALE_FRAC` after absorbing each core's per-column scale.
|
||
*/
|
||
#define SCALE_FRAC 24
|
||
|
||
/**
|
||
* Trits per packed byte. `3^5 = 243 < 256`, the near-entropy-optimal
|
||
* balanced-ternary packing (1.58 bits/trit) the ternary fabric uses.
|
||
*/
|
||
#define TRITS_PER_BYTE 5
|
||
|
||
/**
|
||
* Fixed-point fractional bits. All amplitudes, probabilities and angles are i64
|
||
* at `2^CAL_FRAC`. Probabilities live in `[0, CAL_ONE]`.
|
||
*/
|
||
#define CAL_FRAC 20
|
||
|
||
/**
|
||
* `1.0` in fixed-point.
|
||
*/
|
||
#define CAL_ONE (1 << CAL_FRAC)
|
||
|
||
/**
|
||
* A complex amplitude in the fixed-point floor: `re, im` are `i64` at scale
|
||
* `2^FRAC`. Byte-exact by construction — `Eq` is total (no float), so two
|
||
* statevectors compare and hash identically iff every amplitude matches.
|
||
*/
|
||
typedef struct Amp Amp;
|
||
|
||
/**
|
||
* Q32.32 fixed-point value.
|
||
*/
|
||
typedef struct Fx Fx;
|
||
|
||
typedef struct wai_buffer_t {
|
||
uint8_t *data;
|
||
uintptr_t len;
|
||
uintptr_t cap;
|
||
} wai_buffer_t;
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif // __cplusplus
|
||
|
||
/**
|
||
* Free a buffer previously returned by any `wai_*_encode` /
|
||
* `wai_*_decode` / `wai_envelope_*` call. Safe to call with a null
|
||
* or zero-cap buffer.
|
||
*
|
||
* # Safety
|
||
* `buf.data` must have been produced by this crate.
|
||
*/
|
||
void wai_buffer_free(struct wai_buffer_t buf);
|
||
|
||
/**
|
||
* Returns a pointer to the most recent error message for this thread,
|
||
* or null if there is none. The pointer is valid until the next FFI
|
||
* call on this thread that sets an error.
|
||
*/
|
||
const char *wai_last_error(void);
|
||
|
||
/**
|
||
* Encode RGB pixels (row-major, 3 bytes per pixel) as PNG.
|
||
*
|
||
* # Safety
|
||
* `rgb` must point to a valid RGB buffer of at least `len` bytes;
|
||
* `out` must be a writable `WaiBuffer*`. Pass `(null, 0)` for empty.
|
||
*/
|
||
|
||
int wai_image_png_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Decode a PNG byte stream to RGB. Returns `(rgb, h, w)`.
|
||
*/
|
||
|
||
int wai_image_png_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w);
|
||
|
||
|
||
int wai_image_avif_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
uint8_t quality,
|
||
struct wai_buffer_t *out);
|
||
|
||
|
||
int wai_image_avif_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w);
|
||
|
||
/**
|
||
* `quality = 0` ⇒ lossless. Otherwise butteraugli distance proxy
|
||
* (higher quality = smaller distance internally).
|
||
*/
|
||
|
||
int wai_image_jxl_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
uint8_t quality,
|
||
struct wai_buffer_t *out);
|
||
|
||
|
||
int wai_image_jxl_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w);
|
||
|
||
|
||
int wai_audio_opus_encode(const float *samples,
|
||
uintptr_t n,
|
||
uint32_t sr,
|
||
int32_t bitrate_bps,
|
||
struct wai_buffer_t *out);
|
||
|
||
|
||
int wai_audio_opus_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_sr);
|
||
|
||
|
||
int wai_audio_flac_encode(const float *samples,
|
||
uintptr_t n,
|
||
uint32_t sr,
|
||
struct wai_buffer_t *out);
|
||
|
||
|
||
int wai_audio_flac_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_sr);
|
||
|
||
|
||
int wai_text_zstd_encode(const uint8_t *data,
|
||
uintptr_t len,
|
||
int32_t level,
|
||
struct wai_buffer_t *out);
|
||
|
||
int wai_text_zstd_decode(const uint8_t *bytes, uintptr_t len, struct wai_buffer_t *out);
|
||
|
||
|
||
int wai_text_xz_encode(const uint8_t *data,
|
||
uintptr_t len,
|
||
uint32_t level,
|
||
struct wai_buffer_t *out);
|
||
|
||
int wai_text_xz_decode(const uint8_t *bytes, uintptr_t len, struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Encode a sequence of `n` RGB frames as AV1.
|
||
*/
|
||
|
||
int wai_video_av1_encode(const uint8_t *rgb,
|
||
uintptr_t len,
|
||
uint32_t n,
|
||
uint32_t h,
|
||
uint32_t w,
|
||
uint32_t fps_num,
|
||
uint32_t fps_den,
|
||
uint8_t lossless,
|
||
uint8_t quality,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Decode an AV1 WAI payload to a packed RGB buffer `n*h*w*3` bytes.
|
||
*/
|
||
|
||
int wai_video_av1_decode(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out,
|
||
uint32_t *out_n,
|
||
uint32_t *out_h,
|
||
uint32_t *out_w,
|
||
uint32_t *out_fps_num,
|
||
uint32_t *out_fps_den);
|
||
|
||
/**
|
||
* Builds a complete WAI file from a codec-produced payload + manifest
|
||
* fields. `manifest_json` is a UTF-8 JSON object overriding/supplying
|
||
* any fields; `payload` is the bytes from one of the codec encoders.
|
||
*/
|
||
|
||
int wai_envelope_pack(const char *manifest_json,
|
||
const uint8_t *payload,
|
||
uintptr_t payload_len,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Detect WAI version from a byte stream. Returns 1 (WAI1), 2 (WAI2),
|
||
* or 0 with an error message in `wai_last_error` for unknown magic.
|
||
*/
|
||
int wai_envelope_detect_version(const uint8_t *bytes, uintptr_t len);
|
||
|
||
/**
|
||
* Pack a WAI2 multi-rendition envelope.
|
||
*
|
||
* - `manifest_json` must declare a `renditions` array of length `n`.
|
||
* - `payload_data` is an array of `n` byte-buffer pointers.
|
||
* - `payload_lens` is the matching array of `n` lengths.
|
||
* - The i-th payload pairs with `manifest.renditions[i]`.
|
||
*
|
||
* # Safety
|
||
* All array pointers must point to valid memory of the declared length.
|
||
*/
|
||
|
||
int wai_envelope_pack_multi(const char *manifest_json,
|
||
const uint8_t *const *payload_data,
|
||
const uintptr_t *payload_lens,
|
||
uintptr_t n_payloads,
|
||
struct wai_buffer_t *out);
|
||
|
||
/**
|
||
* Parse a WAI2 envelope. Writes three outputs:
|
||
*
|
||
* - `out_manifest` — the original manifest JSON (UTF-8 bytes, no NUL)
|
||
* - `out_renditions_json` — a JSON array of `{capability, kind, offset,
|
||
* length}` entries. `offset` is into `out_payload_block`, `length`
|
||
* is the rendition's payload byte count.
|
||
* - `out_payload_block` — every rendition's payload bytes, packed
|
||
* contiguously. The caller indexes via the JSON above.
|
||
*
|
||
* This avoids exposing a C struct array (and the ownership pain that
|
||
* comes with it). Any JSON parser the consumer already has decodes
|
||
* the rendition table in two lines.
|
||
*/
|
||
|
||
int wai_envelope_unpack_multi(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out_manifest,
|
||
struct wai_buffer_t *out_renditions_json,
|
||
struct wai_buffer_t *out_payload_block);
|
||
|
||
/**
|
||
* Parses a WAI envelope. Writes the manifest as JSON to `out_manifest`
|
||
* and the raw payload to `out_payload`.
|
||
*/
|
||
|
||
int wai_envelope_unpack(const uint8_t *bytes,
|
||
uintptr_t len,
|
||
struct wai_buffer_t *out_manifest,
|
||
struct wai_buffer_t *out_payload);
|
||
|
||
/**
|
||
* Decode a `wai.neural.<audio>` envelope (encodec32 / dac / mimi /
|
||
* wavtokenizer). Writes mono `f32` samples into `out_samples`; the
|
||
* caller reads them as `float*` of length `out_samples.len / 4`.
|
||
*
|
||
* # Safety
|
||
* `envelope` valid for `envelope_len` bytes. `model_path` NUL-terminated
|
||
* UTF-8 path to the decoder.onnx. `out_samples` writable `WaiBuffer*`.
|
||
* `out_sample_rate` writable `uint32_t*` (or null to skip).
|
||
*/
|
||
|
||
int wai_neural_decode_audio(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *model_path,
|
||
struct wai_buffer_t *out_samples,
|
||
uint32_t *out_sample_rate);
|
||
|
||
/**
|
||
* Decode a `wai.neural.bmshj2018` envelope. Writes packed RGB
|
||
* (row-major, 3 bytes/pixel) into `out_rgb`; writes width/height
|
||
* into `*out_width` / `*out_height`.
|
||
*
|
||
* # Safety
|
||
* See `wai_neural_decode_audio`.
|
||
*/
|
||
|
||
int wai_neural_decode_image(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *model_path,
|
||
struct wai_buffer_t *out_rgb,
|
||
uint32_t *out_width,
|
||
uint32_t *out_height);
|
||
|
||
/**
|
||
* Decode a `wai.neural.video_bmshj2018` envelope. Writes all frames
|
||
* concatenated (frame 0 RGB, then frame 1 RGB, …) into
|
||
* `out_frames_concat`; the caller splits at `width*height*3` strides.
|
||
*
|
||
* # Safety
|
||
* See `wai_neural_decode_audio`.
|
||
*/
|
||
|
||
int wai_neural_decode_video(const uint8_t *envelope,
|
||
uintptr_t envelope_len,
|
||
const char *model_path,
|
||
struct wai_buffer_t *out_frames_concat,
|
||
uint32_t *out_n_frames,
|
||
uint32_t *out_width,
|
||
uint32_t *out_height,
|
||
uint32_t *out_fps_x_1000);
|
||
|
||
#ifdef __cplusplus
|
||
} // extern "C"
|
||
#endif // __cplusplus
|
||
|
||
#endif /* WAI_H */
|