CLAP: HEXAWE voices, bit-identical to the AU #8
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/clap-lgpt-voice"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The CLAP now plays the 212 HEXAWE voices with output bit-identical to the AU.
The voice
core/lgpt_voice.{h,cpp}is a C++17 port ofLGPTVoiceConfigandLGPTVoice. It adds no dependencies, and render never allocates.-ffp-contract=off. Without it, Clang on arm64 and GCC in gnu++17 mode fuse multiply-adds and the output drifts.Choosing a voice
voiceparameter (101,lgpt.voice): 0 is Init (the wavetable engine), and n is the n-th voice. The catalog is sorted the same way as the AU's, so n is the AU's factory preset number.value_to_text.kBanks, voices may only ever be appended to the catalog.Loading and tempo
process()takes it at the next block or note.O1NK_VOICES, then the bundle'sResources/hexawe, theno1nk-voices/beside the.so, then the share directories..device.jsonfiles.UDG
udg_parity.pynow checks that the CLAP's non-OPSL parameters are exactlyEXTENSION_PARAMS. Before this, a new extension parameter went unchecked.Testing
clap/tests/lgpt.shruns each check below alongside a deliberately broken control, which must fail:Other checks:
clap/tests/parity.sh: passes, with 3 new voice scenarios. Its two new controls each fail only the voice scenarios.udg_parity.py(2 extensions) andopsl_parity.pypass.tests/lgpt/run.shpasses.Not covered
- core/lgpt_voice.{h,cpp}: C++17 port of LGPTVoiceConfig and LGPTVoice (no new dependencies; render does not allocate). Swift's wrapping and truncating arithmetic is done in unsigned types, the filter difference in 64 bits, and the file builds with -ffp-contract=off so nothing fuses. - A "voice" parameter (101, lgpt.voice): 0 is Init (the wavetable engine), n the n-th voice in the same sorted catalog the AU uses, so n matches the AU's factory preset number. It is saved as an index, so voices may only be appended, like kBanks. - The main thread builds a voice and hands it over in an atomic mailbox; process() takes it at a block or note, and the replaced voice returns through a lock-free queue to be freed on the main thread. The transport's tempo drives the tables; without one, the song's own. - Voices are found like banks (O1NK_VOICES, the bundle's Resources/hexawe, o1nk-voices/ beside the .so, share dirs); CMake copies the sidecars, samples and credits, not the .device.json files. - udg_parity.py now checks that the CLAP's non-OPSL parameters are exactly EXTENSION_PARAMS; before, a new one went unchecked. clap/tests/lgpt.sh: C++ vs Swift voice on every sidecar (424/424 identical), catalog identical to the AU's, the plugin through a stub host (selection, hand-off, tempo, state), and C++ vs LGPT itself (418/418 bit-exact); each with a control that fails. parity.sh gains voice scenarios and two voice-only controls. Co-Authored-By: Claude <noreply@anthropic.com>