Files
hot-step-cpp-ROCm/engine/vendor/vst3sdk/public.sdk/source/vst/hosting/parameterchanges.cpp
T
2026-08-16 18:24:52 +07:00

299 lines
8.1 KiB
C++

//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/parameterchanges.cpp
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 parameter changes implementation
//
//-----------------------------------------------------------------------------
// 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 "parameterchanges.h"
namespace Steinberg {
namespace Vst {
//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (ParameterChanges, IParameterChanges, IParameterChanges::iid)
IMPLEMENT_FUNKNOWN_METHODS (ParameterValueQueue, IParamValueQueue, IParamValueQueue::iid)
constexpr int32 kQueueReservedPoints = 5;
//-----------------------------------------------------------------------------
ParameterValueQueue::ParameterValueQueue (ParamID paramID)
: paramID (paramID)
{
values.reserve (kQueueReservedPoints);
FUNKNOWN_CTOR
}
//-----------------------------------------------------------------------------
ParameterValueQueue::~ParameterValueQueue ()
{
FUNKNOWN_DTOR
}
//-----------------------------------------------------------------------------
void ParameterValueQueue::clear ()
{
values.clear ();
}
//-----------------------------------------------------------------------------
int32 PLUGIN_API ParameterValueQueue::getPointCount ()
{
return static_cast<int32> (values.size ());
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ParameterValueQueue::getPoint (int32 index, int32& sampleOffset, ParamValue& value)
{
if (index >= 0 && index < static_cast<int32> (values.size ()))
{
const ParameterQueueValue& queueValue = values[index];
sampleOffset = queueValue.sampleOffset;
value = queueValue.value;
return kResultTrue;
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API ParameterValueQueue::addPoint (int32 sampleOffset, ParamValue value, int32& index)
{
auto destIndex = static_cast<int32>(values.size ());
for (uint32 i = 0; i < values.size (); i++)
{
if (values[i].sampleOffset == sampleOffset)
{
values[i].value = value;
index = i;
return kResultTrue;
}
if (values[i].sampleOffset > sampleOffset)
{
destIndex = i;
break;
}
}
// need new point
ParameterQueueValue queueValue (value, sampleOffset);
if (destIndex == static_cast<int32> (values.size ()))
values.emplace_back (queueValue);
else
values.insert (values.begin () + destIndex, queueValue);
index = destIndex;
return kResultTrue;
}
//-----------------------------------------------------------------------------
// ParameterChanges
//-----------------------------------------------------------------------------
ParameterChanges::ParameterChanges (int32 maxParameters)
{
FUNKNOWN_CTOR
setMaxParameters (maxParameters);
}
//-----------------------------------------------------------------------------
ParameterChanges::~ParameterChanges ()
{
FUNKNOWN_DTOR
}
//-----------------------------------------------------------------------------
void ParameterChanges::setMaxParameters (int32 maxParameters)
{
if (maxParameters < 0)
return;
while (static_cast<int32> (queues.size ()) < maxParameters)
{
queues.emplace_back (owned (new ParameterValueQueue (kNoParamId)));
}
while (static_cast<int32> (queues.size ()) > maxParameters)
{
queues.pop_back ();
}
if (usedQueueCount > maxParameters)
usedQueueCount = maxParameters;
}
//-----------------------------------------------------------------------------
void ParameterChanges::clearQueue ()
{
usedQueueCount = 0;
}
//-----------------------------------------------------------------------------
int32 PLUGIN_API ParameterChanges::getParameterCount ()
{
return usedQueueCount;
}
//-----------------------------------------------------------------------------
IParamValueQueue* PLUGIN_API ParameterChanges::getParameterData (int32 index)
{
if (index >= 0 && index < usedQueueCount)
return queues[index];
return nullptr;
}
//-----------------------------------------------------------------------------
IParamValueQueue* PLUGIN_API ParameterChanges::addParameterData (const ParamID& pid, int32& index)
{
for (int32 i = 0; i < usedQueueCount; i++)
{
if (queues[i]->getParameterId () == pid)
{
index = i;
return queues[i];
}
}
ParameterValueQueue* valueQueue = nullptr;
if (usedQueueCount < static_cast<int32> (queues.size ()))
{
valueQueue = queues[usedQueueCount];
valueQueue->setParamID (pid);
valueQueue->clear ();
}
else
{
queues.emplace_back (owned (new ParameterValueQueue (pid)));
valueQueue = queues.back ();
}
index = usedQueueCount;
usedQueueCount++;
return valueQueue;
}
//-----------------------------------------------------------------------------
// ParameterChangeTransfer
//-----------------------------------------------------------------------------
ParameterChangeTransfer::ParameterChangeTransfer (int32 maxParameters)
: size (0)
, changes (nullptr)
, readIndex (0)
, writeIndex (0)
{
setMaxParameters (maxParameters);
}
//-----------------------------------------------------------------------------
ParameterChangeTransfer::~ParameterChangeTransfer ()
{
setMaxParameters (0);
}
//-----------------------------------------------------------------------------
void ParameterChangeTransfer::setMaxParameters (int32 maxParameters)
{
// reserve memory for twice the amount of all parameters
int32 newSize = maxParameters * 2;
if (size != newSize)
{
if (changes)
delete [] changes;
changes = nullptr;
size = newSize;
if (size > 0)
changes = new ParameterChange [size];
}
}
//-----------------------------------------------------------------------------
void ParameterChangeTransfer::addChange (ParamID pid, ParamValue value, int32 sampleOffset)
{
if (changes)
{
changes[writeIndex].id = pid;
changes[writeIndex].value = value;
changes[writeIndex].sampleOffset = sampleOffset;
int32 newWriteIndex = writeIndex + 1;
if (newWriteIndex >= size)
newWriteIndex = 0;
if (readIndex != newWriteIndex)
writeIndex = newWriteIndex;
}
}
//-----------------------------------------------------------------------------
bool ParameterChangeTransfer::getNextChange (ParamID& pid, ParamValue& value, int32& sampleOffset)
{
if (!changes)
return false;
int32 currentWriteIndex = writeIndex;
if (readIndex != currentWriteIndex)
{
pid = changes [readIndex].id;
value = changes [readIndex].value;
sampleOffset = changes [readIndex].sampleOffset;
int32 newReadIndex = readIndex + 1;
if (newReadIndex >= size)
newReadIndex = 0;
readIndex = newReadIndex;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
void ParameterChangeTransfer::transferChangesTo (ParameterChanges& dest)
{
ParamID pid;
ParamValue value;
int32 sampleOffset;
int32 index;
while (getNextChange (pid, value, sampleOffset))
{
IParamValueQueue* queue = dest.addParameterData (pid, index);
if (queue)
{
queue->addPoint (sampleOffset, value, index);
}
}
}
//-----------------------------------------------------------------------------
void ParameterChangeTransfer::transferChangesFrom (ParameterChanges& source)
{
ParamValue value;
int32 sampleOffset;
for (int32 i = 0; i < source.getParameterCount (); i++)
{
IParamValueQueue* queue = source.getParameterData (i);
if (queue)
{
for (int32 j = 0; j < queue->getPointCount (); j++)
{
if (queue->getPoint (j, sampleOffset, value) == kResultTrue)
{
addChange (queue->getParameterId (), value, sampleOffset);
}
}
}
}
}
//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg