Finish implementing YaAudioBusBuffers

This commit is contained in:
Robbert van der Helm
2020-12-15 22:32:42 +01:00
parent 487e6eac98
commit f1aefc0a9d
3 changed files with 106 additions and 1 deletions
+2
View File
@@ -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',
]
@@ -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 <https://www.gnu.org/licenses/>.
#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<std::vector<double>>(
num_channels,
std::vector<double>(num_samples, 0.0)))
: decltype(buffers)(std::vector<std::vector<float>>(
num_channels,
std::vector<float>(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<std::vector<double>> 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<std::vector<float>> 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<std::vector<double>>& 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<std::vector<float>>& 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;
}
+11 -1
View File
@@ -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*> float_buffer_pointers;
std::vector<double*> double_buffer_pointers;
};
/**
* A bitfield for silent channels copied directly from the input struct.
*/