Browse Source

use 2 instances when forcing mono plugins into stereo

Implements https://todo.sr.ht/~alextee/zrythm-feature/528.
audio_region_bpm_change_fix
parent
commit
706d6f5bb2
Signed by: alex
GPG Key ID: 022EAE42313D70F3
  1. 1
      inc/plugins/carla_native_plugin.h
  2. 3
      meson.build
  3. 194
      src/plugins/carla_native_plugin.c
  4. 123
      src/plugins/plugin.c
  5. 51
      tests/plugins/carla_native_plugin.c

1
inc/plugins/carla_native_plugin.h

@ -59,6 +59,7 @@ typedef enum CarlaPluginType @@ -59,6 +59,7 @@ typedef enum CarlaPluginType
typedef struct CarlaPatchbayPortInfo
{
unsigned int plugin_id;
unsigned int port_hints;
unsigned int port_id;
char * port_name;

3
meson.build

@ -244,6 +244,9 @@ ext_lv2_plugins = { @@ -244,6 +244,9 @@ ext_lv2_plugins = {
'sherlock_atom_inspector': [
'Sherlock Atom Inspector',
'http://open-music-kontrollers.ch/lv2/sherlock#atom_inspector'],
'lsp_compressor_mono': [
'LSP Compressor Mono',
'http://lsp-plug.in/plugins/lv2/compressor_mono'],
'lsp_compressor': [
'LSP Compressor',
'http://lsp-plug.in/plugins/lv2/compressor_stereo'],

194
src/plugins/carla_native_plugin.c

@ -243,7 +243,7 @@ host_ui_parameter_changed ( @@ -243,7 +243,7 @@ host_ui_parameter_changed (
uint32_t index,
float value)
{
g_message ("handle ui param changed");
g_debug ("handle ui param changed");
CarlaNativePlugin * self =
(CarlaNativePlugin *) handle;
Port * port =
@ -257,6 +257,13 @@ host_ui_parameter_changed ( @@ -257,6 +257,13 @@ host_ui_parameter_changed (
return;
}
if (carla_get_current_plugin_count (
self->host_handle) == 2)
{
carla_set_parameter_value (
self->host_handle, 1, index, value);
}
port_set_control_value (
port, value, false, false);
}
@ -539,13 +546,14 @@ carla_engine_callback ( @@ -539,13 +546,14 @@ carla_engine_callback (
/* if non-cv variant, there will be no CV
* clients */
if ((is_cv_variant && plugin_id == 7)
|| (!is_cv_variant && plugin_id == 5))
if ((is_cv_variant && plugin_id >= 7)
|| (!is_cv_variant && plugin_id >= 5))
{
unsigned int port_hints =
(unsigned int) val2;
CarlaPatchbayPortInfo * nfo =
object_new (CarlaPatchbayPortInfo);
nfo->plugin_id = plugin_id;
nfo->port_hints = port_hints;
nfo->port_id = port_id;
nfo->port_name = g_strdup (val_str);
@ -1147,7 +1155,10 @@ create_ports ( @@ -1147,7 +1155,10 @@ create_ports (
g_return_if_fail (
(int) audio_port_count_nfo->ins ==
descr->num_audio_ins);
for (int i = 0; i < descr->num_audio_ins; i++)
int audio_ins_to_create =
descr->num_audio_ins == 1
? 2 : descr->num_audio_ins;
for (int i = 0; i < audio_ins_to_create; i++)
{
strcpy (tmp, _("Audio in"));
sprintf (name, "%s %d", tmp, i);
@ -1161,7 +1172,9 @@ create_ports ( @@ -1161,7 +1172,9 @@ create_ports (
unsigned int audio_port_hints =
carla_get_audio_port_hints (
self->host_handle, 0, false,
(uint32_t) i);
(uint32_t)
(descr->num_audio_ins == 1
? 0 : i));
g_debug ("audio port hints %d: %u",
i, audio_port_hints);
if (audio_port_hints
@ -1175,7 +1188,11 @@ create_ports ( @@ -1175,7 +1188,11 @@ create_ports (
plugin_add_in_port (
self->plugin, port);
}
for (int i = 0; i < descr->num_audio_outs; i++)
int audio_outs_to_create =
descr->num_audio_outs == 1
? 2 : descr->num_audio_outs;
for (int i = 0; i < audio_outs_to_create; i++)
{
strcpy (tmp, _("Audio out"));
sprintf (name, "%s %d", tmp, i);
@ -1489,6 +1506,75 @@ carla_native_plugin_update_buffer_size_and_sample_rate ( @@ -1489,6 +1506,75 @@ carla_native_plugin_update_buffer_size_and_sample_rate (
}
}
static int
add_internal_plugin_from_descr (
CarlaNativePlugin * self,
const PluginDescriptor * descr)
{
/** Number of instances to instantiate (1
* normally or 2 for mono plugins). */
int num_instances =
descr->num_audio_ins == 1 ? 2 : 1;
const PluginType type =
get_plugin_type_from_protocol (
descr->protocol);
int ret = 0;
for (int i = 0; i < num_instances; i++)
{
switch (descr->protocol)
{
case PROT_LV2:
case PROT_AU:
g_debug ("uri %s", descr->uri);
ret =
carla_add_plugin (
self->host_handle,
descr->arch == ARCH_64 ?
BINARY_NATIVE : BINARY_WIN32,
type, NULL, descr->name,
descr->uri, 0, NULL, 0);
break;
case PROT_VST:
case PROT_VST3:
ret =
carla_add_plugin (
self->host_handle,
descr->arch == ARCH_64 ?
BINARY_NATIVE : BINARY_WIN32,
type, descr->path, descr->name,
descr->name, descr->unique_id, NULL, 0);
break;
case PROT_DSSI:
case PROT_LADSPA:
ret =
carla_add_plugin (
self->host_handle, BINARY_NATIVE,
type, descr->path, descr->name,
descr->uri, 0, NULL, 0);
break;
case PROT_SFZ:
case PROT_SF2:
ret =
carla_add_plugin (
self->host_handle,
BINARY_NATIVE,
type, descr->path, descr->name,
descr->name, 0, NULL, 0);
break;
default:
g_return_val_if_reached (-1);
break;
}
if (ret != 1)
return ret;
}
return ret;
}
/**
* Instantiates the plugin.
*
@ -1825,53 +1911,8 @@ carla_native_plugin_instantiate ( @@ -1825,53 +1911,8 @@ carla_native_plugin_instantiate (
return -1;
}
const PluginType type =
get_plugin_type_from_protocol (descr->protocol);
int ret = 0;
switch (descr->protocol)
{
case PROT_LV2:
case PROT_AU:
g_message ("uri %s", descr->uri);
ret =
carla_add_plugin (
self->host_handle,
descr->arch == ARCH_64 ?
BINARY_NATIVE : BINARY_WIN32,
type, NULL, descr->name,
descr->uri, 0, NULL, 0);
break;
case PROT_VST:
case PROT_VST3:
ret =
carla_add_plugin (
self->host_handle,
descr->arch == ARCH_64 ?
BINARY_NATIVE : BINARY_WIN32,
type, descr->path, descr->name,
descr->name, descr->unique_id, NULL, 0);
break;
case PROT_DSSI:
case PROT_LADSPA:
ret =
carla_add_plugin (
self->host_handle, BINARY_NATIVE,
type, descr->path, descr->name,
descr->uri, 0, NULL, 0);
break;
case PROT_SFZ:
case PROT_SF2:
ret =
carla_add_plugin (
self->host_handle,
BINARY_NATIVE,
type, descr->path, descr->name,
descr->name, 0, NULL, 0);
break;
default:
g_warn_if_reached ();
break;
}
int ret =
add_internal_plugin_from_descr (self, descr);
carla_native_plugin_update_buffer_size_and_sample_rate (
self);
@ -1922,24 +1963,23 @@ carla_native_plugin_instantiate ( @@ -1922,24 +1963,23 @@ carla_native_plugin_instantiate (
unsigned int num_cv_outs_connected = 0;
unsigned int num_midi_ins_connected = 0;
unsigned int num_midi_outs_connected = 0;
unsigned int plugin_client = 5;
bool is_cv_variant =
self->max_variant_cv_ins > 0
|| self->max_variant_cv_outs > 0;
if (is_cv_variant)
plugin_client = 7;
for (size_t i = 0;
i < self->patchbay_port_info->len; i++)
{
CarlaPatchbayPortInfo * nfo =
g_ptr_array_index (
self->patchbay_port_info, i);
unsigned int plugin_id = nfo->plugin_id;
unsigned int port_hints = nfo->port_hints;
unsigned int port_id = nfo->port_id;
char * port_name = nfo->port_name;
g_debug (
"processing %s, portid %u, port hints %u",
port_name, port_id, port_hints);
"processing %s, plugin id %u, "
"portid %u, port hints %u",
port_name, plugin_id, port_id, port_hints);
if (port_hints & PATCHBAY_PORT_IS_INPUT)
{
if (port_hints &
@ -1953,7 +1993,7 @@ carla_native_plugin_instantiate ( @@ -1953,7 +1993,7 @@ carla_native_plugin_instantiate (
1,
self->audio_input_port_id +
num_audio_ins_connected,
plugin_client, port_id);
plugin_id, port_id);
ret =
carla_patchbay_connect (
self->host_handle,
@ -1961,7 +2001,7 @@ carla_native_plugin_instantiate ( @@ -1961,7 +2001,7 @@ carla_native_plugin_instantiate (
1,
self->audio_input_port_id +
num_audio_ins_connected++,
plugin_client, port_id);
plugin_id, port_id);
if (!ret)
{
g_critical (
@ -1981,7 +2021,7 @@ carla_native_plugin_instantiate ( @@ -1981,7 +2021,7 @@ carla_native_plugin_instantiate (
3,
self->cv_input_port_id +
num_cv_ins_connected,
plugin_client, port_id);
plugin_id, port_id);
ret =
carla_patchbay_connect (
self->host_handle,
@ -1989,7 +2029,7 @@ carla_native_plugin_instantiate ( @@ -1989,7 +2029,7 @@ carla_native_plugin_instantiate (
3,
self->cv_input_port_id +
num_cv_ins_connected++,
plugin_client, port_id);
plugin_id, port_id);
if (!ret)
{
g_critical (
@ -2009,7 +2049,7 @@ carla_native_plugin_instantiate ( @@ -2009,7 +2049,7 @@ carla_native_plugin_instantiate (
is_cv_variant ? 5 : 3,
self->midi_input_port_id +
num_midi_ins_connected,
plugin_client, port_id);
plugin_id, port_id);
ret =
carla_patchbay_connect (
self->host_handle,
@ -2017,7 +2057,7 @@ carla_native_plugin_instantiate ( @@ -2017,7 +2057,7 @@ carla_native_plugin_instantiate (
is_cv_variant ? 5 : 3,
self->midi_input_port_id +
num_midi_ins_connected++,
plugin_client, port_id);
plugin_id, port_id);
if (!ret)
{
g_critical (
@ -2038,7 +2078,7 @@ carla_native_plugin_instantiate ( @@ -2038,7 +2078,7 @@ carla_native_plugin_instantiate (
{
g_debug (
"connecting %d:%u to %d:%u",
plugin_client, port_id,
plugin_id, port_id,
2,
self->audio_output_port_id +
num_audio_outs_connected);
@ -2046,7 +2086,7 @@ carla_native_plugin_instantiate ( @@ -2046,7 +2086,7 @@ carla_native_plugin_instantiate (
carla_patchbay_connect (
self->host_handle,
false,
plugin_client, port_id,
plugin_id, port_id,
2,
self->audio_output_port_id +
num_audio_outs_connected++);
@ -2066,7 +2106,7 @@ carla_native_plugin_instantiate ( @@ -2066,7 +2106,7 @@ carla_native_plugin_instantiate (
{
g_debug (
"connecting %d:%u to %d:%u",
plugin_client, port_id,
plugin_id, port_id,
4,
self->cv_output_port_id +
num_cv_outs_connected);
@ -2074,7 +2114,7 @@ carla_native_plugin_instantiate ( @@ -2074,7 +2114,7 @@ carla_native_plugin_instantiate (
carla_patchbay_connect (
self->host_handle,
false,
plugin_client, port_id,
plugin_id, port_id,
4,
self->cv_output_port_id +
num_cv_outs_connected++);
@ -2094,7 +2134,7 @@ carla_native_plugin_instantiate ( @@ -2094,7 +2134,7 @@ carla_native_plugin_instantiate (
{
g_debug (
"connecting %d:%u to %d:%u",
plugin_client, port_id,
plugin_id, port_id,
is_cv_variant ? 6 : 4,
self->midi_output_port_id +
num_midi_outs_connected);
@ -2102,7 +2142,7 @@ carla_native_plugin_instantiate ( @@ -2102,7 +2142,7 @@ carla_native_plugin_instantiate (
carla_patchbay_connect (
self->host_handle,
false,
plugin_client, port_id,
plugin_id, port_id,
is_cv_variant ? 6 : 4,
self->midi_output_port_id +
num_midi_outs_connected++);
@ -2390,6 +2430,12 @@ carla_native_plugin_set_param_value ( @@ -2390,6 +2430,12 @@ carla_native_plugin_set_param_value (
}
carla_set_parameter_value (
self->host_handle, 0, id, val);
if (carla_get_current_plugin_count (
self->host_handle) == 2)
{
carla_set_parameter_value (
self->host_handle, 1, id, val);
}
}
/**
@ -2588,6 +2634,14 @@ carla_native_plugin_load_state ( @@ -2588,6 +2634,14 @@ carla_native_plugin_load_state (
self->loading_state = true;
carla_load_plugin_state (
self->host_handle, 0, state_file);
uint32_t plugin_count =
carla_get_current_plugin_count (
self->host_handle);
if (plugin_count == 2)
{
carla_load_plugin_state (
self->host_handle, 1, state_file);
}
self->loading_state = false;
if (pl->visible
&& plugin_is_in_active_project (pl))

123
src/plugins/plugin.c

@ -112,51 +112,40 @@ set_stereo_outs_and_midi_in ( @@ -112,51 +112,40 @@ set_stereo_outs_and_midi_in (
pl->setting && pl->setting->descr);
/* set the L/R outputs */
if (pl->setting->descr->num_audio_outs == 1)
int num_audio_outs = 0;
for (int i = 0; i < pl->num_out_ports; i++)
{
/* if mono find the audio out and set it as
* both stereo out L and R */
for (int i = 0; i < pl->num_out_ports; i++)
Port * out_port = pl->out_ports[i];
if (out_port->id.type == TYPE_AUDIO)
{
Port * out_port = pl->out_ports[i];
if (out_port->id.type == TYPE_AUDIO)
if (num_audio_outs == 0)
{
out_port->id.flags |=
PORT_FLAG_STEREO_L;
out_port->id.flags |=
PORT_FLAG_STEREO_R;
pl->l_out = out_port;
pl->r_out = out_port;
break;
}
}
}
else if (pl->setting->descr->num_audio_outs > 1)
{
int last_index = 0;
for (int i = 0; i < pl->num_out_ports; i++)
{
Port * out_port = pl->out_ports[i];
if (out_port->id.type != TYPE_AUDIO)
continue;
if (last_index == 0)
{
out_port->id.flags |=
PORT_FLAG_STEREO_L;
pl->l_out = out_port;
last_index++;
}
else if (last_index == 1)
else if (num_audio_outs == 1)
{
out_port->id.flags |=
PORT_FLAG_STEREO_R;
pl->r_out = out_port;
break;
}
num_audio_outs++;
}
}
/* if mono set it as both stereo out L and
* R */
if (num_audio_outs == 1)
{
/* this code is only accessed by beta
* projects before the change to force
* stereo a few commits after beta 1.1.11 */
g_warning ("should not happen with carla");
pl->l_out->id.flags |= PORT_FLAG_STEREO_R;
pl->r_out = pl->l_out;
}
if (pl->setting->descr->num_audio_outs > 0)
{
g_return_if_fail (pl->l_out && pl->r_out);
@ -2687,8 +2676,25 @@ plugin_connect_to_plugin ( @@ -2687,8 +2676,25 @@ plugin_connect_to_plugin (
int i, j, last_index, num_ports_to_connect;
Port * in_port, * out_port;
if (src->setting->descr->num_audio_outs == 1 &&
dest->setting->descr->num_audio_ins == 1)
/* get actual port counts */
int num_src_audio_outs = 0;
for (i = 0; i < src->num_out_ports; i++)
{
Port * port = src->out_ports[i];
if (port->id.type == TYPE_AUDIO)
num_src_audio_outs++;
}
int num_dest_audio_ins = 0;
for (i = 0; i < dest->num_in_ports; i++)
{
Port * port = dest->in_ports[i];
if (port->id.type == TYPE_AUDIO)
num_dest_audio_ins++;
}
if (num_src_audio_outs == 1 &&
num_dest_audio_ins == 1)
{
last_index = 0;
for (i = 0; i < src->num_out_ports; i++)
@ -2715,8 +2721,8 @@ plugin_connect_to_plugin ( @@ -2715,8 +2721,8 @@ plugin_connect_to_plugin (
done1:
;
}
else if (src->setting->descr->num_audio_outs == 1 &&
dest->setting->descr->num_audio_ins > 1)
else if (num_src_audio_outs == 1 &&
num_dest_audio_ins > 1)
{
/* plugin is mono and next plugin is
* not mono, so connect the mono out to
@ -2744,8 +2750,8 @@ done1: @@ -2744,8 +2750,8 @@ done1:
}
}
}
else if (src->setting->descr->num_audio_outs > 1 &&
dest->setting->descr->num_audio_ins == 1)
else if (num_src_audio_outs > 1 &&
num_dest_audio_ins == 1)
{
/* connect multi-output channel into mono by
* only connecting to the first input channel
@ -2775,15 +2781,15 @@ done1: @@ -2775,15 +2781,15 @@ done1:
done2:
;
}
else if (src->setting->descr->num_audio_outs > 1 &&
dest->setting->descr->num_audio_ins > 1)
else if (num_src_audio_outs > 1 &&
num_dest_audio_ins > 1)
{
/* connect to as many audio outs this
* plugin has, or until we can't connect
* anymore */
num_ports_to_connect =
MIN (src->setting->descr->num_audio_outs,
dest->setting->descr->num_audio_ins);
MIN (num_src_audio_outs,
num_dest_audio_ins);
last_index = 0;
int ports_connected = 0;
for (i = 0; i < src->num_out_ports; i++)
@ -2957,8 +2963,25 @@ plugin_disconnect_from_plugin ( @@ -2957,8 +2963,25 @@ plugin_disconnect_from_plugin (
int i, j, last_index, num_ports_to_connect;
Port * in_port, * out_port;
if (src->setting->descr->num_audio_outs == 1 &&
dest->setting->descr->num_audio_ins == 1)
/* get actual port counts */
int num_src_audio_outs = 0;
for (i = 0; i < src->num_out_ports; i++)
{
Port * port = src->out_ports[i];
if (port->id.type == TYPE_AUDIO)
num_src_audio_outs++;
}
int num_dest_audio_ins = 0;
for (i = 0; i < dest->num_in_ports; i++)
{
Port * port = dest->in_ports[i];
if (port->id.type == TYPE_AUDIO)
num_dest_audio_ins++;
}
if (num_src_audio_outs == 1 &&
num_dest_audio_ins == 1)
{
last_index = 0;
for (i = 0; i < src->num_out_ports; i++)
@ -2985,8 +3008,8 @@ plugin_disconnect_from_plugin ( @@ -2985,8 +3008,8 @@ plugin_disconnect_from_plugin (
done1:
;
}
else if (src->setting->descr->num_audio_outs == 1 &&
dest->setting->descr->num_audio_ins > 1)
else if (num_src_audio_outs == 1 &&
num_dest_audio_ins > 1)
{
/* plugin is mono and next plugin is
* not mono, so disconnect the mono out from
@ -3014,8 +3037,8 @@ done1: @@ -3014,8 +3037,8 @@ done1:
}
}
}
else if (src->setting->descr->num_audio_outs > 1 &&
dest->setting->descr->num_audio_ins == 1)
else if (num_src_audio_outs > 1 &&
num_dest_audio_ins == 1)
{
/* disconnect multi-output channel from mono
* by disconnecting to the first input channel
@ -3045,15 +3068,15 @@ done1: @@ -3045,15 +3068,15 @@ done1:
done2:
;
}
else if (src->setting->descr->num_audio_outs > 1 &&
dest->setting->descr->num_audio_ins > 1)
else if (num_src_audio_outs > 1 &&
num_dest_audio_ins > 1)
{
/* connect to as many audio outs this
* plugin has, or until we can't connect
* anymore */
num_ports_to_connect =
MIN (src->setting->descr->num_audio_outs,
dest->setting->descr->num_audio_ins);
MIN (num_src_audio_outs,
num_dest_audio_ins);
last_index = 0;
int ports_disconnected = 0;
for (i = 0; i < src->num_out_ports; i++)

51
tests/plugins/carla_native_plugin.c

@ -30,6 +30,54 @@ @@ -30,6 +30,54 @@
#include <glib.h>
static void
test_mono_plugin (void)
{
#if defined (HAVE_CARLA) \
&& defined (HAVE_LSP_COMPRESSOR_MONO)
test_helper_zrythm_init ();
/* stop dummy audio engine processing so we can
* process manually */
AUDIO_ENGINE->stop_dummy_audio_thread = true;
g_usleep (1000000);
/* create a track */
Track * track =
track_create_empty_with_action (
TRACK_TYPE_AUDIO_BUS, NULL);
PluginSetting * setting =
test_plugin_manager_get_plugin_setting (
LSP_COMPRESSOR_MONO_BUNDLE,
LSP_COMPRESSOR_MONO_URI,
true);
g_return_if_fail (setting);
bool ret =
mixer_selections_action_perform_create (
PLUGIN_SLOT_INSERT,
track_get_name_hash (track), 0, setting, 1,
NULL);
g_assert_true (ret);
Plugin * pl =
track->channel->inserts[0];
g_assert_true (IS_PLUGIN_AND_NONNULL (pl));
engine_process (
AUDIO_ENGINE, AUDIO_ENGINE->block_length);
engine_process (
AUDIO_ENGINE, AUDIO_ENGINE->block_length);
engine_process (
AUDIO_ENGINE, AUDIO_ENGINE->block_length);
test_helper_zrythm_cleanup ();
#endif
}
#if 0
static void
test_has_custom_ui (void)
@ -150,6 +198,9 @@ main (int argc, char *argv[]) @@ -150,6 +198,9 @@ main (int argc, char *argv[])
#define TEST_PREFIX "/plugins/carla native plugin/"
g_test_add_func (
TEST_PREFIX "test mono plugin",
(GTestFunc) test_mono_plugin);
g_test_add_func (
TEST_PREFIX "test process",
(GTestFunc) test_process);

Loading…
Cancel
Save