Skip to content

Commit

Permalink
Alternative approach to [de]activate clients, do it in parallel
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <falktx@falktx.com>
  • Loading branch information
falkTX committed Aug 20, 2024
1 parent c40de24 commit 995da29
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 27 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ The commands supported by mod-host are:
e.g.: remove 0
when instance_number is -1 all plugins will be removed

activate <instance_number> <activate_value>
* toggle effect activated state
e.g.: activate 0 1
if bypass_value = 1 activate effect
if bypass_value = 0 deactivate effect
activate <instance_number> <instance_number_end> <activate_value>
* toggle effects activated state
e.g.: activate 0 0 1
if activate_value = 1 activate effect
if activate_value = 0 deactivate effect

preload <lv2_uri> <instance_number>
* add an LV2 plugin encapsulated as a jack client, in deactivated state
Expand Down
136 changes: 117 additions & 19 deletions src/effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,11 +1042,13 @@ static int BufferSize(jack_nframes_t nframes, void* data)
options[4].type = 0;
options[4].value = NULL;

lilv_instance_deactivate(effect->lilv_instance);
if (effect->activated)
lilv_instance_deactivate(effect->lilv_instance);

effect->options_interface->set(effect->lilv_instance->lv2_handle, options);

lilv_instance_activate(effect->lilv_instance);
if (effect->activated)
lilv_instance_activate(effect->lilv_instance);
}
}
#ifdef HAVE_HYLIA
Expand Down Expand Up @@ -1719,7 +1721,7 @@ static int ProcessPlugin(jack_nframes_t nframes, void *arg)
if (arg == NULL) return 0;
effect = arg;

if (!g_processing_enabled || !effect->activated || (
if (!g_processing_enabled || (
(effect->hints & HINT_STATE_UNSAFE) && pthread_mutex_trylock(&effect->state_restore_mutex) != 0))
{
for (i = 0; i < effect->output_audio_ports_count; i++)
Expand Down Expand Up @@ -5419,14 +5421,18 @@ int effects_add(const char *uri, int instance, int activate)
jack_set_buffer_size_callback(jack_client, BufferSize, effect);
jack_set_freewheel_callback(jack_client, FreeWheelMode, effect);

lilv_instance_activate(lilv_instance);

/* Try activate the Jack client */
if (jack_activate(jack_client) != 0)
if (activate)
{
fprintf(stderr, "can't activate jack_client\n");
error = ERR_JACK_CLIENT_ACTIVATION;
goto error;
lilv_instance_activate(lilv_instance);

/* Try activate the Jack client */
if (jack_activate(jack_client) != 0)
{
fprintf(stderr, "can't activate jack_client\n");
error = ERR_JACK_CLIENT_ACTIVATION;
goto error;
}
}

if (raw_midi_port != NULL)
Expand Down Expand Up @@ -5974,30 +5980,122 @@ int effects_remove(int effect_id)
return SUCCESS;
}

int effects_activate(int effect_id, int value)
static void* effects_activate_thread(void* arg)
{
jack_client_t *jack_client = arg;

if (jack_activate(jack_client) != 0)
fprintf(stderr, "can't activate jack_client\n");

return NULL;
}

static void* effects_deactivate_thread(void* arg)
{
jack_client_t *jack_client = arg;

if (jack_deactivate(jack_client) != 0)
fprintf(stderr, "can't deactivate jack_client\n");

return NULL;
}

int effects_activate(int effect_id, int effect_id_end, int value)
{
if (!InstanceExist(effect_id))
{
return ERR_INSTANCE_NON_EXISTS;
}
if (effect_id > effect_id_end)
{
return ERR_INVALID_OPERATION;
}

effect_t *effect = &g_effects[effect_id];

if (value)
if (effect_id == effect_id_end)
{
if (! effect->activated)
effect_t *effect = &g_effects[effect_id];

if (value)
{
if (! effect->activated)
{
effect->activated = true;
lilv_instance_activate(effect->lilv_instance);

if (jack_activate(effect->jack_client) != 0)
{
fprintf(stderr, "can't activate jack_client\n");
return ERR_JACK_CLIENT_ACTIVATION;
}
}
}
else
{
lilv_instance_deactivate(effect->lilv_instance);
lilv_instance_activate(effect->lilv_instance);
if (effect->activated)
{
effect->activated = false;

effect->activated = true;
if (jack_deactivate(effect->jack_client) != 0)
{
fprintf(stderr, "can't deactivate jack_client\n");
return ERR_JACK_CLIENT_DEACTIVATION;
}

lilv_instance_deactivate(effect->lilv_instance);
}
}
}
else
{
if (effect->activated)
int num_threads = 0;
pthread_t *threads = malloc(sizeof(pthread_t) * (effect_id_end - effect_id));

// create threads to activate all clients
for (int i = effect_id; i <= effect_id_end; ++i)
{
effect_t *effect = &g_effects[i];

if (effect->jack_client == NULL)
continue;

if (value)
{
if (! effect->activated)
{
effect->activated = true;
lilv_instance_activate(effect->lilv_instance);

pthread_create(&threads[num_threads++], NULL, effects_activate_thread, effect->jack_client);
}
}
else
{
if (effect->activated)
{
pthread_create(&threads[num_threads++], NULL, effects_deactivate_thread, effect->jack_client);
}
}
}

// wait for all threads to be done
for (int i = 0; i < num_threads; ++i)
pthread_join(threads[i], NULL);

free(threads);

// if deactivating, do the last lv2 deactivate step now
if (! value)
{
effect->activated = false;
for (int i = effect_id; i <= effect_id_end; ++i)
{
effect_t *effect = &g_effects[i];

if (! effect->activated || effect->jack_client == NULL)
continue;

effect->activated = false;
lilv_instance_deactivate(effect->lilv_instance);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ int effects_init(void* client);
int effects_finish(int close_client);
int effects_add(const char *uri, int instance, int activate);
int effects_remove(int effect_id);
int effects_activate(int effect_id, int value);
int effects_activate(int effect_id, int effect_id_end, int value);
int effects_preset_load(int effect_id, const char *uri);
int effects_preset_save(int effect_id, const char *dir, const char *file_name, const char *label);
int effects_preset_show(const char *uri, char **state_str);
Expand Down
2 changes: 1 addition & 1 deletion src/mod-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ static void effects_remove_cb(proto_t *proto)
static void effects_activate_cb(proto_t *proto)
{
int resp;
resp = effects_activate(atoi(proto->list[1]), atoi(proto->list[2]));
resp = effects_activate(atoi(proto->list[1]), atoi(proto->list[2]), atoi(proto->list[3]));
protocol_response_int(resp, proto);
}

Expand Down
2 changes: 1 addition & 1 deletion src/mod-host.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
/* Protocol commands definition */
#define EFFECT_ADD "add %s %i"
#define EFFECT_REMOVE "remove %i"
#define EFFECT_ACTIVATE "activate %i %i"
#define EFFECT_ACTIVATE "activate %i %i %i"
#define EFFECT_PRELOAD "preload %s %i"
#define EFFECT_PRESET_LOAD "preset_load %i %s"
#define EFFECT_PRESET_SAVE "preset_save %i %s %s %s"
Expand Down

0 comments on commit 995da29

Please sign in to comment.