mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-16 00:13:55 +02:00
Avoid allocations when reading VST3 process data
On the plugin side. We still need to do a lot of optimizations elsewhere.
This commit is contained in:
@@ -174,19 +174,24 @@ Steinberg::Vst::Event YaEvent::get() const {
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
YaEventList::YaEventList(){FUNKNOWN_CTOR}
|
YaEventList::YaEventList() {
|
||||||
|
|
||||||
YaEventList::YaEventList(Steinberg::Vst::IEventList& event_list) {
|
|
||||||
FUNKNOWN_CTOR
|
FUNKNOWN_CTOR
|
||||||
|
}
|
||||||
|
|
||||||
|
void YaEventList::clear() {
|
||||||
|
events.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YaEventList::repopulate(Steinberg::Vst::IEventList& event_list) {
|
||||||
|
// Copy over all events. Everything gets converted to `YaEvent`s. We sadly
|
||||||
|
// can't construct these in place because we don't know the event type yet.
|
||||||
|
events.clear();
|
||||||
events.reserve(event_list.getEventCount());
|
events.reserve(event_list.getEventCount());
|
||||||
|
|
||||||
// Copy over all events. Everything gets converted to `YaEvent`s.
|
|
||||||
Steinberg::Vst::Event event;
|
|
||||||
for (int i = 0; i < event_list.getEventCount(); i++) {
|
for (int i = 0; i < event_list.getEventCount(); i++) {
|
||||||
// We're skipping the `kResultOk` assertions here
|
// We're skipping the `kResultOk` assertions here
|
||||||
|
Steinberg::Vst::Event event;
|
||||||
event_list.getEvent(i, event);
|
event_list.getEvent(i, event);
|
||||||
events.push_back(event);
|
events.emplace_back(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,15 +213,23 @@ struct YaEvent {
|
|||||||
class YaEventList : public Steinberg::Vst::IEventList {
|
class YaEventList : public Steinberg::Vst::IEventList {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Default constructor with an empty event list. The plugin can use this to
|
* We only provide a default constructor here, because we need to fill the
|
||||||
* output data.
|
* existing object with new events every processing cycle to avoid
|
||||||
|
* reallocating a new object every time.
|
||||||
*/
|
*/
|
||||||
YaEventList();
|
YaEventList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read data from an existing `IEventList` object.
|
* Remove all events. Used when a null pointer gets passed to the input
|
||||||
|
* events field, and so the plugin can output its own events if the host
|
||||||
|
* supports this.
|
||||||
*/
|
*/
|
||||||
YaEventList(Steinberg::Vst::IEventList& event_list);
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data from an `IEventList` object into this existing object.
|
||||||
|
*/
|
||||||
|
void repopulate(Steinberg::Vst::IEventList& event_list);
|
||||||
|
|
||||||
~YaEventList();
|
~YaEventList();
|
||||||
|
|
||||||
|
|||||||
@@ -16,19 +16,22 @@
|
|||||||
|
|
||||||
#include "param-value-queue.h"
|
#include "param-value-queue.h"
|
||||||
|
|
||||||
YaParamValueQueue::YaParamValueQueue(){FUNKNOWN_CTOR}
|
YaParamValueQueue::YaParamValueQueue() {
|
||||||
|
|
||||||
YaParamValueQueue::YaParamValueQueue(Steinberg::Vst::ParamID parameter_id)
|
|
||||||
: parameter_id(parameter_id){FUNKNOWN_CTOR}
|
|
||||||
|
|
||||||
// clang-format /really/ doesn't like these macros
|
|
||||||
YaParamValueQueue::YaParamValueQueue(Steinberg::Vst::IParamValueQueue &
|
|
||||||
original_queue)
|
|
||||||
: parameter_id(original_queue.getParameterId()),
|
|
||||||
queue(original_queue.getPointCount()) {
|
|
||||||
FUNKNOWN_CTOR
|
FUNKNOWN_CTOR
|
||||||
|
}
|
||||||
|
|
||||||
|
void YaParamValueQueue::clear_for_parameter(
|
||||||
|
Steinberg::Vst::ParamID parameter_id) {
|
||||||
|
this->parameter_id = parameter_id;
|
||||||
|
queue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YaParamValueQueue::repopulate(
|
||||||
|
Steinberg::Vst::IParamValueQueue& original_queue) {
|
||||||
|
parameter_id = original_queue.getParameterId();
|
||||||
|
|
||||||
// Copy over all points to our vector
|
// Copy over all points to our vector
|
||||||
|
queue.resize(original_queue.getPointCount());
|
||||||
for (int i = 0; i < original_queue.getPointCount(); i++) {
|
for (int i = 0; i < original_queue.getPointCount(); i++) {
|
||||||
// We're skipping the assertions here and just assume that the function
|
// We're skipping the assertions here and just assume that the function
|
||||||
// returns `kResultOk`
|
// returns `kResultOk`
|
||||||
|
|||||||
@@ -32,20 +32,22 @@
|
|||||||
class YaParamValueQueue : public Steinberg::Vst::IParamValueQueue {
|
class YaParamValueQueue : public Steinberg::Vst::IParamValueQueue {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Default constructor with an empty queue.
|
* We only provide a default constructor here, because we need to fill the
|
||||||
|
* existing object with new data every processing cycle to avoid
|
||||||
|
* reallocating a new object every time.
|
||||||
*/
|
*/
|
||||||
YaParamValueQueue();
|
YaParamValueQueue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an empty queue for a specific parameter. Used in
|
* Clear this queue in place so that it can be used to write parameter data
|
||||||
* `YaParameterChanges::addParameterData`.
|
* to. Used in `YaParameterChanges::addParameterData`.
|
||||||
*/
|
*/
|
||||||
YaParamValueQueue(Steinberg::Vst::ParamID parameter_id);
|
void clear_for_parameter(Steinberg::Vst::ParamID parameter_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read data from an existing `IParamValueQueue` object.
|
* Read data from an `IParamValueQueue` object into this existing object.
|
||||||
*/
|
*/
|
||||||
YaParamValueQueue(Steinberg::Vst::IParamValueQueue& original_queue);
|
void repopulate(Steinberg::Vst::IParamValueQueue& original_queue);
|
||||||
|
|
||||||
~YaParamValueQueue();
|
~YaParamValueQueue();
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,20 @@
|
|||||||
|
|
||||||
#include "parameter-changes.h"
|
#include "parameter-changes.h"
|
||||||
|
|
||||||
YaParameterChanges::YaParameterChanges(){FUNKNOWN_CTOR}
|
YaParameterChanges::YaParameterChanges() {
|
||||||
|
|
||||||
YaParameterChanges::YaParameterChanges(
|
|
||||||
Steinberg::Vst::IParameterChanges& original_queues) {
|
|
||||||
FUNKNOWN_CTOR
|
FUNKNOWN_CTOR
|
||||||
|
}
|
||||||
|
|
||||||
// Copy over all parameter changne queues. Everything gets converted to
|
void YaParameterChanges::clear() {
|
||||||
// `YaParamValueQueue`s.
|
queues.clear();
|
||||||
queues.reserve(original_queues.getParameterCount());
|
}
|
||||||
|
|
||||||
|
void YaParameterChanges::repopulate(
|
||||||
|
Steinberg::Vst::IParameterChanges& original_queues) {
|
||||||
|
// Copy over all parameter changne queues
|
||||||
|
queues.resize(original_queues.getParameterCount());
|
||||||
for (int i = 0; i < original_queues.getParameterCount(); i++) {
|
for (int i = 0; i < original_queues.getParameterCount(); i++) {
|
||||||
queues.push_back(*original_queues.getParameterData(i));
|
queues[i].repopulate(*original_queues.getParameterData(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +78,11 @@ Steinberg::Vst::IParamValueQueue* PLUGIN_API
|
|||||||
YaParameterChanges::addParameterData(const Steinberg::Vst::ParamID& id,
|
YaParameterChanges::addParameterData(const Steinberg::Vst::ParamID& id,
|
||||||
int32& index /*out*/) {
|
int32& index /*out*/) {
|
||||||
index = static_cast<int32>(queues.size());
|
index = static_cast<int32>(queues.size());
|
||||||
queues.push_back(YaParamValueQueue(id));
|
|
||||||
|
// Tiny hack, resizing avoids calling the constructor the second time we
|
||||||
|
// resize the vector to the same size
|
||||||
|
queues.resize(queues.size() + 1);
|
||||||
|
queues[index].clear_for_parameter(id);
|
||||||
|
|
||||||
return &queues[index];
|
return &queues[index];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,15 +31,23 @@
|
|||||||
class YaParameterChanges : public Steinberg::Vst::IParameterChanges {
|
class YaParameterChanges : public Steinberg::Vst::IParameterChanges {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Default constructor with an empty parameter changes list. The plugin can
|
* We only provide a default constructor here, because we need to fill the
|
||||||
* use this to output data.
|
* existing object with new data every processing cycle to avoid
|
||||||
|
* reallocating a new object every time.
|
||||||
*/
|
*/
|
||||||
YaParameterChanges();
|
YaParameterChanges();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read data from an existing `IParameterChanges` object.
|
* Remove all parameter changes. Used when a null pointer gets passed to the
|
||||||
|
* input parameters field, and so the plugin can output its own parameter
|
||||||
|
* changes.
|
||||||
*/
|
*/
|
||||||
YaParameterChanges(Steinberg::Vst::IParameterChanges& original_queues);
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data from an `IParameterChanges` object into this existing object.
|
||||||
|
*/
|
||||||
|
void repopulate(Steinberg::Vst::IParameterChanges& original_queues);
|
||||||
|
|
||||||
~YaParameterChanges();
|
~YaParameterChanges();
|
||||||
|
|
||||||
|
|||||||
@@ -31,33 +31,44 @@ YaAudioBusBuffers::YaAudioBusBuffers(int32 sample_size,
|
|||||||
num_channels,
|
num_channels,
|
||||||
std::vector<float>(num_samples, 0.0)))) {}
|
std::vector<float>(num_samples, 0.0)))) {}
|
||||||
|
|
||||||
YaAudioBusBuffers::YaAudioBusBuffers(
|
void YaAudioBusBuffers::repopulate(
|
||||||
int32 sample_size,
|
int32 sample_size,
|
||||||
int32 num_samples,
|
int32 num_samples,
|
||||||
const Steinberg::Vst::AudioBusBuffers& data)
|
const Steinberg::Vst::AudioBusBuffers& data) {
|
||||||
: silence_flags(data.silenceFlags) {
|
silence_flags = data.silenceFlags;
|
||||||
|
|
||||||
switch (sample_size) {
|
switch (sample_size) {
|
||||||
case Steinberg::Vst::kSample64: {
|
case Steinberg::Vst::kSample64: {
|
||||||
std::vector<std::vector<double>> vector_buffers(data.numChannels);
|
if (!std::holds_alternative<std::vector<std::vector<double>>>(
|
||||||
|
buffers)) {
|
||||||
|
buffers.emplace<std::vector<std::vector<double>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<double>>& vector_buffers =
|
||||||
|
std::get<std::vector<std::vector<double>>>(buffers);
|
||||||
|
vector_buffers.resize(data.numChannels);
|
||||||
for (int channel = 0; channel < data.numChannels; channel++) {
|
for (int channel = 0; channel < data.numChannels; channel++) {
|
||||||
vector_buffers[channel].assign(
|
vector_buffers[channel].assign(
|
||||||
&data.channelBuffers64[channel][0],
|
&data.channelBuffers64[channel][0],
|
||||||
&data.channelBuffers64[channel][num_samples]);
|
&data.channelBuffers64[channel][num_samples]);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers = std::move(vector_buffers);
|
|
||||||
} break;
|
} break;
|
||||||
case Steinberg::Vst::kSample32:
|
case Steinberg::Vst::kSample32:
|
||||||
// I don't think they'll add any other sample sizes any time soon
|
// I don't think they'll add any other sample sizes any time soon
|
||||||
default: {
|
default: {
|
||||||
std::vector<std::vector<float>> vector_buffers(data.numChannels);
|
if (!std::holds_alternative<std::vector<std::vector<float>>>(
|
||||||
|
buffers)) {
|
||||||
|
buffers.emplace<std::vector<std::vector<float>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<float>>& vector_buffers =
|
||||||
|
std::get<std::vector<std::vector<float>>>(buffers);
|
||||||
|
vector_buffers.resize(data.numChannels);
|
||||||
for (int channel = 0; channel < data.numChannels; channel++) {
|
for (int channel = 0; channel < data.numChannels; channel++) {
|
||||||
vector_buffers[channel].assign(
|
vector_buffers[channel].assign(
|
||||||
&data.channelBuffers32[channel][0],
|
&data.channelBuffers32[channel][0],
|
||||||
&data.channelBuffers32[channel][num_samples]);
|
&data.channelBuffers32[channel][num_samples]);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers = std::move(vector_buffers);
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,39 +151,62 @@ void YaProcessDataResponse::write_back_outputs(
|
|||||||
|
|
||||||
YaProcessData::YaProcessData() {}
|
YaProcessData::YaProcessData() {}
|
||||||
|
|
||||||
YaProcessData::YaProcessData(const Steinberg::Vst::ProcessData& process_data)
|
void YaProcessData::repopulate(
|
||||||
: process_mode(process_data.processMode),
|
const Steinberg::Vst::ProcessData& process_data) {
|
||||||
symbolic_sample_size(process_data.symbolicSampleSize),
|
// In this function and in every function we call, we should be careful to
|
||||||
num_samples(process_data.numSamples),
|
// not use `push_back`/`emplace_back` anywhere. Resizing vectors and
|
||||||
outputs_num_channels(process_data.numOutputs),
|
// modifying them in place performs much better because that avoids
|
||||||
// Even though `ProcessData::inputParamterChanges` is mandatory, the VST3
|
// destroying and creating objects most of the time.
|
||||||
// validator will pass a null pointer here
|
process_mode = process_data.processMode;
|
||||||
input_parameter_changes(
|
symbolic_sample_size = process_data.symbolicSampleSize;
|
||||||
process_data.inputParameterChanges
|
num_samples = process_data.numSamples;
|
||||||
? YaParameterChanges(*process_data.inputParameterChanges)
|
|
||||||
: YaParameterChanges()),
|
// We'll make sure to not do any allocations here after the first processing
|
||||||
output_parameter_changes_supported(process_data.outputParameterChanges),
|
// cycle
|
||||||
input_events(process_data.inputEvents ? std::make_optional<YaEventList>(
|
inputs.resize(process_data.numInputs);
|
||||||
*process_data.inputEvents)
|
|
||||||
: std::nullopt),
|
|
||||||
output_events_supported(process_data.outputEvents),
|
|
||||||
process_context(process_data.processContext
|
|
||||||
? std::make_optional<Steinberg::Vst::ProcessContext>(
|
|
||||||
*process_data.processContext)
|
|
||||||
: std::nullopt) {
|
|
||||||
for (int i = 0; i < process_data.numInputs; i++) {
|
for (int i = 0; i < process_data.numInputs; i++) {
|
||||||
inputs.emplace_back(symbolic_sample_size, num_samples,
|
inputs[i].repopulate(symbolic_sample_size, num_samples,
|
||||||
process_data.inputs[i]);
|
process_data.inputs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the number of channels for each output so we can recreate these
|
// We only store how many channels ouch output has so we can recreate the
|
||||||
// buffers in the Wine plugin host
|
// objects on the Wine side
|
||||||
|
outputs_num_channels.resize(process_data.numOutputs);
|
||||||
for (int i = 0; i < process_data.numOutputs; i++) {
|
for (int i = 0; i < process_data.numOutputs; i++) {
|
||||||
outputs_num_channels[i] = process_data.outputs[i].numChannels;
|
outputs_num_channels[i] = process_data.outputs[i].numChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even though `ProcessData::inputParamterChanges` is mandatory, the VST3
|
||||||
|
// validator will pass a null pointer here
|
||||||
|
if (process_data.inputParameterChanges) {
|
||||||
|
input_parameter_changes.repopulate(*process_data.inputParameterChanges);
|
||||||
|
} else {
|
||||||
|
input_parameter_changes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
output_parameter_changes_supported = process_data.outputParameterChanges;
|
||||||
|
|
||||||
|
if (process_data.inputEvents) {
|
||||||
|
if (!input_events) {
|
||||||
|
input_events.emplace();
|
||||||
|
}
|
||||||
|
input_events->repopulate(*process_data.inputEvents);
|
||||||
|
} else {
|
||||||
|
input_events.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
output_events_supported = process_data.outputEvents;
|
||||||
|
|
||||||
|
if (process_data.processContext) {
|
||||||
|
process_context.emplace(*process_data.processContext);
|
||||||
|
} else {
|
||||||
|
process_context.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Steinberg::Vst::ProcessData& YaProcessData::get() {
|
Steinberg::Vst::ProcessData& YaProcessData::get() {
|
||||||
|
// TODO: Also optimize this to make use of the reused objects
|
||||||
|
|
||||||
// We'll have to transform out `YaAudioBusBuffers` objects into an array of
|
// We'll have to transform out `YaAudioBusBuffers` objects into an array of
|
||||||
// `AudioBusBuffers` object so the plugin can deal with them. These objects
|
// `AudioBusBuffers` object so the plugin can deal with them. These objects
|
||||||
// contain pointers to those original objects and thus don't store any
|
// contain pointers to those original objects and thus don't store any
|
||||||
@@ -193,6 +227,13 @@ Steinberg::Vst::ProcessData& YaProcessData::get() {
|
|||||||
outputs_audio_bus_buffers.push_back(buffers.get());
|
outputs_audio_bus_buffers.push_back(buffers.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output_parameter_changes) {
|
||||||
|
output_parameter_changes->clear();
|
||||||
|
}
|
||||||
|
if (output_events) {
|
||||||
|
output_events->clear();
|
||||||
|
}
|
||||||
|
|
||||||
reconstructed_process_data.processMode = process_mode;
|
reconstructed_process_data.processMode = process_mode;
|
||||||
reconstructed_process_data.symbolicSampleSize = symbolic_sample_size;
|
reconstructed_process_data.symbolicSampleSize = symbolic_sample_size;
|
||||||
reconstructed_process_data.numSamples = num_samples;
|
reconstructed_process_data.numSamples = num_samples;
|
||||||
|
|||||||
@@ -39,14 +39,18 @@
|
|||||||
class YaAudioBusBuffers {
|
class YaAudioBusBuffers {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* A default constructor does not make any sense here since the actual data
|
* We only provide a default constructor here, because we need to fill the
|
||||||
* is a union, but we need a default constructor for bitsery.
|
* existing object with new audio data every processing cycle to avoid
|
||||||
|
* reallocating a new object every time.
|
||||||
*/
|
*/
|
||||||
YaAudioBusBuffers();
|
YaAudioBusBuffers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new, zero initialize audio bus buffers object. Used to
|
* Create a new, zero initialize audio bus buffers object. Used to
|
||||||
* reconstruct the output buffers during `YaProcessData::get()`.
|
* reconstruct the output buffers during `YaProcessData::get()`.
|
||||||
|
*
|
||||||
|
* TODO: Replace with a function similar to `repopulate` that just reassigns
|
||||||
|
* the existing buffers for the outputs created on the Wine side.
|
||||||
*/
|
*/
|
||||||
YaAudioBusBuffers(int32 sample_size,
|
YaAudioBusBuffers(int32 sample_size,
|
||||||
size_t num_samples,
|
size_t num_samples,
|
||||||
@@ -54,15 +58,15 @@ class YaAudioBusBuffers {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy data from a host provided `AudioBusBuffers` object during a process
|
* Copy data from a host provided `AudioBusBuffers` object during a process
|
||||||
* call. Constructed as part of `YaProcessData`. Since `AudioBusBuffers`
|
* call. Used in `YaProcessData::repopulate()`. Since `AudioBusBuffers`
|
||||||
* contains an untagged union for storing single and double precision
|
* contains an untagged union for storing single and double precision
|
||||||
* floating point values, the original `ProcessData`'s `symbolicSampleSize`
|
* floating point values, the original `ProcessData`'s `symbolicSampleSize`
|
||||||
* field determines which variant of that union to use. Similarly the
|
* field determines which variant of that union to use. Similarly the
|
||||||
* `ProcessData`' `numSamples` field determines the extent of these arrays.
|
* `ProcessData`' `numSamples` field determines the extent of these arrays.
|
||||||
*/
|
*/
|
||||||
YaAudioBusBuffers(int32 sample_size,
|
void repopulate(int32 sample_size,
|
||||||
int32 num_samples,
|
int32 num_samples,
|
||||||
const Steinberg::Vst::AudioBusBuffers& data);
|
const Steinberg::Vst::AudioBusBuffers& data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconstruct the original `AudioBusBuffers` object passed to the
|
* Reconstruct the original `AudioBusBuffers` object passed to the
|
||||||
@@ -170,14 +174,21 @@ struct YaProcessDataResponse {
|
|||||||
*/
|
*/
|
||||||
class YaProcessData {
|
class YaProcessData {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Initialize the process data. We only provide a default constructor here,
|
||||||
|
* because we need to fill the existing object with new data every
|
||||||
|
* processing cycle to avoid reallocating a new object every time.
|
||||||
|
*/
|
||||||
YaProcessData();
|
YaProcessData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy data from a host provided `ProcessData` object during a process
|
* Copy data from a host provided `ProcessData` object during a process
|
||||||
* call. This struct can then be serialized, and `YaProcessData::get()` can
|
* call. This struct can then be serialized, and `YaProcessData::get()` can
|
||||||
* then be used again to recreate the original `ProcessData` object.
|
* then be used again to recreate the original `ProcessData` object. This
|
||||||
|
* will avoid allocating unless it's absolutely necessary (e.g. when we
|
||||||
|
* receive more parameter changes than we've received in previous calls).
|
||||||
*/
|
*/
|
||||||
YaProcessData(const Steinberg::Vst::ProcessData& process_data);
|
void repopulate(const Steinberg::Vst::ProcessData& process_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconstruct the original `ProcessData` object passed to the constructor
|
* Reconstruct the original `ProcessData` object passed to the constructor
|
||||||
|
|||||||
@@ -186,10 +186,8 @@ Vst3PluginProxyImpl::process(Steinberg::Vst::ProcessData& data) {
|
|||||||
last_audio_thread_priority_synchronization = now;
|
last_audio_thread_priority_synchronization = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document
|
// We reuse this existing object to avoid allocations
|
||||||
// TODO: Actually repopulate `process_data` with new data, right now this
|
process_data.repopulate(data);
|
||||||
// assignment just destroys the old object and creates a new object.
|
|
||||||
process_data = data;
|
|
||||||
|
|
||||||
ProcessResponse response =
|
ProcessResponse response =
|
||||||
bridge.send_audio_processor_message(YaAudioProcessor::Process{
|
bridge.send_audio_processor_message(YaAudioProcessor::Process{
|
||||||
|
|||||||
Reference in New Issue
Block a user