Use our new custom std::variant bitsery extension

This prevents reinitializing `std::variant`s when the variant we want to
deserialize is already active. We store audio buffers in variants, so
reinitializing them results in a lot of unnecessary memory frees,
allocations and writes during every processing cycle.
This commit is contained in:
Robbert van der Helm
2021-05-22 17:38:07 +02:00
parent 6ee905c79f
commit 7c49fe739d
7 changed files with 24 additions and 17 deletions
+6
View File
@@ -30,6 +30,12 @@ Versioning](https://semver.org/spec/v2.0.0.html).
- Redesigned the VST3 audio socket handling to be able to reuse the process data
objects on both sides. This greatly reduces the overhead of our VST3 bridging
by getting rid of all memory allocations during audio processing.
- Considerably optimized both VST2 and VST3 audio processing by preventing
unnecessary memory operations. As it turns out, the underlying binary
serialization library used by yabridge would always reinitialize the type-safe
unions yabridge uses to differentiate between single and double precision
floating point audio buffers, undoing all of our efforts at reusing objects
and preventing memory allocations in the process.
- Changed the way mutual recursion in VST3 plugins on the plugin side works to
counter any potential GUI related timing issues with VST3 plugins.
- The deserialization part of yabridge's communication is now slightly faster by
+4 -4
View File
@@ -19,7 +19,7 @@
#include <variant>
#include <bitsery/ext/std_optional.h>
#include <bitsery/ext/std_variant.h>
#include "../bitsery/ext/in-place-variant.h"
#include <bitsery/traits/array.h>
#include <bitsery/traits/vector.h>
#include <vestige/aeffectx.h>
@@ -402,7 +402,7 @@ struct Vst2Event {
template <typename S>
void serialize(S& s, Vst2Event::Payload& payload) {
s.ext(payload,
bitsery::ext::StdVariant{
bitsery::ext::InPlaceVariant{
[](S&, std::nullptr_t&) {},
[](S& s, std::string& string) {
s.text1b(string, max_string_length);
@@ -486,7 +486,7 @@ struct Vst2EventResult {
template <typename S>
void serialize(S& s, Vst2EventResult::Payload& payload) {
s.ext(payload,
bitsery::ext::StdVariant{
bitsery::ext::InPlaceVariant{
[](S&, std::nullptr_t&) {},
[](S& s, std::string& string) {
s.text1b(string, max_string_length);
@@ -585,7 +585,7 @@ struct AudioBuffers {
void serialize(S& s) {
s.ext(
buffers,
bitsery::ext::StdVariant{
bitsery::ext::InPlaceVariant{
[](S& s, std::vector<std::vector<float>>& buffer) {
s.container(buffer, max_audio_channels, [](S& s, auto& v) {
s.container4b(v, max_buffer_size);
+4 -4
View File
@@ -18,7 +18,7 @@
#include <variant>
#include <bitsery/ext/std_variant.h>
#include "../bitsery/ext/in-place-variant.h"
#include "../bitsery/ext/message-reference.h"
#include "../configuration.h"
@@ -147,7 +147,7 @@ template <typename S>
void serialize(S& s, ControlRequest& payload) {
// All of the objects in `ControlRequest` should have their own
// serialization function.
s.ext(payload, bitsery::ext::StdVariant{});
s.ext(payload, bitsery::ext::InPlaceVariant{});
}
/**
@@ -202,7 +202,7 @@ struct AudioProcessorRequest {
void serialize(S& s) {
s.ext(
payload,
bitsery::ext::StdVariant{
bitsery::ext::InPlaceVariant{
[&](S& s,
MessageReference<YaAudioProcessor::Process>& request_ref) {
// When serializing this reference we'll read the data
@@ -268,7 +268,7 @@ template <typename S>
void serialize(S& s, CallbackRequest& payload) {
// All of the objects in `CallbackRequest` should have their own
// serialization function.
s.ext(payload, bitsery::ext::StdVariant{});
s.ext(payload, bitsery::ext::InPlaceVariant{});
}
/**
+2 -2
View File
@@ -16,7 +16,7 @@
#pragma once
#include <bitsery/ext/std_variant.h>
#include "../../bitsery/ext/in-place-variant.h"
#include <pluginterfaces/vst/ivstevents.h>
#include "base.h"
@@ -202,7 +202,7 @@ struct YaEvent {
s.value4b(sample_offset);
s.value8b(ppq_position);
s.value2b(flags);
s.ext(payload, bitsery::ext::StdVariant{});
s.ext(payload, bitsery::ext::InPlaceVariant{});
}
};
+4 -3
View File
@@ -16,7 +16,7 @@
#pragma once
#include <bitsery/ext/std_variant.h>
#include "../../bitsery/ext/in-place-variant.h"
#include "../common.h"
#include "plugin/audio-presentation-latency.h"
@@ -101,7 +101,8 @@ class Vst3PluginProxy : public YaAudioPresentationLatency,
* Read from an existing object. We will try to mimic this object, so
* we'll support any interfaces this object also supports.
*/
ConstructArgs(Steinberg::IPtr<FUnknown> object, size_t instance_id) noexcept;
ConstructArgs(Steinberg::IPtr<FUnknown> object,
size_t instance_id) noexcept;
/**
* The unique identifier for this specific object instance.
@@ -296,5 +297,5 @@ template <typename S>
void serialize(
S& s,
std::variant<Vst3PluginProxy::ConstructArgs, UniversalTResult>& result) {
s.ext(result, bitsery::ext::StdVariant{});
s.ext(result, bitsery::ext::InPlaceVariant{});
}
@@ -19,7 +19,7 @@
#include <variant>
#include <bitsery/ext/std_optional.h>
#include <bitsery/ext/std_variant.h>
#include "../../../bitsery/ext/in-place-variant.h"
#include <pluginterfaces/vst/ivstmessage.h>
#include "../../common.h"
@@ -133,7 +133,7 @@ class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
void serialize(S& s) {
s.value8b(instance_id);
s.ext(other,
bitsery::ext::StdVariant{
bitsery::ext::InPlaceVariant{
[](S& s, native_size_t& other_instance_id) {
s.value8b(other_instance_id);
},
+2 -2
View File
@@ -19,8 +19,8 @@
#include <variant>
#include <bitsery/ext/std_optional.h>
#include <bitsery/ext/std_variant.h>
#include <pluginterfaces/vst/ivstaudioprocessor.h>
#include "../../bitsery/ext/in-place-variant.h"
#include "base.h"
#include "event-list.h"
@@ -89,7 +89,7 @@ class YaAudioBusBuffers {
template <typename S>
void serialize(S& s) {
s.value8b(silence_flags);
s.ext(buffers, bitsery::ext::StdVariant{
s.ext(buffers, bitsery::ext::InPlaceVariant{
[](S& s, std::vector<std::vector<float>>& buffers) {
s.container(buffers, max_num_speakers,
[](S& s, auto& channel) {