// reasampler_processor.cpp — see reasampler_processor.h. #include "reasampler_processor.h" #include "pluginterfaces/vst/ivstaudioprocessor.h" #include "pluginterfaces/vst/vstspeaker.h" #include "reasampler_editor.h" using namespace Steinberg; using namespace Steinberg::Vst; namespace reasampler::vst { FUnknown* ReaSamplerProcessor::createInstance(void* /*context*/) { // The host owns the returned reference. Cast up to the combined interface the SDK // exposes (IAudioProcessor) so the FUnknown refcount is correctly rooted. return static_cast(new ReaSamplerProcessor()); } tresult PLUGIN_API ReaSamplerProcessor::initialize(FUnknown* context) { tresult result = SingleComponentEffect::initialize(context); if (result != kResultOk) return result; // Connect the REAPER bridge. Non-fatal if it fails (non-REAPER host): the // instrument still loads, the editor just shows "no bridge". bridge_.connect(context); // Instrument bus topology: one event input (MIDI in, 16 channels), one stereo audio // output, no audio input. This is the standard VSTi arrangement. addEventInput(STR16("MIDI In"), 16); addAudioOutput(STR16("Stereo Out"), SpeakerArr::kStereo); return kResultOk; } tresult PLUGIN_API ReaSamplerProcessor::terminate() { return SingleComponentEffect::terminate(); } tresult PLUGIN_API ReaSamplerProcessor::setActive(TBool /*state*/) { // Nothing to allocate/free in the silent skeleton; S4 will size voice buffers here // against the setupProcessing block size. return kResultOk; } tresult PLUGIN_API ReaSamplerProcessor::setupProcessing(ProcessSetup& setup) { return SingleComponentEffect::setupProcessing(setup); } tresult PLUGIN_API ReaSamplerProcessor::process(ProcessData& data) { // Silent skeleton: emit silence on the output bus so the instrument runs cleanly in // REAPER's render/record path without a null buffer. S4 marshals MIDI->core->audio. if (data.numOutputs > 0 && data.outputs && data.numSamples > 0) { AudioBusBuffers& out = data.outputs[0]; for (int32 ch = 0; ch < out.numChannels; ++ch) { if (data.symbolicSampleSize == kSample32) { if (float* buf = out.channelBuffers32[ch]) { for (int32 i = 0; i < data.numSamples; ++i) buf[i] = 0.f; } } else if (data.symbolicSampleSize == kSample64) { if (double* buf = out.channelBuffers64[ch]) { for (int32 i = 0; i < data.numSamples; ++i) buf[i] = 0.0; } } } // Flag output silence so the host can optimize (nothing plays yet). out.silenceFlags = (out.numChannels >= 64) ? ~0ULL : ((1ULL << out.numChannels) - 1); } return kResultOk; } IPlugView* PLUGIN_API ReaSamplerProcessor::createView(FIDString name) { if (name && FIDStringsEqual(name, ViewType::kEditor)) { return new ReaSamplerEditor(&bridge_); } return nullptr; } } // namespace reasampler::vst