CLAP: the sndstation extensions (org.sndstation.*/1), and a faster screen on the SP #9

Merged
peterswimm merged 2 commits from feat/clap-sndstation-extensions into main 2026-10-17 20:46:06 +00:00
Owner

Moves o1nk's CLAP build from the draft game-controller extension (game-controller.*/1) to the sndstation CLAP extensions in sndstation/sndstation#3 (org.sndstation.*/1, split into core, controls and gui). The CLAP build also gets a faster screen on the RG35XX SP.

The extensions (0c867ad)

  • Vendors sndstation_extensions.h with _core.h, _controls.h and _gui.h under third_party/sndstation, unchanged from sndstation af805d1.
  • Display: sndstation_plugin_gui_t plus sndstation_plugin_gui_pixels_t {render}. render() checks each frame's pixel_format.
  • Suspend and resume: suspend stops frame requests. Resume relies on the RESET that follows it.
  • The A button: A is the face button the host labels "A", so Xbox-layout pads work.
  • A host that only knows the old draft gets a message on stderr.
  • Tests: o1nk-controls-test uses a stub host for A-by-label on SNES, Xbox and unlabelled pads, plus MENU, the gui, and suspend.

Screen speed (a488b34)

  • draw() used to build a 300 KB canvas every frame, past malloc's mmap threshold. It now draws straight into the host's frame and scales each row once.
  • Measured on an RG35XX SP (H700, A53 at 1.416 GHz) with o1nk-bench:
    • 320×240 draw time went from 723 to 75 µs.
    • 640×480 went from 2669 to 1446 µs.
    • DSP is 16–334 µs per 256-frame block, well under 1% of a core. It is untouched and stays bit-exact with the AU.

Verified

  • macOS build with no warnings.
  • arm64 Linux build, clapcheck conformant.
  • parity.sh, lgpt.sh and udg_parity.py pass.
  • o1nk-screens output is byte-identical to before at six sizes on every page.
  • o1nk-controls-test passes, including the padded-stride check.
  • gc-host --selftest passes on its sndstation-extensions branch.
  • Benchmarked on the SP itself.

Merge order: this needs sndstation/sndstation#3 to land with these ids unchanged. A host and a plugin on different drafts don't see each other's screen or buttons.

Moves o1nk's CLAP build from the draft game-controller extension (`game-controller.*/1`) to the sndstation CLAP extensions in sndstation/sndstation#3 (`org.sndstation.*/1`, split into core, controls and gui). The CLAP build also gets a faster screen on the RG35XX SP. **The extensions** (0c867ad) - Vendors `sndstation_extensions.h` with `_core.h`, `_controls.h` and `_gui.h` under `third_party/sndstation`, unchanged from sndstation af805d1. - **Display:** `sndstation_plugin_gui_t` plus `sndstation_plugin_gui_pixels_t {render}`. `render()` checks each frame's `pixel_format`. - **Suspend and resume:** suspend stops frame requests. Resume relies on the RESET that follows it. - **The A button:** A is the face button the host *labels* "A", so Xbox-layout pads work. - A host that only knows the old draft gets a message on stderr. - **Tests:** `o1nk-controls-test` uses a stub host for A-by-label on SNES, Xbox and unlabelled pads, plus MENU, the gui, and suspend. **Screen speed** (a488b34) - `draw()` used to build a 300 KB canvas every frame, past malloc's mmap threshold. It now draws straight into the host's frame and scales each row once. - Measured on an RG35XX SP (H700, A53 at 1.416 GHz) with `o1nk-bench`: - 320×240 draw time went from 723 to 75 µs. - 640×480 went from 2669 to 1446 µs. - DSP is 16–334 µs per 256-frame block, well under 1% of a core. It is untouched and stays bit-exact with the AU. **Verified** - macOS build with no warnings. - arm64 Linux build, clapcheck conformant. - `parity.sh`, `lgpt.sh` and `udg_parity.py` pass. - `o1nk-screens` output is byte-identical to before at six sizes on every page. - `o1nk-controls-test` passes, including the padded-stride check. - gc-host `--selftest` passes on its sndstation-extensions branch. - Benchmarked on the SP itself. **Merge order:** this needs sndstation/sndstation#3 to land with these ids unchanged. A host and a plugin on different drafts don't see each other's screen or buttons.
Paul Walker's draft became sndstation/sndstation#3, split into core,
controls and gui, with every id renamed. Hosts and plugins must switch
together: a host on one draft sees none of a plugin on the other.

- third_party/sndstation: sndstation_extensions.h, _core.h, _controls.h and
  _gui.h, vendored unchanged from sndstation af805d1. Not add_subdirectory,
  whose CMake needs SDL2 even for the header-only target.
- The single display extension is now sndstation_plugin_gui_t (lifecycle,
  no is_api_supported) plus sndstation_plugin_gui_pixels_t {render}. The
  config has no pixel format, so render() checks frame->pixel_format.
  request_frame is on the host gui, request_quit_to_launcher on host core.
- Event ports are SNDSTATION_EXT_CONTROLS; the descriptor feature is
  SNDSTATION_PLUGIN_FEATURE.
- sndstation_plugin_core_t: suspend stops frame requests; resume relies on
  the RESET that follows it.
- A is the face button the host labels "A" (get_input_info), east without a
  label, so Xbox-layout pads (A south) work; the pad's A and east swap.
- On a host with only the old draft o1nk says so on stderr.
- tests/plugin_controls.cpp (o1nk-controls-test): a stub host for A by
  label on SNES, Xbox and unlabelled pads, MENU, the gui, suspend. A control
  build with no A lookup fails exactly the two Xbox checks.

Verified: macOS build with no warnings; arm64 Linux build at clapcheck
conformant; parity.sh, lgpt.sh, udg_parity.py; gc-host --selftest on its
sndstation-extensions branch.
o1nk-bench (tools/o1nk_bench.cpp) times process() per block and the
screen's draw on the unit. On an RG35XX SP (H700, Cortex-A53 at 1.416 GHz),
48 kHz / 256 frames: OSC 16-25 us a block, the 212 HEXAWE voices 24 us on
average, worst block 334 us (LGPT renders a whole tick in one block), all
well under 1% of a core. The DSP is left alone, as it must stay bit-exact
with the AU.

The screen was the cost: draw() built a 300 KB canvas vector every frame,
past malloc's mmap threshold, so each frame mapped, faulted and unmapped
it, then divided twice per output pixel to scale. Now it draws straight
into the host's frame at the canvas size and into a buffer kept between
frames otherwise, and scales by widening each row once and copying it.
320x240 (what gc-host asks for): 723 -> 75 us. 640x480: 2669 -> 1446 us.

Verified: o1nk-screens output byte-identical to before at 640x480, 320x240,
700x500, 300x200 (cropped), 1280x720 and 961x721, every page;
o1nk-controls-test adds a padded-stride check (24 checks); parity.sh,
lgpt.sh, udg_parity.py, arm64 clapcheck conformant.
peterswimm deleted branch feat/clap-sndstation-extensions 2026-10-17 20:46:06 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
peterswimm/01nk!9
No description provided.