mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Implement writing back YaProcessDataResponse
Everything around `ProcessData` is now fully implemented and should in theory work.
This commit is contained in:
@@ -26,6 +26,8 @@ incomplete list of things that still have to be done before this can be used:
|
||||
- Fully implemented:
|
||||
- `GetPluginFactory()` and `IPluginFactory{,2,3}`
|
||||
- `IPluginBase` and `IComponent`
|
||||
- Everything surrounding `ProcessData`, `ProcessingContext` and
|
||||
`AudioBusBuffers`
|
||||
- `IParameterChanges`, `IParamValueQueue`, `IEventList`, and all event types
|
||||
in VST 3.7.1
|
||||
- `IBStream`
|
||||
|
||||
@@ -194,6 +194,17 @@ YaEventList::~YaEventList() {
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
void YaEventList::write_back_outputs(
|
||||
Steinberg::Vst::IEventList& output_events) const {
|
||||
// TODO: I assume the host is responsible for directly copying heap data
|
||||
// (e.g. text) in these events and they're not supposed to stay
|
||||
// around, right? If not, then we'll find out very quickly.
|
||||
for (auto& event : events) {
|
||||
Steinberg::Vst::Event reconstructed_event = event.get();
|
||||
output_events.addEvent(reconstructed_event);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
IMPLEMENT_FUNKNOWN_METHODS(YaEventList,
|
||||
|
||||
@@ -227,6 +227,12 @@ class YaEventList : public Steinberg::Vst::IEventList {
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
/**
|
||||
* Write these events an output events queue on the `ProcessData` object
|
||||
* provided by the host.
|
||||
*/
|
||||
void write_back_outputs(Steinberg::Vst::IEventList& output_events) const;
|
||||
|
||||
// From `IEventList`
|
||||
virtual int32 PLUGIN_API getEventCount() override;
|
||||
virtual tresult PLUGIN_API
|
||||
|
||||
@@ -47,6 +47,16 @@ IMPLEMENT_FUNKNOWN_METHODS(YaParamValueQueue,
|
||||
Steinberg::Vst::IParamValueQueue::iid)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void YaParamValueQueue::write_back_outputs(
|
||||
Steinberg::Vst::IParamValueQueue& output_queue) const {
|
||||
// We don't need this value
|
||||
int32 index;
|
||||
for (const auto& [sample_offset, value] : queue) {
|
||||
// We don't check for `kResultOk` here
|
||||
output_queue.addPoint(sample_offset, value, index);
|
||||
}
|
||||
}
|
||||
|
||||
Steinberg::Vst::ParamID PLUGIN_API YaParamValueQueue::getParameterId() {
|
||||
return parameter_id;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,13 @@ class YaParamValueQueue : public Steinberg::Vst::IParamValueQueue {
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
/**
|
||||
* Write this queue back the output parameter changes object on the
|
||||
* `ProcessData` object provided by the host.
|
||||
*/
|
||||
void write_back_outputs(
|
||||
Steinberg::Vst::IParamValueQueue& output_queue) const;
|
||||
|
||||
// From `IParamValueQueue`
|
||||
Steinberg::Vst::ParamID PLUGIN_API getParameterId() override;
|
||||
int32 PLUGIN_API getPointCount() override;
|
||||
@@ -72,12 +79,12 @@ class YaParamValueQueue : public Steinberg::Vst::IParamValueQueue {
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* For `IParamValueQueue::getParameterId`.
|
||||
*/
|
||||
Steinberg::Vst::ParamID parameter_id;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The actual parameter changes queue. The specification doesn't mention
|
||||
* that this should be a priority queue or something, but I'd assume both
|
||||
|
||||
@@ -41,6 +41,19 @@ IMPLEMENT_FUNKNOWN_METHODS(YaParameterChanges,
|
||||
Steinberg::Vst::IParameterChanges::iid)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void YaParameterChanges::write_back_outputs(
|
||||
Steinberg::Vst::IParameterChanges& output_queues) const {
|
||||
for (auto& queue : queues) {
|
||||
// We don't need this, but the SDK requires us to need this
|
||||
int32 output_queue_index;
|
||||
if (Steinberg::Vst::IParamValueQueue* output_queue =
|
||||
output_queues.addParameterData(queue.parameter_id,
|
||||
output_queue_index)) {
|
||||
queue.write_back_outputs(*output_queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 PLUGIN_API YaParameterChanges::getParameterCount() {
|
||||
return queues.size();
|
||||
}
|
||||
|
||||
@@ -45,6 +45,13 @@ class YaParameterChanges : public Steinberg::Vst::IParameterChanges {
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
/**
|
||||
* Write these changes back to an output parameter changes queue on the
|
||||
* `ProcessData` object provided by the host.
|
||||
*/
|
||||
void write_back_outputs(
|
||||
Steinberg::Vst::IParameterChanges& output_queues) const;
|
||||
|
||||
// From `IParameterChanges`
|
||||
int32 PLUGIN_API getParameterCount() override;
|
||||
Steinberg::Vst::IParamValueQueue* PLUGIN_API
|
||||
|
||||
@@ -92,6 +92,45 @@ Steinberg::Vst::AudioBusBuffers YaAudioBusBuffers::get() {
|
||||
return reconstructed_buffers;
|
||||
}
|
||||
|
||||
void YaAudioBusBuffers::write_back_outputs(
|
||||
Steinberg::Vst::AudioBusBuffers& output_buffers) const {
|
||||
output_buffers.silenceFlags = silence_flags;
|
||||
std::visit(
|
||||
overload{
|
||||
[&](const std::vector<std::vector<double>>& buffers) {
|
||||
for (int channel = 0; channel < output_buffers.numChannels;
|
||||
channel++) {
|
||||
std::copy(buffers[channel].begin(), buffers[channel].end(),
|
||||
output_buffers.channelBuffers64[channel]);
|
||||
}
|
||||
},
|
||||
[&](const std::vector<std::vector<float>>& buffers) {
|
||||
for (int channel = 0; channel < output_buffers.numChannels;
|
||||
channel++) {
|
||||
std::copy(buffers[channel].begin(), buffers[channel].end(),
|
||||
output_buffers.channelBuffers32[channel]);
|
||||
}
|
||||
},
|
||||
},
|
||||
buffers);
|
||||
}
|
||||
|
||||
void YaProcessDataResponse::write_back_outputs(
|
||||
Steinberg::Vst::ProcessData& process_data) {
|
||||
for (int i = 0; i < process_data.numOutputs; i++) {
|
||||
outputs[i].write_back_outputs(process_data.outputs[i]);
|
||||
}
|
||||
|
||||
if (output_parameter_changes && process_data.outputParameterChanges) {
|
||||
output_parameter_changes->write_back_outputs(
|
||||
*process_data.outputParameterChanges);
|
||||
}
|
||||
|
||||
if (output_events && process_data.outputEvents) {
|
||||
output_events->write_back_outputs(*process_data.outputEvents);
|
||||
}
|
||||
}
|
||||
|
||||
YaProcessData::YaProcessData() {}
|
||||
|
||||
YaProcessData::YaProcessData(const Steinberg::Vst::ProcessData& process_data)
|
||||
|
||||
@@ -72,6 +72,13 @@ class YaAudioBusBuffers {
|
||||
*/
|
||||
Steinberg::Vst::AudioBusBuffers get();
|
||||
|
||||
/**
|
||||
* Write these buffers and the silence flag back to an `AudioBusBuffers
|
||||
* object provided by the host.
|
||||
*/
|
||||
void write_back_outputs(
|
||||
Steinberg::Vst::AudioBusBuffers& output_buffers) const;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.value8b(silence_flags);
|
||||
@@ -134,7 +141,10 @@ struct YaProcessDataResponse {
|
||||
std::optional<YaParameterChanges> output_parameter_changes;
|
||||
std::optional<YaEventList> output_events;
|
||||
|
||||
// TODO: Add function to write these back to the host's `ProcessData`
|
||||
/**
|
||||
* Write all of this output data back to the host's `ProcessData` object.
|
||||
*/
|
||||
void write_back_outputs(Steinberg::Vst::ProcessData& process_data);
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
|
||||
Reference in New Issue
Block a user