Initial release
This commit is contained in:
+522
@@ -0,0 +1,522 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plug.cpp
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "plug.h"
|
||||
#include "plugcids.h" // for class ids
|
||||
#include "plugparamids.h"
|
||||
|
||||
#include "public.sdk/source/vst/vsteventshelper.h"
|
||||
#include "pluginterfaces/base/futils.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/vst/ivstevents.h"
|
||||
#include "pluginterfaces/vst/ivstmidicontrollers.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
|
||||
#include "base/source/fstreamer.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace LegacyMIDICCOut {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Plug Implementation
|
||||
//------------------------------------------------------------------------
|
||||
Plug::Plug ()
|
||||
{
|
||||
// register its editor class (the same than used in plugentry.cpp)
|
||||
setControllerClass (PlugControllerUID);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::initialize (FUnknown* context)
|
||||
{
|
||||
//---always initialize the parent-------
|
||||
tresult result = AudioEffect::initialize (context);
|
||||
// if everything Ok, continue
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//---create Audio In/Out busses------
|
||||
// we want a stereo Input and a Stereo Output
|
||||
addAudioInput (STR16 ("Stereo In"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR16 ("Stereo Out"), SpeakerArr::kStereo);
|
||||
|
||||
// one output for event and only 1 channel wanted
|
||||
addEventOutput (STR16 ("Event Out"), kMaxMIDIChannelSupported);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::process (ProcessData& data)
|
||||
{
|
||||
//---1) Read inputs parameter changes-----------
|
||||
if (IParameterChanges* paramChanges = data.inputParameterChanges)
|
||||
{
|
||||
IEventList* eventList = data.outputEvents;
|
||||
|
||||
int32 numParamsChanged = paramChanges->getParameterCount ();
|
||||
// for each parameter which are some changes in this audio block:
|
||||
for (int32 i = 0; i < numParamsChanged; i++)
|
||||
{
|
||||
IParamValueQueue* paramQueue = paramChanges->getParameterData (i);
|
||||
if (!paramQueue)
|
||||
continue;
|
||||
|
||||
int32 offsetSamples;
|
||||
double value;
|
||||
int32 numPoints = paramQueue->getPointCount ();
|
||||
ParamID id = paramQueue->getParameterId ();
|
||||
switch (id)
|
||||
{
|
||||
//--- ----------------------------------------------
|
||||
case kBypassId:
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
bBypass = (value > 0.5f);
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kChannelId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
mChannel = FromNormalized<ParamValue> (value, kMaxMIDIChannelSupported - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kControllerNumId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
mControllerNum = FromNormalized<ParamValue> (value, 127);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kControllerId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastController)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, mControllerNum, mChannel,
|
||||
newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
event.flags = Event::kIsLive;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastController = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kAftertouchId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastAftertouch)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kAfterTouch, mChannel,
|
||||
newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastAftertouch = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kProgramChangeId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastProgramChange)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kCtrlProgramChange,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastProgramChange = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kPolyPressureNoteId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
mPolyPressureKey = Helpers::boundTo<uint8> (
|
||||
0, 127, FromNormalized<ParamValue> (value, 127));
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kPolyPressureId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastPolyPressure)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (
|
||||
event, kCtrlPolyPressure, mChannel, mPolyPressureKey, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastPolyPressure = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kPitchBendId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDI14BitValue (value);
|
||||
if (newValue != mLastPitchBend)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kPitchBend, mChannel);
|
||||
Helpers::setPitchBendValue (event.midiCCOut, value);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastPitchBend = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kCtrlQuarterFrameId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastCtrlQuarterFrame)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kCtrlQuarterFrame,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastCtrlQuarterFrame = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemSongSelectId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastSystemSongSelect)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemSongSelect,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemSongSelect = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemSongPointerId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDI14BitValue (value);
|
||||
if (newValue != mLastSystemSongPointer)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
///< use LegacyMIDICCOutEvent.value for LSB and
|
||||
/// LegacyMIDICCOutEvent.value2 for MSB
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemSongPointer,
|
||||
mChannel);
|
||||
Helpers::setPitchBendValue (event.midiCCOut, value);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemSongPointer = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemCableSelectId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = Helpers::getMIDICCOutValue (value);
|
||||
if (newValue != mLastSystemCableSelect)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemCableSelect,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemCableSelect = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemTuneRequestId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = value >= 0.5 ? 127 : 0;
|
||||
if (newValue != mLastSystemTuneRequest)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemTuneRequest,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemTuneRequest = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemMidiClockStartId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = value >= 0.5 ? 127 : 0;
|
||||
if (newValue != mLastSystemMidiClockStart)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemMidiClockStart,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemMidiClockStart = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//--- ----------------------------------------------
|
||||
case kSystemMidiClockContinueId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = value >= 0.5 ? 127 : 0;
|
||||
if (newValue != mLastSystemMidiClockContinue)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemMidiClockContinue,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemMidiClockContinue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemMidiClockStopId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = value >= 0.5 ? 127 : 0;
|
||||
if (newValue != mLastSystemMidiClockStop)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemMidiClockStop,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemMidiClockStop = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- ----------------------------------------------
|
||||
case kSystemActiveSensingId:
|
||||
{
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
auto newValue = value >= 0.5 ? 127 : 0;
|
||||
if (newValue != mLastSystemActiveSensing)
|
||||
{
|
||||
if (eventList && !bBypass)
|
||||
{
|
||||
Event event {};
|
||||
Helpers::initLegacyMIDICCOutEvent (event, kSystemActiveSensing,
|
||||
mChannel, newValue);
|
||||
event.sampleOffset = offsetSamples;
|
||||
eventList->addEvent (event);
|
||||
}
|
||||
mLastSystemActiveSensing = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- ----------------------------------
|
||||
//---3) Process Audio---------------------
|
||||
//--- ----------------------------------
|
||||
if (data.numInputs == 0 || data.numOutputs == 0)
|
||||
{
|
||||
// nothing to do
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
// (simplification) we suppose in this example that we have the same input channel count than
|
||||
// the output
|
||||
int32 numChannels = data.inputs[0].numChannels;
|
||||
|
||||
//---get audio buffers----------------
|
||||
float** in = data.inputs[0].channelBuffers32;
|
||||
float** out = data.outputs[0].channelBuffers32;
|
||||
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be copied if the buffers are the same
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memcpy (out[i], in[i], data.numSamples * sizeof (float));
|
||||
}
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::setState (IBStream* state)
|
||||
{
|
||||
// called when we load a preset, the model has to be reloaded
|
||||
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
// read the bypass
|
||||
int32 savedBypass = 0;
|
||||
if (streamer.readInt32 (savedBypass) == false)
|
||||
return kResultFalse;
|
||||
|
||||
bBypass = savedBypass > 0;
|
||||
|
||||
streamer.readInt8u (mChannel);
|
||||
streamer.readInt8u (mControllerNum);
|
||||
streamer.readInt8u (mPolyPressureKey);
|
||||
|
||||
streamer.readInt8 (mLastController);
|
||||
streamer.readInt8 (mLastProgramChange);
|
||||
streamer.readInt8 (mLastAftertouch);
|
||||
streamer.readInt8 (mLastPolyPressure);
|
||||
streamer.readInt16 (mLastPitchBend);
|
||||
|
||||
streamer.readInt8 (mLastCtrlQuarterFrame);
|
||||
streamer.readInt8 (mLastSystemSongSelect);
|
||||
streamer.readInt16 (mLastSystemSongPointer);
|
||||
streamer.readInt8 (mLastSystemCableSelect);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::getState (IBStream* state)
|
||||
{
|
||||
// here we need to save the model
|
||||
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
streamer.writeInt32 (bBypass ? 1 : 0);
|
||||
|
||||
streamer.writeInt8u (mChannel);
|
||||
streamer.writeInt8u (mControllerNum);
|
||||
streamer.writeInt8u (mPolyPressureKey);
|
||||
|
||||
streamer.writeInt8 (mLastController);
|
||||
streamer.writeInt8 (mLastProgramChange);
|
||||
streamer.writeInt8 (mLastAftertouch);
|
||||
streamer.writeInt8 (mLastPolyPressure);
|
||||
streamer.writeInt16 (mLastPitchBend);
|
||||
|
||||
streamer.writeInt8 (mLastCtrlQuarterFrame);
|
||||
streamer.writeInt8 (mLastSystemSongSelect);
|
||||
streamer.writeInt16 (mLastSystemSongPointer);
|
||||
streamer.writeInt8 (mLastSystemCableSelect);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace LegacyMIDICCOut
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,78 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plug.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioeffect.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace LegacyMIDICCOut {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Plug: directly derived from the helper class AudioEffect
|
||||
//------------------------------------------------------------------------
|
||||
class Plug : public AudioEffect
|
||||
{
|
||||
public:
|
||||
Plug ();
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this plug-in
|
||||
//--- ---------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void* /*context*/) { return (IAudioProcessor*)new Plug; }
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// AudioEffect overrides:
|
||||
//--- ---------------------------------------------------------------------
|
||||
/** Called at first after constructor */
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
|
||||
/** Here we go...the process call */
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
|
||||
/** For persistence */
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
int8 mLastController {0};
|
||||
int8 mLastProgramChange {0};
|
||||
int8 mLastAftertouch {0};
|
||||
int8 mLastPolyPressure {0};
|
||||
int16 mLastPitchBend {0};
|
||||
|
||||
int8 mLastCtrlQuarterFrame {0};
|
||||
int8 mLastSystemSongSelect {0};
|
||||
int16 mLastSystemSongPointer {0};
|
||||
int8 mLastSystemCableSelect {0};
|
||||
int8 mLastSystemTuneRequest {0};
|
||||
int8 mLastSystemMidiClockStart {0};
|
||||
int8 mLastSystemMidiClockContinue {0};
|
||||
int8 mLastSystemMidiClockStop {0};
|
||||
int8 mLastSystemActiveSensing {0};
|
||||
|
||||
uint8 mChannel {0};
|
||||
uint8 mControllerNum {11};
|
||||
uint8 mPolyPressureKey {36};
|
||||
|
||||
bool bBypass {false};
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace LegacyMIDICCOut
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plugcids.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace LegacyMIDICCOut {
|
||||
static const FUID PlugProcessorUID (0x5DDBB0D4, 0xF9284622, 0x90FE5A5E, 0x1414905A);
|
||||
static const FUID PlugControllerUID (0x9F34E8E9, 0x22FC42E6, 0x993C6007, 0x642512C9);
|
||||
}
|
||||
}
|
||||
} // namespaces
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plugcontroller.cpp
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "plugcontroller.h"
|
||||
#include "plugparamids.h"
|
||||
|
||||
#include "public.sdk/source/vst/vsteventshelper.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
#include "pluginterfaces/base/futils.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/vst/ivstcomponent.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace LegacyMIDICCOut {
|
||||
//------------------------------------------------------------------------
|
||||
// PlugController Implementation
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API PlugController::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = EditControllerEx1::initialize (context);
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//---Create Parameters------------
|
||||
|
||||
//---Bypass parameter---
|
||||
int32 stepCount = 1;
|
||||
ParamValue defaultVal = 0;
|
||||
int32 flags = ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass;
|
||||
int32 tag = kBypassId;
|
||||
parameters.addParameter (STR ("Bypass"), nullptr, stepCount, defaultVal, flags, tag);
|
||||
|
||||
//---Controller parameter - only for demo ---
|
||||
parameters.addParameter (new RangeParameter (
|
||||
STR16 ("MIDI Channel"), kChannelId, nullptr, 1, kMaxMIDIChannelSupported, 1,
|
||||
kMaxMIDIChannelSupported - 1, ParameterInfo::kNoFlags));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("Controller Num"), kControllerNumId,
|
||||
nullptr, 0., 127., 0., 127,
|
||||
ParameterInfo::kCanAutomate));
|
||||
parameters.addParameter (new RangeParameter (STR16 ("Controller"), kControllerId, nullptr, 0.,
|
||||
127., 0., 127, ParameterInfo::kCanAutomate));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("PitchBend"), kPitchBendId, nullptr,
|
||||
-0x2000, 0x1FFF, 0, 0x3FFF,
|
||||
ParameterInfo::kCanAutomate));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("ProgramChange"), kProgramChangeId, nullptr,
|
||||
1., 128., 1., 127, ParameterInfo::kCanAutomate));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("PolyPressure Key"), kPolyPressureNoteId,
|
||||
nullptr, 0., 127., 0., 127,
|
||||
ParameterInfo::kCanAutomate));
|
||||
parameters.addParameter (new RangeParameter (STR16 ("PolyPressure"), kPolyPressureId, nullptr,
|
||||
0., 127., 0., 127, ParameterInfo::kCanAutomate));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("Aftertouch"), kAftertouchId, nullptr, 0.,
|
||||
127., 0., 127, ParameterInfo::kCanAutomate));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("CtrlQuarterFrame"), kCtrlQuarterFrameId,
|
||||
nullptr, 0., 127., 0., 127,
|
||||
ParameterInfo::kCanAutomate));
|
||||
parameters.addParameter (new RangeParameter (STR16 ("SystemSongSelect"), kSystemSongSelectId,
|
||||
nullptr, 0., 127., 0., 127,
|
||||
ParameterInfo::kCanAutomate));
|
||||
parameters.addParameter (new RangeParameter (STR16 ("SystemSongPointer"), kSystemSongPointerId,
|
||||
nullptr, 0x0000, 0x3FFF, 0, 0x3FFF,
|
||||
ParameterInfo::kCanAutomate));
|
||||
|
||||
parameters.addParameter (new RangeParameter (STR16 ("SystemCableSelect"), kSystemCableSelectId,
|
||||
nullptr, 0., 127., 0., 127,
|
||||
ParameterInfo::kCanAutomate));
|
||||
parameters.addParameter (STR ("SystemTuneRequest"), nullptr, 1, 0, ParameterInfo::kCanAutomate,
|
||||
kSystemTuneRequestId);
|
||||
parameters.addParameter (STR ("SystemMidiClockStart"), nullptr, 1, 0,
|
||||
ParameterInfo::kCanAutomate, kSystemMidiClockStartId);
|
||||
parameters.addParameter (STR ("SystemMidiClockContinue"), nullptr, 1, 0,
|
||||
ParameterInfo::kCanAutomate, kSystemMidiClockContinueId);
|
||||
parameters.addParameter (STR ("SystemMidiClockStop"), nullptr, 1, 0,
|
||||
ParameterInfo::kCanAutomate, kSystemMidiClockStopId);
|
||||
parameters.addParameter (STR ("SystemActiveSensing"), nullptr, 1, 0,
|
||||
ParameterInfo::kCanAutomate, kSystemActiveSensingId);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API PlugController::setComponentState (IBStream* state)
|
||||
{
|
||||
// we receive the current state of the component (processor part)
|
||||
// we read only the gain and bypass value...
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
// read the bypass
|
||||
int32 bypassState = 0;
|
||||
if (streamer.readInt32 (bypassState) == false)
|
||||
return kResultFalse;
|
||||
setParamNormalized (kBypassId, bypassState ? 1 : 0);
|
||||
|
||||
uint8 ui8Val;
|
||||
if (streamer.readInt8u (ui8Val) == true)
|
||||
setParamNormalized (kChannelId, ToNormalized<ParamValue> (ui8Val, kMaxMIDIChannelSupported - 1));
|
||||
|
||||
if (streamer.readInt8u (ui8Val) == true)
|
||||
setParamNormalized (kControllerNumId, Helpers::getMIDINormValue (ui8Val));
|
||||
|
||||
if (streamer.readInt8u (ui8Val) == true)
|
||||
setParamNormalized (kPolyPressureNoteId, Helpers::getMIDINormValue (ui8Val));
|
||||
|
||||
int8 i8Val;
|
||||
int16 i16Val;
|
||||
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kControllerId, Helpers::getMIDINormValue (i8Val));
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kProgramChangeId, Helpers::getMIDINormValue (i8Val));
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kAftertouchId, Helpers::getMIDINormValue (i8Val));
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kPolyPressureId, Helpers::getMIDINormValue (i8Val));
|
||||
if (streamer.readInt16 (i16Val) == true)
|
||||
setParamNormalized (kPitchBendId, Helpers::getMIDI14BitNormValue (i16Val));
|
||||
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kCtrlQuarterFrameId, Helpers::getMIDINormValue (i8Val));
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kSystemSongSelectId, Helpers::getMIDINormValue (i8Val));
|
||||
|
||||
if (streamer.readInt16 (i16Val) == true)
|
||||
setParamNormalized (kSystemSongPointerId, Helpers::getMIDI14BitNormValue (i16Val));
|
||||
|
||||
if (streamer.readInt8 (i8Val) == true)
|
||||
setParamNormalized (kSystemCableSelectId, Helpers::getMIDINormValue (i8Val));
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace LegacyMIDICCOut
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plugcontroller.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace LegacyMIDICCOut {
|
||||
//------------------------------------------------------------------------
|
||||
// PlugController
|
||||
//------------------------------------------------------------------------
|
||||
class PlugController : public EditControllerEx1
|
||||
{
|
||||
public:
|
||||
//--- ---------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this controller
|
||||
//--- ---------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void* /*context*/) { return (IEditController*)new PlugController; }
|
||||
|
||||
//---from IPluginBase--------
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
|
||||
//---from EditControllerEx1-----
|
||||
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
|
||||
|
||||
DELEGATE_REFCOUNT (EditControllerEx1)
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace LegacyMIDICCOut
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plugentry.cpp
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "plug.h"
|
||||
#include "plugcontroller.h"
|
||||
#include "plugcids.h" // for class ids
|
||||
#include "version.h" // for versioning
|
||||
|
||||
#include "public.sdk/source/main/pluginfactory.h"
|
||||
|
||||
#define stringPluginName "Test Legacy MIDI CC Out"
|
||||
|
||||
using namespace Steinberg;
|
||||
using namespace Steinberg::Vst;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// VST Plug-in Entry
|
||||
//------------------------------------------------------------------------
|
||||
// Windows: do not forget to include a .def file in your project to export
|
||||
// GetPluginFactory function!
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
BEGIN_FACTORY_DEF (stringCompanyName, stringCompanyWeb, stringCompanyEmail)
|
||||
|
||||
//---First plug-in included in this factory-------
|
||||
// its kVstAudioEffectClass component
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID(LegacyMIDICCOut::PlugProcessorUID),
|
||||
PClassInfo::kManyInstances, // cardinality
|
||||
kVstAudioEffectClass, // the component category (do not change this)
|
||||
stringPluginName, // here the plug-in name (to be changed)
|
||||
Vst::kDistributable, // means that component and controller could be distributed on different computers
|
||||
"Fx", // Subcategory for this plug-in (to be changed)
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString, // the VST 3 SDK version (do not change this, always use this define)
|
||||
LegacyMIDICCOut::Plug::createInstance) // function pointer called when this component should be instantiated
|
||||
|
||||
// its kVstComponentControllerClass component
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (LegacyMIDICCOut::PlugControllerUID),
|
||||
PClassInfo::kManyInstances, // cardinality
|
||||
kVstComponentControllerClass,// the Controller category (do not change this)
|
||||
stringPluginName "Controller", // controller name (can be the same as the component name)
|
||||
0, // not used here
|
||||
"", // not used here
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString, // the VST 3 SDK version (do not change this, always use this define)
|
||||
LegacyMIDICCOut::PlugController::createInstance)// function pointer called when this component should be instantiated
|
||||
|
||||
END_FACTORY
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/plugparamids.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
/** parameter ID */
|
||||
kBypassId = 0, ///< Bypass value (we will handle the bypass process) (is automatable)
|
||||
|
||||
kChannelId,
|
||||
kControllerNumId,
|
||||
kControllerId,
|
||||
kProgramChangeId,
|
||||
kPitchBendId,
|
||||
kPolyPressureNoteId,
|
||||
kPolyPressureId,
|
||||
kAftertouchId,
|
||||
|
||||
kCtrlQuarterFrameId,
|
||||
kSystemSongSelectId,
|
||||
kSystemSongPointerId,
|
||||
kSystemCableSelectId,
|
||||
kSystemTuneRequestId,
|
||||
kSystemMidiClockStartId,
|
||||
kSystemMidiClockContinueId,
|
||||
kSystemMidiClockStopId,
|
||||
kSystemActiveSensingId,
|
||||
|
||||
//--- others
|
||||
kMaxMIDIChannelSupported = 16
|
||||
};
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/legacymidiccout/source/version.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : Plug-in Example for VST SDK 3.x using Legacy MIDI CC
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/fplatform.h"
|
||||
|
||||
// Plain project version file generated by cmake
|
||||
#include "projectversion.h"
|
||||
|
||||
#define stringOriginalFilename "legacymidiccout.vst3"
|
||||
#if SMTG_PLATFORM_64
|
||||
#define stringFileDescription "LegacyMIDICCOut VST3-SDK (64Bit)"
|
||||
#else
|
||||
#define stringFileDescription "LegacyMIDICCOut VST3-SDK"
|
||||
#endif
|
||||
#define stringCompanyWeb "http://www.steinberg.net"
|
||||
#define stringCompanyEmail "mailto:info@steinberg.de"
|
||||
#define stringCompanyName "Steinberg Media Technologies"
|
||||
#define stringLegalCopyright "© 2025 Steinberg Media Technologies"
|
||||
#define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH"
|
||||
Reference in New Issue
Block a user