diff options
author | David Robillard <d@drobilla.net> | 2024-11-21 14:08:02 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2024-11-24 19:11:44 -0500 |
commit | 2a5bc1ca7aee36cd763ac10c894b84eef347fe25 (patch) | |
tree | b145b86c8f98fb6d7adab34f69c1bcb0114e34fa /src | |
parent | 724aab7a868ed0200afbeecf056e53b5ea16b23d (diff) | |
download | jalv-2a5bc1ca7aee36cd763ac10c894b84eef347fe25.tar.gz jalv-2a5bc1ca7aee36cd763ac10c894b84eef347fe25.tar.bz2 jalv-2a5bc1ca7aee36cd763ac10c894b84eef347fe25.zip |
Factor out "settings" that affect the execution process
Diffstat (limited to 'src')
-rw-r--r-- | src/features.c | 62 | ||||
-rw-r--r-- | src/features.h | 8 | ||||
-rw-r--r-- | src/jack.c | 20 | ||||
-rw-r--r-- | src/jalv.c | 127 | ||||
-rw-r--r-- | src/jalv.h | 35 | ||||
-rw-r--r-- | src/jalv_gtk.c | 3 | ||||
-rw-r--r-- | src/jalv_qt.cpp | 2 | ||||
-rw-r--r-- | src/portaudio.c | 6 | ||||
-rw-r--r-- | src/process.c | 5 | ||||
-rw-r--r-- | src/settings.h | 27 |
10 files changed, 176 insertions, 119 deletions
diff --git a/src/features.c b/src/features.c new file mode 100644 index 0000000..82d8c27 --- /dev/null +++ b/src/features.c @@ -0,0 +1,62 @@ +// Copyright 2018-2024 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#include "features.h" + +#include "macros.h" +#include "settings.h" +#include "urids.h" + +#include <lv2/options/options.h> + +#include <stdint.h> +#include <string.h> + +void +jalv_init_lv2_options(JalvFeatures* const features, + const JalvURIDs* const urids, + const JalvSettings* const settings) +{ + const LV2_Options_Option options[ARRAY_SIZE(features->options)] = { + {LV2_OPTIONS_INSTANCE, + 0, + urids->param_sampleRate, + sizeof(float), + urids->atom_Float, + &settings->sample_rate}, + {LV2_OPTIONS_INSTANCE, + 0, + urids->bufsz_minBlockLength, + sizeof(int32_t), + urids->atom_Int, + &settings->block_length}, + {LV2_OPTIONS_INSTANCE, + 0, + urids->bufsz_maxBlockLength, + sizeof(int32_t), + urids->atom_Int, + &settings->block_length}, + {LV2_OPTIONS_INSTANCE, + 0, + urids->bufsz_sequenceSize, + sizeof(int32_t), + urids->atom_Int, + &settings->midi_buf_size}, + {LV2_OPTIONS_INSTANCE, + 0, + urids->ui_updateRate, + sizeof(float), + urids->atom_Float, + &settings->ui_update_hz}, + {LV2_OPTIONS_INSTANCE, + 0, + urids->ui_scaleFactor, + sizeof(float), + urids->atom_Float, + &settings->ui_scale_factor}, + {LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL}}; + + memcpy(features->options, options, sizeof(features->options)); + features->options_feature.URI = LV2_OPTIONS__options; + features->options_feature.data = (void*)features->options; +} diff --git a/src/features.h b/src/features.h index b6855f5..54742d7 100644 --- a/src/features.h +++ b/src/features.h @@ -5,6 +5,8 @@ #define JALV_FEATURES_H #include "attributes.h" +#include "settings.h" +#include "urids.h" #include <lv2/core/lv2.h> #include <lv2/data-access/data-access.h> @@ -37,6 +39,12 @@ typedef struct { LV2_Extension_Data_Feature ext_data; } JalvFeatures; +/// Set LV2 options feature for passing to plugin after settings are determined +void +jalv_init_lv2_options(JalvFeatures* features, + const JalvURIDs* urids, + const JalvSettings* settings); + JALV_END_DECLS #endif // JALV_FEATURES_H @@ -12,6 +12,7 @@ #include "lv2_evbuf.h" #include "port.h" #include "process.h" +#include "settings.h" #include "string_utils.h" #include "types.h" #include "urids.h" @@ -50,11 +51,13 @@ static const float max_latency = 16777216.0f; static int jack_buffer_size_cb(jack_nframes_t nframes, void* data) { - Jalv* const jalv = (Jalv*)data; - jalv->block_length = nframes; + Jalv* const jalv = (Jalv*)data; + JalvSettings* const settings = &jalv->settings; + + settings->block_length = nframes; #if USE_JACK_PORT_TYPE_GET_BUFFER_SIZE - jalv->midi_buf_size = jack_port_type_get_buffer_size(jalv->backend->client, - JACK_DEFAULT_MIDI_TYPE); + settings->midi_buf_size = jack_port_type_get_buffer_size( + jalv->backend->client, JACK_DEFAULT_MIDI_TYPE); #endif if (jalv->run_state == JALV_RUNNING) { jalv_allocate_port_buffers(jalv); @@ -355,11 +358,12 @@ jalv_backend_open(Jalv* jalv) jalv_log(JALV_LOG_INFO, "JACK name: %s\n", jack_get_client_name(client)); // Set audio engine properties - jalv->sample_rate = (float)jack_get_sample_rate(client); - jalv->block_length = jack_get_buffer_size(client); - jalv->midi_buf_size = 4096; + JalvSettings* const settings = &jalv->settings; + settings->sample_rate = (float)jack_get_sample_rate(client); + settings->block_length = jack_get_buffer_size(client); + settings->midi_buf_size = 4096; #if USE_JACK_PORT_TYPE_GET_BUFFER_SIZE - jalv->midi_buf_size = + settings->midi_buf_size = jack_port_type_get_buffer_size(client, JACK_DEFAULT_MIDI_TYPE); #endif @@ -7,6 +7,7 @@ #include "comm.h" #include "control.h" #include "dumper.h" +#include "features.h" #include "frontend.h" #include "jalv_config.h" #include "log.h" @@ -14,8 +15,10 @@ #include "macros.h" #include "mapper.h" #include "nodes.h" +#include "options.h" #include "port.h" #include "query.h" +#include "settings.h" #include "state.h" #include "string_utils.h" #include "types.h" @@ -31,7 +34,6 @@ #include <lv2/data-access/data-access.h> #include <lv2/instance-access/instance-access.h> #include <lv2/log/log.h> -#include <lv2/options/options.h> #include <lv2/patch/patch.h> #include <lv2/state/state.h> #include <lv2/ui/ui.h> @@ -135,7 +137,7 @@ create_port(Jalv* jalv, uint32_t port_index) jalv->plugin, port->lilv_port, port->index, - jalv->sample_rate, + jalv->settings.sample_rate, &jalv->nodes, &jalv->forge)); } @@ -219,7 +221,8 @@ jalv_allocate_port_buffers(Jalv* jalv) for (uint32_t i = 0; i < jalv->num_ports; ++i) { JalvPort* const port = &jalv->ports[i]; if (port->type == TYPE_EVENT) { - const size_t size = port->buf_size ? port->buf_size : jalv->midi_buf_size; + const size_t size = + port->buf_size ? port->buf_size : jalv->settings.midi_buf_size; lv2_evbuf_free(port->evbuf); port->evbuf = @@ -698,87 +701,34 @@ jalv_init_features(Jalv* const jalv) } static void -jalv_init_options(Jalv* const jalv) -{ - const LV2_Options_Option options[ARRAY_SIZE(jalv->features.options)] = { - {LV2_OPTIONS_INSTANCE, - 0, - jalv->urids.param_sampleRate, - sizeof(float), - jalv->urids.atom_Float, - &jalv->sample_rate}, - {LV2_OPTIONS_INSTANCE, - 0, - jalv->urids.bufsz_minBlockLength, - sizeof(int32_t), - jalv->urids.atom_Int, - &jalv->block_length}, - {LV2_OPTIONS_INSTANCE, - 0, - jalv->urids.bufsz_maxBlockLength, - sizeof(int32_t), - jalv->urids.atom_Int, - &jalv->block_length}, - {LV2_OPTIONS_INSTANCE, - 0, - jalv->urids.bufsz_sequenceSize, - sizeof(int32_t), - jalv->urids.atom_Int, - &jalv->midi_buf_size}, - {LV2_OPTIONS_INSTANCE, - 0, - jalv->urids.ui_updateRate, - sizeof(float), - jalv->urids.atom_Float, - &jalv->ui_update_hz}, - {LV2_OPTIONS_INSTANCE, - 0, - jalv->urids.ui_scaleFactor, - sizeof(float), - jalv->urids.atom_Float, - &jalv->ui_scale_factor}, - {LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL}}; - - memcpy(jalv->features.options, options, sizeof(jalv->features.options)); - - init_feature(&jalv->features.options_feature, - LV2_OPTIONS__options, - (void*)jalv->features.options); -} - -static void jalv_init_ui_settings(Jalv* const jalv) { - if (!jalv->opts.ring_size) { + JalvOptions* const opts = &jalv->opts; + JalvSettings* const settings = &jalv->settings; + + if (!settings->ring_size) { /* The UI ring is fed by plugin output ports (usually one), and the UI updates roughly once per cycle. The ring size is a few times the size of the MIDI output to give the UI a chance to keep up. */ - jalv->opts.ring_size = jalv->midi_buf_size * N_BUFFER_CYCLES; + settings->ring_size = settings->midi_buf_size * N_BUFFER_CYCLES; } - if (!jalv->opts.update_rate) { + if (opts->update_rate <= 0.0f) { // Calculate a reasonable UI update frequency - jalv->ui_update_hz = jalv_frontend_refresh_rate(jalv); - } else { - // Use user-specified UI update rate - jalv->ui_update_hz = jalv->opts.update_rate; - jalv->ui_update_hz = MAX(1.0f, jalv->ui_update_hz); + settings->ui_update_hz = jalv_frontend_refresh_rate(jalv); } - if (!jalv->opts.scale_factor) { + if (opts->scale_factor <= 0.0f) { // Calculate the monitor's scale factor - jalv->ui_scale_factor = jalv_frontend_scale_factor(jalv); - } else { - // Use user-specified UI scale factor - jalv->ui_scale_factor = jalv->opts.scale_factor; + settings->ui_scale_factor = jalv_frontend_scale_factor(jalv); } // The UI can only go so fast, clamp to reasonable limits - jalv->ui_update_hz = MIN(60, jalv->ui_update_hz); - jalv->opts.ring_size = MAX(4096, jalv->opts.ring_size); - jalv_log(JALV_LOG_INFO, "Comm buffers: %u bytes\n", jalv->opts.ring_size); - jalv_log(JALV_LOG_INFO, "Update rate: %.01f Hz\n", jalv->ui_update_hz); - jalv_log(JALV_LOG_INFO, "Scale factor: %.01f\n", jalv->ui_scale_factor); + settings->ui_update_hz = MAX(1.0f, MIN(60.0f, settings->ui_update_hz)); + settings->ring_size = MAX(4096, settings->ring_size); + jalv_log(JALV_LOG_INFO, "Comm buffers: %u bytes\n", settings->ring_size); + jalv_log(JALV_LOG_INFO, "Update rate: %.01f Hz\n", settings->ui_update_hz); + jalv_log(JALV_LOG_INFO, "Scale factor: %.01f\n", settings->ui_scale_factor); } static LilvState* @@ -813,20 +763,26 @@ jalv_open(Jalv* const jalv, int* argc, char*** argv) return ret; } + JalvSettings* const settings = &jalv->settings; + + settings->block_length = 4096U; + settings->midi_buf_size = 1024U; + settings->ring_size = jalv->opts.ring_size; + settings->ui_update_hz = jalv->opts.update_rate; + settings->ui_scale_factor = jalv->opts.scale_factor; + // Load the LV2 world LilvWorld* const world = lilv_world_new(); lilv_world_load_all(world); - jalv->world = world; - jalv->mapper = jalv_mapper_new(); - jalv->block_length = 4096U; - jalv->midi_buf_size = 1024U; - jalv->msg_buf_size = 1024U; - jalv->run_state = JALV_PAUSED; - jalv->bpm = 120.0f; - jalv->control_in = UINT32_MAX; - jalv->log.urids = &jalv->urids; - jalv->log.tracing = jalv->opts.trace; + jalv->world = world; + jalv->mapper = jalv_mapper_new(); + jalv->msg_buf_size = 1024U; + jalv->run_state = JALV_PAUSED; + jalv->bpm = 120.0f; + jalv->control_in = UINT32_MAX; + jalv->log.urids = &jalv->urids; + jalv->log.tracing = jalv->opts.trace; // Set up atom dumping for debugging if enabled LV2_URID_Map* const urid_map = jalv_mapper_urid_map(jalv->mapper); @@ -957,12 +913,13 @@ jalv_open(Jalv* const jalv, int* argc, char*** argv) return -6; } - jalv_log(JALV_LOG_INFO, "Sample rate: %u Hz\n", (uint32_t)jalv->sample_rate); - jalv_log(JALV_LOG_INFO, "Block length: %u frames\n", jalv->block_length); - jalv_log(JALV_LOG_INFO, "MIDI buffers: %zu bytes\n", jalv->midi_buf_size); + jalv_log( + JALV_LOG_INFO, "Sample rate: %u Hz\n", (uint32_t)settings->sample_rate); + jalv_log(JALV_LOG_INFO, "Block length: %u frames\n", settings->block_length); + jalv_log(JALV_LOG_INFO, "MIDI buffers: %zu bytes\n", settings->midi_buf_size); jalv_init_ui_settings(jalv); - jalv_init_options(jalv); + jalv_init_lv2_options(&jalv->features, &jalv->urids, &jalv->settings); // Create Plugin <=> UI communication buffers jalv->audio_msg = zix_aligned_alloc(NULL, 8U, jalv->msg_buf_size); @@ -1004,7 +961,7 @@ jalv_open(Jalv* const jalv, int* argc, char*** argv) // Instantiate the plugin jalv->instance = lilv_plugin_instantiate( - jalv->plugin, jalv->sample_rate, jalv->feature_list); + jalv->plugin, settings->sample_rate, jalv->feature_list); if (!jalv->instance) { jalv_log(JALV_LOG_ERR, "Failed to instantiate plugin\n"); return -9; @@ -14,6 +14,7 @@ #include "nodes.h" #include "options.h" #include "port.h" +#include "settings.h" #include "types.h" #include "urids.h" #include "worker.h" @@ -47,6 +48,7 @@ struct JalvImpl { LV2_Atom_Forge forge; ///< Atom forge JalvDumper* dumper; ///< Atom dumper (console debug output) JalvBackend* backend; ///< Audio system backend + JalvSettings settings; ///< Processing settings ZixRing* ui_to_plugin; ///< Port events from UI ZixRing* plugin_to_ui; ///< Port events from plugin void* audio_msg; ///< Buffer for messages in the audio thread @@ -69,25 +71,20 @@ struct JalvImpl { SuilHost* ui_host; ///< Plugin UI host support SuilInstance* ui_instance; ///< Plugin UI instance (shared library) #endif - void* window; ///< Window (if applicable) - JalvPort* ports; ///< Port array of size num_ports - Controls controls; ///< Available plugin controls - float* controls_buf; ///< Control port buffers array - uint32_t block_length; ///< Audio buffer size (block length) - size_t midi_buf_size; ///< Size of MIDI port buffers - size_t msg_buf_size; ///< Maximum size of a single message - uint32_t control_in; ///< Index of control input port - uint32_t num_ports; ///< Total number of ports on the plugin - uint32_t plugin_latency; ///< Latency reported by plugin (if any) - float ui_update_hz; ///< Frequency of UI updates - float ui_scale_factor; ///< UI scale factor - float sample_rate; ///< Sample rate - uint32_t event_delta_t; ///< Frames since last update sent to UI - uint32_t position; ///< Transport position in frames - float bpm; ///< Transport tempo in beats per minute - bool rolling; ///< Transport speed (0=stop, 1=play) - bool has_ui; ///< True iff a control UI is present - bool safe_restore; ///< Plugin restore() is thread-safe + void* window; ///< Window (if applicable) + JalvPort* ports; ///< Port array of size num_ports + Controls controls; ///< Available plugin controls + float* controls_buf; ///< Control port buffers array + size_t msg_buf_size; ///< Maximum size of a single message + uint32_t control_in; ///< Index of control input port + uint32_t num_ports; ///< Total number of ports on the plugin + uint32_t plugin_latency; ///< Latency reported by plugin (if any) + uint32_t event_delta_t; ///< Frames since last update sent to UI + uint32_t position; ///< Transport position in frames + float bpm; ///< Transport tempo in beats per minute + bool rolling; ///< Transport speed (0=stop, 1=play) + bool has_ui; ///< True iff a control UI is present + bool safe_restore; ///< Plugin restore() is thread-safe JalvFeatures features; const LV2_Feature** feature_list; }; diff --git a/src/jalv_gtk.c b/src/jalv_gtk.c index 15d43bb..4a8930d 100644 --- a/src/jalv_gtk.c +++ b/src/jalv_gtk.c @@ -1521,7 +1521,8 @@ jalv_frontend_open(Jalv* jalv) jalv_init_ui(jalv); - g_timeout_add(1000 / jalv->ui_update_hz, (GSourceFunc)jalv_update, jalv); + const float update_interval_ms = 1000.0f / jalv->settings.ui_update_hz; + g_timeout_add((unsigned)update_interval_ms, (GSourceFunc)jalv_update, jalv); gtk_window_present(GTK_WINDOW(window)); diff --git a/src/jalv_qt.cpp b/src/jalv_qt.cpp index 24b4ce6..8fd5495 100644 --- a/src/jalv_qt.cpp +++ b/src/jalv_qt.cpp @@ -712,7 +712,7 @@ jalv_frontend_open(Jalv* jalv) } auto* const timer = new Timer(jalv); - timer->start(1000 / jalv->ui_update_hz); + timer->start((int)(1000.0f / jalv->settings.ui_update_hz)); const int ret = app->exec(); zix_sem_post(&jalv->done); diff --git a/src/portaudio.c b/src/portaudio.c index 540e138..e4a8f1a 100644 --- a/src/portaudio.c +++ b/src/portaudio.c @@ -185,9 +185,9 @@ jalv_backend_open(Jalv* jalv) } // Set audio parameters - jalv->sample_rate = in_dev->defaultSampleRate; - // jalv->block_length = FIXME - jalv->midi_buf_size = 4096; + jalv->settings.sample_rate = in_dev->defaultSampleRate; + // jalv->settings.block_length = FIXME + jalv->settings.midi_buf_size = 4096; jalv->backend->stream = stream; return 0; diff --git a/src/process.c b/src/process.c index 2f88316..3348877 100644 --- a/src/process.c +++ b/src/process.c @@ -120,8 +120,9 @@ jalv_run(Jalv* const jalv, const uint32_t nframes) // Check if it's time to send updates to the UI jalv->event_delta_t += nframes; - bool send_ui_updates = false; - uint32_t update_frames = (uint32_t)(jalv->sample_rate / jalv->ui_update_hz); + bool send_ui_updates = false; + const uint32_t update_frames = + (uint32_t)(jalv->settings.sample_rate / jalv->settings.ui_update_hz); if (jalv->has_ui && (jalv->event_delta_t > update_frames)) { send_ui_updates = true; jalv->event_delta_t = 0U; diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..0cb548e --- /dev/null +++ b/src/settings.h @@ -0,0 +1,27 @@ +// Copyright 2018-2024 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef JALV_SETTINGS_H +#define JALV_SETTINGS_H + +#include "attributes.h" + +#include <stddef.h> +#include <stdint.h> + +// Process thread settings +JALV_BEGIN_DECLS + +/// System and/or configuration settings for the execution process +typedef struct { + float sample_rate; ///< Sample rate + uint32_t block_length; ///< Audio buffer length in frames + size_t midi_buf_size; ///< MIDI buffer size in bytes + uint32_t ring_size; ///< Communication ring size in bytes + float ui_update_hz; ///< Frequency of UI updates + float ui_scale_factor; ///< UI scale factor +} JalvSettings; + +JALV_END_DECLS + +#endif // JALV_SETTINGS_H |