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/generic.h>

FILE *alog;
static sample_t gbuf[4096];

static void
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++) {
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;
}

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);
@@ -937,20 +898,16 @@ alsa_driver_process (nframes_t nframes, void *arg)
channel_t chn;
jack_port_t *port;
GSList *node;
sample_t *buf;

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

port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) {
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;
@@ -1330,8 +1287,6 @@ driver_initialize (va_list ap)
char *pcm_name;
int hw_monitoring;

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

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


+ 4
- 0
client.c View File

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

rdtscll (client->control->when_started);

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

rdtscll (control->when_done);

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_MINOR_VERSION=11
JACK_MICRO_VERSION=0
JACK_MICRO_VERSION=1

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

printf ("start subgraph\n");

if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) {
jack_error ("cannot initiate graph processing (%s)", strerror (errno));
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].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
pollfd[0].revents = 0;

if (poll (pollfd, 1, engine->driver->period_interval) < 0) {
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) */

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

printf ("ack message, id = %lu\n", req.client_id);
if ((client = jack_client_internal_by_id (engine, req.client_id)) == NULL) {
jack_error ("unknown client ID in ACK connection request");
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->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_rechain_graph (engine, FALSE);
jack_sort_graph (engine);

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

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

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

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);
} else if (pfd[i].revents & POLLIN) {
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 */

printf ("remove client\n");

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

jack_clear_fifos (engine);

/* We're going to try to avoid reconnecting clients that
don't need to be reconnected. This is slightly tricky,
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
jack_sort_graph (jack_engine_t *engine, int take_lock)
jack_sort_graph (jack_engine_t *engine)
{
GSList *node, *onode;
jack_client_internal_t *client;
jack_client_internal_t *oclient;

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

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

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);
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);
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, dstport->shared->client_id, dst_id, src_id, TRUE);
@@ -2029,7 +2019,7 @@ jack_port_disconnect_internal (jack_engine_t *engine,
}

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

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

pthread_mutex_lock (&engine->graph_lock);
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);

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

{
/* caller must hold graph_lock */

char path[PATH_MAX+1];
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] = 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));
return -1;
}
@@ -2173,6 +2165,31 @@ jack_get_fifo_fd (jack_engine_t *engine, int 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
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 char active : 1; /* w: engine r: engine and client */
volatile char dead : 1; /* r/w: engine */
volatile unsigned long long when_started;
volatile unsigned long long when_done;

/* 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);

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

return 0;
}

@@ -118,9 +119,9 @@ main (int argc, char *argv[])
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);
exit (0);
}


Loading…
Cancel
Save