Browse Source

fixed random data left in FIFO problem- phew!

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@102 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 23 years ago
parent
commit
e98f76e511
6 changed files with 59 additions and 80 deletions
  1. +4
    -49
      alsa_driver.c
  2. +4
    -0
      client.c
  3. +1
    -1
      configure.in
  4. +45
    -28
      engine.c
  5. +2
    -0
      jack/internal.h
  6. +3
    -2
      simple_client.c

+ 4
- 49
alsa_driver.c View File

@@ -35,9 +35,6 @@
#include <jack/hammerfall.h> #include <jack/hammerfall.h>
#include <jack/generic.h> #include <jack/generic.h>


FILE *alog;
static sample_t gbuf[4096];

static void static void
alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver) alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver)


@@ -837,48 +834,12 @@ alsa_driver_wait (alsa_driver_t *driver)
for (chn = 0, prev = 0, node = driver->playback_ports; node; prev = node, node = g_slist_next (node), chn++) { for (chn = 0, prev = 0, node = driver->playback_ports; node; prev = node, node = g_slist_next (node), chn++) {
jack_port_t *port = (jack_port_t *) node->data; jack_port_t *port = (jack_port_t *) node->data;
sample_t *buf;

/* optimize needless data copying away */
if (chn == 1) {
nframes_t nn;
sample_t *prevbuf;

/* 1 read the actual data from channel 0 */
alsa_driver_read_from_channel (driver, 0, gbuf, contiguous);
buf = gbuf;

if (jack_port_connected ((jack_port_t *) prev->data)) {
prevbuf = jack_port_get_buffer (((jack_port_t *) prev->data), contiguous);
printf ("compare with %p\n", prevbuf);
for (nn = 0; nn < contiguous; nn++) {
if (gbuf[nn] != prevbuf[nn]) {
printf ("%d different at %lu (chn=%d, gbuf=%f, prevbuf=%f\n",
waitcnt, nn, driver->capture_addr[0][nn],
gbuf[nn], prevbuf[nn]);
break;
}
}
}

} else if (chn == 0) {

if (jack_port_connected (port)) {
buf = jack_port_get_buffer (port, contiguous);
printf ("%d buffer = %p\n", waitcnt, buf);
} else {
continue;
}


} else {
if (!jack_port_connected (port)) {
continue; continue;
} }


alsa_driver_write_to_channel (driver, chn, buf, contiguous, 1.0);

alsa_driver_write_to_channel (driver, 1, jack_port_get_buffer (port, contiguous), contiguous, 1.0);
} }
engine->process_unlock (engine); engine->process_unlock (engine);
@@ -937,20 +898,16 @@ alsa_driver_process (nframes_t nframes, void *arg)
channel_t chn; channel_t chn;
jack_port_t *port; jack_port_t *port;
GSList *node; GSList *node;
sample_t *buf;


for (chn = 0, node = driver->capture_ports; node; node = g_slist_next (node), chn++) { for (chn = 0, node = driver->capture_ports; node; node = g_slist_next (node), chn++) {


port = (jack_port_t *) node->data; port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) { if (!jack_port_connected (port)) {
continue; continue;
} }
buf = jack_port_get_buffer (port, nframes);
alsa_driver_read_from_channel (driver, chn, buf, nframes);
printf ("%d: read into %p with %d => %f\n", waitcnt, buf, driver->capture_addr[0][0], buf[0]);
alsa_driver_read_from_channel (driver, chn, jack_port_get_buffer (port, nframes), nframes);
} }


return 0; return 0;
@@ -1330,8 +1287,6 @@ driver_initialize (va_list ap)
char *pcm_name; char *pcm_name;
int hw_monitoring; int hw_monitoring;


alog = fopen ("/dev/null", "w");

pcm_name = va_arg (ap, char *); pcm_name = va_arg (ap, char *);
frames_per_interrupt = va_arg (ap, nframes_t); frames_per_interrupt = va_arg (ap, nframes_t);
user_nperiods = va_arg(ap, unsigned long); user_nperiods = va_arg(ap, unsigned long);


+ 4
- 0
client.c View File

@@ -500,6 +500,8 @@ jack_client_thread (void *arg)
break; break;
} }


rdtscll (client->control->when_started);

if (client->pollfd[0].revents & ~POLLIN) { if (client->pollfd[0].revents & ~POLLIN) {
jack_error ("engine has shut down socket; thread exiting"); jack_error ("engine has shut down socket; thread exiting");
if (client->on_shutdown) { if (client->on_shutdown) {
@@ -595,6 +597,8 @@ jack_client_thread (void *arg)
effort. effort.
*/ */


rdtscll (control->when_done);

write (client->graph_next_fd, &c, 1); write (client->graph_next_fd, &c, 1);
} }
} }


+ 1
- 1
configure.in View File

@@ -5,7 +5,7 @@ AC_CONFIG_AUX_DIR(.)


JACK_MAJOR_VERSION=0 JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=11 JACK_MINOR_VERSION=11
JACK_MICRO_VERSION=0
JACK_MICRO_VERSION=1


BETA= BETA=




+ 45
- 28
engine.c View File

@@ -78,9 +78,11 @@ static void jack_remove_client (jack_engine_t *engine, jack_client_internal_t *c
static jack_client_internal_t *jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_request_t *); static jack_client_internal_t *jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_request_t *);
static jack_client_internal_t *jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id); 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, int take_lock);
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, int take_lock);
static int jack_get_fifo_fd (jack_engine_t *engine, int which_fifo); static int jack_get_fifo_fd (jack_engine_t *engine, int which_fifo);
static void jack_clear_fifos (jack_engine_t *engine);

static int jack_port_do_connect (jack_engine_t *engine, const char *source_port, const char *destination_port); static int jack_port_do_connect (jack_engine_t *engine, const char *source_port, const char *destination_port);
static int jack_port_do_disconnect (jack_engine_t *engine, const char *source_port, const char *destination_port); static int jack_port_do_disconnect (jack_engine_t *engine, const char *source_port, const char *destination_port);
static int jack_port_do_disconnect_all (jack_engine_t *engine, jack_port_id_t); static int jack_port_do_disconnect_all (jack_engine_t *engine, jack_port_id_t);
@@ -470,8 +472,6 @@ jack_process (jack_engine_t *engine, nframes_t nframes)


ctl->state = Triggered; // a race exists if we do this after the write(2) ctl->state = Triggered; // a race exists if we do this after the write(2)


printf ("start subgraph\n");

if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) { if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) {
jack_error ("cannot initiate graph processing (%s)", strerror (errno)); jack_error ("cannot initiate graph processing (%s)", strerror (errno));
engine->process_errors++; engine->process_errors++;
@@ -484,6 +484,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes)


pollfd[0].fd = client->subgraph_wait_fd; pollfd[0].fd = client->subgraph_wait_fd;
pollfd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL; pollfd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
pollfd[0].revents = 0;


if (poll (pollfd, 1, engine->driver->period_interval) < 0) { if (poll (pollfd, 1, engine->driver->period_interval) < 0) {
if (errno == EINTR) { if (errno == EINTR) {
@@ -510,8 +511,6 @@ jack_process (jack_engine_t *engine, nframes_t nframes)
} }
} }


printf ("subgraph done\n");

/* Move to next in-process client (or end of client list) */ /* Move to next in-process client (or end of client list) */


while (node) { while (node) {
@@ -686,8 +685,6 @@ handle_client_ack_connection (jack_engine_t *engine, int client_fd)
return -1; return -1;
} }


printf ("ack message, id = %lu\n", req.client_id);
if ((client = jack_client_internal_by_id (engine, req.client_id)) == NULL) { if ((client = jack_client_internal_by_id (engine, req.client_id)) == NULL) {
jack_error ("unknown client ID in ACK connection request"); jack_error ("unknown client ID in ACK connection request");
return -1; return -1;
@@ -722,13 +719,15 @@ jack_client_activate (jack_engine_t *engine, jack_client_id_t id)
client = (jack_client_internal_t *) node->data; client = (jack_client_internal_t *) node->data;
client->control->active = TRUE; client->control->active = TRUE;


/* we call this to make sure the FIFO is built by the time
the client needs it. we don't care about the return
value at this point.
/* we call this to make sure the
FIFO is built+ready by the time
the client needs it. we don't
care about the return value at
this point.
*/ */


jack_get_fifo_fd (engine, ++engine->external_client_cnt); jack_get_fifo_fd (engine, ++engine->external_client_cnt);
jack_rechain_graph (engine, FALSE);
jack_sort_graph (engine);


ret = 0; ret = 0;
break; break;
@@ -753,7 +752,7 @@ jack_client_do_deactivate (jack_engine_t *engine, jack_client_internal_t *client
engine->external_client_cnt--; engine->external_client_cnt--;
} }


jack_sort_graph (engine, FALSE);
jack_sort_graph (engine);
return 0; return 0;
} }


@@ -1034,7 +1033,6 @@ jack_server_thread (void *arg)
} }


if (pfd[i].revents & ~POLLIN) { if (pfd[i].revents & ~POLLIN) {
printf ("bad poll status on pfd[%d] (%d) = 0x%x\n", i, pfd[i].fd, pfd[i].revents);
handle_client_jack_error (engine, pfd[i].fd); handle_client_jack_error (engine, pfd[i].fd);
} else if (pfd[i].revents & POLLIN) { } else if (pfd[i].revents & POLLIN) {
if (handle_client_io (engine, pfd[i].fd)) { if (handle_client_io (engine, pfd[i].fd)) {
@@ -1390,8 +1388,6 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)


/* caller must hold the graph_lock */ /* caller must hold the graph_lock */


printf ("remove client\n");

/* these stop the process() loop from paying this client any attention, /* these stop the process() loop from paying this client any attention,
as well as stopping jack_deliver_event() from bothering to try to as well as stopping jack_deliver_event() from bothering to try to
talk to the client. talk to the client.
@@ -1575,6 +1571,8 @@ jack_rechain_graph (jack_engine_t *engine, int take_lock)
pthread_mutex_lock (&engine->graph_lock); pthread_mutex_lock (&engine->graph_lock);
} }


jack_clear_fifos (engine);

/* We're going to try to avoid reconnecting clients that /* We're going to try to avoid reconnecting clients that
don't need to be reconnected. This is slightly tricky, don't need to be reconnected. This is slightly tricky,
but worth it for performance reasons. but worth it for performance reasons.
@@ -1803,16 +1801,12 @@ jack_client_feeds (jack_client_internal_t *might, jack_client_internal_t *target
*/ */


static void static void
jack_sort_graph (jack_engine_t *engine, int take_lock)
jack_sort_graph (jack_engine_t *engine)
{ {
GSList *node, *onode; GSList *node, *onode;
jack_client_internal_t *client; jack_client_internal_t *client;
jack_client_internal_t *oclient; jack_client_internal_t *oclient;


if (take_lock) {
pthread_mutex_lock (&engine->graph_lock);
}

for (node = engine->clients; node; node = g_slist_next (node)) { for (node = engine->clients; node; node = g_slist_next (node)) {


client = (jack_client_internal_t *) node->data; client = (jack_client_internal_t *) node->data;
@@ -1837,10 +1831,6 @@ jack_sort_graph (jack_engine_t *engine, int take_lock)


engine->clients = g_slist_sort (engine->clients, (GCompareFunc) jack_client_sort); engine->clients = g_slist_sort (engine->clients, (GCompareFunc) jack_client_sort);
jack_rechain_graph (engine, FALSE); jack_rechain_graph (engine, FALSE);

if (take_lock) {
pthread_mutex_unlock (&engine->graph_lock);
}
} }


/** /**
@@ -1966,7 +1956,7 @@ jack_port_do_connect (jack_engine_t *engine,
dstport->connections = g_slist_prepend (dstport->connections, connection); dstport->connections = g_slist_prepend (dstport->connections, connection);
srcport->connections = g_slist_prepend (srcport->connections, connection); srcport->connections = g_slist_prepend (srcport->connections, connection);
jack_sort_graph (engine, FALSE);
jack_sort_graph (engine);


jack_send_connection_notification (engine, srcport->shared->client_id, src_id, dst_id, TRUE); jack_send_connection_notification (engine, srcport->shared->client_id, src_id, dst_id, TRUE);
jack_send_connection_notification (engine, dstport->shared->client_id, dst_id, src_id, TRUE); jack_send_connection_notification (engine, dstport->shared->client_id, dst_id, src_id, TRUE);
@@ -2029,7 +2019,7 @@ jack_port_disconnect_internal (jack_engine_t *engine,
} }


if (sort_graph) { if (sort_graph) {
jack_sort_graph (engine, FALSE);
jack_sort_graph (engine);
} }


return ret; return ret;
@@ -2050,7 +2040,7 @@ jack_port_do_disconnect_all (jack_engine_t *engine,


pthread_mutex_lock (&engine->graph_lock); pthread_mutex_lock (&engine->graph_lock);
jack_port_clear_connections (engine, &engine->internal_ports[port_id]); jack_port_clear_connections (engine, &engine->internal_ports[port_id]);
jack_sort_graph (engine, FALSE);
jack_sort_graph (engine);
pthread_mutex_unlock (&engine->graph_lock); pthread_mutex_unlock (&engine->graph_lock);


return 0; return 0;
@@ -2131,6 +2121,8 @@ static int
jack_get_fifo_fd (jack_engine_t *engine, int which_fifo) jack_get_fifo_fd (jack_engine_t *engine, int which_fifo)


{ {
/* caller must hold graph_lock */

char path[PATH_MAX+1]; char path[PATH_MAX+1];
struct stat statbuf; struct stat statbuf;


@@ -2164,7 +2156,7 @@ jack_get_fifo_fd (jack_engine_t *engine, int which_fifo)
} }


if (engine->fifo[which_fifo] < 0) { if (engine->fifo[which_fifo] < 0) {
if ((engine->fifo[which_fifo] = open (path, O_RDWR|O_CREAT, 0666)) < 0) {
if ((engine->fifo[which_fifo] = open (path, O_RDWR|O_CREAT|O_NONBLOCK, 0666)) < 0) {
jack_error ("cannot open fifo [%s] (%s)", path, strerror (errno)); jack_error ("cannot open fifo [%s] (%s)", path, strerror (errno));
return -1; return -1;
} }
@@ -2173,6 +2165,31 @@ jack_get_fifo_fd (jack_engine_t *engine, int which_fifo)
return engine->fifo[which_fifo]; return engine->fifo[which_fifo];
} }


static void
jack_clear_fifos (jack_engine_t *engine)
{
/* caller must hold graph_lock */

int i;
char buf[16];

/* this just drains the existing FIFO's of any data left in them
by aborted clients, etc. there is only ever going to be
0, 1 or 2 bytes in them, but we'll allow for up to 16.
*/

for (i = 0; i < engine->fifo_size; i++) {
if (engine->fifo[i] >= 0) {
int nread = read (engine->fifo[i], buf, sizeof (buf));
if (nread < 0 && errno != EAGAIN) {
printf ("clear fifo[%d]: %s\n", i, strerror (errno));
} else if (nread > 0) {
printf ("clear fifo[%d]: %d bytes\n", i, nread);
}
}
}
}

int int
jack_use_driver (jack_engine_t *engine, jack_driver_t *driver) jack_use_driver (jack_engine_t *engine, jack_driver_t *driver)




+ 2
- 0
jack/internal.h View File

@@ -125,6 +125,8 @@ typedef volatile struct {
volatile ClientType type; /* w: engine r: engine and client */ volatile ClientType type; /* w: engine r: engine and client */
volatile char active : 1; /* w: engine r: engine and client */ volatile char active : 1; /* w: engine r: engine and client */
volatile char dead : 1; /* r/w: engine */ volatile char dead : 1; /* r/w: engine */
volatile unsigned long long when_started;
volatile unsigned long long when_done;


/* callbacks */ /* callbacks */


+ 3
- 2
simple_client.c View File

@@ -17,6 +17,7 @@ process (nframes_t nframes, void *arg)
sample_t *in = (sample_t *) jack_port_get_buffer (input_port, nframes); sample_t *in = (sample_t *) jack_port_get_buffer (input_port, nframes);


memcpy (out, in, sizeof (sample_t) * nframes); memcpy (out, in, sizeof (sample_t) * nframes);

return 0; return 0;
} }


@@ -118,9 +119,9 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot connect output ports\n"); fprintf (stderr, "cannot connect output ports\n");
} }


/* Since this is just a toy, run for 5 seconds, then finish */
/* Since this is just a toy, run for a few seconds, then finish */


sleep (2);
sleep (10);
jack_client_close (client); jack_client_close (client);
exit (0); exit (0);
} }


Loading…
Cancel
Save