diff --git a/src/Makefile.am b/src/Makefile.am
index ce576bd..8116491 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -200,6 +200,6 @@ ngspice.idx: makeidx
 
 INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices @X_CFLAGS@
 
-LIBS = @LIBS@ @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@
+LIBS = @LIBS@ @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@ -lsndfile
 
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/spicelib/devices/vsrc/Makefile.am b/src/spicelib/devices/vsrc/Makefile.am
index 92ece97..d17e97d 100644
--- a/src/spicelib/devices/vsrc/Makefile.am
+++ b/src/spicelib/devices/vsrc/Makefile.am
@@ -21,7 +21,9 @@ libvsrc_a_SOURCES = 	\
 	vsrcpzld.c	\
 	vsrcpzs.c	\
 	vsrcset.c	\
-	vsrctemp.c
+	vsrctemp.c	\
+	vsjack.c	\
+	vsjack.h
 
 
 
diff --git a/src/spicelib/devices/vsrc/vsjack.c b/src/spicelib/devices/vsrc/vsjack.c
new file mode 100644
index 0000000..aa8f21f
--- /dev/null
+++ b/src/spicelib/devices/vsrc/vsjack.c
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+/////// SNDFILE ///////
+#include <stdlib.h>
+#include <math.h>
+#include <sndfile.h>
+#include <jack/jack.h>
+#define VS_BUFSIZ 1024
+
+#define MAX_D 3 
+//char *(sources[MAX_D]) = { "/tmp/test.wav", "/tmp/test1.wav" , "" };
+char *(sources[MAX_D]);
+
+SNDFILE * m_sndfile[MAX_D]; 
+int m_channels[MAX_D]; //< number of channles in src-file
+jack_nframes_t m_samplerate[MAX_D]; //< samplerate of source
+jack_nframes_t m_frames[MAX_D]; //< duration of source in frames
+float *(interleaved[MAX_D]); //< internal soundfile buffer
+jack_nframes_t ilb_start[MAX_D]; //< first sample in buffer 
+jack_nframes_t ilb_end[MAX_D]; //< last sample in buffer
+
+void vsjack_initialize(void) {
+	int d;
+	for (d=0;d<MAX_D;d++) {
+		m_sndfile[d]=NULL;
+		interleaved[d]=NULL;
+		sources[d]=NULL;
+	}
+	sources[0]=strdup("/tmp/test.wav");
+	sources[1]=strdup("/tmp/test1.wav");
+}
+
+void realloc_sf (int d, jack_nframes_t buffersize) {
+	if (interleaved[d]) free(interleaved[d]);
+	interleaved[d] = (float *) calloc(m_channels[d]*buffersize, sizeof(float));
+}
+
+int openfile_sf (int d, char *filename) {
+	SF_INFO sfinfo;
+	if (!m_sndfile[d]) sf_close(m_sndfile[d]);
+	printf("opening file '%s' for id:%i\n",filename, d);
+	m_sndfile[d] = sf_open( filename, SFM_READ, &sfinfo );	
+	ilb_end[d]=ilb_start[d]=0;
+
+	if ( SF_ERR_NO_ERROR != sf_error( m_sndfile[d] ) ) {
+		fprintf(stderr, "This is not a sndfile supported audio file format\n" );
+		return (-1);
+	}
+	if ( sfinfo.frames==0 ) {
+		fprintf(stderr, "This is an empty audio file\n" );
+		return (-1);
+	}
+	m_channels[d] = sfinfo.channels;
+	m_samplerate[d] = sfinfo.samplerate;
+	m_frames[d] = (jack_nframes_t) sfinfo.frames;
+	realloc_sf(d, VS_BUFSIZ);
+	return (0);
+}
+
+void load_buffer(int d, jack_nframes_t sample) {
+	sf_seek( m_sndfile[d], sample, SEEK_SET );
+	ilb_start[d] = sample;
+	jack_nframes_t nframes;
+	if ((nframes=sf_readf_float( m_sndfile[d], (interleaved[d]), VS_BUFSIZ))>0) {
+		ilb_end[d] = ilb_start[d] + nframes; 
+	} else {
+		ilb_end[d] = ilb_start[d];
+		printf ("Decoder error.\n");
+	}
+
+}
+
+double get_value(int d, jack_nframes_t sample) {
+	if (sample > m_frames[d] ) return (0.0); // TODO: print EOF warning (once). FIXME move to load_buffer
+
+	if (sample < ilb_start[d] || sample >= ilb_end[d]) 
+		load_buffer(d, sample);
+
+	if (sample < ilb_start[d] || sample >= ilb_end[d]) {
+		printf ("no such value for jack:%i.\n",d);
+		return (0.0); // nan ?
+	}
+
+	int offset = sample - ilb_start[d];
+	if (offset > VS_BUFSIZ || offset < 0) {
+		printf ("value not in buffer:%i.\n",d);
+		return (0.0); // nan ?
+	}
+	return (((double) (((float *)(interleaved[d]))[m_channels[d]*offset+0]))); // first channel
+}
+
+
+///////////////////////////////////////////////
+
+
+double vsjack_get_value (int d, double time, double time_offset) {
+	assert (d>=0 && d< MAX_D );
+	if (m_sndfile[d] == NULL) return (0.0); // FIXME
+	jack_nframes_t sample = (jack_nframes_t) rint((time+time_offset)*((double)m_samplerate[d]));
+	double value = get_value(d,sample);
+	return (value);
+}
+
+void vsjack_set_file (int d , char *fn) {
+	assert (d>=0 && d< MAX_D );
+	if (sources[d] != NULL) free (sources[d]);
+	sources[d] = strdup(fn);
+}
+
+int vsjack_open (int d) {
+	static int initialized =0;
+	if (!initialized) {
+		initialized=1;
+		vsjack_initialize();
+	}
+	if (d==-1) return -1;// initialize only
+	assert (d>=0 && d< MAX_D );
+	assert (sources[d]!=NULL);
+	if (openfile_sf(d, sources[d])) {
+		printf ("could not open JACK data\n");
+		exit (1);
+	}
+	return (d);
+}
+
+
diff --git a/src/spicelib/devices/vsrc/vsrc.c b/src/spicelib/devices/vsrc/vsrc.c
index c73da4d..d671be7 100644
--- a/src/spicelib/devices/vsrc/vsrc.c
+++ b/src/spicelib/devices/vsrc/vsrc.c
@@ -17,6 +17,8 @@ IFparm VSRCpTable[] = { /* parameters */
  IP ("sine",    VSRC_SINE,      IF_REALVEC,"Sinusoidal source description"),
  IP ("sin",     VSRC_SINE,      IF_REALVEC,"Sinusoidal source description"),
  IP ("exp",     VSRC_EXP,       IF_REALVEC,"Exponential source description"),
+ IP ("jack",    VSRC_JACK,      IF_REALVEC,"External source jack"),
+ OPU ("file",   VSRC_JFILE,     IF_STRING,"External source jackfile"),
  IP ("pwl",     VSRC_PWL,       IF_REALVEC,"Piecewise linear description"),
  IP ("sffm",    VSRC_SFFM,      IF_REALVEC,"Single freq. FM descripton"),
  IP ("am",      VSRC_AM,        IF_REALVEC,"Amplitude modulation descripton"),
diff --git a/src/spicelib/devices/vsrc/vsrcacct.c b/src/spicelib/devices/vsrc/vsrcacct.c
index ac0edc5..fd391b5 100644
--- a/src/spicelib/devices/vsrc/vsrcacct.c
+++ b/src/spicelib/devices/vsrc/vsrcacct.c
@@ -149,6 +149,10 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
                     /* no  breakpoints (yet) */
                 }
                 break;
+                case JACK: {
+                    /* no  breakpoints (yet) */
+                }
+                break;
                 case EXP: {
                     /* no  breakpoints (yet) */
                 }
diff --git a/src/spicelib/devices/vsrc/vsrcask.c b/src/spicelib/devices/vsrc/vsrcask.c
index 639709e..b68b25c 100644
--- a/src/spicelib/devices/vsrc/vsrcask.c
+++ b/src/spicelib/devices/vsrc/vsrcask.c
@@ -39,6 +39,7 @@ VSRCask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *
             value->rValue = here->VSRCacPhase;
             return (OK);
         case VSRC_PULSE:
+        case VSRC_JACK:
         case VSRC_SINE:
         case VSRC_EXP:
         case VSRC_PWL:
diff --git a/src/spicelib/devices/vsrc/vsrcdefs.h b/src/spicelib/devices/vsrc/vsrcdefs.h
index 28c836b..5905c71 100644
--- a/src/spicelib/devices/vsrc/vsrcdefs.h
+++ b/src/spicelib/devices/vsrc/vsrcdefs.h
@@ -89,6 +89,7 @@ typedef struct sVSRCmodel {
 #define SFFM 4
 #define PWL 5
 #define AM 6
+#define JACK 7
 #endif /*PULSE*/
 
 /* device parameters */
@@ -115,6 +116,8 @@ typedef struct sVSRCmodel {
 #define VSRC_D_F2 21
 
 #define VSRC_AM 22
+#define VSRC_JACK 23
+#define VSRC_JFILE 24
 
 /* model parameters */
 
diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c
index e173a8f..ee3af8a 100644
--- a/src/spicelib/devices/vsrc/vsrcload.c
+++ b/src/spicelib/devices/vsrc/vsrcload.c
@@ -10,6 +10,7 @@ Modified: 2000 AlansFixes
 #include "trandefs.h"
 #include "sperror.h"
 #include "suffix.h"
+#include "vsjack.h"
 
 #ifdef XSPICE_EXP
 /* gtri - begin - wbk - modify for supply ramping option */
@@ -121,6 +122,12 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
                 }
                 break;
 
+                case JACK: {
+			value=here->VSRCcoeffs[2] * vsjack_get_value((int) here->VSRCcoeffs[0], time, here->VSRCcoeffs[3]);
+			value+=here->VSRCcoeffs[1];
+		}
+		break;
+
                 case SINE: {
 		
 		    double VO, VA, FREQ, TD, THETA;
diff --git a/src/spicelib/devices/vsrc/vsrcpar.c b/src/spicelib/devices/vsrc/vsrcpar.c
index c59c354..0ec1b9a 100644
--- a/src/spicelib/devices/vsrc/vsrcpar.c
+++ b/src/spicelib/devices/vsrc/vsrcpar.c
@@ -11,6 +11,7 @@ Modified: 2000 AlansFixes
 #include "ifsim.h"
 #include "sperror.h"
 #include "suffix.h"
+#include "vsjack.h"
 
 
 /* ARGSUSED */
@@ -19,6 +20,7 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
 {
     int i;
     VSRCinstance *here = (VSRCinstance *)inst;
+    static char *jfile = NULL;
     switch(param) {
         case VSRC_DC:
             here->VSRCdcValue = value->rValue;
@@ -56,6 +58,25 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
             here->VSRCfunctionOrder = value->v.numValue;
             here->VSRCcoeffsGiven = TRUE;
             break;
+        case VSRC_JFILE:
+	    jfile=strdup(value->sValue);
+	    printf("JFILE: %s\n",jfile);
+            break;
+        case VSRC_JACK:
+            here->VSRCfunctionType = JACK;
+            here->VSRCfuncTGiven = TRUE;
+            here->VSRCcoeffs = value->v.vec.rVec;
+            here->VSRCcoeffsGiven = TRUE;
+	    vsjack_open(-1); // initialize
+	    if (jfile) {
+		vsjack_set_file((int) rint(here->VSRCcoeffs[0]), jfile);
+		free(jfile);
+		jfile=NULL;
+	    }
+	    if (value->v.numValue!=4) 
+		fprintf(stderr, "Warning! invalid jack args: %i\nFormat: jack(id v_off v_mult t_off)",value->v.numValue);
+	    vsjack_open((int) rint(here->VSRCcoeffs[0]));
+            break;
         case VSRC_SINE:
             here->VSRCfunctionType = SINE;
             here->VSRCfuncTGiven = TRUE;
