mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Reduce duplication in VST3 audio buffers
Using C++20 templated lambdas.
This commit is contained in:
@@ -23,29 +23,25 @@ YaAudioBusBuffers::YaAudioBusBuffers() noexcept {}
|
|||||||
void YaAudioBusBuffers::clear(int32 sample_size,
|
void YaAudioBusBuffers::clear(int32 sample_size,
|
||||||
size_t num_samples,
|
size_t num_samples,
|
||||||
size_t num_channels) {
|
size_t num_channels) {
|
||||||
|
auto do_clear = [&]<typename T>(T) {
|
||||||
|
if (!std::holds_alternative<std::vector<std::vector<T>>>(buffers)) {
|
||||||
|
buffers.emplace<std::vector<std::vector<T>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<T>>& vector_buffers =
|
||||||
|
std::get<std::vector<std::vector<T>>>(buffers);
|
||||||
|
vector_buffers.resize(num_channels);
|
||||||
|
for (size_t i = 0; i < vector_buffers.size(); i++) {
|
||||||
|
vector_buffers[i].resize(num_samples);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (sample_size == Steinberg::Vst::SymbolicSampleSizes::kSample64) {
|
if (sample_size == Steinberg::Vst::SymbolicSampleSizes::kSample64) {
|
||||||
if (!std::holds_alternative<std::vector<std::vector<double>>>(
|
// XXX: Clangd doesn't let you specify template parameters for templated
|
||||||
buffers)) {
|
// lambdas. This argument should get optimized out
|
||||||
buffers.emplace<std::vector<std::vector<double>>>();
|
do_clear(double());
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::vector<double>>& vector_buffers =
|
|
||||||
std::get<std::vector<std::vector<double>>>(buffers);
|
|
||||||
vector_buffers.resize(num_channels);
|
|
||||||
for (size_t i = 0; i < vector_buffers.size(); i++) {
|
|
||||||
vector_buffers[i].resize(num_samples);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!std::holds_alternative<std::vector<std::vector<float>>>(buffers)) {
|
do_clear(float());
|
||||||
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(num_channels);
|
|
||||||
for (size_t i = 0; i < vector_buffers.size(); i++) {
|
|
||||||
vector_buffers[i].resize(num_samples);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,39 +51,26 @@ void YaAudioBusBuffers::repopulate(
|
|||||||
const Steinberg::Vst::AudioBusBuffers& data) {
|
const Steinberg::Vst::AudioBusBuffers& data) {
|
||||||
silence_flags = data.silenceFlags;
|
silence_flags = data.silenceFlags;
|
||||||
|
|
||||||
switch (sample_size) {
|
auto do_repopuldate = [&]<typename T>(T** original_buffer) {
|
||||||
case Steinberg::Vst::kSample64: {
|
if (!std::holds_alternative<std::vector<std::vector<T>>>(buffers)) {
|
||||||
if (!std::holds_alternative<std::vector<std::vector<double>>>(
|
buffers.emplace<std::vector<std::vector<T>>>();
|
||||||
buffers)) {
|
}
|
||||||
buffers.emplace<std::vector<std::vector<double>>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::vector<double>>& vector_buffers =
|
std::vector<std::vector<T>>& vector_buffers =
|
||||||
std::get<std::vector<std::vector<double>>>(buffers);
|
std::get<std::vector<std::vector<T>>>(buffers);
|
||||||
vector_buffers.resize(data.numChannels);
|
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],
|
&original_buffer[channel][0],
|
||||||
&data.channelBuffers64[channel][num_samples]);
|
&original_buffer[channel][num_samples]);
|
||||||
}
|
}
|
||||||
} break;
|
};
|
||||||
case Steinberg::Vst::kSample32:
|
|
||||||
|
if (sample_size == Steinberg::Vst::kSample64) {
|
||||||
|
do_repopuldate(data.channelBuffers64);
|
||||||
|
} else {
|
||||||
// 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: {
|
do_repopuldate(data.channelBuffers32);
|
||||||
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++) {
|
|
||||||
vector_buffers[channel].assign(
|
|
||||||
&data.channelBuffers32[channel][0],
|
|
||||||
&data.channelBuffers32[channel][num_samples]);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,31 +79,25 @@ void YaAudioBusBuffers::reconstruct(
|
|||||||
// We'll update the `AudioBusBuffers` object in place to point to our new
|
// We'll update the `AudioBusBuffers` object in place to point to our new
|
||||||
// data
|
// data
|
||||||
reconstructed_buffers.silenceFlags = silence_flags;
|
reconstructed_buffers.silenceFlags = silence_flags;
|
||||||
std::visit(overload{
|
|
||||||
[&](std::vector<std::vector<double>>& buffers) {
|
|
||||||
buffer_pointers.resize(buffers.size());
|
|
||||||
for (size_t i = 0; i < buffers.size(); i++) {
|
|
||||||
buffer_pointers[i] = buffers[i].data();
|
|
||||||
}
|
|
||||||
|
|
||||||
reconstructed_buffers.numChannels =
|
std::visit(
|
||||||
static_cast<int32>(buffers.size());
|
[&]<typename T>(std::vector<std::vector<T>>& buffers) {
|
||||||
reconstructed_buffers.channelBuffers64 =
|
buffer_pointers.resize(buffers.size());
|
||||||
reinterpret_cast<double**>(buffer_pointers.data());
|
for (size_t i = 0; i < buffers.size(); i++) {
|
||||||
},
|
buffer_pointers[i] = buffers[i].data();
|
||||||
[&](std::vector<std::vector<float>>& buffers) {
|
}
|
||||||
buffer_pointers.resize(buffers.size());
|
|
||||||
for (size_t i = 0; i < buffers.size(); i++) {
|
|
||||||
buffer_pointers[i] = buffers[i].data();
|
|
||||||
}
|
|
||||||
|
|
||||||
reconstructed_buffers.numChannels =
|
reconstructed_buffers.numChannels =
|
||||||
static_cast<int32>(buffers.size());
|
static_cast<int32>(buffers.size());
|
||||||
reconstructed_buffers.channelBuffers32 =
|
if constexpr (std::is_same_v<T, double>) {
|
||||||
reinterpret_cast<float**>(buffer_pointers.data());
|
reconstructed_buffers.channelBuffers64 =
|
||||||
},
|
reinterpret_cast<T**>(buffer_pointers.data());
|
||||||
},
|
} else {
|
||||||
buffers);
|
reconstructed_buffers.channelBuffers32 =
|
||||||
|
reinterpret_cast<T**>(buffer_pointers.data());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t YaAudioBusBuffers::num_channels() const {
|
size_t YaAudioBusBuffers::num_channels() const {
|
||||||
@@ -131,22 +108,19 @@ size_t YaAudioBusBuffers::num_channels() const {
|
|||||||
void YaAudioBusBuffers::write_back_outputs(
|
void YaAudioBusBuffers::write_back_outputs(
|
||||||
Steinberg::Vst::AudioBusBuffers& output_buffers) const {
|
Steinberg::Vst::AudioBusBuffers& output_buffers) const {
|
||||||
output_buffers.silenceFlags = silence_flags;
|
output_buffers.silenceFlags = silence_flags;
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
overload{
|
[&]<typename T>(const std::vector<std::vector<T>>& buffers) {
|
||||||
[&](const std::vector<std::vector<double>>& buffers) {
|
for (int channel = 0; channel < output_buffers.numChannels;
|
||||||
for (int channel = 0; channel < output_buffers.numChannels;
|
channel++) {
|
||||||
channel++) {
|
if constexpr (std::is_same_v<T, double>) {
|
||||||
std::copy(buffers[channel].begin(), buffers[channel].end(),
|
std::copy(buffers[channel].begin(), buffers[channel].end(),
|
||||||
output_buffers.channelBuffers64[channel]);
|
output_buffers.channelBuffers64[channel]);
|
||||||
}
|
} else {
|
||||||
},
|
|
||||||
[&](const std::vector<std::vector<float>>& buffers) {
|
|
||||||
for (int channel = 0; channel < output_buffers.numChannels;
|
|
||||||
channel++) {
|
|
||||||
std::copy(buffers[channel].begin(), buffers[channel].end(),
|
std::copy(buffers[channel].begin(), buffers[channel].end(),
|
||||||
output_buffers.channelBuffers32[channel]);
|
output_buffers.channelBuffers32[channel]);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
buffers);
|
buffers);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user