diff --git a/meson.build b/meson.build
index 7e514e0b..93443962 100644
--- a/meson.build
+++ b/meson.build
@@ -84,6 +84,7 @@ vst3_plugin_sources = [
'src/common/serialization/vst3/param-value-queue.cpp',
'src/common/serialization/vst3/parameter-changes.cpp',
'src/common/serialization/vst3/plugin-factory.cpp',
+ 'src/common/serialization/vst3/process-data.cpp',
'src/common/configuration.cpp',
'src/common/plugins.cpp',
'src/common/utils.cpp',
@@ -122,6 +123,7 @@ if with_vst3
'src/common/serialization/vst3/param-value-queue.cpp',
'src/common/serialization/vst3/parameter-changes.cpp',
'src/common/serialization/vst3/plugin-factory.cpp',
+ 'src/common/serialization/vst3/process-data.cpp',
'src/wine-host/bridges/vst3-impls/host-application.cpp',
'src/wine-host/bridges/vst3.cpp',
]
diff --git a/src/common/serialization/vst3/process-data.cpp b/src/common/serialization/vst3/process-data.cpp
new file mode 100644
index 00000000..0fd0662e
--- /dev/null
+++ b/src/common/serialization/vst3/process-data.cpp
@@ -0,0 +1,93 @@
+// yabridge: a Wine VST bridge
+// Copyright (C) 2020 Robbert van der Helm
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "process-data.h"
+
+#include "src/common/utils.h"
+
+YaAudioBusBuffers::YaAudioBusBuffers() {}
+
+YaAudioBusBuffers::YaAudioBusBuffers(
+ Steinberg::Vst::SymbolicSampleSizes sample_size,
+ size_t num_channels,
+ size_t num_samples)
+ : buffers(sample_size == Steinberg::Vst::SymbolicSampleSizes::kSample64
+ ? decltype(buffers)(std::vector>(
+ num_channels,
+ std::vector(num_samples, 0.0)))
+ : decltype(buffers)(std::vector>(
+ num_channels,
+ std::vector(num_samples, 0.0)))) {}
+
+YaAudioBusBuffers::YaAudioBusBuffers(
+ Steinberg::Vst::SymbolicSampleSizes sample_size,
+ int32 num_samples,
+ const Steinberg::Vst::AudioBusBuffers& data)
+ : silence_flags(data.silenceFlags) {
+ switch (sample_size) {
+ case Steinberg::Vst::kSample64: {
+ std::vector> vector_buffers(data.numChannels);
+ for (int channel = 0; channel < data.numChannels; channel++) {
+ vector_buffers[channel].assign(
+ &data.channelBuffers64[channel][0],
+ &data.channelBuffers64[channel][num_samples]);
+ }
+
+ buffers = std::move(vector_buffers);
+ } break;
+ case Steinberg::Vst::kSample32:
+ // I don't think they'll add any other sample sizes any time soon
+ default: {
+ std::vector> vector_buffers(data.numChannels);
+ for (int channel = 0; channel < data.numChannels; channel++) {
+ vector_buffers[channel].assign(
+ &data.channelBuffers32[channel][0],
+ &data.channelBuffers32[channel][num_samples]);
+ }
+
+ buffers = std::move(vector_buffers);
+ } break;
+ }
+}
+
+Steinberg::Vst::AudioBusBuffers& YaAudioBusBuffers::get() {
+ reconstructed_buffers.silenceFlags = silence_flags;
+ std::visit(overload{
+ [&](std::vector>& buffers) {
+ double_buffer_pointers.clear();
+ for (auto& buffer : buffers) {
+ double_buffer_pointers.push_back(buffer.data());
+ }
+
+ reconstructed_buffers.numChannels = buffers.size();
+ reconstructed_buffers.channelBuffers64 =
+ double_buffer_pointers.data();
+ },
+ [&](std::vector>& buffers) {
+ float_buffer_pointers.clear();
+ for (auto& buffer : buffers) {
+ float_buffer_pointers.push_back(buffer.data());
+ }
+
+ reconstructed_buffers.numChannels = buffers.size();
+ reconstructed_buffers.channelBuffers32 =
+ float_buffer_pointers.data();
+ },
+ },
+ buffers);
+
+ return reconstructed_buffers;
+}
diff --git a/src/common/serialization/vst3/process-data.h b/src/common/serialization/vst3/process-data.h
index ccc07c24..b441452e 100644
--- a/src/common/serialization/vst3/process-data.h
+++ b/src/common/serialization/vst3/process-data.h
@@ -57,9 +57,11 @@ class YaAudioBusBuffers {
* call. Constructed as part of `YaProcessData`. Since `AudioBusBuffers`
* contains an untagged union for storing single and double precision
* floating point values, the original `ProcessData`'s `symbolicSampleSize`
- * field determines which variant of that union to use.
+ * field determines which variant of that union to use. Similarly the
+ * `ProcessData`' `numSamples` field determines the extent of these arrays.
*/
YaAudioBusBuffers(Steinberg::Vst::SymbolicSampleSizes sample_size,
+ int32 num_samples,
const Steinberg::Vst::AudioBusBuffers& data);
/**
@@ -94,6 +96,14 @@ class YaAudioBusBuffers {
*/
Steinberg::Vst::AudioBusBuffers reconstructed_buffers;
+ // Used in reconstructed_buffers, because we need to store pointers to the
+ // inner vectors in `buffers`. We're using a union instead of void pointers
+ // here to have at least some resemblance of type safety.
+ union {
+ std::vector float_buffer_pointers;
+ std::vector double_buffer_pointers;
+ };
+
/**
* A bitfield for silent channels copied directly from the input struct.
*/