Context
plugins/sampler.cpp is implemented against the raw C API (namespaced Methcla_SynthDef with C function pointers + a host-command lifecycle for buffer loading). plugins/README.md declares the C++ wrapper API "preferred". This issue migrates Sampler to StaticSynthDef using kSynthDefHasCleanup.
Outcome: sampler.cpp uses the wrapper API; load → silence-until-loaded → play → synthDone semantics preserved.
Scope
Convert synth boilerplate. Keep load_sound_file, set_buffer, free_buffer_cb, hermite1, resample as free helpers (they run on host or are state-free templates). Use kSynthDefHasCleanup — cleanup runs free_buffer_cb via world.performCommand.
SamplerOptions constructor mirrors current configure (sampler.cpp:100–112) verbatim, just sourcing args from the ArgStream passed in. Preserve the existing size_t numFrames with -1 sentinel (surgical; the original quirk stays).
Construct moves the variable-length LoadMessage allocation (sampler.cpp:203–212) into the C++ constructor using world.alloc(). set_buffer writes back via a Sampler::setBuffer(...) member (keeps fields private).
process_interp (sampler.cpp:328) becomes a private member function Sampler::processInterp(...). freeBuffer(world, self) becomes inline:
world.performCommand(free_buffer_cb, m_buffer);
m_buffer = nullptr;
and methcla_world_synth_done(world, self) becomes world.synthDone(this).
Update LoadMessage::synth from Synth* to Sampler*.
Register:
StaticSynthDef<Sampler, SamplerOptions, SamplerPorts, kSynthDefHasCleanup>
kSamplerDef;
Files
plugins/sampler.cpp — convert synth boilerplate; kSynthDefHasCleanup
plugins/README.md — update the "Implementation styles" table row to move sampler.cpp under the wrapper category (the table currently mis-classifies it under C API, which this issue corrects).
CHANGELOG.md — add a ### Changed entry under ## [Unreleased] referencing this issue.
Verification
pre-commit run --all-files
cmake --preset debug
cmake --build build/debug
ctest --test-dir build/debug --output-on-failure
Confirm methcla_plugin_sampler builds. Run any test exercising sampler load-and-play (check tests/ for what exists).
Behavioural equivalence (no audible / log diff expected):
- Load → silence-until-loaded → play →
synthDone on end (non-loop).
This plugin requires a Soundfile API Plugin to be registered (see plugins/README.md).
Context
plugins/sampler.cppis implemented against the raw C API (namespacedMethcla_SynthDefwith C function pointers + a host-command lifecycle for buffer loading).plugins/README.mddeclares the C++ wrapper API "preferred". This issue migratesSamplertoStaticSynthDefusingkSynthDefHasCleanup.Outcome:
sampler.cppuses the wrapper API; load → silence-until-loaded → play →synthDonesemantics preserved.Scope
Convert synth boilerplate. Keep
load_sound_file,set_buffer,free_buffer_cb,hermite1,resampleas free helpers (they run on host or are state-free templates). UsekSynthDefHasCleanup— cleanup runsfree_buffer_cbviaworld.performCommand.SamplerOptionsconstructor mirrors currentconfigure(sampler.cpp:100–112) verbatim, just sourcing args from theArgStreampassed in. Preserve the existingsize_t numFrameswith-1sentinel (surgical; the original quirk stays).Construct moves the variable-length
LoadMessageallocation (sampler.cpp:203–212) into the C++ constructor usingworld.alloc().set_bufferwrites back via aSampler::setBuffer(...)member (keeps fields private).process_interp(sampler.cpp:328) becomes a private member functionSampler::processInterp(...).freeBuffer(world, self)becomes inline:world.performCommand(free_buffer_cb, m_buffer); m_buffer = nullptr;and
methcla_world_synth_done(world, self)becomesworld.synthDone(this).Update
LoadMessage::synthfromSynth*toSampler*.Register:
Files
plugins/sampler.cpp— convert synth boilerplate;kSynthDefHasCleanupplugins/README.md— update the "Implementation styles" table row to movesampler.cppunder the wrapper category (the table currently mis-classifies it under C API, which this issue corrects).CHANGELOG.md— add a### Changedentry under## [Unreleased]referencing this issue.Verification
Confirm
methcla_plugin_samplerbuilds. Run any test exercising sampler load-and-play (checktests/for what exists).Behavioural equivalence (no audible / log diff expected):
synthDoneon end (non-loop).This plugin requires a Soundfile API Plugin to be registered (see
plugins/README.md).