mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Process offline audio from the GUI thread
Because T-RackS 5 won't have it any other way.
This commit is contained in:
@@ -17,6 +17,16 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
[!1120](https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/1120)
|
[!1120](https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/1120)
|
||||||
have been merged.
|
have been merged.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the VST3 version of _IK Multimedia's T-RackS 5_ producing silence while
|
||||||
|
doing offline rendering. This could happen when exporting or bouncing audio in
|
||||||
|
**Bitwig Studio 4.1**, **Ardour** and in **REAPER**. These plugins apparently
|
||||||
|
need to process audio from the main GUI thread when in offline rendering mode.
|
||||||
|
If you try to process audio from the...audio thread, then they will produce
|
||||||
|
silence and hang afterwards (which a fix in yabridge 3.7.0 previously
|
||||||
|
addressed).
|
||||||
|
|
||||||
## [3.8.0] - 2022-01-15
|
## [3.8.0] - 2022-01-15
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -115,10 +115,7 @@ bool Vst3Bridge::inhibits_event_loop() noexcept {
|
|||||||
std::shared_lock lock(object_instances_mutex_);
|
std::shared_lock lock(object_instances_mutex_);
|
||||||
|
|
||||||
for (const auto& [instance_id, instance] : object_instances_) {
|
for (const auto& [instance_id, instance] : object_instances_) {
|
||||||
// HACK: IK Multimedia's T-RackS 5 will deadlock if it receives a timer
|
if (!instance.is_initialized) {
|
||||||
// proc during offline processing, so we need to prevent that from
|
|
||||||
// happening.
|
|
||||||
if (!instance.is_initialized || instance.is_offline_processing) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1559,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
const auto& [instance, _] =
|
const auto& [instance, _] =
|
||||||
get_instance(request.instance_id);
|
get_instance(request.instance_id);
|
||||||
|
|
||||||
// See the comment in
|
// See the comment in the
|
||||||
// `Vst3Bridge::inhibits_event_loop()`
|
// `YaAudioProcessor::Process` handler
|
||||||
instance.is_offline_processing =
|
instance.is_offline_processing =
|
||||||
request.setup.processMode ==
|
request.setup.processMode ==
|
||||||
Steinberg::Vst::kOffline;
|
Steinberg::Vst::kOffline;
|
||||||
@@ -1631,11 +1628,28 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
// The actual audio is stored in the shared memory
|
// The actual audio is stored in the shared memory
|
||||||
// buffers, so the reconstruction function will need to
|
// buffers, so the reconstruction function will need to
|
||||||
// know where it should point the `AudioBusBuffers` to
|
// know where it should point the `AudioBusBuffers` to
|
||||||
const tresult result =
|
// HACK: IK-Multimedia's T-RackS 5 will hang if audio
|
||||||
instance.interfaces.audio_processor->process(
|
// processing is done from the audio thread while
|
||||||
request.data.reconstruct(
|
// the plugin is in offline processing mode. Yes
|
||||||
|
// that's as silly as it sounds.
|
||||||
|
tresult result;
|
||||||
|
auto& reconstructed = request.data.reconstruct(
|
||||||
instance.process_buffers_input_pointers,
|
instance.process_buffers_input_pointers,
|
||||||
instance.process_buffers_output_pointers));
|
instance.process_buffers_output_pointers);
|
||||||
|
if (instance.is_offline_processing) {
|
||||||
|
result = main_context_
|
||||||
|
.run_in_context([&instance = instance,
|
||||||
|
&reconstructed]() {
|
||||||
|
return instance.interfaces
|
||||||
|
.audio_processor->process(
|
||||||
|
reconstructed);
|
||||||
|
})
|
||||||
|
.get();
|
||||||
|
} else {
|
||||||
|
result =
|
||||||
|
instance.interfaces.audio_processor->process(
|
||||||
|
reconstructed);
|
||||||
|
}
|
||||||
|
|
||||||
return YaAudioProcessor::ProcessResponse{
|
return YaAudioProcessor::ProcessResponse{
|
||||||
.result = result,
|
.result = result,
|
||||||
|
|||||||
@@ -249,8 +249,8 @@ struct Vst3PluginInstance {
|
|||||||
/**
|
/**
|
||||||
* Whether the plugin instance is currently in offline processing mode or
|
* Whether the plugin instance is currently in offline processing mode or
|
||||||
* not. Needed as a HACK for IK Multimedia's T-RackS 5 because those plugins
|
* not. Needed as a HACK for IK Multimedia's T-RackS 5 because those plugins
|
||||||
* will deadlock if they receive a timer proc on the Win32 message loop
|
* will deadlock if they don't process audio from the GUI thread while doing
|
||||||
* while doing offline processing.
|
* offline processing.
|
||||||
*/
|
*/
|
||||||
bool is_offline_processing = false;
|
bool is_offline_processing = false;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user