Browse Source

intermediate debugging state, trying to track down clicking problem after aborted client restart, but contains several important fixes

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@101 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 23 years ago
parent
commit
bf12d41e3a
8 changed files with 197 additions and 173 deletions
  1. +76
    -69
      alsa_driver.c
  2. +9
    -18
      client.c
  3. +100
    -70
      engine.c
  4. +3
    -8
      jack/alsa_driver.h
  5. +4
    -5
      jack/internal.h
  6. +1
    -0
      jack/port.h
  7. +1
    -1
      monitor_client.c
  8. +3
    -2
      simple_client.c

+ 76
- 69
alsa_driver.c View File

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


static int config_max_level = 0;
static int config_min_level = 0;
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)
@@ -364,35 +364,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver, nframes_t frames_per_cycle, n


switch (driver->sample_format) { switch (driver->sample_format) {
case SND_PCM_FORMAT_S32_LE: case SND_PCM_FORMAT_S32_LE:

/* XXX must handle the n-bits of 24-in-32 problems here */

if (config_max_level) {
driver->max_level = config_max_level;
} else {
driver->max_level = INT_MAX;
}

if (config_min_level) {
driver->min_level = config_min_level;
} else {
driver->min_level = INT_MIN;
}
break;

case SND_PCM_FORMAT_S16_LE: case SND_PCM_FORMAT_S16_LE:

if (config_max_level) {
driver->max_level = config_max_level;
} else {
driver->max_level = SHRT_MAX;
}

if (config_min_level) {
driver->min_level = config_min_level;
} else {
driver->min_level = SHRT_MIN;
}
break; break;


default: default:
@@ -679,6 +651,8 @@ alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, ClockSy
} }


static int under_gdb = FALSE; static int under_gdb = FALSE;
static int waitcnt = 0;



static int static int
alsa_driver_wait (alsa_driver_t *driver) alsa_driver_wait (alsa_driver_t *driver)
@@ -697,9 +671,11 @@ alsa_driver_wait (alsa_driver_t *driver)
int need_playback = 1; int need_playback = 1;
jack_engine_t *engine = driver->engine; jack_engine_t *engine = driver->engine;
int i; int i;
static unsigned long long last = 0;
unsigned long long start;


again: again:
while (need_playback || need_capture) { while (need_playback || need_capture) {


int p_timed_out, c_timed_out; int p_timed_out, c_timed_out;
@@ -740,6 +716,10 @@ alsa_driver_wait (alsa_driver_t *driver)
return -1; return -1;
} }


rdtscll (start);
// fprintf (stderr, "engine cycle %.6f msecs\n", (((float) (start - last))/450000.0f));
last = start;

if (driver->engine) { if (driver->engine) {
struct timeval tv; struct timeval tv;
gettimeofday (&tv, NULL); gettimeofday (&tv, NULL);
@@ -822,7 +802,9 @@ alsa_driver_wait (alsa_driver_t *driver)
avail = avail - (avail % driver->frames_per_cycle); avail = avail - (avail % driver->frames_per_cycle);


while (avail) { while (avail) {

waitcnt++;

capture_avail = (avail > driver->frames_per_cycle) ? driver->frames_per_cycle : avail; capture_avail = (avail > driver->frames_per_cycle) ? driver->frames_per_cycle : avail;
playback_avail = (avail > driver->frames_per_cycle) ? driver->frames_per_cycle : avail; playback_avail = (avail > driver->frames_per_cycle) ? driver->frames_per_cycle : avail;
@@ -835,45 +817,72 @@ alsa_driver_wait (alsa_driver_t *driver)


contiguous = capture_avail < playback_avail ? capture_avail : playback_avail; contiguous = capture_avail < playback_avail ? capture_avail : playback_avail;


/* XXX possible race condition here with silence_pending */
/* XXX this design is wrong. cf. ardour/audioengine *** FIX ME *** */

if (driver->silence_pending) {
for (chn = 0; chn < driver->playback_nchannels; chn++) {
if (driver->silence_pending & (1<<chn)) {
alsa_driver_silence_on_channel (driver, chn, contiguous);
}
}
driver->silence_pending = 0;
}

driver->channels_not_done = driver->channel_done_bits; driver->channels_not_done = driver->channel_done_bits;


if (engine->process_lock (engine) == 0) { if (engine->process_lock (engine) == 0) {
if (engine->process (engine, contiguous)) {
jack_error ("alsa_pcm: engine processing error - stopping.");
return -1;
int ret;
GSList *prev;

if ((ret = engine->process (engine, contiguous)) != 0) {
engine->process_unlock (engine);
alsa_driver_audio_stop (driver);
if (ret > 0) {
engine->post_process (engine);
}
return ret;
} }
/* now move data from ports to channels */ /* now move data from ports to channels */
for (chn = 0, node = driver->playback_ports; 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 */ /* optimize needless data copying away */
if (!jack_port_connected (port)) {
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 {
continue; continue;
} }
alsa_driver_write_to_channel (driver, chn, jack_port_get_buffer (port, contiguous), contiguous, 0, 1.0);

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

} }
engine->process_unlock (engine); engine->process_unlock (engine);
}
}


/* Now handle input monitoring */ /* Now handle input monitoring */
@@ -917,10 +926,6 @@ alsa_driver_wait (alsa_driver_t *driver)
} }
engine->post_process (engine); engine->post_process (engine);
// rdtscl (now);
// fprintf (stderr, "engine cycle took %.6f usecs\n", (((float) (now - start))/450.0f));

return 0; return 0;
} }


@@ -932,6 +937,7 @@ 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++) {


@@ -940,8 +946,11 @@ alsa_driver_process (nframes_t nframes, void *arg)
if (!jack_port_connected (port)) { if (!jack_port_connected (port)) {
continue; continue;
} }

alsa_driver_read_from_channel (driver, chn, jack_port_get_buffer (port, nframes), nframes, 0);
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]);
} }


return 0; return 0;
@@ -1044,12 +1053,6 @@ alsa_driver_change_sample_clock (alsa_driver_t *driver, SampleClockMode mode)
return driver->hw->change_sample_clock (driver->hw, mode); return driver->hw->change_sample_clock (driver->hw, mode);
} }


static void
alsa_driver_mark_channel_silent (alsa_driver_t *driver, unsigned long chn)
{
driver->silence_pending |= (1<<chn);
}

static void static void
alsa_driver_request_all_monitor_input (alsa_driver_t *driver, int yn) alsa_driver_request_all_monitor_input (alsa_driver_t *driver, int yn)


@@ -1181,7 +1184,6 @@ alsa_driver_new (char *name, char *alsa_device,
driver->capture_nchannels = 0; driver->capture_nchannels = 0;
driver->playback_addr = 0; driver->playback_addr = 0;
driver->capture_addr = 0; driver->capture_addr = 0;
driver->silence_pending = 0;
driver->silent = 0; driver->silent = 0;
driver->all_monitor_in = FALSE; driver->all_monitor_in = FALSE;


@@ -1207,12 +1209,15 @@ alsa_driver_new (char *name, char *alsa_device,
driver->alsa_name = strdup (alsa_device); driver->alsa_name = strdup (alsa_device);


if ((err = snd_pcm_open (&driver->capture_handle, alsa_device, SND_PCM_STREAM_CAPTURE, 0)) < 0) { if ((err = snd_pcm_open (&driver->capture_handle, alsa_device, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
snd_pcm_close (driver->playback_handle);
jack_error ("ALSA: Cannot open PCM device %s", name); jack_error ("ALSA: Cannot open PCM device %s", name);
free (driver); free (driver);
return 0; return 0;
} }


if (alsa_driver_check_card_type (driver)) { if (alsa_driver_check_card_type (driver)) {
snd_pcm_close (driver->capture_handle);
snd_pcm_close (driver->playback_handle);
free (driver); free (driver);
return 0; return 0;
} }
@@ -1325,6 +1330,8 @@ 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);


+ 9
- 18
client.c View File

@@ -565,7 +565,6 @@ jack_client_thread (void *arg)
err++; err++;
break; break;
} }

} }


if (client->pollfd[1].revents & POLLIN) { if (client->pollfd[1].revents & POLLIN) {
@@ -583,12 +582,10 @@ jack_client_thread (void *arg)
control->state = Running; control->state = Running;


if (control->process) { if (control->process) {
status = control->process (control->nframes, control->process_arg);
if (control->process (control->nframes, control->process_arg) == 0) {
control->state = Finished;
}
} else { } else {
status = 0;
}
if (!status) {
control->state = Finished; control->state = Finished;
} }


@@ -725,12 +722,8 @@ jack_client_close (jack_client_t *client)


{ {
GSList *node; GSList *node;
jack_request_t req;
void *status; void *status;


req.type = DropClient;
req.x.client_id = client->control->id;

/* stop the thread that communicates with the jack server */ /* stop the thread that communicates with the jack server */


pthread_cancel (client->thread); pthread_cancel (client->thread);
@@ -758,18 +751,13 @@ jack_client_close (jack_client_t *client)
close (client->graph_next_fd); close (client->graph_next_fd);
} }


if (write (client->request_fd, &req, sizeof (req)) != sizeof (req)) {
jack_error ("cannot send drop client request to server");
req.status = -1;
}

close (client->event_fd); close (client->event_fd);
close (client->request_fd); close (client->request_fd);


free (client->pollfd); free (client->pollfd);
free (client); free (client);


return req.status;
return 0;
} }


int int
@@ -1221,8 +1209,7 @@ jack_port_get_buffer (jack_port_t *port, nframes_t nframes)
} }


port->shared->type_info.mixdown (port, nframes); port->shared->type_info.mixdown (port, nframes);

return jack_port_buffer (port);
return (sample_t *) port->shared->offset;
} }


int int
@@ -1393,6 +1380,8 @@ jack_port_request_monitor (jack_port_t *port, int onoff)
int int
jack_ensure_port_monitor_input (jack_port_t *port, int yn) jack_ensure_port_monitor_input (jack_port_t *port, int yn)
{ {
printf ("ENSURE PORT monitor, req = %d, status = %d\n", yn, port->shared->monitor_requests);
if (yn) { if (yn) {
if (port->shared->monitor_requests == 0) { if (port->shared->monitor_requests == 0) {
port->shared->monitor_requests++; port->shared->monitor_requests++;
@@ -1570,6 +1559,8 @@ jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes)
sample_t *buffer; sample_t *buffer;
sample_t *dst, *src; sample_t *dst, *src;


printf ("audio mixdown on %s\n", port->shared->name);

/* by the time we've called this, we've already established /* by the time we've called this, we've already established
the existence of more than 1 connection to this input port. the existence of more than 1 connection to this input port.
*/ */


+ 100
- 70
engine.c View File

@@ -441,7 +441,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes)


client = (jack_client_internal_t *) node->data; client = (jack_client_internal_t *) node->data;


if (!client->control->active) {
if (!client->control->active || client->control->dead) {
node = g_slist_next (node); node = g_slist_next (node);
continue; continue;
} }
@@ -470,6 +470,8 @@ 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++;
@@ -491,7 +493,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes)
engine->process_errors++; engine->process_errors++;
break; break;
} }
if (pollfd[0].revents == 0) { if (pollfd[0].revents == 0) {
jack_error ("subgraph starting at %s timed out (state = %d)", client->control->name, client->control->state); jack_error ("subgraph starting at %s timed out (state = %d)", client->control->name, client->control->state);
engine->process_errors++; engine->process_errors++;
@@ -508,6 +510,8 @@ 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) {
@@ -520,7 +524,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes)
} }
} }


return 0;
return engine->process_errors > 0;
} }


int int
@@ -616,7 +620,9 @@ handle_new_client (jack_engine_t *engine, int client_fd)
} }


if (engine->verbose) { if (engine->verbose) {
fprintf (stderr, "new client: %s, type %d @ %p\n", client->control->name, req.type, client->control);
fprintf (stderr, "new client: %s, id = %d type %d @ %p fd = %d\n",
client->control->name, client->control->id,
req.type, client->control, client_fd);
} }


res.client_key = client->shm_key; res.client_key = client->shm_key;
@@ -648,8 +654,8 @@ handle_new_client (jack_engine_t *engine, int client_fd)
} }


pthread_mutex_lock (&engine->graph_lock); pthread_mutex_lock (&engine->graph_lock);

engine->clients = g_slist_prepend (engine->clients, client); engine->clients = g_slist_prepend (engine->clients, client);
pthread_mutex_unlock (&engine->graph_lock);


if (client->control->type != ClientDynamic) { if (client->control->type != ClientDynamic) {
if (engine->pfd_max >= engine->pfd_size) { if (engine->pfd_max >= engine->pfd_size) {
@@ -662,6 +668,7 @@ handle_new_client (jack_engine_t *engine, int client_fd)
engine->pfd_max++; engine->pfd_max++;
} }


pthread_mutex_unlock (&engine->graph_lock);


return 0; return 0;
} }
@@ -678,6 +685,8 @@ handle_client_ack_connection (jack_engine_t *engine, int client_fd)
jack_error ("cannot read ACK connection request from client"); jack_error ("cannot read ACK connection request from client");
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");
@@ -696,21 +705,6 @@ handle_client_ack_connection (jack_engine_t *engine, int client_fd)
return 0; return 0;
} }


static int
jack_client_drop (jack_engine_t *engine, jack_client_id_t id)

{
jack_client_internal_t *client;

if ((client = jack_client_internal_by_id (engine, id)) == 0) {
jack_error ("unknown client ID in DropClient request");
return -1;
}

jack_remove_client (engine, client);
return 0;
}

static int static int
jack_client_activate (jack_engine_t *engine, jack_client_id_t id) jack_client_activate (jack_engine_t *engine, jack_client_id_t id)


@@ -758,7 +752,7 @@ jack_client_do_deactivate (jack_engine_t *engine, jack_client_internal_t *client
if (!jack_client_is_inprocess (client)) { if (!jack_client_is_inprocess (client)) {
engine->external_client_cnt--; engine->external_client_cnt--;
} }
jack_sort_graph (engine, FALSE); jack_sort_graph (engine, FALSE);
return 0; return 0;
} }
@@ -839,7 +833,6 @@ jack_set_timebase (jack_engine_t *engine, jack_client_id_t client)


static int static int
handle_client_jack_error (jack_engine_t *engine, int fd) handle_client_jack_error (jack_engine_t *engine, int fd)

{ {
jack_client_internal_t *client = 0; jack_client_internal_t *client = 0;
GSList *node; GSList *node;
@@ -854,8 +847,8 @@ handle_client_jack_error (jack_engine_t *engine, int fd)
} }


if (client == 0) { if (client == 0) {
jack_error ("no client found for fd %d\n", fd);
pthread_mutex_unlock (&engine->graph_lock); pthread_mutex_unlock (&engine->graph_lock);
jack_error ("i/o error on unknown client fd %d", fd);
return -1; return -1;
} }


@@ -891,6 +884,7 @@ handle_client_io (jack_engine_t *engine, int fd)


if (read (client->request_fd, &req, sizeof (req)) < sizeof (req)) { if (read (client->request_fd, &req, sizeof (req)) < sizeof (req)) {
jack_error ("cannot read request from client"); jack_error ("cannot read request from client");
/* XXX interlock problems with the driver thread here */
jack_remove_client (engine, client); jack_remove_client (engine, client);
return -1; return -1;
} }
@@ -918,11 +912,6 @@ handle_client_io (jack_engine_t *engine, int fd)
req.status = jack_port_do_disconnect (engine, req.x.connect.source_port, req.x.connect.destination_port); req.status = jack_port_do_disconnect (engine, req.x.connect.source_port, req.x.connect.destination_port);
break; break;


case DropClient:
req.status = jack_client_drop (engine, req.x.client_id);
reply_fd = -1;
break;

case ActivateClient: case ActivateClient:
req.status = jack_client_activate (engine, req.x.client_id); req.status = jack_client_activate (engine, req.x.client_id);
break; break;
@@ -1045,6 +1034,7 @@ 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)) {
@@ -1196,19 +1186,8 @@ jack_become_real_time (pthread_t thread, int priority)
return 0; return 0;
} }


void
cancel_cleanup1 (void *arg)

{
jack_engine_t *engine = (jack_engine_t *) arg;
if (engine->verbose) {
fprintf (stderr, "audio thread cancelled or finished\n");
}
engine->driver->stop (engine->driver);
}

void
cancel_cleanup2 (int status, void *arg)
static void
cancel_cleanup (int status, void *arg)


{ {
jack_engine_t *engine = (jack_engine_t *) arg; jack_engine_t *engine = (jack_engine_t *) arg;
@@ -1230,7 +1209,7 @@ jack_main_thread (void *arg)
} }


pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
on_exit (cancel_cleanup2, engine);
on_exit (cancel_cleanup, engine);


if (driver->start (driver)) { if (driver->start (driver)) {
jack_error ("cannot start driver"); jack_error ("cannot start driver");
@@ -1238,7 +1217,20 @@ jack_main_thread (void *arg)
} }


while (1) { while (1) {
if (driver->wait (driver)) {
switch (driver->wait (driver)) {
case -1:
jack_error ("driver wait function failed, exiting");
pthread_exit (0);
break;

case 1:
if (driver->start (driver)) {
jack_error ("cannot restart driver");
pthread_exit (0);
}
break;

default:
break; break;
} }
} }
@@ -1396,11 +1388,17 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)
GSList *node; GSList *node;
int i; int i;


if (engine->verbose) {
fprintf (stderr, "removing client %s\n", client->control->name);
}
/* 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.
*/


client->control->dead = TRUE; client->control->dead = TRUE;
client->control->active = FALSE;


if (client == engine->timebase_client) { if (client == engine->timebase_client) {
engine->timebase_client = 0; engine->timebase_client = 0;
@@ -1409,6 +1407,11 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)


jack_client_disconnect (engine, client); jack_client_disconnect (engine, client);


/* try to force the server thread to return from poll */

close (client->event_fd);
close (client->request_fd);

for (node = engine->clients; node; node = g_slist_next (node)) { for (node = engine->clients; node; node = g_slist_next (node)) {
if (((jack_client_internal_t *) node->data)->control->id == client->control->id) { if (((jack_client_internal_t *) node->data)->control->id == client->control->id) {
engine->clients = g_slist_remove_link (engine->clients, node); engine->clients = g_slist_remove_link (engine->clients, node);
@@ -1416,13 +1419,13 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)
break; break;
} }
} }
jack_client_do_deactivate (engine, client); jack_client_do_deactivate (engine, client);


/* rearrange the pollfd array so that things work right the /* rearrange the pollfd array so that things work right the
next time we go into poll(2). next time we go into poll(2).
*/ */
for (i = 0; i < engine->pfd_max; i++) { for (i = 0; i < engine->pfd_max; i++) {
if (engine->pfd[i].fd == client->request_fd) { if (engine->pfd[i].fd == client->request_fd) {
if (i+1 < engine->pfd_max) { if (i+1 < engine->pfd_max) {
@@ -1432,9 +1435,6 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)
} }
} }


close (client->event_fd);
close (client->request_fd);

jack_client_delete (engine, client); jack_client_delete (engine, client);
} }


@@ -1497,7 +1497,8 @@ static int
jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_event_t *event) jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_event_t *event)
{ {
char status; char status;
int client_err = 0;

if (client->control->dead) { if (client->control->dead) {
return 0; return 0;
} }
@@ -1530,12 +1531,18 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_
} else { } else {
if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) { if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) {
jack_error ("cannot send event to client [%s] (%s)", client->control->name, strerror (errno)); jack_error ("cannot send event to client [%s] (%s)", client->control->name, strerror (errno));
return -1;
client_err++;
} }
if (read (client->event_fd, &status, sizeof (status)) != sizeof (status)) {
if (!client_err && (read (client->event_fd, &status, sizeof (status)) != sizeof (status))) {
jack_error ("cannot read event response from client [%s] (%s)", client->control->name, strerror (errno)); jack_error ("cannot read event response from client [%s] (%s)", client->control->name, strerror (errno));
return -1;
client_err++;
}

if (client_err || status != 0) {
pthread_mutex_lock (&engine->graph_lock);
jack_remove_client (engine, client);
pthread_mutex_unlock (&engine->graph_lock);
} }
} }


@@ -1704,20 +1711,37 @@ static int
jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b) jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b)


{ {
/* the driver client always comes after everything else */
if (g_slist_find (a->fed_by, b)) {
if (g_slist_find (b->fed_by, a)) {


if (a->control->type == ClientDriver) {
return 1;
}
/* feedback loop: if `a' is the driver
client, let that execute first.
*/


if (b->control->type == ClientDriver) {
return -1;
}
if (a->control->type == ClientDriver) {
/* b comes after a */
return -1;
}
}


if (g_slist_find (a->fed_by, b)) {
/* a comes after b */ /* a comes after b */
return 1; return 1;

} else if (g_slist_find (b->fed_by, a)) { } else if (g_slist_find (b->fed_by, a)) {
if (g_slist_find (a->fed_by, b)) {

/* feedback loop: if `b' is the driver
client, let that execute first.
*/

if (b->control->type == ClientDriver) {
/* b comes before a */
return 1;
}
}

/* b comes after a */ /* b comes after a */
return -1; return -1;
} else { } else {
@@ -1775,7 +1799,9 @@ jack_client_feeds (jack_client_internal_t *might, jack_client_internal_t *target
* *
* 3) now sort according to whether or not client1->fed_by (client2) is true. * 3) now sort according to whether or not client1->fed_by (client2) is true.
* if the condition is true, client2 must execute before client1 * if the condition is true, client2 must execute before client1
*
*/ */

static void static void
jack_sort_graph (jack_engine_t *engine, int take_lock) jack_sort_graph (jack_engine_t *engine, int take_lock)
{ {
@@ -2197,10 +2223,14 @@ static void
jack_port_release (jack_engine_t *engine, jack_port_internal_t *port) jack_port_release (jack_engine_t *engine, jack_port_internal_t *port)


{ {
/* XXX add the buffer used by the port back the (correct) freelist */

pthread_mutex_lock (&engine->port_lock); pthread_mutex_lock (&engine->port_lock);
port->shared->in_use = 0; port->shared->in_use = 0;

if (port->buffer_info) {
pthread_mutex_lock (&engine->buffer_lock);
engine->port_buffer_freelist = g_slist_prepend (engine->port_buffer_freelist, port->buffer_info);
pthread_mutex_unlock (&engine->buffer_lock);
}
pthread_mutex_unlock (&engine->port_lock); pthread_mutex_unlock (&engine->port_lock);
} }


@@ -2274,7 +2304,7 @@ jack_port_do_register (jack_engine_t *engine, jack_request_t *req)
pthread_mutex_unlock (&engine->graph_lock); pthread_mutex_unlock (&engine->graph_lock);


if (engine->verbose) { if (engine->verbose) {
fprintf (stderr, "registered port %s\n", shared->name);
fprintf (stderr, "registered port %s, offset = %u\n", shared->name, shared->offset);
} }


req->x.port_info.port_id = port_id; req->x.port_info.port_id = port_id;
@@ -2349,7 +2379,7 @@ int
jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port) jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
{ {
GSList *node; GSList *node;
jack_port_segment_info_t *psi;
jack_port_segment_info_t *psi = 0;
jack_port_buffer_info_t *bi; jack_port_buffer_info_t *bi;


port->shared->shm_key = -1; port->shared->shm_key = -1;
@@ -2367,7 +2397,7 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
} }


bi = (jack_port_buffer_info_t *) engine->port_buffer_freelist->data; bi = (jack_port_buffer_info_t *) engine->port_buffer_freelist->data;
for (node = engine->port_segments; node; node = g_slist_next (node)) { for (node = engine->port_segments; node; node = g_slist_next (node)) {


psi = (jack_port_segment_info_t *) node->data; psi = (jack_port_segment_info_t *) node->data;
@@ -2375,9 +2405,9 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
if (bi->shm_key == psi->shm_key) { if (bi->shm_key == psi->shm_key) {
port->shared->shm_key = psi->shm_key; port->shared->shm_key = psi->shm_key;
port->shared->offset = bi->offset; port->shared->offset = bi->offset;
port->buffer_info = bi;
break; break;
} }

} }
if (port->shared->shm_key >= 0) { if (port->shared->shm_key >= 0) {
@@ -2417,7 +2447,7 @@ jack_get_port_by_name (jack_engine_t *engine, const char *name)


static int static int
jack_send_connection_notification (jack_engine_t *engine, jack_client_id_t client_id, jack_send_connection_notification (jack_engine_t *engine, jack_client_id_t client_id,
jack_port_id_t self_id, jack_port_id_t other_id, int connected)
jack_port_id_t self_id, jack_port_id_t other_id, int connected)


{ {
jack_client_internal_t *client; jack_client_internal_t *client;


+ 3
- 8
jack/alsa_driver.h View File

@@ -77,10 +77,7 @@ typedef struct {
float max_sample_val; float max_sample_val;
unsigned long user_nperiods; unsigned long user_nperiods;
unsigned long nfragments; unsigned long nfragments;
int max_level;
int min_level;
unsigned long last_mask; unsigned long last_mask;
unsigned long silence_pending;
snd_ctl_t *ctl_handle; snd_ctl_t *ctl_handle;
snd_pcm_t *playback_handle; snd_pcm_t *playback_handle;
snd_pcm_t *capture_handle; snd_pcm_t *capture_handle;
@@ -147,11 +144,10 @@ static __inline__ void alsa_driver_silence_on_channel_no_mark (alsa_driver_t *dr


static __inline__ void alsa_driver_read_from_channel (alsa_driver_t *driver, static __inline__ void alsa_driver_read_from_channel (alsa_driver_t *driver,
channel_t channel, sample_t *buf, channel_t channel, sample_t *buf,
nframes_t nsamples,
unsigned long offset)
nframes_t nsamples)
{ {
driver->read_via_copy (buf, driver->read_via_copy (buf,
driver->capture_addr[channel] + offset,
driver->capture_addr[channel],
nsamples, nsamples,
driver->capture_interleave_skip); driver->capture_interleave_skip);
} }
@@ -160,10 +156,9 @@ static __inline__ void alsa_driver_write_to_channel (alsa_driver_t *driver,
channel_t channel, channel_t channel,
sample_t *buf, sample_t *buf,
nframes_t nsamples, nframes_t nsamples,
unsigned long offset,
gain_t gain) gain_t gain)
{ {
driver->write_via_copy (driver->playback_addr[channel] + offset,
driver->write_via_copy (driver->playback_addr[channel],
buf, buf,
nsamples, nsamples,
driver->playback_interleave_skip, driver->playback_interleave_skip,


+ 4
- 5
jack/internal.h View File

@@ -191,11 +191,10 @@ typedef enum {
ConnectPorts = 3, ConnectPorts = 3,
DisconnectPorts = 4, DisconnectPorts = 4,
SetTimeBaseClient = 5, SetTimeBaseClient = 5,
DropClient = 6,
ActivateClient = 7,
DeactivateClient = 8,
GetPortTotalLatency = 9,
DisconnectPort = 10
ActivateClient = 6,
DeactivateClient = 7,
GetPortTotalLatency = 8,
DisconnectPort = 9
} AudioEngineRequestType; } AudioEngineRequestType;


typedef struct { typedef struct {


+ 1
- 0
jack/port.h View File

@@ -95,6 +95,7 @@ struct _jack_port {
typedef struct _jack_port_internal { typedef struct _jack_port_internal {
struct _jack_port_shared *shared; struct _jack_port_shared *shared;
GSList *connections; GSList *connections;
void *buffer_info;
} jack_port_internal_t; } jack_port_internal_t;


#endif /* __jack_port_h__ */ #endif /* __jack_port_h__ */


+ 1
- 1
monitor_client.c View File

@@ -20,7 +20,7 @@ main (int argc, char *argv[])
if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", TRUE)) { if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", TRUE)) {
fprintf (stderr, "could not enable monitoring for in_1\n"); fprintf (stderr, "could not enable monitoring for in_1\n");
} }
sleep (10);
sleep (30);
if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", FALSE)) { if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", FALSE)) {
fprintf (stderr, "could not disable monitoring for in_1\n"); fprintf (stderr, "could not disable monitoring for in_1\n");
} }


+ 3
- 2
simple_client.c View File

@@ -3,6 +3,8 @@
#include <unistd.h> #include <unistd.h>


#include <jack/jack.h> #include <jack/jack.h>
#include <glib.h>
#include <jack/port.h>


jack_port_t *input_port; jack_port_t *input_port;
jack_port_t *output_port; jack_port_t *output_port;
@@ -15,7 +17,6 @@ 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;
} }


@@ -119,7 +120,7 @@ main (int argc, char *argv[])


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


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


Loading…
Cancel
Save