Browse Source

support for port total latency computation

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@143 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 24 years ago
parent
commit
598b6c4634
5 changed files with 70 additions and 26 deletions
  1. +3
    -3
      alsa_driver.c
  2. +22
    -0
      client.c
  3. +2
    -2
      configure.in
  4. +36
    -21
      engine.c
  5. +7
    -0
      jack/jack.h

+ 3
- 3
alsa_driver.c View File

@@ -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;


+ 22
- 0
client.c View File

@@ -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;
}

+ 2
- 2
configure.in View File

@@ -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=



+ 36
- 21
engine.c View File

@@ -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


+ 7
- 0
jack/jack.h View File

@@ -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


Loading…
Cancel
Save