git-svn-id: svn+ssh://jackaudio.org/trunk/jack@101 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -35,8 +35,8 @@ | |||
#include <jack/hammerfall.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 | |||
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) { | |||
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: | |||
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; | |||
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 waitcnt = 0; | |||
static int | |||
alsa_driver_wait (alsa_driver_t *driver) | |||
@@ -697,9 +671,11 @@ alsa_driver_wait (alsa_driver_t *driver) | |||
int need_playback = 1; | |||
jack_engine_t *engine = driver->engine; | |||
int i; | |||
static unsigned long long last = 0; | |||
unsigned long long start; | |||
again: | |||
while (need_playback || need_capture) { | |||
int p_timed_out, c_timed_out; | |||
@@ -740,6 +716,10 @@ alsa_driver_wait (alsa_driver_t *driver) | |||
return -1; | |||
} | |||
rdtscll (start); | |||
// fprintf (stderr, "engine cycle %.6f msecs\n", (((float) (start - last))/450000.0f)); | |||
last = start; | |||
if (driver->engine) { | |||
struct timeval tv; | |||
gettimeofday (&tv, NULL); | |||
@@ -822,7 +802,9 @@ alsa_driver_wait (alsa_driver_t *driver) | |||
avail = avail - (avail % driver->frames_per_cycle); | |||
while (avail) { | |||
waitcnt++; | |||
capture_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; | |||
/* 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; | |||
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 */ | |||
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; | |||
sample_t *buf; | |||
/* 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; | |||
} | |||
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); | |||
} | |||
} | |||
/* Now handle input monitoring */ | |||
@@ -917,10 +926,6 @@ alsa_driver_wait (alsa_driver_t *driver) | |||
} | |||
engine->post_process (engine); | |||
// rdtscl (now); | |||
// fprintf (stderr, "engine cycle took %.6f usecs\n", (((float) (now - start))/450.0f)); | |||
return 0; | |||
} | |||
@@ -932,6 +937,7 @@ 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++) { | |||
@@ -940,8 +946,11 @@ alsa_driver_process (nframes_t nframes, void *arg) | |||
if (!jack_port_connected (port)) { | |||
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; | |||
@@ -1044,12 +1053,6 @@ alsa_driver_change_sample_clock (alsa_driver_t *driver, SampleClockMode 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 | |||
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->playback_addr = 0; | |||
driver->capture_addr = 0; | |||
driver->silence_pending = 0; | |||
driver->silent = 0; | |||
driver->all_monitor_in = FALSE; | |||
@@ -1207,12 +1209,15 @@ alsa_driver_new (char *name, char *alsa_device, | |||
driver->alsa_name = strdup (alsa_device); | |||
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); | |||
free (driver); | |||
return 0; | |||
} | |||
if (alsa_driver_check_card_type (driver)) { | |||
snd_pcm_close (driver->capture_handle); | |||
snd_pcm_close (driver->playback_handle); | |||
free (driver); | |||
return 0; | |||
} | |||
@@ -1325,6 +1330,8 @@ 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); | |||
@@ -565,7 +565,6 @@ jack_client_thread (void *arg) | |||
err++; | |||
break; | |||
} | |||
} | |||
if (client->pollfd[1].revents & POLLIN) { | |||
@@ -583,12 +582,10 @@ jack_client_thread (void *arg) | |||
control->state = Running; | |||
if (control->process) { | |||
status = control->process (control->nframes, control->process_arg); | |||
if (control->process (control->nframes, control->process_arg) == 0) { | |||
control->state = Finished; | |||
} | |||
} else { | |||
status = 0; | |||
} | |||
if (!status) { | |||
control->state = Finished; | |||
} | |||
@@ -725,12 +722,8 @@ jack_client_close (jack_client_t *client) | |||
{ | |||
GSList *node; | |||
jack_request_t req; | |||
void *status; | |||
req.type = DropClient; | |||
req.x.client_id = client->control->id; | |||
/* stop the thread that communicates with the jack server */ | |||
pthread_cancel (client->thread); | |||
@@ -758,18 +751,13 @@ jack_client_close (jack_client_t *client) | |||
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->request_fd); | |||
free (client->pollfd); | |||
free (client); | |||
return req.status; | |||
return 0; | |||
} | |||
int | |||
@@ -1221,8 +1209,7 @@ jack_port_get_buffer (jack_port_t *port, nframes_t nframes) | |||
} | |||
port->shared->type_info.mixdown (port, nframes); | |||
return jack_port_buffer (port); | |||
return (sample_t *) port->shared->offset; | |||
} | |||
int | |||
@@ -1393,6 +1380,8 @@ jack_port_request_monitor (jack_port_t *port, int onoff) | |||
int | |||
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 (port->shared->monitor_requests == 0) { | |||
port->shared->monitor_requests++; | |||
@@ -1570,6 +1559,8 @@ jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes) | |||
sample_t *buffer; | |||
sample_t *dst, *src; | |||
printf ("audio mixdown on %s\n", port->shared->name); | |||
/* by the time we've called this, we've already established | |||
the existence of more than 1 connection to this input port. | |||
*/ | |||
@@ -441,7 +441,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | |||
client = (jack_client_internal_t *) node->data; | |||
if (!client->control->active) { | |||
if (!client->control->active || client->control->dead) { | |||
node = g_slist_next (node); | |||
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) | |||
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++; | |||
@@ -491,7 +493,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | |||
engine->process_errors++; | |||
break; | |||
} | |||
if (pollfd[0].revents == 0) { | |||
jack_error ("subgraph starting at %s timed out (state = %d)", client->control->name, client->control->state); | |||
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) */ | |||
while (node) { | |||
@@ -520,7 +524,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | |||
} | |||
} | |||
return 0; | |||
return engine->process_errors > 0; | |||
} | |||
int | |||
@@ -616,7 +620,9 @@ handle_new_client (jack_engine_t *engine, int client_fd) | |||
} | |||
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; | |||
@@ -648,8 +654,8 @@ handle_new_client (jack_engine_t *engine, int client_fd) | |||
} | |||
pthread_mutex_lock (&engine->graph_lock); | |||
engine->clients = g_slist_prepend (engine->clients, client); | |||
pthread_mutex_unlock (&engine->graph_lock); | |||
if (client->control->type != ClientDynamic) { | |||
if (engine->pfd_max >= engine->pfd_size) { | |||
@@ -662,6 +668,7 @@ handle_new_client (jack_engine_t *engine, int client_fd) | |||
engine->pfd_max++; | |||
} | |||
pthread_mutex_unlock (&engine->graph_lock); | |||
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"); | |||
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"); | |||
@@ -696,21 +705,6 @@ handle_client_ack_connection (jack_engine_t *engine, int client_fd) | |||
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 | |||
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)) { | |||
engine->external_client_cnt--; | |||
} | |||
jack_sort_graph (engine, FALSE); | |||
return 0; | |||
} | |||
@@ -839,7 +833,6 @@ jack_set_timebase (jack_engine_t *engine, jack_client_id_t client) | |||
static int | |||
handle_client_jack_error (jack_engine_t *engine, int fd) | |||
{ | |||
jack_client_internal_t *client = 0; | |||
GSList *node; | |||
@@ -854,8 +847,8 @@ handle_client_jack_error (jack_engine_t *engine, int fd) | |||
} | |||
if (client == 0) { | |||
jack_error ("no client found for fd %d\n", fd); | |||
pthread_mutex_unlock (&engine->graph_lock); | |||
jack_error ("i/o error on unknown client fd %d", fd); | |||
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)) { | |||
jack_error ("cannot read request from client"); | |||
/* XXX interlock problems with the driver thread here */ | |||
jack_remove_client (engine, client); | |||
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); | |||
break; | |||
case DropClient: | |||
req.status = jack_client_drop (engine, req.x.client_id); | |||
reply_fd = -1; | |||
break; | |||
case ActivateClient: | |||
req.status = jack_client_activate (engine, req.x.client_id); | |||
break; | |||
@@ -1045,6 +1034,7 @@ 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)) { | |||
@@ -1196,19 +1186,8 @@ jack_become_real_time (pthread_t thread, int priority) | |||
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; | |||
@@ -1230,7 +1209,7 @@ jack_main_thread (void *arg) | |||
} | |||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | |||
on_exit (cancel_cleanup2, engine); | |||
on_exit (cancel_cleanup, engine); | |||
if (driver->start (driver)) { | |||
jack_error ("cannot start driver"); | |||
@@ -1238,7 +1217,20 @@ jack_main_thread (void *arg) | |||
} | |||
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; | |||
} | |||
} | |||
@@ -1396,11 +1388,17 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) | |||
GSList *node; | |||
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->active = FALSE; | |||
if (client == engine->timebase_client) { | |||
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); | |||
/* 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)) { | |||
if (((jack_client_internal_t *) node->data)->control->id == client->control->id) { | |||
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; | |||
} | |||
} | |||
jack_client_do_deactivate (engine, client); | |||
/* rearrange the pollfd array so that things work right the | |||
next time we go into poll(2). | |||
*/ | |||
for (i = 0; i < engine->pfd_max; i++) { | |||
if (engine->pfd[i].fd == client->request_fd) { | |||
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); | |||
} | |||
@@ -1497,7 +1497,8 @@ static int | |||
jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_event_t *event) | |||
{ | |||
char status; | |||
int client_err = 0; | |||
if (client->control->dead) { | |||
return 0; | |||
} | |||
@@ -1530,12 +1531,18 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_ | |||
} else { | |||
if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) { | |||
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)); | |||
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) | |||
{ | |||
/* 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 */ | |||
return 1; | |||
} 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 */ | |||
return -1; | |||
} 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. | |||
* if the condition is true, client2 must execute before client1 | |||
* | |||
*/ | |||
static void | |||
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) | |||
{ | |||
/* XXX add the buffer used by the port back the (correct) freelist */ | |||
pthread_mutex_lock (&engine->port_lock); | |||
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); | |||
} | |||
@@ -2274,7 +2304,7 @@ jack_port_do_register (jack_engine_t *engine, jack_request_t *req) | |||
pthread_mutex_unlock (&engine->graph_lock); | |||
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; | |||
@@ -2349,7 +2379,7 @@ int | |||
jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port) | |||
{ | |||
GSList *node; | |||
jack_port_segment_info_t *psi; | |||
jack_port_segment_info_t *psi = 0; | |||
jack_port_buffer_info_t *bi; | |||
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; | |||
for (node = engine->port_segments; node; node = g_slist_next (node)) { | |||
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) { | |||
port->shared->shm_key = psi->shm_key; | |||
port->shared->offset = bi->offset; | |||
port->buffer_info = bi; | |||
break; | |||
} | |||
} | |||
if (port->shared->shm_key >= 0) { | |||
@@ -2417,7 +2447,7 @@ jack_get_port_by_name (jack_engine_t *engine, const char *name) | |||
static int | |||
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; | |||
@@ -77,10 +77,7 @@ typedef struct { | |||
float max_sample_val; | |||
unsigned long user_nperiods; | |||
unsigned long nfragments; | |||
int max_level; | |||
int min_level; | |||
unsigned long last_mask; | |||
unsigned long silence_pending; | |||
snd_ctl_t *ctl_handle; | |||
snd_pcm_t *playback_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, | |||
channel_t channel, sample_t *buf, | |||
nframes_t nsamples, | |||
unsigned long offset) | |||
nframes_t nsamples) | |||
{ | |||
driver->read_via_copy (buf, | |||
driver->capture_addr[channel] + offset, | |||
driver->capture_addr[channel], | |||
nsamples, | |||
driver->capture_interleave_skip); | |||
} | |||
@@ -160,10 +156,9 @@ static __inline__ void alsa_driver_write_to_channel (alsa_driver_t *driver, | |||
channel_t channel, | |||
sample_t *buf, | |||
nframes_t nsamples, | |||
unsigned long offset, | |||
gain_t gain) | |||
{ | |||
driver->write_via_copy (driver->playback_addr[channel] + offset, | |||
driver->write_via_copy (driver->playback_addr[channel], | |||
buf, | |||
nsamples, | |||
driver->playback_interleave_skip, | |||
@@ -191,11 +191,10 @@ typedef enum { | |||
ConnectPorts = 3, | |||
DisconnectPorts = 4, | |||
SetTimeBaseClient = 5, | |||
DropClient = 6, | |||
ActivateClient = 7, | |||
DeactivateClient = 8, | |||
GetPortTotalLatency = 9, | |||
DisconnectPort = 10 | |||
ActivateClient = 6, | |||
DeactivateClient = 7, | |||
GetPortTotalLatency = 8, | |||
DisconnectPort = 9 | |||
} AudioEngineRequestType; | |||
typedef struct { | |||
@@ -95,6 +95,7 @@ struct _jack_port { | |||
typedef struct _jack_port_internal { | |||
struct _jack_port_shared *shared; | |||
GSList *connections; | |||
void *buffer_info; | |||
} jack_port_internal_t; | |||
#endif /* __jack_port_h__ */ | |||
@@ -20,7 +20,7 @@ main (int argc, char *argv[]) | |||
if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", TRUE)) { | |||
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)) { | |||
fprintf (stderr, "could not disable monitoring for in_1\n"); | |||
} | |||
@@ -3,6 +3,8 @@ | |||
#include <unistd.h> | |||
#include <jack/jack.h> | |||
#include <glib.h> | |||
#include <jack/port.h> | |||
jack_port_t *input_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); | |||
memcpy (out, in, sizeof (sample_t) * nframes); | |||
return 0; | |||
} | |||
@@ -119,7 +120,7 @@ main (int argc, char *argv[]) | |||
/* Since this is just a toy, run for 5 seconds, then finish */ | |||
sleep (5); | |||
sleep (2); | |||
jack_client_close (client); | |||
exit (0); | |||
} | |||