aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2024-11-21 14:08:02 -0500
committerDavid Robillard <d@drobilla.net>2024-11-24 19:11:44 -0500
commit2a5bc1ca7aee36cd763ac10c894b84eef347fe25 (patch)
treeb145b86c8f98fb6d7adab34f69c1bcb0114e34fa /src
parent724aab7a868ed0200afbeecf056e53b5ea16b23d (diff)
downloadjalv-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.c62
-rw-r--r--src/features.h8
-rw-r--r--src/jack.c20
-rw-r--r--src/jalv.c127
-rw-r--r--src/jalv.h35
-rw-r--r--src/jalv_gtk.c3
-rw-r--r--src/jalv_qt.cpp2
-rw-r--r--src/portaudio.c6
-rw-r--r--src/process.c5
-rw-r--r--src/settings.h27
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
diff --git a/src/jack.c b/src/jack.c
index a5f26c6..f848476 100644
--- a/src/jack.c
+++ b/src/jack.c
@@ -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
diff --git a/src/jalv.c b/src/jalv.c
index 82674a0..818ff82 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -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;
diff --git a/src/jalv.h b/src/jalv.h
index 7caf8a6..894b2c4 100644
--- a/src/jalv.h
+++ b/src/jalv.h
@@ -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