diff -Nur jack-audio-connection-kit-0.109.2/drivers/alsa/alsa_driver.c jack-audio-connection-kit-0.109.2-alsa-disconnect/drivers/alsa/alsa_driver.c --- jack-audio-connection-kit-0.109.2/drivers/alsa/alsa_driver.c 2008-01-30 19:23:52.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/drivers/alsa/alsa_driver.c 2008-03-01 13:40:27.000000000 +0100 @@ -53,6 +53,8 @@ /* Delay (in process calls) before jackd will report an xrun */ #define XRUN_REPORT_DELAY 0 +static int alsa_driver_connect (alsa_driver_t *driver); + static void alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver) { @@ -130,6 +132,7 @@ jack_error ("control hardware info \"%s\" (%s)", driver->alsa_name_playback, snd_strerror (err)); snd_ctl_close (driver->ctl_handle); + driver->ctl_handle = 0; } driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); @@ -964,6 +967,9 @@ snd_pcm_uframes_t poffset, pavail; channel_t chn; + if(!driver->connected) + return 0; + driver->poll_last = 0; driver->poll_next = 0; @@ -1092,6 +1098,8 @@ /* silence all capture port buffers, because we might be entering offline mode. */ + if (!driver->connected) + return 0; for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { @@ -1157,6 +1165,9 @@ snd_pcm_status_t *status; int res; + if (!driver->connected) + return 0; + snd_pcm_status_alloca(&status); if (driver->capture_handle) { @@ -1198,6 +1209,9 @@ jack_nframes_t buffer_frames = driver->frames_per_cycle * driver->playback_nperiods; + if(!driver->connected) + return; + for (chn = 0; chn < driver->playback_nchannels; chn++) { if (bitset_contains (driver->channels_not_done, chn)) { if (driver->silent[chn] < buffer_frames) { @@ -1924,8 +1938,8 @@ } #endif -static void -alsa_driver_delete (alsa_driver_t *driver) +static int +alsa_driver_disconnect (alsa_driver_t *driver) { JSList *node; @@ -1945,7 +1959,7 @@ if (driver->playback_handle) { snd_pcm_close (driver->playback_handle); - driver->capture_handle = 0; + driver->playback_handle = 0; } if (driver->capture_hw_params) { @@ -1968,16 +1982,34 @@ driver->playback_sw_params = 0; } + if(driver->ctl_handle) { + snd_ctl_close(driver->ctl_handle); + driver->ctl_handle = 0; + } + if (driver->pfd) { free (driver->pfd); + driver->pfd = 0; } - + if (driver->hw) { driver->hw->release (driver->hw); driver->hw = 0; } + + driver->connected = 0; + + return 0; +} + +static void +alsa_driver_delete (alsa_driver_t *driver) +{ + alsa_driver_disconnect(driver); + free(driver->alsa_name_playback); free(driver->alsa_name_capture); + free(driver->alsa_driver); alsa_driver_release_channel_dependent_memory (driver); @@ -2007,8 +2039,6 @@ alsa_midi_t *midi_driver ) { - int err; - alsa_driver_t *driver; printf ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32 @@ -2036,6 +2066,8 @@ driver->nt_start = (JackDriverNTStartFunction) alsa_driver_start; driver->nt_stop = (JackDriverNTStopFunction) alsa_driver_stop; driver->nt_run_cycle = (JackDriverNTRunCycleFunction) alsa_driver_run_cycle; + driver->nt_connect = (JackDriverNTConnectFunction) alsa_driver_connect; + driver->nt_disconnect = (JackDriverNTDisconnectFunction) alsa_driver_disconnect; driver->playback_handle = NULL; driver->capture_handle = NULL; @@ -2095,11 +2127,47 @@ return NULL; } - alsa_driver_hw_specific (driver, hw_monitoring, hw_metering); + alsa_driver_hw_specific (driver, driver->hw_monitoring, driver->hw_metering); + + driver->alsa_name_playback = strdup (playback_alsa_device); + driver->alsa_name_capture = strdup (capture_alsa_device); + + driver->name = strdup (name); + + driver->playback = playing; + driver->capture = capturing; + + driver->frames_per_cycle = frames_per_cycle; + driver->user_nperiods = user_nperiods; + driver->frame_rate = rate; + + driver->client = client; + + driver->connected = 0; + + // if we don't connect now then the hardware capability detection bits won't + // get run before we're asked to register our ports. and if that happens + // our capture & playback port numbers will be 0 causing us to not register anything + // and that's bad. + if (alsa_driver_connect(driver) != 0) { + alsa_driver_delete (driver); + return NULL; + } + + return (jack_driver_t *)driver; +} - if (playing) { +static int +alsa_driver_connect (alsa_driver_t *driver) +{ + int err; + + if (driver->connected) + return 0; + + if (driver->playback) { if (snd_pcm_open (&driver->playback_handle, - playback_alsa_device, + driver->alsa_name_playback, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) { switch (errno) { @@ -2108,17 +2176,25 @@ "already in use. Please stop the" " application using it and " "run JACK again", - playback_alsa_device); - alsa_driver_delete (driver); - return NULL; + driver->alsa_name_playback); + return -1; break; case EPERM: jack_error ("you do not have permission to open " "the audio device \"%s\" for playback", - playback_alsa_device); - alsa_driver_delete (driver); - return NULL; + driver->alsa_name_playback); + return -1; + break; + + default: + if (errno) { + char *str = strerror(errno); + jack_error ("the playback device \"%s\" could not be opened" + " because of: \"%s\"\n", + driver->alsa_name_playback,str); + return -1; + } break; } @@ -2130,9 +2206,9 @@ } } - if (capturing) { + if (driver->capture) { if (snd_pcm_open (&driver->capture_handle, - capture_alsa_device, + driver->alsa_name_capture, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK) < 0) { switch (errno) { @@ -2141,17 +2217,25 @@ "already in use. Please stop the" " application using it and " "run JACK again", - capture_alsa_device); - alsa_driver_delete (driver); - return NULL; + driver->alsa_name_capture); + return -1; break; case EPERM: jack_error ("you do not have permission to open " "the audio device \"%s\" for capture", - capture_alsa_device); - alsa_driver_delete (driver); - return NULL; + driver->alsa_name_capture); + return -1; + break; + + default: + if (errno) { + char *str = strerror(errno); + jack_error ("the capture device \"%s\" could not be opened" + " because of: \"%s\"\n", + driver->alsa_name_playback,str); + return -1; + } break; } @@ -2164,40 +2248,38 @@ } if (driver->playback_handle == NULL) { - if (playing) { + if (driver->playback) { /* they asked for playback, but we can't do it */ jack_error ("ALSA: Cannot open PCM device %s for " "playback. Falling back to capture-only" - " mode", name); + " mode", driver->name); if (driver->capture_handle == NULL) { /* can't do anything */ - alsa_driver_delete (driver); - return NULL; + return -1; } - playing = FALSE; + driver->playback = FALSE; } } if (driver->capture_handle == NULL) { - if (capturing) { + if (driver->capture) { /* they asked for capture, but we can't do it */ jack_error ("ALSA: Cannot open PCM device %s for " "capture. Falling back to playback-only" - " mode", name); + " mode", driver->name); if (driver->playback_handle == NULL) { /* can't do anything */ - alsa_driver_delete (driver); - return NULL; + return -1; } - capturing = FALSE; + driver->capture = FALSE; } } @@ -2211,16 +2293,14 @@ &driver->playback_hw_params)) < 0) { jack_error ("ALSA: could not allocate playback hw" " params structure"); - alsa_driver_delete (driver); - return NULL; + return -1; } if ((err = snd_pcm_sw_params_malloc ( &driver->playback_sw_params)) < 0) { jack_error ("ALSA: could not allocate playback sw" " params structure"); - alsa_driver_delete (driver); - return NULL; + return -1; } } @@ -2229,23 +2309,20 @@ &driver->capture_hw_params)) < 0) { jack_error ("ALSA: could not allocate capture hw" " params structure"); - alsa_driver_delete (driver); - return NULL; + return -1; } if ((err = snd_pcm_sw_params_malloc ( &driver->capture_sw_params)) < 0) { jack_error ("ALSA: could not allocate capture sw" " params structure"); - alsa_driver_delete (driver); - return NULL; + return -1; } } - if (alsa_driver_set_parameters (driver, frames_per_cycle, - user_nperiods, rate)) { - alsa_driver_delete (driver); - return NULL; + if (alsa_driver_set_parameters (driver, driver->frames_per_cycle, + driver->user_nperiods, driver->frame_rate)) { + return -1; } driver->capture_and_playback_not_synced = FALSE; @@ -2257,9 +2334,9 @@ } } - driver->client = client; + driver->connected = 1; - return (jack_driver_t *) driver; + return 0; } int diff -Nur jack-audio-connection-kit-0.109.2/drivers/alsa/alsa_driver.h jack-audio-connection-kit-0.109.2-alsa-disconnect/drivers/alsa/alsa_driver.h --- jack-audio-connection-kit-0.109.2/drivers/alsa/alsa_driver.h 2008-01-30 19:23:52.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/drivers/alsa/alsa_driver.h 2008-03-01 13:40:27.000000000 +0100 @@ -136,6 +136,12 @@ pthread_mutex_t clock_sync_lock; unsigned long next_clock_sync_listener_id; + char playback : 1; + char capture : 1; + char connected : 1; + + char *name; + int running; int run; diff -Nur jack-audio-connection-kit-0.109.2/example-clients/Makefile.am jack-audio-connection-kit-0.109.2-alsa-disconnect/example-clients/Makefile.am --- jack-audio-connection-kit-0.109.2/example-clients/Makefile.am 2008-01-30 19:23:43.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/example-clients/Makefile.am 2008-03-01 13:40:27.000000000 +0100 @@ -36,6 +36,7 @@ jack_bufsize \ jack_lsp \ jack_freewheel \ + jack_device_connect \ jack_evmon \ jack_alias \ $(JACKREC) \ @@ -101,6 +102,10 @@ jack_freewheel_LDFLAGS = @OS_LDFLAGS@ jack_freewheel_LDADD = ../libjack/libjack.la +jack_device_connect_SOURCES = device_connect.c +jack_device_connect_LDFLAGS = @OS_LDFLAGS@ +jack_device_connect_LDADD = ../libjack/libjack.la + if HAVE_SNDFILE jackrec_SOURCES = capture_client.c jackrec_LDFLAGS = @SNDFILE_LIBS@ @OS_LDFLAGS@ diff -Nur jack-audio-connection-kit-0.109.2/example-clients/Makefile.in jack-audio-connection-kit-0.109.2-alsa-disconnect/example-clients/Makefile.in --- jack-audio-connection-kit-0.109.2/example-clients/Makefile.in 2008-01-30 19:24:36.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/example-clients/Makefile.in 2008-03-01 13:48:04.000000000 +0100 @@ -40,7 +40,7 @@ target_triplet = @target@ bin_PROGRAMS = jack_load$(EXEEXT) jack_unload$(EXEEXT) \ jack_simple_client$(EXEEXT) jack_monitor_client$(EXEEXT) \ - jack_impulse_grabber$(EXEEXT) jack_connect$(EXEEXT) \ + jack_impulse_grabber$(EXEEXT) jack_connect$(EXEEXT) jack_device_connect$(EXEEXT) \ jack_disconnect$(EXEEXT) jack_metro$(EXEEXT) \ jack_showtime$(EXEEXT) jack_bufsize$(EXEEXT) jack_lsp$(EXEEXT) \ jack_freewheel$(EXEEXT) jack_evmon$(EXEEXT) \ @@ -85,6 +85,9 @@ am_jack_connect_OBJECTS = connect.$(OBJEXT) jack_connect_OBJECTS = $(am_jack_connect_OBJECTS) jack_connect_DEPENDENCIES = ../libjack/libjack.la +am_jack_device_connect_OBJECTS = device_connect.$(OBJEXT) +jack_device_connect_OBJECTS = $(am_jack_device_connect_OBJECTS) +jack_device_connect_DEPENDENCIES = ../libjack/libjack.la am_jack_disconnect_OBJECTS = connect.$(OBJEXT) jack_disconnect_OBJECTS = $(am_jack_disconnect_OBJECTS) jack_disconnect_DEPENDENCIES = ../libjack/libjack.la @@ -149,7 +152,7 @@ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(inprocess_la_SOURCES) $(intime_la_SOURCES) \ $(jack_alias_SOURCES) $(jack_bufsize_SOURCES) \ - $(jack_connect_SOURCES) $(jack_disconnect_SOURCES) \ + $(jack_connect_SOURCES) $(jack_device_connect_SOURCES) $(jack_disconnect_SOURCES) \ $(jack_evmon_SOURCES) $(jack_freewheel_SOURCES) \ $(jack_impulse_grabber_SOURCES) $(jack_load_SOURCES) \ $(jack_lsp_SOURCES) $(jack_metro_SOURCES) \ @@ -160,7 +163,7 @@ $(jackrec_SOURCES) DIST_SOURCES = $(inprocess_la_SOURCES) $(intime_la_SOURCES) \ $(jack_alias_SOURCES) $(jack_bufsize_SOURCES) \ - $(jack_connect_SOURCES) $(jack_disconnect_SOURCES) \ + $(jack_connect_SOURCES) $(jack_device_connect_SOURCES) $(jack_disconnect_SOURCES) \ $(jack_evmon_SOURCES) $(jack_freewheel_SOURCES) \ $(jack_impulse_grabber_SOURCES) $(jack_load_SOURCES) \ $(jack_lsp_SOURCES) $(jack_metro_SOURCES) \ @@ -351,6 +354,9 @@ jack_connect_SOURCES = connect.c jack_connect_LDFLAGS = @OS_LDFLAGS@ jack_connect_LDADD = ../libjack/libjack.la +jack_device_connect_SOURCES = connect.c +jack_device_connect_LDFLAGS = @OS_LDFLAGS@ +jack_device_connect_LDADD = ../libjack/libjack.la jack_disconnect_SOURCES = connect.c jack_disconnect_LDFLAGS = @OS_LDFLAGS@ jack_disconnect_LDADD = ../libjack/libjack.la @@ -524,6 +530,9 @@ jack_connect$(EXEEXT): $(jack_connect_OBJECTS) $(jack_connect_DEPENDENCIES) @rm -f jack_connect$(EXEEXT) $(LINK) $(jack_connect_LDFLAGS) $(jack_connect_OBJECTS) $(jack_connect_LDADD) $(LIBS) +jack_device_connect$(EXEEXT): $(jack_device_connect_OBJECTS) $(jack_device_connect_DEPENDENCIES) + @rm -f jack_device_connect$(EXEEXT) + $(LINK) $(jack_device_connect_LDFLAGS) $(jack_device_connect_OBJECTS) $(jack_device_connect_LDADD) $(LIBS) jack_disconnect$(EXEEXT): $(jack_disconnect_OBJECTS) $(jack_disconnect_DEPENDENCIES) @rm -f jack_disconnect$(EXEEXT) $(LINK) $(jack_disconnect_LDFLAGS) $(jack_disconnect_OBJECTS) $(jack_disconnect_LDADD) $(LIBS) diff -Nur jack-audio-connection-kit-0.109.2/example-clients/device_connect.c jack-audio-connection-kit-0.109.2-alsa-disconnect/example-clients/device_connect.c --- jack-audio-connection-kit-0.109.2/example-clients/device_connect.c 1970-01-01 01:00:00.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/example-clients/device_connect.c 2008-03-01 13:40:27.000000000 +0100 @@ -0,0 +1,86 @@ +/* + * freewheel - start/stop JACK "freewheeling" mode + * + * Copyright (C) 2003 Paul Davis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +char *package; /* program name */ +jack_client_t *client; +int onoff; + +void jack_shutdown(void *arg) +{ + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); +} + +void signal_handler(int sig) +{ + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +void parse_arguments(int argc, char *argv[]) +{ + if (argc < 2) { + fprintf(stderr, "usage: %s y|n\n", package); + exit(9); + } + + if (argv[1][0] == 'y' || argv[1][0] == 'Y' || argv[1][0] == '1') { + onoff = 1; + } else { + onoff = 0; + } +} + +int +main (int argc, char *argv[]) +{ + parse_arguments (argc, argv); + + /* become a JACK client */ + if ((client = jack_client_new ("device_connect")) == 0) { + fprintf (stderr, "JACK server not running?\n"); + exit(1); + } + + signal (SIGQUIT, signal_handler); + signal (SIGTERM, signal_handler); + signal (SIGHUP, signal_handler); + signal (SIGINT, signal_handler); + + jack_on_shutdown (client, jack_shutdown, 0); + + if (jack_set_connected (client, onoff)) { + fprintf (stderr, "failed to reset connect state\n"); + } + + jack_client_close(client); + + return 0; +} diff -Nur jack-audio-connection-kit-0.109.2/jack/driver.h jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/driver.h --- jack-audio-connection-kit-0.109.2/jack/driver.h 2008-01-30 19:23:50.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/driver.h 2008-03-01 13:40:27.000000000 +0100 @@ -60,6 +60,9 @@ typedef int (*JackDriverStartFunction)(struct _jack_driver *); typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *, jack_nframes_t nframes); +typedef int (*JackDriverConnectFunction)(struct _jack_driver *); +typedef int (*JackDriverDisconnectFunction)(struct _jack_driver *); + /* Call sequence summary: @@ -221,7 +224,9 @@ JackDriverNullCycleFunction null_cycle; \ JackDriverStopFunction stop; \ JackDriverStartFunction start; \ - JackDriverBufSizeFunction bufsize; + JackDriverBufSizeFunction bufsize; \ + JackDriverConnectFunction connect; \ + JackDriverDisconnectFunction disconnect; JACK_DRIVER_DECL /* expand the macro */ @@ -273,6 +278,8 @@ typedef int (*JackDriverNTBufSizeFunction)(struct _jack_driver_nt *, jack_nframes_t nframes); typedef int (*JackDriverNTRunCycleFunction)(struct _jack_driver_nt *); +typedef int (*JackDriverNTConnectFunction)(struct _jack_driver_nt *); +typedef int (*JackDriverNTDisconnectFunction)(struct _jack_driver_nt *); typedef struct _jack_driver_nt { @@ -287,7 +294,9 @@ JackDriverNTStopFunction nt_stop; \ JackDriverNTStartFunction nt_start; \ JackDriverNTBufSizeFunction nt_bufsize; \ - JackDriverNTRunCycleFunction nt_run_cycle; + JackDriverNTRunCycleFunction nt_run_cycle; \ + JackDriverNTConnectFunction nt_connect; \ + JackDriverNTDisconnectFunction nt_disconnect; #define nt_read read #define nt_write write #define nt_null_cycle null_cycle diff -Nur jack-audio-connection-kit-0.109.2/jack/engine.h jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/engine.h --- jack-audio-connection-kit-0.109.2/jack/engine.h 2008-01-30 19:23:50.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/engine.h 2008-03-01 13:40:27.000000000 +0100 @@ -109,6 +109,7 @@ unsigned long external_client_cnt; int rtpriority; char freewheeling; + char connected; char verbose; char do_munlock; const char *server_name; diff -Nur jack-audio-connection-kit-0.109.2/jack/internal.h jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/internal.h --- jack-audio-connection-kit-0.109.2/jack/internal.h 2008-01-30 19:23:50.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/internal.h 2008-03-01 13:40:27.000000000 +0100 @@ -172,7 +172,9 @@ StartFreewheel, StopFreewheel, ClientRegistered, - ClientUnregistered + ClientUnregistered, + Connected, + Disconnected } JackEventType; typedef struct { @@ -338,7 +340,9 @@ IntClientName = 21, IntClientUnload = 22, RecomputeTotalLatencies = 23, - RecomputeTotalLatency = 24 + RecomputeTotalLatency = 24, + Connect = 42, + Disconnect = 43 } RequestType; struct _jack_request { diff -Nur jack-audio-connection-kit-0.109.2/jack/jack.h jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/jack.h --- jack-audio-connection-kit-0.109.2/jack/jack.h 2008-01-30 19:23:50.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/jack/jack.h 2008-03-01 13:40:27.000000000 +0100 @@ -246,6 +246,8 @@ */ int jack_set_freewheel(jack_client_t* client, int onoff); +int jack_set_connected(jack_client_t* client, int connected); + /** * Change the buffer size passed to the @a process_callback. * diff -Nur jack-audio-connection-kit-0.109.2/jackd/engine.c jack-audio-connection-kit-0.109.2-alsa-disconnect/jackd/engine.c --- jack-audio-connection-kit-0.109.2/jackd/engine.c 2008-01-30 19:23:51.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/jackd/engine.c 2008-03-01 13:40:27.000000000 +0100 @@ -128,6 +128,8 @@ static void jack_check_acyclic (jack_engine_t* engine); static void jack_compute_all_port_total_latencies (jack_engine_t *engine); static void jack_compute_port_total_latency (jack_engine_t *engine, jack_port_shared_t*); +static int jack_device_connect (jack_engine_t *engine); +static int jack_device_disconnect (jack_engine_t *engine); static inline int @@ -911,7 +913,11 @@ while (1) { usleep (1000 * JACKD_WATCHDOG_TIMEOUT); - if (!engine->freewheeling && engine->watchdog_check == 0) { + if ( ! engine->connected ) { + // cheap trick to avoid a potential race condition when we reconnect + engine->watchdog_check = 1; + } + else if (!engine->freewheeling && engine->watchdog_check == 0) { jack_error ("jackd watchdog: timeout - killing jackd"); @@ -1270,6 +1276,14 @@ req->status = jack_stop_freewheeling (engine); break; + case Connect: + req->status = jack_device_connect (engine); + break; + + case Disconnect: + req->status = jack_device_disconnect (engine); + break; + case SetBufferSize: req->status = jack_set_buffer_size_request (engine, req->x.nframes); @@ -1630,6 +1644,8 @@ engine->clients = 0; + engine->connected = 0; + engine->pfd_size = 16; engine->pfd_max = 0; engine->pfd = (struct pollfd *) malloc (sizeof (struct pollfd) @@ -1956,6 +1972,71 @@ return 0; } +static int jack_device_connect (jack_engine_t *engine) +{ + jack_event_t event; + void *ftstatus; + + if (engine->connected) { + VERBOSE (engine, "connect when already connected\n"); + return 0; + } + + if (engine->driver == NULL) { + jack_error ("cannot connect without a driver!"); + return -1; + } + + if(engine->driver->connect (engine->driver)) + { + jack_error ("driver will not connect"); + return -1; + } + + if(engine->driver->start (engine->driver)) + { + jack_error ("driver will not start after disconnection"); + return -1; + } + + engine->connected = 1; + /* tell everyone we've connected */ + + event.type = Connected; + jack_deliver_event_to_all (engine, &event); + + return 0; +} + +static int jack_device_disconnect (jack_engine_t *engine) +{ + jack_event_t event; + + if(!engine->connected) + { + VERBOSE (engine, "disconnect when already disconnected\n"); + return 0; + } + + if (engine->driver == NULL) { + jack_error ("cannot disconnect without a driver!"); + return -1; + } + + if (engine->driver->stop (engine->driver)) { + jack_error ("could not stop driver for disconnection"); + return -1; + } + + engine->driver->disconnect (engine->driver); + engine->connected = 0; + + event.type = Disconnected; + jack_deliver_event_to_all (engine, &event); + + return 0; +} + static int jack_run_one_cycle (jack_engine_t *engine, jack_nframes_t nframes, float delayed_usecs) @@ -3398,6 +3479,7 @@ if (engine->driver) { engine->driver->detach (engine->driver, engine); engine->driver = 0; + engine->connected = 0; } engine->driver = driver; @@ -3409,7 +3491,7 @@ engine->rolling_interval = jack_rolling_interval (driver->period_usecs); } - + engine->connected = 1; return 0; } diff -Nur jack-audio-connection-kit-0.109.2/libjack/client.c jack-audio-connection-kit-0.109.2-alsa-disconnect/libjack/client.c --- jack-audio-connection-kit-0.109.2/libjack/client.c 2008-01-30 19:23:43.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/libjack/client.c 2008-03-01 13:40:27.000000000 +0100 @@ -1205,6 +1205,14 @@ return jack_client_deliver_request (client, &request); } +int +jack_set_connected(jack_client_t* client, int connected) +{ + jack_request_t request; + request.type = connected ? Connect : Disconnect; + return jack_client_deliver_request (client, &request); +} + void jack_start_freewheel (jack_client_t* client) { diff -Nur jack-audio-connection-kit-0.109.2/libjack/driver.c jack-audio-connection-kit-0.109.2-alsa-disconnect/libjack/driver.c --- jack-audio-connection-kit-0.109.2/libjack/driver.c 2008-01-30 19:23:43.000000000 +0100 +++ jack-audio-connection-kit-0.109.2-alsa-disconnect/libjack/driver.c 2008-03-01 13:40:27.000000000 +0100 @@ -46,6 +46,8 @@ jack_nframes_t nframes) {return 0;} static int dummy_stop (jack_driver_t *drv) { return 0; } static int dummy_start (jack_driver_t *drv) { return 0; } +static int dummy_connect (jack_driver_t *drv) { return 0; } +static int dummy_disconnect (jack_driver_t *drv) { return 0; } void jack_driver_init (jack_driver_t *driver) @@ -60,6 +62,8 @@ driver->bufsize = dummy_bufsize; driver->start = dummy_start; driver->stop = dummy_stop; + driver->connect = dummy_connect; + driver->disconnect = dummy_disconnect; } @@ -199,6 +203,34 @@ } static int +jack_driver_nt_connect (jack_driver_nt_t * driver) +{ + int err; + + err = driver->nt_connect (driver); + if (err) { + jack_error ("DRIVER NT: could not connect driver"); + return err; + } + + return 0; +} + +static int +jack_driver_nt_disconnect (jack_driver_nt_t * driver) +{ + int err; + + err = driver->nt_disconnect (driver); + if (err) { + jack_error ("DRIVER NT: could not disconnect driver"); + return err; + } + + return 0; +} + +static int jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes) { int err; @@ -235,10 +267,14 @@ driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize; driver->stop = (JackDriverStartFunction) jack_driver_nt_stop; driver->start = (JackDriverStopFunction) jack_driver_nt_start; + driver->connect = (JackDriverConnectFunction) jack_driver_nt_connect; + driver->disconnect = (JackDriverDisconnectFunction)jack_driver_nt_disconnect; driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize; driver->nt_start = (JackDriverNTStartFunction) dummy_start; driver->nt_stop = (JackDriverNTStopFunction) dummy_stop; + driver->nt_connect = (JackDriverNTConnectFunction) dummy_connect; + driver->nt_disconnect= (JackDriverNTDisconnectFunction)dummy_connect; driver->nt_attach = dummy_nt_attach; driver->nt_detach = dummy_nt_detach; driver->nt_run_cycle = dummy_nt_run_cycle;