diff -uNrw sweep-0.9.1.orig/config.h.in sweep-0.9.1.jack/config.h.in
--- sweep-0.9.1.orig/config.h.in	2006-01-28 17:18:23.000000000 -0500
+++ sweep-0.9.1.jack/config.h.in	2007-01-05 14:16:19.000000000 -0500
@@ -20,6 +20,9 @@
 /* Define if we have and want the solaris audio driver. */
 #undef DRIVER_SOLARIS_AUDIO
 
+/* Define if we have and want the Jack driver. */
+#undef DRIVER_JACK
+
 /* Define to 1 if translation of program messages to the user's native
    language is requested. */
 #undef ENABLE_NLS
diff -uNrw sweep-0.9.1.orig/configure sweep-0.9.1.jack/configure
--- sweep-0.9.1.orig/configure	2006-01-28 17:04:47.000000000 -0500
+++ sweep-0.9.1.jack/configure	2007-01-05 15:23:03.000000000 -0500
@@ -463,7 +463,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL HAVE_GNOME_MOZ_REMOTE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE GLIBC2 ALLOCA GLIBC21 INTL_MACOSX_LIBS HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB PTHREAD_LIBS PKG_CONFIG ac_pt_PKG_CONFIG GTK_CFLAGS GTK_LIBS GLIB_CFLAGS GLIB_LIBS GTHREADS_CFLAGS GTHREADS_LIBS SNDFILE_LIBS SNDFILE_CFLAGS OGG_CFLAGS OGG_LIBS VORBIS_CFLAGS VORBIS_LIBS VORBISFILE_LIBS VORBISENC_LIBS SPEEX_CFLAGS SPEEX_LIBS MAD_LIBS SAMPLERATE_CFLAGS SAMPLERATE_LIBS ALSA_CFLAGS ALSA_LIBS PACKAGE_PLUGIN_DIR EXPORT_DYNAMIC_FLAGS LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL HAVE_GNOME_MOZ_REMOTE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE GLIBC2 ALLOCA GLIBC21 INTL_MACOSX_LIBS HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB PTHREAD_LIBS PKG_CONFIG ac_pt_PKG_CONFIG GTK_CFLAGS GTK_LIBS GLIB_CFLAGS GLIB_LIBS GTHREADS_CFLAGS GTHREADS_LIBS SNDFILE_LIBS SNDFILE_CFLAGS OGG_CFLAGS OGG_LIBS VORBIS_CFLAGS VORBIS_LIBS VORBISFILE_LIBS VORBISENC_LIBS SPEEX_CFLAGS SPEEX_LIBS MAD_LIBS SAMPLERATE_CFLAGS SAMPLERATE_LIBS ALSA_CFLAGS ALSA_LIBS JACK_CFLAGS JACK_LIBS PACKAGE_PLUGIN_DIR EXPORT_DYNAMIC_FLAGS LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -32392,6 +32392,48 @@
 fi
 
 
+HAVE_JACK=no
+
+pkg_failed=no
+echo "$as_me:$LINENO: checking for jack >= 0.34.0" >&5
+echo $ECHO_N "checking for jack >= 0.34.0... $ECHO_C" >&6
+
+if test -n "$PKG_CONFIG"; then
+  if $PKG_CONFIG --exists "jack >= 0.34.0" ; then
+    echo "$as_me:$LINENO: result: yes" >&5
+    echo "${ECHO_T}yes" >&6
+    HAVE_JACK=yes
+    echo "$as_me:$LINENO: checking JACK_CFLAGS" >&5
+    echo $ECHO_N "checking JACK_CFLAGS... $ECHO_C" >&6
+    JACK_CFLAGS=`$PKG_CONFIG --cflags "jack >= 0.34.0"`
+    echo "${ECHO_T}$JACK_CFLAGS" >&6
+    echo "$as_me:$LINENO: checking JACK_LIBS" >&5
+    echo $ECHO_N "checking JACK_LIBS... $ECHO_C" 1>&6
+    JACK_LIBS=`$PKG_CONFIG --libs "jack >= 0.34.0"`
+    echo "${ECHO_T}$JACK_LIBS" >&6
+  else
+    JACK_CFLAGS=""
+    JACK_LIBS=""
+  ## If we have a custom action on failure, don't print errors, but
+  ## do set a variable so people can do so.
+    JACK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "jack >= 0.34.0"`
+    echo "$JACK_PKG_ERRORS" 1>&5
+    pkg_failed=yes
+  fi
+else
+  pkg_failed=untried
+fi
+
+if test $HAVE_JACK = yes; then
+  sweep_config_driver="JACK"
+  cat >> confdefs.h <<\_ACEOF
+#define DRIVER_JACK 1
+_ACEOF
+else
+  echo "${ECHO_T}jack not found" >&6
+fi
+
+
 HAVE_LIBSAMPLERATE=no
 
 ac_enable_src=yes
@@ -32468,7 +32510,6 @@
 
 
 
-
 ac_enable_alsa=no
 # Check whether --enable-alsa or --disable-alsa was given.
 if test "${enable_alsa+set}" = set; then
@@ -34198,6 +34239,8 @@
 s,@SAMPLERATE_LIBS@,$SAMPLERATE_LIBS,;t t
 s,@ALSA_CFLAGS@,$ALSA_CFLAGS,;t t
 s,@ALSA_LIBS@,$ALSA_LIBS,;t t
+s,@JACK_CFLAGS@,$JACK_CFLAGS,;t t
+s,@JACK_LIBS@,$JACK_LIBS,;t t
 s,@PACKAGE_PLUGIN_DIR@,$PACKAGE_PLUGIN_DIR,;t t
 s,@EXPORT_DYNAMIC_FLAGS@,$EXPORT_DYNAMIC_FLAGS,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
diff -uNrw sweep-0.9.1.orig/src/Makefile.am sweep-0.9.1.jack/src/Makefile.am
--- sweep-0.9.1.orig/src/Makefile.am	2006-01-24 13:04:33.000000000 -0500
+++ sweep-0.9.1.jack/src/Makefile.am	2007-01-05 14:16:19.000000000 -0500
@@ -29,6 +29,7 @@
 	db_slider.c db_slider.h \
 	driver.c driver.h \
 	driver_alsa.c \
+	driver_jack.c \
 	driver_oss.c \
 	driver_solaris.c \
 	edit.c edit.h \
@@ -76,6 +77,7 @@
 	$(MAD_LIBS) $(SPEEX_LIBS) \
 	$(SAMPLERATE_LIBS) \
 	@GLIB_LIBS@ @GTHREADS_LIBS@ \
-	@ALSA_LIBS@
+	@ALSA_LIBS@ \
+	@JACK_LIBS@
 
 sweep_LDFLAGS = @EXPORT_DYNAMIC_FLAGS@
diff -uNrw sweep-0.9.1.orig/src/Makefile.in sweep-0.9.1.jack/src/Makefile.in
--- sweep-0.9.1.orig/src/Makefile.in	2006-01-28 17:04:54.000000000 -0500
+++ sweep-0.9.1.jack/src/Makefile.in	2007-01-05 14:20:39.000000000 -0500
@@ -68,7 +68,7 @@
 am_sweep_OBJECTS = main.$(OBJEXT) about_dialog.$(OBJEXT) \
 	callbacks.$(OBJEXT) channelops.$(OBJEXT) cursors.$(OBJEXT) \
 	db_ruler.$(OBJEXT) db_slider.$(OBJEXT) driver.$(OBJEXT) \
-	driver_alsa.$(OBJEXT) driver_oss.$(OBJEXT) \
+	driver_alsa.$(OBJEXT) driver_jack.$(OBJEXT) driver_oss.$(OBJEXT) \
 	driver_solaris.$(OBJEXT) edit.$(OBJEXT) file_dialogs.$(OBJEXT) \
 	file_sndfile0.$(OBJEXT) file_sndfile1.$(OBJEXT) \
 	file_mad.$(OBJEXT) file_speex.$(OBJEXT) file_vorbis.$(OBJEXT) \
@@ -293,6 +293,7 @@
 	driver.c driver.h \
 	driver_alsa.c \
 	driver_oss.c \
+	driver_jack.c \
 	driver_solaris.c \
 	edit.c edit.h \
 	file_dialogs.c file_dialogs.h \
@@ -339,7 +340,7 @@
 	$(MAD_LIBS) $(SPEEX_LIBS) \
 	$(SAMPLERATE_LIBS) \
 	@GLIB_LIBS@ @GTHREADS_LIBS@ \
-	@ALSA_LIBS@
+	@ALSA_LIBS@ @JACK_LIBS@
 
 sweep_LDFLAGS = @EXPORT_DYNAMIC_FLAGS@
 all: all-recursive
diff -uNrw sweep-0.9.1.orig/src/driver.c sweep-0.9.1.jack/src/driver.c
--- sweep-0.9.1.orig/src/driver.c	2005-10-02 12:58:42.000000000 -0400
+++ sweep-0.9.1.jack/src/driver.c	2007-01-05 14:16:19.000000000 -0500
@@ -45,6 +45,7 @@
 extern sw_driver * driver_alsa;
 extern sw_driver * driver_oss;
 extern sw_driver * driver_solaris;
+extern sw_driver * driver_jack;
 
 extern GMutex * play_mutex;
 
@@ -749,6 +750,8 @@
   pref = driver_alsa;
 #elif defined(DRIVER_OSS)
   pref = driver_oss;
+#elif defined(DRIVER_JACK)
+  pref = driver_jack;
 #elif defined(DRIVER_SOLARIS_AUDIO)
   pref = driver_solaris;
 #endif
diff -uNrw sweep-0.9.1.orig/src/driver_jack.c sweep-0.9.1.jack/src/driver_jack.c
--- sweep-0.9.1.orig/src/driver_jack.c	1969-12-31 19:00:00.000000000 -0500
+++ sweep-0.9.1.jack/src/driver_jack.c	2007-01-08 12:49:58.000000000 -0500
@@ -0,0 +1,237 @@
+/*
+* Sweep, a sound wave editor.
+*
+* Copyright(C) 2000 Conrad Parker
+*
+* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+* ALSA 0.6 support by Paul Davis
+* ALSA 0.9 updates by Zenaan Harkness
+*/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+#include <sys/ioctl.h>
+#include <pthread.h>
+
+#include <sweep/sweep_types.h>
+#include <sweep/sweep_sample.h>
+
+#include "driver.h"
+#include "pcmio.h"
+#include "question_dialogs.h"
+
+#ifdef DRIVER_JACK
+
+#include <jack/jack.h>
+
+
+jack_client_t *jack_client = NULL;
+
+
+typedef struct sw_jack_handle {
+    jack_port_t *port_l, *port_r;
+} sw_jack_handle_t;
+
+static GList * jack_get_names(void)
+{
+    GList * names = NULL;
+
+    names = g_list_append(names, "jack_playback");
+
+    return names;
+}
+
+static sw_handle *jack_device_open(int monitoring, int flags)
+{
+    char * jack_out_pcm_name;
+    sw_handle * handle;
+    sw_jack_handle_t * jack_data;
+    unsigned long stream;
+    
+    /*printf ("sweep: jack_device_open\n");*/
+    if (monitoring) {
+        return NULL;
+    } else {
+        jack_out_pcm_name = pcmio_get_main_dev();
+    }
+
+    if (flags == O_RDONLY) {
+        stream = JackPortIsInput;
+    } else if (flags == O_WRONLY) {
+        stream = JackPortIsOutput;
+    } else {
+        return NULL;
+    }
+
+    if ( jack_client == NULL )
+        jack_client = jack_client_new( "sweep" );
+
+
+    if (jack_client == NULL) {
+        //popup_msgbox("Error", MSGBOX_OK, 120000, MSGBOX_OK,
+        //		 "Could not open Jack Client");
+        return NULL;
+    }
+        
+    jack_data = g_malloc0(sizeof(sw_jack_handle_t));
+    jack_data->port_l = jack_port_register(jack_client,
+        (stream == JackPortIsOutput) ? "out_left" : "input_left",
+        JACK_DEFAULT_AUDIO_TYPE, stream, 0);
+    jack_data->port_r = jack_port_register(jack_client,
+        (stream == JackPortIsOutput) ? "out_right" : "input_right",
+        JACK_DEFAULT_AUDIO_TYPE, stream, 0);
+        
+    // FIXME: check the ports....
+
+    handle = g_malloc0(sizeof(sw_handle));
+        
+    handle->driver_flags = flags;
+    handle->custom_data = jack_data;
+    return handle;
+}
+
+// /src/alsa/alsaplayer-0.99.72/output/alsa-final/alsa.c
+// /src/alsa/alsa-lib-0.9.0rc3/test/pcm.c
+static void jack_device_setup(sw_handle * handle, sw_format * format)
+{
+    //int err;
+    //sw_jack_handle_t * jack_handle =(sw_jack_handle_t *)handle->custom_data;
+    unsigned int rate = 44100;
+    unsigned int channels = 2;
+    
+    /*printf("sweep: jack_device_setup\n");*/
+    
+#if 0
+    if (handle->driver_flags == O_RDONLY) {
+        dir =(int)SND_PCM_STREAM_CAPTURE;
+    } else if (handle->driver_flags == O_WRONLY) {
+        dir =(int)SND_PCM_STREAM_PLAYBACK;
+    } else {
+        return;
+    }
+#else
+    //dir = 0;
+#endif
+    
+    handle->driver_rate = rate;
+    handle->driver_channels = channels;
+}
+
+static int jack_device_wait(sw_handle * handle)
+{
+    /*printf("sweep: jack_device_wait\n");*/
+}
+
+#define PLAYBACK_SCALE (32768 / SW_AUDIO_T_MAX)
+
+static ssize_t jack_device_read(sw_handle * handle, sw_audio_t * buf,
+    size_t count)
+{
+    sw_jack_handle_t * pcm_handle =(sw_jack_handle_t *)handle->custom_data;
+    int i;
+    gfloat *lport, *rport;
+    
+    /*printf("sweep: jack_device_read\n");*/
+    lport = jack_port_get_buffer( pcm_handle->port_l, count/handle->driver_channels );
+    rport = jack_port_get_buffer( pcm_handle->port_r, count/handle->driver_channels  );
+    for (i = 0; i < count/handle->driver_channels; i++ ) {
+        *(buf++) = lport[i];
+        *(buf++) = rport[i];
+    }
+    
+    return 0;
+}
+
+static ssize_t jack_device_write(sw_handle * handle, sw_audio_t * buf,
+    size_t count, sw_framecount_t offset)
+{
+    sw_jack_handle_t * pcm_handle =(sw_jack_handle_t *)handle->custom_data;
+    int i;
+    gfloat *lport, *rport;
+    
+    /*printf("sweep: jack_device_write\n"); //Generates a lot of messages.*/
+    lport = jack_port_get_buffer( pcm_handle->port_l, count/handle->driver_channels  );
+    rport = jack_port_get_buffer( pcm_handle->port_r, count/handle->driver_channels  );
+    for (i = 0; i < count/handle->driver_channels; i++ ) {
+        lport[i] = *(buf++);
+        rport[i] = *(buf++);
+    }
+    
+    return 0;
+}
+
+sw_framecount_t jack_device_offset(sw_handle * handle)
+{
+    /*printf("sweep: jack_device_offset\n"); //Generates a lot of messages.*/
+    return -1;
+}
+
+static void jack_device_reset(sw_handle * handle)
+{
+    /*printf("sweep: jack_device_reset\n");*/
+}
+
+static void jack_device_flush(sw_handle * handle)
+{
+    /*printf("sweep: jack_device_flush\n");*/
+}
+
+static void jack_device_drain(sw_handle * handle)
+{
+    /*printf("sweep: jack_device_drain\n");*/
+}
+
+static void jack_device_close(sw_handle * handle)
+{
+    /*printf("sweep: jack_device_close\n");*/
+}
+
+static sw_driver _driver_jack = {
+    jack_get_names,
+    jack_device_open,
+    jack_device_setup,
+    jack_device_wait,
+    jack_device_read,
+    jack_device_write,
+    jack_device_offset,
+    jack_device_reset,
+    jack_device_flush,
+    jack_device_drain,
+    jack_device_close
+};
+
+#else
+
+static sw_driver _driver_jack = {
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+#endif
+
+sw_driver * driver_jack = &_driver_jack;
diff -uNrw sweep-0.9.1.orig/src/play.c sweep-0.9.1.jack/src/play.c
--- sweep-0.9.1.orig/src/play.c	2006-01-17 23:06:33.000000000 -0500
+++ sweep-0.9.1.jack/src/play.c	2007-01-05 14:23:41.000000000 -0500
@@ -55,6 +55,7 @@
 #include "driver.h"
 #include "preferences.h"
 #include "sample-display.h"
+#include "jack/jack.h"
 
 /*#define DEBUG*/
 
@@ -64,6 +65,8 @@
 
 GMutex * play_mutex = NULL;
 
+extern jack_client_t * jack_client;
+
 static sw_handle * main_handle = NULL;
 static sw_handle * monitor_handle = NULL;
 
@@ -658,6 +661,7 @@
 #endif
 
 #define PSIZ 64
+#define MAX_PSIZ 8192
 
 static void
 prepare_to_play_heads (GList * heads, sw_handle * handle)
@@ -673,7 +677,7 @@
     f = head->sample->sounddata->format;
     
     if (f->channels > pbuf_chans) {
-      pbuf = g_realloc (pbuf, PSIZ * f->channels * sizeof (sw_audio_t));
+      pbuf = g_realloc (pbuf, MAX_PSIZ * f->channels * sizeof (sw_audio_t));
       pbuf_chans = f->channels;
     }
   }
@@ -688,26 +692,25 @@
     if (select (handle->driver_fd+1, &fds, NULL, NULL, &tv_instant) == 0);
   }
 #else
+#ifndef DRIVER_JACK
   device_wait (handle);
 #endif
+#endif
 
   return;
 }
 
 static void
-play_heads (GList ** heads, sw_handle * handle)
+play_heads (GList ** heads, sw_handle * handle, sw_framecount_t n)
 {
   sw_sample * s;
   sw_head * head;
   sw_format * f;
-  sw_framecount_t n;
 
   GList * gl, * gl_next;
 
   if (*heads == NULL) return;
 
-  n = PSIZ;
-  
   for (gl = *heads; gl; gl = gl_next) {
 
     g_mutex_lock (play_mutex);
@@ -881,18 +884,18 @@
     if (use_monitor) {
       count = PSIZ * monitor_handle->driver_channels;
       memset (devbuf, 0, count * sizeof (sw_audio_t));
-      play_heads (&active_monitor_heads, monitor_handle);
+      play_heads (&active_monitor_heads, monitor_handle, PSIZ);
       device_write (monitor_handle, devbuf, count, -1 /* offset reference */);  
       
       count = PSIZ * main_handle->driver_channels;
       memset (devbuf, 0, count * sizeof (sw_audio_t));
-      play_heads (&active_main_heads, main_handle);
+      play_heads (&active_main_heads, main_handle, PSIZ);
       device_write (main_handle, devbuf, count, -1 /* offset reference */);
     } else {
       count = PSIZ * main_handle->driver_channels;
       memset (devbuf, 0, count * sizeof (sw_audio_t));
-      play_heads (&active_monitor_heads, main_handle);
-      play_heads (&active_main_heads, main_handle);
+      play_heads (&active_monitor_heads, main_handle, PSIZ);
+      play_heads (&active_main_heads, main_handle, PSIZ);
       device_write (main_handle, devbuf, count, -1 /* offset reference */);  
     }
 
@@ -928,6 +931,165 @@
   player_thread = (pthread_t) -1;
 }
 
+#ifdef DRIVER_JACK
+
+typedef struct jack_process_data {
+  sw_framecount_t count;
+  int inactive_writes;
+  GList * gl;
+  sw_head * head;
+  sw_format * f;
+  int max_driver_chans;
+
+  gboolean use_monitor;
+
+#ifdef RECORD_DEMO_FILES
+  gchar * filename;
+  SNDFILE * sndfile;
+  SF_INFO sfinfo;
+#endif
+
+} jack_process_data_t;
+
+static int process_callback( jack_nframes_t nframes, void *data ) {
+    struct jack_process_data *jack_data = data;
+
+    if (active_main_heads == NULL && active_monitor_heads == NULL) {
+      //jack_data->inactive_writes++;
+    } else {
+      jack_data->inactive_writes = 0;
+    }
+
+    g_mutex_lock (play_mutex);
+    if (jack_data->use_monitor) {
+      prepare_to_play_heads (active_monitor_heads, monitor_handle);
+      prepare_to_play_heads (active_main_heads, main_handle);
+    } else {
+      prepare_to_play_heads (active_monitor_heads, main_handle);
+      prepare_to_play_heads (active_main_heads, main_handle);
+    }
+    g_mutex_unlock (play_mutex);
+
+    if (jack_data->use_monitor) {
+      jack_data->count = nframes * monitor_handle->driver_channels;
+      memset (devbuf, 0, jack_data->count * sizeof (sw_audio_t));
+      play_heads (&active_monitor_heads, monitor_handle, nframes);
+      device_write (monitor_handle, devbuf, jack_data->count, -1 /* offset reference */);
+
+      jack_data->count = nframes * main_handle->driver_channels;
+      memset (devbuf, 0, jack_data->count * sizeof (sw_audio_t));
+      play_heads (&active_main_heads, main_handle, nframes);
+      device_write (main_handle, devbuf, jack_data->count, -1 /* offset reference */);
+    } else {
+      jack_data->count = nframes * main_handle->driver_channels;
+      memset (devbuf, 0, jack_data->count * sizeof (sw_audio_t));
+      play_heads (&active_monitor_heads, main_handle, nframes);
+      play_heads (&active_main_heads, main_handle, nframes);
+      device_write (main_handle, devbuf, jack_data->count, -1 /* offset reference */);
+    }
+
+#ifdef RECORD_DEMO_FILES
+    if (sndfile)
+      sf_writef_float (jack_data->sndfile, devbuf, jack_data->count / main_handle->driver_channels);
+#endif
+
+#if 0
+  if (!head->looping) {
+    device_drain (handle);
+
+    HEAD_SET_GOING (head, FALSE);
+  }
+#endif
+
+  return 0;
+}
+
+static void init_play_thread() {
+    jack_process_data_t *data = g_malloc0( sizeof( jack_process_data_t ) );
+
+  if (!active_main_heads && !active_monitor_heads) return;
+
+  data->use_monitor = (monitor_handle != NULL);
+
+  if (data->use_monitor) {
+    if ((data->gl = active_monitor_heads)) {
+      data->head = (sw_head *)data->gl->data;
+      data->f = data->head->sample->sounddata->format;
+
+      device_setup (monitor_handle, data->f);
+    } else if ((data->gl = active_main_heads)) {
+      data->head = (sw_head *)data->gl->data;
+      data->f = data->head->sample->sounddata->format;
+
+      device_setup (monitor_handle, data->f);
+    }
+  }
+
+  if ((data->gl = active_main_heads)) {
+    data->head = (sw_head *)data->gl->data;
+    data->f = data->head->sample->sounddata->format;
+
+    device_setup (main_handle, data->f);
+
+#ifdef RECORD_DEMO_FILES
+    data->filename = generate_demo_filename ();
+    data->sfinfo.samplerate = data->f->rate;
+    data->sfinfo.channels = handle->driver_channels;
+    data->sfinfo.format = SF_FORMAT_AU | SF_FORMAT_FLOAT | SF_ENDIAN_CPU;
+    data->sndfile = sf_open (fdata->ilename, SFM_WRITE, &sfinfo);
+    if (data->sndfile == NULL) sf_perror (NULL);
+    else printf ("Writing to %s\n", data->filename);
+#endif
+  } else if ((data->gl = active_monitor_heads)) {
+    data->head = (sw_head *)data->gl->data;
+    data->f = data->head->sample->sounddata->format;
+
+    device_setup (main_handle, data->f);
+  } else {
+    return;
+  }
+
+  if (data->use_monitor) {
+    data->max_driver_chans = MAX (main_handle->driver_channels,
+			    monitor_handle->driver_channels);
+  } else {
+    data->max_driver_chans = main_handle->driver_channels;
+  }
+
+  if (data->max_driver_chans > devbuf_chans) {
+    devbuf = g_realloc (devbuf,
+			MAX_PSIZ * data->max_driver_chans * sizeof (sw_audio_t));
+    devbuf_chans = data->max_driver_chans;
+  }
+
+      jack_set_process_callback( jack_client, process_callback, data );
+
+      jack_activate( jack_client );
+}
+
+static gboolean
+ensure_playing (void)
+{
+  sw_handle * h;
+  if (player_thread == -1) {
+    if ((h = device_open (0, O_WRONLY)) != NULL) {
+      main_handle = h;
+      if (monitor_active()) {
+	monitor_handle = device_open (1, O_WRONLY);
+      } else {
+	monitor_handle = NULL;
+      }
+
+      init_play_thread();
+      player_thread = 0;
+      return TRUE;
+    } else {
+      return FALSE;
+    }
+  }
+}
+
+#else
 static gboolean
 ensure_playing (void)
 {
@@ -952,6 +1114,7 @@
 
   return TRUE;
 }
+#endif
 
 void
 sample_play (sw_sample * sample)
