Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,219 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/common/logscale.h
// Created by : Steinberg, 10/2010
// Description :
//
//-----------------------------------------------------------------------------
// 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/ftypes.h"
#include "pluginterfaces/base/ustring.h"
#include "public.sdk/source/vst/vstparameters.h"
#include <cmath>
namespace Steinberg {
namespace Vst {
//-----------------------------------------------------------------------------
/** LogScale class.
Scales [srcMin srcMax] to [destMin destMax]
Scaling curve is defined by given outValue for given inValue
\section example1 Example for stretched lower range
LogScale myLogScale (0, 1, 0, 1, 0.5, 0.1); \n
means: input and output ranges are the same, but myLogScale.scale (0.5) is 0.1 ([0, 0.5, 1] => [0, 0.1, 1])
\section example2 Example for compressed lower range
LogScale myLogScale (0, 1, 0, 1, 0.5, 0.9); \n
means: input and output ranges are the same, but myLogScale.scale (0.5) is 0.9 ([0, 0.5, 1] => [0, 0.9, 1])
\section example3 Example for filter frequency range
LogScale myLogScale (0, 1, 80, 22000, 0.5, 2000); \n
means: input range is between 0 and 1 and output range is between 80 and 22000 and myLogScale.scale (0.5) is 2000
([0, 0.5, 1] => [80, 2000, 22000])
*/
template <class T>
class LogScale
{
public:
/** Constructor. */
LogScale (T srcMin, T srcMax, T destMin, T destMax, T inValue=0.5, T outValue=0.1);
/** Default Constructor with [0, 0.5, 1] => [0, 0.1, 1]. */
LogScale ();
/** Applies a new scale setting. Note that destMin should be different than destMax! The same for srcMin and srcMax. */
void changeScaling (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue);
/** Computes the scale from pIn input buffer to pOut output buffer (pIn and POut could be the same buffer). */
void scale (T* pIn, T* pOut, int32 nSamples);
/** Computes for one given value the scale. */
T scale (T input) const;
/** Computes the inverse scale from pIn input buffer to pOut output buffer (pIn and POut could be the same buffer). */
void invscale (T* pIn, T* pOut, int32 nSamples);
/** Computes for one given value the inverse scale. */
T invscale (T input) const;
/** Same than invscale with a check of the input. */
T invscaleCheck (T in) const;
protected:
void setScaling (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue);
T scaleFactor;
T scaleFactorInv;
T srcScale;
T srcScaleInv;
T srcMin;
T expo;
T expoInv;
T destMin;
};
//-----------------------------------------------------------------------------
template <class T>
LogScale<T>::LogScale (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue)
{
setScaling (srcMin, srcMax, destMin, destMax, inValue, outValue);
}
//-----------------------------------------------------------------------------
template <class T>
LogScale<T>::LogScale ()
{
setScaling (0.f, 1.f, 0.f, 1.f, 0.5f, 0.1f);
}
//-----------------------------------------------------------------------------
template <class T>
void LogScale<T>::changeScaling (T srcMin, T srcMax, T destMin, T destMax, T inValue, T outValue)
{
setScaling (srcMin, srcMax, destMin, destMax, inValue, outValue);
}
//-----------------------------------------------------------------------------
template <class T>
void LogScale<T>::setScaling (T _srcMin, T _srcMax, T _destMin, T _destMax, T inValue, T outValue)
{
srcMin = _srcMin;
destMin = _destMin;
scaleFactor = (_destMax - _destMin);
scaleFactorInv = 1.f / scaleFactor;
inValue = (inValue - _srcMin) / (_srcMax - _srcMin);
SMTG_ASSERT (inValue > 0.);
expo = ::log ((outValue - _destMin) / scaleFactor) / ::log (inValue);
expoInv = 1.f / expo;
srcScale = (_srcMax - _srcMin);
srcScaleInv = 1.f / srcScale;
}
//-----------------------------------------------------------------------------
template <class T>
void LogScale<T>::scale (T* pIn, T* pOut, int32 nSamples)
{
for (int32 i = 0; i < nSamples; i++)
pOut[i] = ::powf ((float)((pIn[i] - srcMin) * srcScaleInv), (float)expo) * scaleFactor + destMin;
}
//-----------------------------------------------------------------------------
template <class T>
T LogScale<T>::scale (T input) const
{
return ::powf ((float)((input - srcMin) * srcScaleInv), (float)expo) * scaleFactor + destMin;
}
//-----------------------------------------------------------------------------
template <class T>
void LogScale<T>::invscale (T* pIn, T* pOut, int32 nSamples)
{
for (int32 i = 0; i < nSamples; i++)
pOut[i] = ::powf ((float)((pIn[i] - destMin) * scaleFactorInv), (float)expoInv) * srcScale + srcMin;
}
//-----------------------------------------------------------------------------
template <class T>
T LogScale<T>::invscale (T input) const
{
return ::powf ((float)((input - destMin) * scaleFactorInv), (float)expoInv) * srcScale + srcMin;
}
//-----------------------------------------------------------------------------
template <class T>
T LogScale<T>::invscaleCheck (T input) const
{
T basis = (float)((input - destMin) * scaleFactorInv);
if (basis < 0.)
basis = 0.;
return ::powf ((float)basis, (float)expoInv) * srcScale + srcMin;
}
//-----------------------------------------------------------------------------
/** Parameter class with a LogScale.
Define a parameter using the LogScale.
\sa Steinberg::Vst::LogScale
*/
template <class T>
class LogScaleParameter : public Parameter
{
public:
LogScaleParameter (const TChar* title, ParamID tag, LogScale<T>& logScale,
const TChar* units = nullptr, int32 flags = ParameterInfo::kCanAutomate,
UnitID unitID = kRootUnitId)
: Parameter (title, tag, units, 0., 0, flags, unitID), logScale (logScale)
{
}
void toString (ParamValue _valueNormalized, String128 string) const SMTG_OVERRIDE
{
UString128 wrapper;
wrapper.printFloat (toPlain (_valueNormalized), precision);
wrapper.copyTo (string, 128);
}
bool fromString (const TChar* string, ParamValue& _valueNormalized) const SMTG_OVERRIDE
{
UString wrapper ((TChar*)string, strlen16 (string));
if (wrapper.scanFloat (_valueNormalized))
{
_valueNormalized = toNormalized (_valueNormalized);
return true;
}
return false;
}
ParamValue toPlain (ParamValue _valueNormalized) const SMTG_OVERRIDE
{
return logScale.scale (_valueNormalized);
}
ParamValue toNormalized (ParamValue plainValue) const SMTG_OVERRIDE
{
return logScale.invscale (plainValue);
}
OBJ_METHODS (LogScaleParameter<T>, Parameter)
protected:
LogScale<T>& logScale;
};
//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg
@@ -0,0 +1,164 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/common/voicebase.h
// Created by : Steinberg, 02/2010
// Description :
//
//-----------------------------------------------------------------------------
// 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 "base/source/fdebug.h"
#include "pluginterfaces/vst/vsttypes.h"
#ifdef DEBUG_LOG
#undef DEBUG_LOG
#endif
#define DEBUG_LOG DEVELOPMENT
namespace Steinberg {
namespace Vst {
//-----------------------------------------------------------------------------
/** Example Voice class for the Steinberg::Vst::VoiceProcessorImplementation
Implementation classes need to implement the following additional method:
\code{.cpp}
bool process (SamplePrecision* outputBuffers[numChannels], int32 numSamples);
\endcode
*/
//-----------------------------------------------------------------------------
template <uint32 numValues, class SamplePrecision, uint32 numChannels, class GlobalParameterStorage>
class VoiceBase
{
public:
/** Returns the current note id of this voice. */
int32 getNoteId () const { return noteId; }
/** Sets a new GlobalParameterStorage. */
virtual void setGlobalParameterStorage (GlobalParameterStorage* globalParameters)
{
this->globalParameters = globalParameters;
}
/** Sets the sampleRate. */
virtual void setSampleRate (ParamValue sampleRate) { this->sampleRate = sampleRate; }
/** Returns the sampleRate. */
float getSampleRate () const { return (float)sampleRate; }
virtual void setNoteExpressionValue (int32 index, ParamValue value)
{
if (index < numValues)
values[index] = value;
}
virtual void noteOn (int32 pitch, ParamValue velocity, float tuning, int32 sampleOffset,
int32 noteId);
virtual void noteOff (ParamValue velocity, int32 sampleOffset);
virtual void reset ()
{
noteOnSampleOffset = -1;
noteOffSampleOffset = -1;
noteId = -1;
tuning = 0;
}
//-----------------------------------------------------------------------------
protected:
VoiceBase ();
VoiceBase (const VoiceBase& vb);
virtual ~VoiceBase ();
GlobalParameterStorage* globalParameters;
int32 noteId;
int32 pitch;
int32 noteOnSampleOffset;
int32 noteOffSampleOffset;
float tuning {0};
ParamValue sampleRate;
ParamValue noteOnVelocity;
ParamValue noteOffVelocity;
ParamValue values[numValues];
};
//-----------------------------------------------------------------------------
template <uint32 numValues, class SamplePrecision, uint32 numChannels, class GlobalParameterStorage>
VoiceBase<numValues, SamplePrecision, numChannels, GlobalParameterStorage>::VoiceBase ()
: globalParameters (0)
, noteId (-1)
, pitch (-1)
, noteOnSampleOffset (0)
, noteOffSampleOffset (0)
, sampleRate (44100.)
, noteOnVelocity (0.)
, noteOffVelocity (0.)
, values {0}
{
}
//-----------------------------------------------------------------------------
template <uint32 numValues, class SamplePrecision, uint32 numChannels, class GlobalParameterStorage>
VoiceBase<numValues, SamplePrecision, numChannels, GlobalParameterStorage>::VoiceBase (
const VoiceBase<numValues, SamplePrecision, numChannels, GlobalParameterStorage>& vb)
: globalParameters (vb.globalParameters)
, noteId (vb.noteId)
, pitch (vb.pitch)
, noteOnSampleOffset (vb.noteOnSampleOffset)
, noteOffSampleOffset (vb.noteOffSampleOffset)
, noteOnVelocity (vb.noteOnVelocity)
, noteOffVelocity (vb.noteOffVelocity)
, sampleRate (vb.sampleRate)
{
for (uint32 i = 0; i < numValues; i++)
values[i] = vb.values[i];
}
//-----------------------------------------------------------------------------
template <uint32 numValues, class SamplePrecision, uint32 numChannels, class GlobalParameterStorage>
VoiceBase<numValues, SamplePrecision, numChannels, GlobalParameterStorage>::~VoiceBase ()
{
}
//-----------------------------------------------------------------------------
template <uint32 numValues, class SamplePrecision, uint32 numChannels, class GlobalParameterStorage>
void VoiceBase<numValues, SamplePrecision, numChannels, GlobalParameterStorage>::noteOn (
int32 pitch, ParamValue velocity, float tuning, int32 sampleOffset, int32 nId)
{
this->pitch = pitch;
noteOnVelocity = velocity;
noteOnSampleOffset = sampleOffset;
noteId = nId;
this->tuning = tuning;
#if DEBUG_LOG
FDebugPrint ("NoteOn :%d\n", nId);
#endif
}
//-----------------------------------------------------------------------------
template <uint32 numValues, class SamplePrecision, uint32 numChannels, class GlobalParameterStorage>
void VoiceBase<numValues, SamplePrecision, numChannels, GlobalParameterStorage>::noteOff (
ParamValue velocity, int32 sampleOffset)
{
noteOffVelocity = velocity;
noteOffSampleOffset = sampleOffset;
#if DEBUG_LOG
FDebugPrint ("NoteOff:%d\n", this->noteId);
#endif
}
//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg
@@ -0,0 +1,438 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Examples
// Filename : public.sdk/samples/vst/common/voiceprocessor.h
// Created by : Steinberg, 02/2010
// Description :
//
//-----------------------------------------------------------------------------
// 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 "base/source/fdebug.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivstevents.h"
#include <algorithm>
#ifdef DEBUG_LOG
#undef DEBUG_LOG
#endif
#define DEBUG_LOG DEVELOPMENT
#ifndef VOICEPROCESSOR_BLOCKSIZE
#define VOICEPROCESSOR_BLOCKSIZE 32
#endif
namespace Steinberg {
namespace Vst {
//-----------------------------------------------------------------------------
/** A Voice Processor class.
A virtual base class for a voice manager implementation.
The idea behind this class is to make it easier to support either single precision or double
precision samples (float or double) or different channel layouts.
Example:
\code{.cpp}
//------------------------------------------------------------------------
class MySynthProcessor : public AudioEffect
{
public:
tresult PLUGIN_API setActive (TBool state);
tresult PLUGIN_API process (ProcessData& data);
protected:
VoiceProcessor* voiceProcessor;
};
//------------------------------------------------------------------------
tresult PLUGIN_API MySynthProcessor::setActive (TBool state)
{
if (state)
{
if (processSetup.symbolicSampleSize == kSample32)
voiceProcessor = new VoiceProcessorImplementation<float, Voice<float>, 2, MAX_VOICES, void> (processSetup.sampleRate, 0);
else if (processSetup.symbolicSampleSize == kSample64)
voiceProcessor = new VoiceProcessorImplementation<double, Voice<double>, 2, MAX_VOICES, void> (processSetup.sampleRate, 0);
else
return kInvalidArgument;
}
else
{
delete voiceProcessor;
voiceProcessor = 0;
}
return kResultTrue;
}
//------------------------------------------------------------------------
tresult PLUGIN_API MySynthProcessor::process (ProcessData& data)
{
return voiceProcessor->process (data);
}
\endcode
\sa Steinberg::Vst::VoiceProcessorImplementation
*/
//-----------------------------------------------------------------------------
class VoiceProcessor
{
public:
VoiceProcessor () {}
virtual ~VoiceProcessor () {}
virtual tresult process (ProcessData& data) = 0;
virtual void processEvent (Event evt) = 0;
virtual void clearAllVoices ()
{
activeVoices = 0;
}
/** Returns the number of active voices. */
int32 getActiveVoices () const { return activeVoices; }
void clearOutputNeeded (bool val) { mClearOutputNeeded = val; }
protected:
int32 activeVoices {0};
bool mClearOutputNeeded {true};
};
//-----------------------------------------------------------------------------
/** A Simple Voice Processor Implementation supporting note expression events.
\param Precision must be either float or double
\param VoiceClass the voice class
\param numChannels number of channels
\param maxVoices number of maximum voices
\param GlobalParameterStorage a class holding global parameters
The VoiceClass must implement the following methods:
\code{.cpp}
int32 getNoteId () const;
void setGlobalParameterStorage (GlobalParameterStorage* globalParameters);
void setSampleRate (ParamValue sampleRate);
void setNoteExpressionValue (int32 index, ParamValue value);
void noteOn (int32 pitch, ParamValue velocity, float tuning, int32 sampleOffset, int32 noteId);
void noteOff (ParamValue velocity, int32 sampleOffset);
bool process (SamplePrecision* outputBuffers[numChannels], int32 numSamples);
void reset ()
\endcode
See \ref Steinberg::Vst::VoiceBase for an example base class.
This implementation does not support advanced features like voice stealing when maxVoices is
reached, etc ...
*/
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
class VoiceProcessorImplementation : public VoiceProcessor
{
public:
VoiceProcessorImplementation (float sampleRate, GlobalParameterStorage* globalParameters = 0);
~VoiceProcessorImplementation () override;
tresult process (ProcessData& data) override;
void processEvent (Event evt) override;
void clearAllVoices () override;
protected:
VoiceClass* getVoice (int32 noteId);
VoiceClass* findVoice (int32 noteId);
VoiceClass voices[maxVoices];
};
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
VoiceProcessorImplementation<
Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::VoiceProcessorImplementation (float sampleRate,
GlobalParameterStorage* globalParameters)
{
for (int32 i = 0; i < maxVoices; i++)
{
voices[i].setGlobalParameterStorage (globalParameters);
voices[i].setSampleRate (sampleRate);
voices[i].reset ();
}
}
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::~VoiceProcessorImplementation ()
{
}
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
VoiceClass* VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::getVoice (int32 noteId)
{
VoiceClass* firstFreeVoice = 0;
if (noteId != -1)
{
for (int32 i = 0; i < maxVoices; i++)
{
if (voices[i].getNoteId () == noteId)
{
return &voices[i];
}
else if (firstFreeVoice == 0 && voices[i].getNoteId () == -1)
{
firstFreeVoice = &voices[i];
}
}
}
return firstFreeVoice;
}
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
VoiceClass* VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::findVoice (int32 noteId)
{
if (noteId != -1)
{
for (int32 i = 0; i < maxVoices; i++)
{
if (voices[i].getNoteId () == noteId)
{
return &voices[i];
}
}
}
return 0;
}
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
void VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::clearAllVoices ()
{
for (int32 i = 0; i < maxVoices; i++)
{
if (voices[i].getNoteId () != -1)
voices[i].reset ();
}
VoiceProcessor::clearAllVoices ();
}
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
void VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::processEvent (Event e)
{
switch (e.type)
{
//--- --------------------
case Event::kNoteOnEvent:
{
if (e.noteOn.noteId == -1)
e.noteOn.noteId = e.noteOn.pitch;
VoiceClass* voice = getVoice (e.noteOn.noteId);
if (voice)
{
voice->noteOn (e.noteOn.pitch, e.noteOn.velocity, e.noteOn.tuning, e.sampleOffset,
e.noteOn.noteId);
this->activeVoices++;
// data.outputEvents->addEvent (e);
}
break;
}
//--- --------------------
case Event::kNoteOffEvent:
{
if (e.noteOff.noteId == -1)
e.noteOff.noteId = e.noteOff.pitch;
VoiceClass* voice = findVoice (e.noteOff.noteId);
if (voice)
{
voice->noteOff (e.noteOff.velocity, e.sampleOffset);
// data.outputEvents->addEvent (e);
}
#if DEBUG_LOG
else
{
FDebugPrint ("Voice for kNoteOffEvent not found : %d\n", e.noteOff.noteId);
}
#endif
break;
}
//--- --------------------
case Event::kNoteExpressionValueEvent:
{
VoiceClass* voice = findVoice (e.noteExpressionValue.noteId);
if (voice)
{
voice->setNoteExpressionValue (e.noteExpressionValue.typeId,
e.noteExpressionValue.value);
// data.outputEvents->addEvent (e);
}
#if DEBUG_LOG
else
{
FDebugPrint ("Voice for kNoteExpressionValueEvent not found : %d\n",
e.noteExpressionValue.noteId);
}
#endif
break;
}
}
}
//-----------------------------------------------------------------------------
#if VOICEPROCESSOR_BLOCKSIZE <= 0 // voice processing happens in chunks of the block size
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
tresult VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::process (ProcessData& data)
{
if (mClearOutputNeeded)
for (int32 i = 0; i < numChannels; i++)
memset (data.outputs[0].channelBuffers32[i], 0, data.numSamples * sizeof (Precision));
IEventList* inputEvents = data.inputEvents;
if (inputEvents)
{
Event e;
int32 numEvents = inputEvents->getEventCount ();
for (int32 i = 0; i < numEvents; i++)
{
if (inputEvents->getEvent (i, e) == kResultTrue)
{
processEvent (e);
}
}
}
for (int32 i = 0; i < maxVoices; i++)
{
if (voices[i].getNoteId () != -1)
{
if (!voices[i].process ((Precision**)data.outputs[0].channelBuffers32, data.numSamples))
{
voices[i].reset ();
this->activeVoices--;
}
}
}
return kResultTrue;
}
//-----------------------------------------------------------------------------
#else // voice processing happens in chunks of VOICEPROCESSOR_BLOCKSIZE samples
//-----------------------------------------------------------------------------
template <class Precision, class VoiceClass, int32 numChannels, int32 maxVoices,
class GlobalParameterStorage>
tresult VoiceProcessorImplementation<Precision, VoiceClass, numChannels, maxVoices,
GlobalParameterStorage>::process (ProcessData& data)
{
const int32 kBlockSize = VOICEPROCESSOR_BLOCKSIZE;
int32 numSamples = data.numSamples;
int32 samplesProcessed = 0;
IEventList* inputEvents = data.inputEvents;
Event e = {};
Event* eventPtr = nullptr;
int32 eventIndex = 0;
int32 numEvents = inputEvents ? inputEvents->getEventCount () : 0;
// get the first event
if (numEvents)
{
inputEvents->getEvent (0, e);
eventPtr = &e;
}
// initialize audio output buffers
Precision* buffers[numChannels];
for (int32 i = 0; i < numChannels; i++)
{
buffers[i] = (Precision*)data.outputs[0].channelBuffers32[i];
if (mClearOutputNeeded)
memset (buffers[i], 0, data.numSamples * sizeof (Precision));
}
while (numSamples > 0)
{
int32 samplesToProcess = std::min<int32> (kBlockSize, numSamples);
while (eventPtr != nullptr)
{
// if the event is not in the current processing block then adapt offset for next block
if (e.sampleOffset > samplesToProcess)
{
e.sampleOffset -= samplesToProcess;
break;
}
processEvent (e);
// get next event
eventIndex++;
if (eventIndex < numEvents)
{
if (inputEvents->getEvent (eventIndex, e) == kResultTrue)
{
e.sampleOffset -= samplesProcessed;
}
else
{
eventPtr = nullptr;
}
}
else
{
eventPtr = nullptr;
}
} // end while (event != 0)
// now process the block
for (int32 i = 0; i < maxVoices; i++)
{
if (voices[i].getNoteId () != -1)
{
if (!voices[i].process (buffers, samplesToProcess))
{
voices[i].reset ();
this->activeVoices--;
}
}
}
// update the counters
for (int32 i = 0; i < numChannels; i++)
buffers[i] += samplesToProcess;
numSamples -= samplesToProcess;
samplesProcessed += samplesToProcess;
} // end while (numSamples > 0)
return kResultTrue;
}
#endif
//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg