JACK device disconnect patch

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

JACK device disconnect patch

Salvatore Di Pietro
Whoops! I accidentally sent an unnecessary humungous patch!
Here is the post with the correct size patch. Sorry!

Hi all,

Some years ago I noticed a post by Sean Meiners from Linspire about a
patch to let JACK release the audio device on command, derived from
jack_freewheel.
With this patch (that makes available a new client, jack_device_connect
y|n ) it is possible to temporarily free the audio device without the
need to close jackd and its client programs. It's very useful if no
dedicated JACK audio card is available, and the only one you have has no
hardware mixing (like most laptops and motherboard builtin stuff but not
only), and you have the need to watch i.e. youtube while in the middle
of a JACK session :). Just run

jack_device_connect n

All jack clients freeze, the audio from jackd stops, jackd releases the
audio device and you're free to do what you want with your audio card.
When you are done, just do

jack_device_connect y

All jack clients and jackd unfreeze, and you can continue your JACK
session as nothing happened.

I asked for the patches a while ago, which he sent me, for jack 0.99.0
and 0.100.0. I just adapted the latter to apply to current stable jack
0.103.0. Any hopes it will be merged to official jack?

It's in attachment, hope it helps!

Ciao and happy jacking
--
            salvuz
       POST FATA RESVRGO
   Linux registered user #291700 | machine #174619
   get counted on ---> http://counter.li.org/ <---


diff -Naur jack-audio-connection-kit-0.103.0/drivers/alsa/alsa_driver.c jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/drivers/alsa/alsa_driver.c
--- jack-audio-connection-kit-0.103.0/drivers/alsa/alsa_driver.c 2006-05-26 04:45:25.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/drivers/alsa/alsa_driver.c 2007-11-22 01:17:12.000000000 +0100
@@ -54,6 +54,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)
 {
@@ -131,6 +133,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));
@@ -965,6 +968,9 @@
  snd_pcm_uframes_t poffset, pavail;
  channel_t chn;
 
+ if(!driver->connected)
+ return 0;
+
  driver->poll_last = 0;
  driver->poll_next = 0;
 
@@ -1090,6 +1096,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++) {
@@ -1144,6 +1152,9 @@
  snd_pcm_status_t *status;
  int res;
 
+ if (!driver->connected)
+ return 0;
+
  snd_pcm_status_alloca(&status);
 
  if (driver->capture_handle) {
@@ -1185,6 +1196,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) {
@@ -1900,8 +1914,8 @@
 }
 #endif
 
-static void
-alsa_driver_delete (alsa_driver_t *driver)
+static int
+alsa_driver_disconnect (alsa_driver_t *driver)
 {
  JSList *node;
 
@@ -1918,7 +1932,7 @@
 
  if (driver->playback_handle) {
  snd_pcm_close (driver->playback_handle);
- driver->capture_handle = 0;
+ driver->playback_handle = 0;
  }
 
  if (driver->capture_hw_params) {
@@ -1941,16 +1955,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);
@@ -1979,8 +2011,6 @@
  jack_nframes_t playback_latency
  )
 {
- int err;
-
  alsa_driver_t *driver;
 
  printf ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32
@@ -2008,6 +2038,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;
@@ -2064,11 +2096,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) {
@@ -2077,17 +2145,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;
  }
 
@@ -2099,9 +2175,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) {
@@ -2110,17 +2186,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;
  }
 
@@ -2133,40 +2217,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;
  }
  }
 
@@ -2180,16 +2262,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;
  }
  }
 
@@ -2198,23 +2278,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;
@@ -2226,9 +2303,9 @@
  }
  }
 
- driver->client = client;
+ driver->connected = 1;
 
- return (jack_driver_t *) driver;
+ return 0;
 }
 
 int
diff -Naur jack-audio-connection-kit-0.103.0/drivers/alsa/alsa_driver.h jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/drivers/alsa/alsa_driver.h
--- jack-audio-connection-kit-0.103.0/drivers/alsa/alsa_driver.h 2006-05-26 04:45:25.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/drivers/alsa/alsa_driver.h 2007-11-22 01:17:12.000000000 +0100
@@ -135,6 +135,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 -Naur jack-audio-connection-kit-0.103.0/example-clients/Makefile.am jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/example-clients/Makefile.am
--- jack-audio-connection-kit-0.103.0/example-clients/Makefile.am 2006-05-26 04:45:08.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/example-clients/Makefile.am 2007-11-22 01:17:12.000000000 +0100
@@ -36,6 +36,7 @@
                jack_bufsize \
        jack_lsp \
        jack_freewheel \
+       jack_device_connect \
        $(JACKREC) \
        $(JACK_TRANSPORT) \
    jack_midisine \
@@ -85,6 +86,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 -Naur jack-audio-connection-kit-0.103.0/example-clients/Makefile.in jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/example-clients/Makefile.in
--- jack-audio-connection-kit-0.103.0/example-clients/Makefile.in 2007-03-18 23:32:58.000000000 +0100
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/example-clients/Makefile.in 2007-11-22 01:17:12.000000000 +0100
@@ -36,7 +36,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) $(am__EXEEXT_1) $(am__EXEEXT_2) \
@@ -88,6 +88,12 @@
 jack_connect_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
  $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
  $(jack_connect_LDFLAGS) $(LDFLAGS) -o $@
+am_jack_device_connect_OBJECTS = device_connect.$(OBJEXT)
+jack_device_connect_OBJECTS = $(am_jack_device_connect_OBJECTS)
+jack_device_connect_DEPENDENCIES = ../libjack/libjack.la
+jack_device_connect_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(jack_device_connect_LDFLAGS) $(LDFLAGS) -o $@
 am_jack_disconnect_OBJECTS = connect.$(OBJEXT)
 jack_disconnect_OBJECTS = $(am_jack_disconnect_OBJECTS)
 jack_disconnect_DEPENDENCIES = ../libjack/libjack.la
@@ -154,7 +160,6 @@
 jack_simple_client_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
  $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
  $(jack_simple_client_LDFLAGS) $(LDFLAGS) -o $@
-am__jack_transport_SOURCES_DIST = transport.c
 @HAVE_READLINE_TRUE@am_jack_transport_OBJECTS = transport.$(OBJEXT)
 jack_transport_OBJECTS = $(am_jack_transport_OBJECTS)
 @HAVE_READLINE_TRUE@jack_transport_DEPENDENCIES =  \
@@ -188,7 +193,7 @@
  --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
  $(LDFLAGS) -o $@
 SOURCES = $(inprocess_la_SOURCES) $(intime_la_SOURCES) \
- $(jack_bufsize_SOURCES) $(jack_connect_SOURCES) \
+ $(jack_bufsize_SOURCES) $(jack_connect_SOURCES) $(jack_device_connect_SOURCES) \
  $(jack_disconnect_SOURCES) $(jack_freewheel_SOURCES) \
  $(jack_impulse_grabber_SOURCES) $(jack_load_SOURCES) \
  $(jack_lsp_SOURCES) $(jack_metro_SOURCES) \
@@ -197,7 +202,7 @@
  $(jack_simple_client_SOURCES) $(jack_transport_SOURCES) \
  $(jack_unload_SOURCES) $(jackrec_SOURCES)
 DIST_SOURCES = $(inprocess_la_SOURCES) $(intime_la_SOURCES) \
- $(jack_bufsize_SOURCES) $(jack_connect_SOURCES) \
+ $(jack_bufsize_SOURCES) $(jack_connect_SOURCES) $(jack_device_connect_SOURCES) \
  $(jack_disconnect_SOURCES) $(jack_freewheel_SOURCES) \
  $(jack_impulse_grabber_SOURCES) $(jack_load_SOURCES) \
  $(jack_lsp_SOURCES) $(jack_metro_SOURCES) \
@@ -361,6 +366,9 @@
 jack_connect_SOURCES = connect.c
 jack_connect_LDFLAGS = @OS_LDFLAGS@
 jack_connect_LDADD = ../libjack/libjack.la
+jack_device_connect_SOURCES = device_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
@@ -515,6 +523,9 @@
 jack_connect$(EXEEXT): $(jack_connect_OBJECTS) $(jack_connect_DEPENDENCIES)
  @rm -f jack_connect$(EXEEXT)
  $(jack_connect_LINK) $(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)
+ $(jack_device_connect_LINK) $(jack_device_connect_OBJECTS) $(jack_device_connect_LDADD) $(LIBS)
 jack_disconnect$(EXEEXT): $(jack_disconnect_OBJECTS) $(jack_disconnect_DEPENDENCIES)
  @rm -f jack_disconnect$(EXEEXT)
  $(jack_disconnect_LINK) $(jack_disconnect_OBJECTS) $(jack_disconnect_LDADD) $(LIBS)
@@ -567,6 +578,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bufsize.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/capture_client.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device_connect.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freewheel.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impulse_grabber.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inprocess.Plo@am__quote@
@@ -684,7 +696,7 @@
   fi; \
  done
  $(MAKE) $(AM_MAKEFLAGS) \
-  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+  top_distdir="${top_distdir}" distdir="$(distdir)" \
   dist-hook
 check-am: all-am
 check: check-am
@@ -712,7 +724,7 @@
 clean-generic:
 
 distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f Makefile $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
  @echo "This command is intended for maintainers to use"
@@ -758,8 +770,7 @@
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
+
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
diff -Naur jack-audio-connection-kit-0.103.0/example-clients/device_connect.c jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/example-clients/device_connect.c
--- jack-audio-connection-kit-0.103.0/example-clients/device_connect.c 1970-01-01 01:00:00.000000000 +0100
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/example-clients/device_connect.c 2007-11-22 01:17:12.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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <jack/jack.h>
+#include <jack/transport.h>
+
+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 -Naur jack-audio-connection-kit-0.103.0/jack/driver.h jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/driver.h
--- jack-audio-connection-kit-0.103.0/jack/driver.h 2006-05-26 04:45:22.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/driver.h 2007-11-22 01:17:12.000000000 +0100
@@ -61,6 +61,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:
 
@@ -222,7 +225,9 @@
     JackDriverNullCycleFunction null_cycle; \
     JackDriverStopFunction stop; \
     JackDriverStartFunction start; \
-    JackDriverBufSizeFunction bufsize;
+    JackDriverBufSizeFunction bufsize; \
+    JackDriverConnectFunction connect; \
+    JackDriverDisconnectFunction disconnect;
 
     JACK_DRIVER_DECL /* expand the macro */
 
@@ -274,6 +279,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 {
 
@@ -288,7 +295,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 -Naur jack-audio-connection-kit-0.103.0/jack/engine.h jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/engine.h
--- jack-audio-connection-kit-0.103.0/jack/engine.h 2006-06-22 06:39:02.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/engine.h 2007-11-22 01:17:12.000000000 +0100
@@ -110,6 +110,7 @@
     unsigned long   external_client_cnt;
     int    rtpriority;
     char    freewheeling;
+    char            connected;
     char    verbose;
     char    do_munlock;
     const char   *server_name;
diff -Naur jack-audio-connection-kit-0.103.0/jack/internal.h jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/internal.h
--- jack-audio-connection-kit-0.103.0/jack/internal.h 2006-05-26 04:45:22.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/internal.h 2007-11-22 01:17:12.000000000 +0100
@@ -171,7 +171,9 @@
   PortUnregistered,
   XRun,
   StartFreewheel,
-  StopFreewheel
+  StopFreewheel,
+  Connected,
+  Disconnected
 } JackEventType;
 
 typedef struct {
@@ -330,7 +332,9 @@
  IntClientLoad = 20,
  IntClientName = 21,
  IntClientUnload = 22,
- RecomputeTotalLatencies = 23
+ RecomputeTotalLatencies = 23,
+ Connect = 42,
+ Disconnect = 43
 } RequestType;
 
 struct _jack_request {
diff -Naur jack-audio-connection-kit-0.103.0/jack/jack.h jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/jack.h
--- jack-audio-connection-kit-0.103.0/jack/jack.h 2006-05-26 04:45:22.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/jack.h 2007-11-22 01:17:12.000000000 +0100
@@ -251,6 +251,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 -Naur jack-audio-connection-kit-0.103.0/jack/version.h jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/version.h
--- jack-audio-connection-kit-0.103.0/jack/version.h 2007-03-18 23:33:34.000000000 +0100
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jack/version.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,20 +0,0 @@
-/*
-    Copyright (C) 2003 Paul Davis
-
-    jack/version.h.  Generated from version.h.in by configure.
-    
-    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.
-*/
-#define jack_protocol_version 16
diff -Naur jack-audio-connection-kit-0.103.0/jackd/engine.c jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jackd/engine.c
--- jack-audio-connection-kit-0.103.0/jackd/engine.c 2007-03-06 06:24:05.000000000 +0100
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/jackd/engine.c 2007-11-22 01:17:12.000000000 +0100
@@ -124,6 +124,8 @@
      jack_client_internal_t *b);
 static void jack_check_acyclic (jack_engine_t* engine);
 static void jack_compute_all_port_total_latencies (jack_engine_t *engine);
+static int  jack_device_connect (jack_engine_t *engine);
+static int  jack_device_disconnect (jack_engine_t *engine);
 
 
 static inline int
@@ -898,7 +900,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");
 
@@ -1257,6 +1263,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);
@@ -1604,6 +1618,8 @@
 
  engine->clients = 0;
 
+ engine->connected = 0;
+
  engine->pfd_size = 16;
  engine->pfd_max = 0;
  engine->pfd = (struct pollfd *) malloc (sizeof (struct pollfd)
@@ -1928,6 +1944,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)
@@ -3327,6 +3408,7 @@
  if (engine->driver) {
  engine->driver->detach (engine->driver, engine);
  engine->driver = 0;
+ engine->connected = 0;
  }
 
  if (driver) {
@@ -3338,6 +3420,7 @@
  }
 
  engine->driver = driver;
+ engine->connected = 1;
  return 0;
 }
 
diff -Naur jack-audio-connection-kit-0.103.0/libjack/client.c jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/libjack/client.c
--- jack-audio-connection-kit-0.103.0/libjack/client.c 2007-03-06 06:24:05.000000000 +0100
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/libjack/client.c 2007-11-22 01:17:12.000000000 +0100
@@ -1225,6 +1225,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 -Naur jack-audio-connection-kit-0.103.0/libjack/driver.c jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/libjack/driver.c
--- jack-audio-connection-kit-0.103.0/libjack/driver.c 2006-05-26 04:45:11.000000000 +0200
+++ jack-audio-connection-kit-0.103.0_alsa_disconnect_patch/libjack/driver.c 2007-11-22 01:17:12.000000000 +0100
@@ -47,6 +47,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)
@@ -61,6 +63,8 @@
  driver->bufsize = dummy_bufsize;
  driver->start = dummy_start;
  driver->stop = dummy_stop;
+ driver->connect = dummy_connect;
+ driver->disconnect = dummy_disconnect;
 }
 
 
@@ -200,6 +204,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;
@@ -236,10 +268,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;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Jackit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jackit-devel
Reply | Threaded
Open this post in threaded view
|

Re: JACK device disconnect patch

Kjetil Matheussen

Pieter Palmers:

>> Why? Wouldn't be more convenient to stop the audio stream and the transport?
>
> An RT watchdog is usually implemented as a high-priority RT thread that
> checks whether a lower priority RT thread updates a variable in time. e.g.:
>
> high prio thread:
> while(1) {
> keepalive = false;
> sleep(WATCHDOG_TIMEOUT);
> if (!keepalive) {
> error("watchdog timeout!");
> }
> }
>
> the monitored thread:
> while(1) {
> doWork();
> keepalive = true;
> }
>
> This makes that if doWork() is not finished within WATCHDOG_TIMEOUT
> (when the sleep call returns), the watchdog variable is still false and
> the watchdog thread kicks in and kills the thread.
>
> If the watchdog variable update is done in e.g. the jackd process call
> and your patch 'freezes' by stopping the call to process(), it will
> trigger the watchdog of applications.
>
> das_watchdog works along the same principle, but only kicks in if a
> process actually hogs the CPU. However, applications relying on the
> process() call to provide the keepalive feedback can have their watchdog
> kick in without hogging the cpu.
>

Yepp. I just want to add that das_watchdog doesn't kill
any threads. Instead it just temporarily sets all realtime
threads to run non-realtime for a few seconds so that the user
gets a chance to manually stop runaway programs, if necesarry.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Jackit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jackit-devel