open-standards/wai/wai-rs/examples/c/neural_decode.c
Transaction Science 3b6fd99989 Add WAI — Web AI Media Transport & Execution standard
WAI is a container + capability-dispatch standard for media. It does not
re-implement codecs; it dispatches to SOTA standard libraries (PNG, FLAC,
zstd as the mandatory floor; AVIF, JPEG-XL, Opus, AV1, XZ as the
recommended modern set) and adds an envelope that lets a neural
shared-prior path coexist with the model-free floor.

The capability a file requires is named, not supplied. Two paths open
every conforming file: the neural condition (sink regenerates from a
shared ambient prior) and the zeroth condition (registered SOTA codec
menu). Apache-2.0.

Adds:
- wai/SPEC.md — WAI v1.0 spec (envelope, manifest, capability dispatch,
  registered capabilities including v1.1 multi-rendition extension)
- wai/wai-rs/ — Rust reference implementation: lib + cdylib + staticlib,
  C FFI, 11 capability + envelope round-trip tests passing
- wai/wai-web/ — wasm-bindgen wrapper for browser sinks
- wai/wai-neural/ — Python tooling for neural-condition models
- wai/tools/ — codec export + encode helpers (Python)
- wai/corpus/CORPUS.md — third-party test corpus reacquisition guide

Updates README.md to list four standards instead of three.

Known consumer: CommunicationOS uses WAI for media transport over
MoQT/MLS sessions.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-24 13:36:51 -04:00

95 lines
3.3 KiB
C

/*
* Native neural decode through the C ABI.
*
* Builds against libwai.dylib (with the `neural` feature) and decodes
* one each of the audio, image, and video sample WAI envelopes.
*
* Build (from repo root):
* cargo build --release --features neural --manifest-path wai-rs/Cargo.toml
* cc -I wai-rs/include wai-rs/examples/c/neural_decode.c \
* wai-rs/target/release/libwai.dylib -o /tmp/wai_neural
*
* Run:
* DYLD_LIBRARY_PATH=wai-rs/target/release /tmp/wai_neural
*/
#include "wai.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REPO ".."
#define M(n) REPO "/wai-web/demo/models/" n "/decoder.onnx"
#define S(n) REPO "/wai-web/demo/samples/" n
#define CHECK(call, msg) do { \
int rc = (call); \
if (rc != 0) { fprintf(stderr, "FAIL %s: rc=%d\n", (msg), rc); return rc; } \
} while (0)
static int load_file(const char *path, uint8_t **out, size_t *out_len) {
FILE *f = fopen(path, "rb");
if (!f) { fprintf(stderr, "open %s failed\n", path); return -1; }
fseek(f, 0, SEEK_END);
long n = ftell(f);
fseek(f, 0, SEEK_SET);
*out = (uint8_t *)malloc((size_t)n);
*out_len = (size_t)fread(*out, 1, (size_t)n, f);
fclose(f);
return 0;
}
int main(void) {
/* ---- audio: wai.neural.encodec32 -------------------------- */
{
uint8_t *env; size_t env_len;
if (load_file(S("glass.encodec.wai"), &env, &env_len) != 0) return 1;
struct wai_buffer_t samples = {0};
uint32_t sr = 0;
CHECK(wai_neural_decode_audio(env, env_len, M("encodec_32khz"),
&samples, &sr),
"encodec32 decode");
size_t n = samples.len / sizeof(float);
const float *s = (const float *)samples.data;
float peak = 0.0f;
for (size_t i = 0; i < n; i++) {
float a = s[i] < 0 ? -s[i] : s[i];
if (a > peak) peak = a;
}
printf("encodec32 : %zu samples @ %u Hz, peak %.3f\n", n, sr, peak);
wai_buffer_free(samples);
free(env);
}
/* ---- image: wai.neural.bmshj2018 --------------------------- */
{
uint8_t *env; size_t env_len;
if (load_file(S("kodim23.bmshj2018.wai"), &env, &env_len) != 0) return 1;
struct wai_buffer_t rgb = {0};
uint32_t w = 0, h = 0;
CHECK(wai_neural_decode_image(env, env_len, M("bmshj2018"), &rgb, &w, &h),
"bmshj2018 decode");
printf("bmshj2018 : %ux%u RGB, %zu bytes\n", w, h, (size_t)rgb.len);
wai_buffer_free(rgb);
free(env);
}
/* ---- video: wai.neural.video_bmshj2018 ---------------------- */
{
uint8_t *env; size_t env_len;
if (load_file(S("test.video.wai"), &env, &env_len) != 0) return 1;
struct wai_buffer_t frames = {0};
uint32_t n_frames = 0, w = 0, h = 0, fps_x_1000 = 0;
CHECK(wai_neural_decode_video(env, env_len, M("bmshj2018"),
&frames, &n_frames, &w, &h, &fps_x_1000),
"video_bmshj2018 decode");
printf("video_bmshj : %u frames %ux%u @ %.2f fps, %zu bytes\n",
n_frames, w, h, fps_x_1000 / 1000.0, (size_t)frames.len);
wai_buffer_free(frames);
free(env);
}
puts("ok");
return 0;
}