Metadata-Version: 2.1
Name: mudraka
Version: 0.2.1
Summary: C++ sEMG engine for Mudra Link raw SNC decoding
Author: ttktjmt
License: Apache-2.0
Classifier: License :: OSI Approved :: Apache Software License
Requires-Python: >=3.9
Provides-Extra: numpy
Requires-Dist: numpy>=1.23; extra == "numpy"
Description-Content-Type: text/markdown

# mudraka

[![PyPI](https://img.shields.io/pypi/v/mudraka?logo=pypi&logoColor=white)](https://pypi.org/project/mudraka/)
[![npm](https://img.shields.io/npm/v/mudraka?logo=npm)](https://www.npmjs.com/package/mudraka)

A transport-agnostic **C++17 engine** that decodes the Mudra Link wristband's raw
surface-EMG (SNC) stream into samples, buffers them, and serves them for real-time
use. It is the shared core of three projects (this repo is **mudraka only**):

- **mudraka** — this engine.
- **mudra-lsl** — Python/PyPI wrapper publishing LSL (consumes the wheel).
- **mudra-web-viewer** — Web Bluetooth live viewer (consumes the WASM/npm build).

One C++ core fans out to two distributions: **npm** (Emscripten→WASM) and **PyPI**
(nanobind wheel). See **[docs/](docs/README.md)** for the full design (start with
[docs/CONTEXT.md](docs/CONTEXT.md)).

## Status

| Part | State |
|------|-------|
| Native C++ core (decoder, ring, clock, stream, diagnostics) | ✅ implemented, tested against real captures (22k+ assertions) |
| Python binding (nanobind) | ✅ **published to [PyPI](https://pypi.org/project/mudraka/)**; verified bit-exact on real fixtures |
| WASM binding (Embind) | ✅ **published to [npm](https://www.npmjs.com/package/mudraka)** (with TypeScript types); verified bit-exact under Node |
| Tri-target parity + CI/release | ✅ native == python == wasm (golden `expected.jsonl`); CI matrix + tag/dispatch publish automation |
| **SNC decode** | ✅ decoded **directly**, empirically validated for Mudra Link (16-bit, ~834 Hz); no official lib/oracle (see [docs/DECODE_VERIFICATION.md](docs/DECODE_VERIFICATION.md)) |

> Target is the **retail Mudra Link** (~834 Hz / 16-bit — the vendor-confirmed limit).
> The 2080 Hz figure is a **separate product, Mudra Pro**, a future target that slots in
> as a new `IDecoder` — see [docs/CONTEXT.md](docs/CONTEXT.md).

## Layout

```
include/mudraka/   public headers          src/        core implementation
tests/             doctest suite           bindings/   python (nanobind) + wasm (embind)
tools/             BLE capture (bleak)      fixtures/   recorded test sessions
docs/              design docs (indexed by docs/README.md)
```

## Build & test (native)

```sh
cmake -S . -B build -G Ninja -DMUDRAKA_BUILD_TESTS=ON
cmake --build build
ctest --test-dir build --output-on-failure      # or: ./build/tests/mudraka_tests
```

## Python wheel

```sh
pip install .            # scikit-build-core + nanobind; needs a C++17 compiler
```
```python
import numpy as np
from mudraka import Stream, Config
s = Stream(Config())
s.feed(notification_bytes, recv_time_s)          # one BLE notification per call
out = np.empty((3, 4096), dtype=np.int32)
written, cursor, lost = s.latest_into(out)       # zero-copy into `out`
```

## WASM (npm)

Published as [`mudraka`](https://www.npmjs.com/package/mudraka) for the browser (Web
Bluetooth), Workers, and Node — **`npm install mudraka`**. JS/TS usage, Web Bluetooth
wiring, and bundler `.wasm` notes are in [npm/README.md](npm/README.md) (the package's
own README); types ship in [npm/mudraka.d.ts](npm/mudraka.d.ts).

To build the artifacts locally (needs the Emscripten toolchain):

```sh
emcmake cmake -S . -B build-wasm -DMUDRAKA_BUILD_WASM=ON -DMUDRAKA_BUILD_TESTS=OFF
cmake --build build-wasm                         # -> mudraka.js + mudraka.wasm
node tools/verify_wasm.mjs                        # end-to-end golden parity check
```

## Recording fixtures

See [tools/README.md](tools/README.md) — `capture_session.py` records a full BLE
session from a real band.

## Acknowledgements

- [Prodilink](https://github.com/JayTheProdigy16/Prodilink) — reverse-engineering
  reference for the Mudra Link BLE protocol.
