mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Also cache audioMasterGetCurrentProcessLevel()
Melda plugins seem to call this during every processing cycle.
This commit is contained in:
@@ -19,6 +19,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
information repeatedly for every sample they process. Previously yabridge had
|
||||
a `cache_time_info` compatibility option to mitigate the performance hit for
|
||||
those plugins, but this new caching behaviour supercedes that.
|
||||
- Similarly, yabridge will also cache the current process level during audio
|
||||
processing to reduce bridging overhead for plugins that use this.
|
||||
- We now always force the CPU's flush-to-zero flag to be set when processing
|
||||
audio. Most plugins will already do this themselves, but plugins like _Kush
|
||||
Audio REDDI_ and _Expressive E Noisy_ that don't will otherwise suffer from
|
||||
|
||||
@@ -559,11 +559,16 @@ struct AudioBuffers {
|
||||
* We'll send the current transport information as part of an audio
|
||||
* processing call. This lets us a void an unnecessary callback (or in some
|
||||
* cases, more than one) during every processing cycle.
|
||||
*
|
||||
* TODO: Do the same thing for the current process level
|
||||
*/
|
||||
std::optional<VstTimeInfo> current_time_info;
|
||||
|
||||
/**
|
||||
* Some plugins will also ask for the current process level during audio
|
||||
* processing. To prevent unnecessary expensive callbacks, we'll send this
|
||||
* information along with the processing call.
|
||||
*/
|
||||
int current_process_level;
|
||||
|
||||
/**
|
||||
* We'll periodically synchronize the realtime priority setting of the
|
||||
* host's audio thread with the Wine plugin host. We'll do this
|
||||
@@ -592,6 +597,8 @@ struct AudioBuffers {
|
||||
s.value4b(sample_frames);
|
||||
|
||||
s.ext(current_time_info, bitsery::ext::StdOptional{});
|
||||
s.value4b(current_process_level);
|
||||
|
||||
s.ext(new_realtime_priority, bitsery::ext::StdOptional{},
|
||||
[](S& s, int& priority) { s.value4b(priority); });
|
||||
}
|
||||
|
||||
@@ -568,10 +568,18 @@ void Vst2PluginBridge::do_process(T** inputs, T** outputs, int sample_frames) {
|
||||
current_time_info = *returned_time_info;
|
||||
}
|
||||
|
||||
// Some plugisn also ask for the current process level, so we'll cache that
|
||||
// information as well
|
||||
const int current_process_level = static_cast<int>(host_callback_function(
|
||||
&plugin, audioMasterGetCurrentProcessLevel, 0, 0, nullptr, 0.0));
|
||||
if (returned_time_info) {
|
||||
current_time_info = *returned_time_info;
|
||||
}
|
||||
|
||||
// We'll synchronize the scheduling priority of the audio thread on the Wine
|
||||
// plugin host with that of the host's audio thread every once in a while
|
||||
std::optional<int> new_realtime_priority;
|
||||
time_t now = std::time(nullptr);
|
||||
const time_t now = std::time(nullptr);
|
||||
if (now > last_audio_thread_priority_synchronization +
|
||||
audio_thread_priority_synchronization_interval) {
|
||||
new_realtime_priority = get_realtime_priority();
|
||||
@@ -590,6 +598,7 @@ void Vst2PluginBridge::do_process(T** inputs, T** outputs, int sample_frames) {
|
||||
const AudioBuffers request{.buffers = input_buffers,
|
||||
.sample_frames = sample_frames,
|
||||
.current_time_info = current_time_info,
|
||||
.current_process_level = current_process_level,
|
||||
.new_realtime_priority = new_realtime_priority};
|
||||
sockets.host_vst_process_replacing.send(request, process_buffer);
|
||||
|
||||
|
||||
@@ -190,11 +190,17 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context,
|
||||
// we'll send the current transport information as part of the
|
||||
// request so we cache it to avoid unnecessary callbacks from
|
||||
// the audio thread
|
||||
std::optional<decltype(time_info_cache)::Guard> cache_guard =
|
||||
request.current_time_info
|
||||
? std::optional(
|
||||
time_info_cache.set(*request.current_time_info))
|
||||
: std::nullopt;
|
||||
std::optional<decltype(time_info_cache)::Guard>
|
||||
time_info_cache_guard =
|
||||
request.current_time_info
|
||||
? std::optional(time_info_cache.set(
|
||||
*request.current_time_info))
|
||||
: std::nullopt;
|
||||
|
||||
// We'll also cache the process level, since some plugins will
|
||||
// ask for this during every processing cycle
|
||||
decltype(process_level_cache)::Guard process_level_cache_guard =
|
||||
process_level_cache.set(request.current_process_level);
|
||||
|
||||
// As suggested by Jack Winter, we'll synchronize this thread's
|
||||
// audio processing priority with that of the host's audio
|
||||
@@ -266,6 +272,7 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context,
|
||||
.buffers = output_buffers_single_precision,
|
||||
.sample_frames = request.sample_frames,
|
||||
.current_time_info = std::nullopt,
|
||||
.current_process_level = 0,
|
||||
.new_realtime_priority = std::nullopt};
|
||||
sockets.host_vst_process_replacing.send(response,
|
||||
buffer);
|
||||
@@ -295,6 +302,7 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context,
|
||||
.buffers = output_buffers_double_precision,
|
||||
.sample_frames = request.sample_frames,
|
||||
.current_time_info = std::nullopt,
|
||||
.current_process_level = 0,
|
||||
.new_realtime_priority = std::nullopt};
|
||||
sockets.host_vst_process_replacing.send(response,
|
||||
buffer);
|
||||
@@ -620,6 +628,18 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
|
||||
return result;
|
||||
}
|
||||
} break;
|
||||
case audioMasterGetCurrentProcessLevel: {
|
||||
// We also send the current process level for similar reasons
|
||||
const int* current_process_level = process_level_cache.get();
|
||||
if (current_process_level) {
|
||||
logger.log_event(false, opcode, index, value, nullptr, option,
|
||||
std::nullopt);
|
||||
logger.log_event_response(false, opcode, *current_process_level,
|
||||
nullptr, std::nullopt, true);
|
||||
|
||||
return *current_process_level;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
HostCallbackDataConverter converter(effect, last_time_info);
|
||||
|
||||
@@ -129,6 +129,12 @@ class Vst2Bridge : public HostBridge {
|
||||
*/
|
||||
ScopedValueCache<VstTimeInfo> time_info_cache;
|
||||
|
||||
/**
|
||||
* Some plugins will also ask for the current process level during audio
|
||||
* processing, so we'll also cache that to prevent expensive callbacks.
|
||||
*/
|
||||
ScopedValueCache<int> process_level_cache;
|
||||
|
||||
// FIXME: This emits `-Wignored-attributes` as of Wine 5.22
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
|
||||
Reference in New Issue
Block a user