From 84a86ae683ce632acb906da2cd7d7a99626db38c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 28 Apr 2012 04:15:57 +0000 Subject: Tune UI update rate and ring size based on JACK rate and MIDI buffer size to handle the handle the maximum message rate the plugin can send. git-svn-id: http://svn.drobilla.net/lad/trunk/jalv@4298 a436a847-0d15-0410-975c-d299462d15a1 --- src/jalv.c | 31 +++++++++++++++++++++++++++---- src/jalv_gtk2.c | 2 +- src/jalv_gtkmm2.cpp | 2 +- src/jalv_internal.h | 3 +-- src/jalv_qt4.cpp | 2 +- 5 files changed, 31 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/jalv.c b/src/jalv.c index 4d680a5..db2e32a 100644 --- a/src/jalv.c +++ b/src/jalv.c @@ -56,6 +56,14 @@ #define USTR(str) ((const uint8_t*)str) +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + ZixSem exit_sem; /**< Exit semaphore */ LV2_URID @@ -441,7 +449,7 @@ jack_process_cb(jack_nframes_t nframes, void* data) /* Check if it's time to send updates to the UI */ host->event_delta_t += nframes; bool send_ui_updates = false; - jack_nframes_t update_frames = host->sample_rate / JALV_UI_UPDATE_HZ; + jack_nframes_t update_frames = host->sample_rate / host->ui_update_hz; if (host->has_ui && (host->event_delta_t > update_frames)) { send_ui_updates = true; host->event_delta_t = 0; @@ -837,19 +845,34 @@ main(int argc, char** argv) printf("MIDI buffers: %zu bytes\n", host.midi_buf_size); if (host.opts.buffer_size == 0) { - host.opts.buffer_size = host.midi_buf_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. The UI + should be able to keep up with 4 cycles, and tests show this works + for me, but this value might need increasing to avoid overflows. + */ + host.opts.buffer_size = host.midi_buf_size * 4; } + /* Calculate theoretical UI update frequency. */ + host.sample_rate = jack_get_sample_rate(host.jack_client); + host.ui_update_hz = (double)host.sample_rate / host.midi_buf_size; + + /* The UI can only go so fast, clamp to reasonable limits */ + host.ui_update_hz = MIN(60, host.ui_update_hz); + host.opts.buffer_size = MAX(4096, host.opts.buffer_size); + fprintf(stderr, "Comm buffers: %d bytes\n", host.opts.buffer_size); + fprintf(stderr, "Update rate: %d Hz\n", host.ui_update_hz); + /* Create Plugin <=> UI communication buffers */ host.ui_events = jack_ringbuffer_create(host.opts.buffer_size); host.plugin_events = jack_ringbuffer_create(host.opts.buffer_size); jack_ringbuffer_mlock(host.ui_events); jack_ringbuffer_mlock(host.plugin_events); - /* Instantiate the plugin */ host.instance = lilv_plugin_instantiate( - host.plugin, jack_get_sample_rate(host.jack_client), features); + host.plugin, host.sample_rate, features); if (!host.instance) { die("Failed to instantiate plugin.\n"); } diff --git a/src/jalv_gtk2.c b/src/jalv_gtk2.c index ec0c444..4e0a8f8 100644 --- a/src/jalv_gtk2.c +++ b/src/jalv_gtk2.c @@ -578,7 +578,7 @@ jalv_open_ui(Jalv* jalv, box_size.height + controls_size.height); } - g_timeout_add(1000 / JALV_UI_UPDATE_HZ, + g_timeout_add(1000 / jalv->ui_update_hz, (GSourceFunc)jalv_emit_ui_events, jalv); jalv->has_ui = TRUE; diff --git a/src/jalv_gtkmm2.cpp b/src/jalv_gtkmm2.cpp index e24bf40..c2f764a 100644 --- a/src/jalv_gtkmm2.cpp +++ b/src/jalv_gtkmm2.cpp @@ -68,7 +68,7 @@ jalv_open_ui(Jalv* jalv, window->add(*Gtk::manage(widgetmm)); widgetmm->show_all(); - g_timeout_add(1000 / JALV_UI_UPDATE_HZ, + g_timeout_add(1000 / jalv->ui_update_hz, (GSourceFunc)jalv_emit_ui_events, jalv); } else { Gtk::Button* button = Gtk::manage(new Gtk::Button("Close")); diff --git a/src/jalv_internal.h b/src/jalv_internal.h index bca3c92..b76af60 100644 --- a/src/jalv_internal.h +++ b/src/jalv_internal.h @@ -47,8 +47,6 @@ extern "C" { #endif -#define JALV_UI_UPDATE_HZ 15 - enum PortFlow { FLOW_UNKNOWN, FLOW_INPUT, @@ -168,6 +166,7 @@ typedef struct { size_t midi_buf_size; ///< Size of MIDI port buffers uint32_t num_ports; ///< Size of the two following arrays: uint32_t longest_sym; ///< Longest port symbol + uint32_t ui_update_hz; ///< Frequency of UI updates jack_nframes_t sample_rate; ///< Sample rate jack_nframes_t event_delta_t; ///< Frames since last update sent to UI uint32_t midi_event_id; ///< MIDI event class ID in event context diff --git a/src/jalv_qt4.cpp b/src/jalv_qt4.cpp index 3aa7e88..4798b45 100644 --- a/src/jalv_qt4.cpp +++ b/src/jalv_qt4.cpp @@ -87,7 +87,7 @@ jalv_open_ui(Jalv* jalv, app->connect(app, SIGNAL(lastWindowClosed()), app, SLOT(quit())); Timer* timer = new Timer(jalv); - timer->start(1000 / JALV_UI_UPDATE_HZ); + timer->start(1000 / jalv->ui_update_hz); int ret = app->exec(); zix_sem_post(jalv->done); -- cgit v1.2.1