diff --git a/Makefile b/Makefile
index ca6979a..e7dc0d1 100644
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,14 @@ CFLAGS=	-O $(DEFINES)
 
 LIBS=	-lm -lpthread
 
+# JACKify
+CFLAGS+= -DHAVE_JACK
+LIBS+= -ljack
+
+# Do not use libsamplerate (experimental).
+#CFLAGS+= -DHAVE_SRC
+#LIBS+= -lsamplerate
+
 beatrix:	$(OBJS)
 	cc -o $(@) $(OBJS) $(LIBS)
 
diff --git a/main.c b/main.c
index 8735e5c..47a9076 100644
--- a/main.c
+++ b/main.c
@@ -120,6 +120,172 @@ static void setAudioDevice (char * s) {
   }
 }
 
+#ifdef HAVE_JACK
+#include <jack/jack.h>
+
+jack_client_t *j_client = NULL;
+jack_port_t **j_output_port; 
+jack_default_audio_sample_t **j_output_bufferptrs; // 
+jack_default_audio_sample_t bufJ [2][BUFFER_SIZE_SAMPLES];
+
+jack_nframes_t jack_splrate=44100;
+jack_nframes_t jack_fragsize=128;
+
+
+/* when jack shuts down... */
+void jack_shutdown_callback(void *arg) {
+  fprintf(stderr,"jack server shut us down.\n");
+  jack_deactivate(j_client);
+  j_client=NULL;
+}
+
+int jack_srate_callback(jack_nframes_t nframes, void *arg) {
+  jack_splrate= nframes;
+  return(0); 
+}
+
+int jack_bufsiz_callback(jack_nframes_t nframes, void *arg) {
+  jack_fragsize= nframes;
+  return(0); 
+}
+#ifdef HAVE_SRC
+#include<samplerate.h>
+#include<math.h>
+#endif
+
+int jack_audio_callback (jack_nframes_t nframes, void *arg) {
+  jack_default_audio_sample_t **out = j_output_bufferptrs; 
+  int i,s;
+  jack_nframes_t my_tot_latency = 0;
+
+  for (i=0;i<audio_channels;i++) {
+  	jack_nframes_t my_latency = jack_port_get_total_latency(j_client,j_output_port[i]);
+  	if (my_latency > my_tot_latency) my_tot_latency = my_latency;
+  	//printf("DEBUG: c=%i pl=%i tl=%i\n",i,jack_port_get_latency(j_output_port[i]) ,jack_port_get_total_latency(j_client,j_output_port[i]));
+  	out[i] = jack_port_get_buffer (j_output_port[i], nframes);
+  	//memset(out[i],0, sizeof (jack_default_audio_sample_t) * nframes);
+  }
+
+  static unsigned char * obuf;
+  static int boffset = BUFFER_SIZE_SAMPLES;
+
+  float m_fResampleRatio = (float) jack_splrate / (float)SampleRateD;
+#ifndef HAVE_SRC
+  static int info =0;
+#if 1 
+  if (!info) { 
+    info=1;
+    printf ("JACK: integer resampling factor: %f\nJACK: suggest: osc.tuning=%f\n",
+      floorf(m_fResampleRatio+.5),
+      440.0/m_fResampleRatio*floorf(m_fResampleRatio+.5));
+  }
+  m_fResampleRatio = floorf(m_fResampleRatio+.5);
+# endif
+#endif
+
+  jack_nframes_t out_off = 0; 
+
+  while (out_off < nframes) {
+    int remain_src = BUFFER_SIZE_SAMPLES - boffset;
+    int remain_dst = nframes - out_off;
+    if (remain_src <= 0)  {
+      boffset = 0; remain_src+=BUFFER_SIZE_SAMPLES;
+      // generate sound
+      oscGenerateFragment (bufA, BUFFER_SIZE_SAMPLES);
+      obuf = preamp (bufA, bufB, BUFFER_SIZE_SAMPLES);
+      obuf = reverb (obuf, bufB, BUFFER_SIZE_SAMPLES);
+      whirlProc (obuf, bufC, BUFFER_SIZE_SAMPLES);
+
+      // convert interlaced channels
+      for (s=0;s<BUFFER_SIZE_SAMPLES;s++)
+	for (i=0;i<audio_channels;i++) 
+	  //bufJ[i][s]= (((jack_default_audio_sample_t)(((signed short*)bufA)[s]))/65536.0);
+	  //bufJ[i][s]= ((((signed short*)obuf)[s]))/65536.0;
+	  bufJ[i][s]= ((((signed short*)bufC)[audio_channels*s+i]))/65536.0;
+    }
+
+    jack_nframes_t nread = (jack_nframes_t) ceilf((float)remain_dst / m_fResampleRatio);
+    if (nread > remain_src) nread = remain_src;
+    jack_nframes_t nwrite = (jack_nframes_t) floorf((float)nread * m_fResampleRatio);
+    //printf("DEBUG %i %i %f\n", nread, nwrite, m_fResampleRatio);
+#ifdef HAVE_SRC 
+    SRC_DATA src_data;
+    src_data.input_frames  = nread;
+    src_data.output_frames = nwrite;
+    src_data.end_of_input  = 0;
+    src_data.src_ratio     = m_fResampleRatio;
+    src_data.input_frames_used = 0;
+    src_data.output_frames_gen = 0;
+
+    for (i=0;i< audio_channels; i++ ) {
+      src_data.data_in       = &(bufJ[i][boffset]);
+      src_data.data_out      = &(out[i][out_off]);
+      src_simple (&src_data, SRC_SINC_FASTEST, 1) ;
+      //src_simple (&src_data, SRC_SINC_MEDIUM_QUALITY, 1) ;
+      //src_simple (&src_data, SRC_ZERO_ORDER_HOLD, 1) ;
+      //src_simple (&src_data, SRC_LINEAR, 1) ;
+      //src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1) ;
+    }
+    out_off+=src_data.output_frames_gen;
+    boffset+=src_data.input_frames_used;
+#else
+    assert (m_fResampleRatio == 2.0 || m_fResampleRatio==1.0 || m_fResampleRatio==4.0 || m_fResampleRatio==3.0);
+    int r,stride = (int) rintf(m_fResampleRatio);
+
+    for (i=0;i< audio_channels; i++ ) {
+      for (s=0;s<nread;s++) {
+	for (r=0;r<stride;r++)
+	  out[i][out_off+r+stride*s] = bufJ[i][boffset+s];
+      }
+    }
+    out_off+=stride*nread;
+    boffset+=nread;
+#endif
+  }
+  return(0);
+}
+
+int open_jack(void) {
+  int i;
+  i = 0;
+  do {
+    char jackid[16];
+    snprintf(jackid,16,"beatrix-%i",i);
+    j_client = jack_client_new (jackid);
+  } while (j_client == 0 && i++<16);
+
+  if (!j_client) {
+    fprintf(stderr, "could not connect to jack.\n");
+    return(1);
+  }	
+  audio_channels=audio_channels_requested;
+  audio_format = audio_format_requested;
+
+  jack_on_shutdown (j_client, jack_shutdown_callback, NULL);
+  jack_set_process_callback(j_client,jack_audio_callback,NULL);
+  jack_set_sample_rate_callback (j_client, jack_srate_callback, NULL);
+  jack_set_buffer_size_callback (j_client, jack_bufsiz_callback, NULL);
+
+  j_output_port= calloc(audio_channels,sizeof(jack_port_t*));
+  j_output_bufferptrs = calloc(audio_channels,sizeof(jack_default_audio_sample_t*));
+
+  for (i=0;i<audio_channels;i++) {
+    char channelid[16];
+    snprintf(channelid,16,"output-%i",i);
+    j_output_port[i] = jack_port_register (j_client, channelid, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+    if (!j_output_port[i]) {
+      fprintf(stderr, "no more jack ports available.\n");
+      jack_client_close (j_client);
+      return(1);
+    }
+  }
+  jack_srate_callback(jack_get_sample_rate(j_client),NULL); // init j_srate
+  jack_bufsiz_callback(jack_get_buffer_size(j_client),NULL); // init j_bufsiz & alloc
+
+  return(0);
+}
+#endif
+
 /*
  * This routine initializes the audio driver according to the current
  * configuration parameters.
@@ -127,6 +293,13 @@ static void setAudioDevice (char * s) {
 static void initAudio () {
   /* Open the audio hardware. */
 
+#ifdef HAVE_JACK
+  if (open_jack()) {
+    perror ("could not connect to JACK.");
+    exit(1);
+  }
+#else /* NO JACK - OSS */
+
   if ((audio_fd = open (audioDevice, O_WRONLY, 0)) == -1) {
     perror (audioDevice);
     exit (1);
@@ -209,6 +382,7 @@ static void initAudio () {
   fprintf (stderr, "AUDIO FRAGMENT SIZE : %d\n", audio_fragsize);
 #endif /* COMMENT */
 
+#endif /* NO JACK = OSS */
 }
 
 /*
@@ -400,12 +574,14 @@ void makeChord (int key) {
  * Print rudimentary commandline syntax.
  */
 static void Usage () {
-  printf ("Syntax: [-r][c][-p pgmfile] [property=value ...]\n");
+  printf ("Syntax: [-r][c][-p pgmfile][-R internal-samplerate] [property=value ...]\n");
   printf ("Where:\n");
   printf ("-r         Randomize initial preset (whacky but true)\n");
   printf ("-c         Do not read the default configuration file '%s'\n",
 	  defaultConfigFile);
   printf ("-p pgmfile Load alternate programme file over default.\n");
+  printf ("-R <rate>  set samplerate for synth. default 22050.\n");
+  printf ("           jack-sr must be a multiple of this.\n");
   printf ("property=value  Set/Override configuration property.\n");
 }
 
@@ -453,6 +629,9 @@ int main (int argc, char * argv []) {
       else if (!strcmp (av, "-p")) {
 	state = 1;
       }
+      else if (!strcmp (av, "-R")) {
+	state = 2;
+      }
       else if (strchr (av, '=') != NULL) {
 	/* Remember this as a config parameter */
 	if (configOverEnd < NOF_CFG_OVERS) {
@@ -477,6 +656,12 @@ int main (int argc, char * argv []) {
       alternateProgrammeFile = av;
       state = 0;
     }
+    else if (state == 2) {
+      SampleRateI = atoi (av);
+      SampleRateD = (double) SampleRateI;
+      printf(" beatrix internal samplerate: %.1f SPS\n",SampleRateD);
+      state = 0;
+    }
   }
 
   /*
@@ -592,7 +777,12 @@ int main (int argc, char * argv []) {
 #endif /* STATIC_CHORD */
 
     while (TRUE) {
-
+#ifdef HAVE_JACK
+      jack_activate(j_client);
+      while (j_client)
+	sleep (1); // jack callback is doing this:
+      return(0);
+#else
       oscGenerateFragment (bufA, BUFFER_SIZE_SAMPLES);
 
       obuf = preamp (bufA, bufB, BUFFER_SIZE_SAMPLES);
@@ -627,6 +817,7 @@ int main (int argc, char * argv []) {
 	perror ("write audio_fd bufC");
 	exit (1);
       }
+#endif
     }
   }
 
@@ -634,3 +825,5 @@ int main (int argc, char * argv []) {
 
   return 0;
 }
+
+/* vi:set ts=8 sts=2 sw=2: */
