Skip to content

Instantly share code, notes, and snippets.

@skitaoka
Created July 16, 2023 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skitaoka/6f5413ee12af4e6890be0419a969313b to your computer and use it in GitHub Desktop.
Save skitaoka/6f5413ee12af4e6890be0419a969313b to your computer and use it in GitHub Desktop.
31平均律にするため 3ch を束ねて tuning を修正して出力する VSTi
#include <public.sdk/source/main/pluginfactory.h>
#include <public.sdk/source/vst/vstaudioeffect.h>
#include <public.sdk/source/vst/vstguieditor.h>
#include <public.sdk/source/vst/vsteditcontroller.h>
#include <public.sdk/source/vst/vstaudioprocessoralgo.h>
#include <public.sdk/source/vst/vstaudioprocessoralgo.h>
#include <pluginterfaces/base/ibstream.h>
#include <pluginterfaces/base/ustring.h>
#include <pluginterfaces/vst/ivstevents.h>
#include <pluginterfaces/vst/ivstparameterchanges.h>
#include <pluginterfaces/vst/ivstplugview.h>
#include <pluginterfaces/vst/ivsteditcontroller.h>
#include <pluginterfaces/vst/ivstmidicontrollers.h>
#include <pluginterfaces/vst/vstpresetkeys.h>
#include <vstgui/vstgui.h>
#include <vstgui/plugin-bindings/vst3editor.h>
#include <base/source/fstreamer.h>
#include <cstring>
namespace {
Steinberg::FUID const NoteTuner31ProcessorUID{0xE4905858, 0xA99745C5, 0x95B241B9, 0xCDDF27D5};
Steinberg::FUID const NoteTuner31ControllerUID{0xE2975EFA, 0x610F41F6, 0xB86661E4, 0x61D511E3};
class NoteTuner31Processor : public Steinberg::Vst::AudioEffect {
public:
static Steinberg::FUnknown* createInstance(void*) {
return reinterpret_cast<Steinberg::FUnknown*>(new NoteTuner31Processor());
}
public:
NoteTuner31Processor() {
setControllerClass(NoteTuner31ControllerUID);
}
Steinberg::tresult PLUGIN_API initialize(Steinberg::FUnknown* context) SMTG_OVERRIDE {
if (Steinberg::tresult const retval = AudioEffect::initialize(context)) {
return retval;
}
this->addAudioOutput(STR16("Mono Out"), Steinberg::Vst::SpeakerArr::kMono);
this->addEventInput(STR16("Event In"), 3);
this->addEventOutput(STR16("Event Out"), 1);
return Steinberg::kResultOk;
}
Steinberg::tresult PLUGIN_API setBusArrangements(
Steinberg::Vst::SpeakerArrangement* inputs, Steinberg::int32 numIns,
Steinberg::Vst::SpeakerArrangement* outputs, Steinberg::int32 numOuts) SMTG_OVERRIDE {
if ((numOuts == 1) && (outputs[0] == Steinberg::Vst::SpeakerArr::kMono)) {
return AudioEffect::setBusArrangements(inputs, numIns, outputs, numOuts);
}
return Steinberg::kNotImplemented;
}
public:
Steinberg::tresult PLUGIN_API process(Steinberg::Vst::ProcessData& data) SMTG_OVERRIDE {
static constexpr float tuning_amounts[3][12] = {
{ 9.677f, -12.903f, 3.226f, -19.355f, -3.226f, 12.903f, -9.677f, 6.452f, -16.129f, 0.000f, -22.581f, -6.452f },
{ 48.387f, 25.806f, 41.935f, 19.355f, 35.484f, 51.613f, 29.032f, 45.161f, 22.581f, 38.710f, 16.129f, 32.258f },
{ -29.032f, -51.613f, -35.484f, -58.065f, -41.935f, -25.806f, -48.387f, -32.258f, -54.839f, -38.710f, -61.290f, -45.161f },
};
if (Steinberg::Vst::IEventList* const inputEvents = data.inputEvents) {
if (Steinberg::Vst::IEventList* const outputEvents = data.outputEvents) {
for (Steinberg::int32 i = 0, n = inputEvents->getEventCount(); i < n; ++i) {
Steinberg::Vst::Event evt;
if (!inputEvents->getEvent(i, evt)) {
switch (evt.type) {
case Steinberg::Vst::Event::kNoteOnEvent:
{
evt.noteOn.channel = 0;
evt.noteOn.tuning += tuning_amounts[evt.noteOn.channel][evt.noteOn.pitch % 12];
outputEvents->addEvent(evt);
break;
}
case Steinberg::Vst::Event::kNoteOffEvent:
{
evt.noteOff.channel = 0;
evt.noteOff.tuning += tuning_amounts[evt.noteOff.channel][evt.noteOff.pitch % 12];
outputEvents->addEvent(evt);
break;
}
case Steinberg::Vst::Event::kPolyPressureEvent:
evt.polyPressure.channel = 0;
outputEvents->addEvent(evt);
break;
case Steinberg::Vst::Event::kLegacyMIDICCOutEvent:
evt.midiCCOut.channel = 0;
outputEvents->addEvent(evt);
break;
case Steinberg::Vst::Event::kDataEvent:
case Steinberg::Vst::Event::kNoteExpressionValueEvent:
case Steinberg::Vst::Event::kNoteExpressionTextEvent:
case Steinberg::Vst::Event::kChordEvent:
case Steinberg::Vst::Event::kScaleEvent:
outputEvents->addEvent(evt);
break;
}
}
}
}
}
Steinberg::uint32 const sampleFramesSize = Steinberg::Vst::getSampleFramesSizeInBytes(processSetup, data.numSamples);
for (Steinberg::int32 i = 0, n = data.numOutputs; i < n; ++i) {
for (Steinberg::int32 j = 0, m = data.outputs[i].numChannels; j < m; ++j) {
std::memset(data.outputs[i].channelBuffers64[j], 0, sampleFramesSize);
data.outputs[i].silenceFlags |= 1ull << j;
}
}
return Steinberg::kResultOk;
}
};
class NoteTuner31Controller : public Steinberg::Vst::EditController {
public:
static Steinberg::FUnknown* createInstance(void* /*context*/) {
return static_cast<Steinberg::Vst::IEditController*>(new NoteTuner31Controller());
}
OBJ_METHODS(NoteTuner31Controller, EditController)
DEFINE_INTERFACES
END_DEFINE_INTERFACES(EditController)
REFCOUNT_METHODS(EditController)
};
BEGIN_FACTORY_DEF("Shinya Kitaoka", "https://github.com/skitaoka", "mailto:skitaoka@gmail.com")
DEF_CLASS2(
INLINE_UID_FROM_FUID(NoteTuner31ProcessorUID),
Steinberg::PClassInfo::kManyInstances,
kVstAudioEffectClass,
"NoteTuner31",
Vst::kDistributable,
Steinberg::Vst::PlugType::kInstrument,
"1.0.0",
kVstVersionString,
NoteTuner31Processor::createInstance)
DEF_CLASS2(
INLINE_UID_FROM_FUID(NoteTuner31ControllerUID),
Steinberg::PClassInfo::kManyInstances,
kVstComponentControllerClass,
"NoteTuner31Controller",
0, "",
"1.0.0",
kVstVersionString,
NoteTuner31Controller::createInstance)
END_FACTORY
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment