From 598b6c463466a7d20f1975ce9ef87f855856bb32 Mon Sep 17 00:00:00 2001 From: pbd Date: Tue, 5 Mar 2002 03:28:46 +0000 Subject: [PATCH] support for port total latency computation git-svn-id: svn+ssh://jackaudio.org/trunk/jack@143 0c269be4-1314-0410-8aa9-9f06e86f4224 --- alsa_driver.c | 6 +++--- client.c | 22 ++++++++++++++++++++ configure.in | 4 ++-- engine.c | 57 ++++++++++++++++++++++++++++++++------------------- jack/jack.h | 7 +++++++ 5 files changed, 70 insertions(+), 26 deletions(-) diff --git a/alsa_driver.c b/alsa_driver.c index bbcc1ac..d1e0a11 100644 --- a/alsa_driver.c +++ b/alsa_driver.c @@ -1074,7 +1074,7 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine) snprintf (buf, sizeof(buf) - 1, "in_%lu", chn+1); port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput|JackPortIsPhysical|JackPortCanMonitor, 0); + JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal|JackPortCanMonitor, 0); if (port == 0) { jack_error ("ALSA: cannot register port for %s", buf); break; @@ -1083,7 +1083,7 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine) /* XXX fix this so that it can handle: systemic (external) latency */ - jack_port_set_latency (port, driver->frames_per_cycle * driver->nfragments); + jack_port_set_latency (port, driver->frames_per_cycle); driver->capture_ports = g_slist_append (driver->capture_ports, port); } @@ -1092,7 +1092,7 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine) snprintf (buf, sizeof(buf) - 1, "out_%lu", chn+1); port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput|JackPortIsPhysical, 0); + JackPortIsInput|JackPortIsTerminal|JackPortIsPhysical, 0); if (port == 0) { jack_error ("ALSA: cannot register port for %s", buf); break; diff --git a/client.c b/client.c index b0105a3..7678432 100644 --- a/client.c +++ b/client.c @@ -1737,3 +1737,25 @@ jack_set_transport_info (jack_client_t *client, return 0; } + +nframes_t +jack_port_get_total_latency (jack_client_t *client, + jack_port_t *port) +{ + jack_request_t req; + + req.type = GetPortTotalLatency; + strcpy (req.x.port_info.name, port->shared->name); + + if (write (client->request_fd, &req, sizeof (req)) != sizeof (req)) { + jack_error ("cannot send port total latency request to server"); + return 0; + } + + if (read (client->request_fd, &req, sizeof (req)) != sizeof (req)) { + jack_error ("cannot read port total latency result from server (%s)", strerror (errno)); + return 0; + } + + return req.x.nframes; +} diff --git a/configure.in b/configure.in index 642dee2..7732082 100644 --- a/configure.in +++ b/configure.in @@ -4,8 +4,8 @@ AC_INIT(client.c) AC_CONFIG_AUX_DIR(.) JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=17 -JACK_MICRO_VERSION=2 +JACK_MINOR_VERSION=18 +JACK_MICRO_VERSION=0 BETA= diff --git a/engine.c b/engine.c index 8a2518f..996adcc 100644 --- a/engine.c +++ b/engine.c @@ -79,7 +79,7 @@ static jack_client_internal_t *jack_client_internal_new (jack_engine_t *engine, static jack_client_internal_t *jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id); static void jack_sort_graph (jack_engine_t *engine); -static int jack_rechain_graph (jack_engine_t *engine, int take_lock); +static int jack_rechain_graph (jack_engine_t *engine); static int jack_get_fifo_fd (jack_engine_t *engine, int which_fifo); static void jack_clear_fifos (jack_engine_t *engine); @@ -1592,17 +1592,13 @@ jack_client_set_order (jack_engine_t *engine, jack_client_internal_t *client) } int -jack_rechain_graph (jack_engine_t *engine, int take_lock) +jack_rechain_graph (jack_engine_t *engine) { GSList *node, *next; unsigned long n; int err = 0; jack_client_internal_t *client, *subgraph_client, *next_client; - if (take_lock) { - pthread_mutex_lock (&engine->graph_lock); - } - jack_clear_fifos (engine); subgraph_client = 0; @@ -1705,10 +1701,6 @@ jack_rechain_graph (jack_engine_t *engine, int take_lock) } } - if (take_lock) { - pthread_mutex_unlock (&engine->graph_lock); - } - return err; } @@ -1891,7 +1883,7 @@ jack_sort_graph (jack_engine_t *engine) } engine->clients = g_slist_sort (engine->clients, (GCompareFunc) jack_client_sort); - jack_rechain_graph (engine, FALSE); + jack_rechain_graph (engine); } /** @@ -2138,14 +2130,16 @@ jack_port_do_disconnect (jack_engine_t *engine, return ret; } -static int -jack_port_get_total_latency (jack_engine_t *engine, jack_port_internal_t *port, nframes_t *latency) +static nframes_t +jack_get_port_total_latency (jack_engine_t *engine, jack_port_internal_t *port) { GSList *node; + nframes_t latency; + nframes_t max_latency = 0; - /* call tree should hold engine->graph_lock. */ + /* call tree must hold engine->graph_lock. */ - (*latency) = port->shared->latency; + latency = port->shared->latency; for (node = port->connections; node; node = g_slist_next (node)) { @@ -2160,15 +2154,29 @@ jack_port_get_total_latency (jack_engine_t *engine, jack_port_internal_t *port, if (connection->destination == port) { - jack_port_get_total_latency (engine, connection->source, &this_latency); - - if (this_latency > *latency) { - (*latency) = this_latency; + if (connection->source->shared->flags & JackPortIsTerminal) { + this_latency = connection->source->shared->latency; + } else { + this_latency = jack_get_port_total_latency (engine, connection->source); + } + + } else { + + /* "port" is the source, so get the latency of the destination */ + + if (connection->destination->shared->flags & JackPortIsTerminal) { + this_latency = connection->destination->shared->latency; + } else { + this_latency = jack_get_port_total_latency (engine, connection->destination); } } + + if (this_latency > max_latency) { + max_latency = this_latency; + } } - return 0; + return latency + max_latency; } static int @@ -2176,11 +2184,18 @@ jack_get_total_latency (jack_engine_t *engine, const char *portname, nframes_t * { jack_port_internal_t *port; + pthread_mutex_lock (&engine->graph_lock); + if ((port = jack_get_port_by_name (engine, portname)) == NULL) { + pthread_mutex_unlock (&engine->graph_lock); return -1; } - return jack_port_get_total_latency (engine, port, latency); + *latency = jack_get_port_total_latency (engine, port); + + pthread_mutex_unlock (&engine->graph_lock); + + return 0; } static int diff --git a/jack/jack.h b/jack/jack.h index 370ae5d..befb5e1 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -269,6 +269,13 @@ int jack_port_unlock (jack_client_t *, jack_port_t *); nframes_t jack_port_get_latency (jack_port_t *port); +/* this returns the maximum of the sum of the latencies in every + connection path that can be drawn between the port and other + ports with the JackPortIsTerminal flag set. +*/ + +nframes_t jack_port_get_total_latency (jack_client_t *, jack_port_t *port); + /* the port latency is zero by default. clients that control physical hardware with non-zero latency should call this to set the latency to its correct value. note that the value