diff --git a/pd/src/dialog_audio.tcl b/pd/src/dialog_audio.tcl
index 878adacdd6d60506a2fb4af9d8f3f5613b9be3cb..b88b84681a844e8c97b18fb0f28af0c5f44a65ff 100644
--- a/pd/src/dialog_audio.tcl
+++ b/pd/src/dialog_audio.tcl
@@ -65,7 +65,7 @@ proc ::dialog_audio::apply {mytoplevel} {
         $audio_sr \
         $audio_advance \
         $audio_callback \
-        $audio_blocksize" \
+        $audio_blocksize \
         \;]
 
     # Pd always makes devices contiguous-- for example, if you only set
diff --git a/pd/src/s_audio.c b/pd/src/s_audio.c
index 1dce94ca59a46a0e6e7e19245234f2f9e0a3a2a0..33f8ef04fccb9460cf6118e59de155ec24fefd30 100644
--- a/pd/src/s_audio.c
+++ b/pd/src/s_audio.c
@@ -63,12 +63,15 @@ static int audio_state;
 static int audio_naudioindev = -1;
 static int audio_audioindev[MAXAUDIOINDEV];
 static int audio_audiochindev[MAXAUDIOINDEV];
+static char audio_indevnames[MAXMIDIINDEV * DEVDESCSIZE];
 static int audio_naudiooutdev = -1;
 static int audio_audiooutdev[MAXAUDIOOUTDEV];
 static int audio_audiochoutdev[MAXAUDIOOUTDEV];
+static char audio_outdevnames[MAXMIDIINDEV * DEVDESCSIZE];
 static int audio_rate;
-static int audio_advance;
+static int audio_advance = -1;
 static int audio_callback;
+static int audio_blocksize;
 
 static int audio_callback_is_open;  /* reflects true actual state */
 static int audio_nextinchans, audio_nextoutchans;
@@ -80,7 +83,7 @@ void sched_reopenmeplease(void);
 extern int jack_get_srate(void);
 #endif /* JACK */
 
-static int audio_isopen(void)
+int audio_isopen(void)
 {
     return (audio_state &&
         ((audio_naudioindev > 0 && audio_audiochindev[0] > 0) 
@@ -90,48 +93,60 @@ static int audio_isopen(void)
 void sys_get_audio_params(
     int *pnaudioindev, int *paudioindev, int *chindev,
     int *pnaudiooutdev, int *paudiooutdev, int *choutdev,
-    int *prate, int *padvance, int *pcallback)
+    int *prate, int *padvance, int *pcallback, int *pblocksize)
 {
-    int i;
+    int i, devn;
     *pnaudioindev = audio_naudioindev;
-    for (i = 0; i < MAXAUDIOINDEV; i++)
-        paudioindev[i] = audio_audioindev[i],
-            chindev[i] = audio_audiochindev[i]; 
+    for (i = 0; i < audio_naudioindev; i++)
+    {
+        if ((devn = sys_audiodevnametonumber(0,
+            &audio_indevnames[i * DEVDESCSIZE])) >= 0)
+                paudioindev[i] = devn;
+        else paudioindev[i] = audio_audioindev[i];
+        chindev[i] = audio_audiochindev[i];
+    }
     *pnaudiooutdev = audio_naudiooutdev;
-    for (i = 0; i < MAXAUDIOOUTDEV; i++)
-        paudiooutdev[i] = audio_audiooutdev[i],
-            choutdev[i] = audio_audiochoutdev[i];
-#ifdef USEAPI_JACK
-    if (sys_audioapiopened == API_JACK)
+    for (i = 0; i < audio_naudiooutdev; i++)
     {
-        if (jack_get_srate())
-        {
-            audio_rate = jack_get_srate();
-        }
+        if ((devn = sys_audiodevnametonumber(1,
+            &audio_outdevnames[i * DEVDESCSIZE])) >= 0)
+                paudiooutdev[i] = devn;
+        else paudiooutdev[i] = audio_audiooutdev[i];
+        choutdev[i] = audio_audiochoutdev[i]; 
     }
-#endif /* JACK */
     *prate = audio_rate;
     *padvance = audio_advance;
     *pcallback = audio_callback;
+    *pblocksize = audio_blocksize;
 }
 
 void sys_save_audio_params(
     int naudioindev, int *audioindev, int *chindev,
     int naudiooutdev, int *audiooutdev, int *choutdev,
-    int rate, int advance, int callback)
+    int rate, int advance, int callback, int blocksize)
 {
     int i;
     audio_naudioindev = naudioindev;
-    for (i = 0; i < MAXAUDIOINDEV; i++)
+    for (i = 0; i < naudioindev; i++)
+    {
         audio_audioindev[i] = audioindev[i],
-            audio_audiochindev[i] = chindev[i]; 
+        audio_audiochindev[i] = chindev[i];
+        sys_audiodevnumbertoname(0, audioindev[i],
+            &audio_indevnames[i * DEVDESCSIZE], DEVDESCSIZE);
+    }
     audio_naudiooutdev = naudiooutdev;
-    for (i = 0; i < MAXAUDIOOUTDEV; i++)
+    for (i = 0; i < naudiooutdev; i++)
+    {
         audio_audiooutdev[i] = audiooutdev[i],
-            audio_audiochoutdev[i] = choutdev[i]; 
+        audio_audiochoutdev[i] = choutdev[i];
+        sys_audiodevnumbertoname(1, audiooutdev[i],
+            &audio_outdevnames[i * DEVDESCSIZE], DEVDESCSIZE);
+    }
     audio_rate = rate;
     audio_advance = advance;
     audio_callback = callback;
+    audio_blocksize = blocksize;
+    fprintf(stderr,"blocksize=%d\n", blocksize);
 }
 
     /* init routines for any API which needs to set stuff up before
@@ -196,9 +211,9 @@ void sys_setchsr(int chin, int chout, int sr)
 
 void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev,
     int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
-    int *choutdev, int rate, int advance, int callback)
+    int *choutdev, int rate, int advance, int callback, int blocksize)
 {
-    int i;
+    int i, *ip;
     int defaultchannels = SYS_DEFAULTCH;
     int inchans, outchans, nrealindev, nrealoutdev;
     int realindev[MAXAUDIOINDEV], realoutdev[MAXAUDIOOUTDEV];
@@ -211,8 +226,10 @@ void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev,
 
     if (rate < 1)
         rate = DEFAULTSRATE;
-    if (advance <= 0)
+    if (advance < 0)
         advance = DEFAULTADVANCE;
+    if (blocksize != (1 << ilog2(blocksize)) || blocksize < DEFDACBLKSIZE)
+        blocksize = DEFDACBLKSIZE;
      audio_init();
         /* Since the channel vector might be longer than the
         audio device vector, or vice versa, we fill the shorter one
@@ -339,8 +356,10 @@ void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev,
     sys_log_error(ERR_NOTHING);
     audio_nextinchans = inchans;
     audio_nextoutchans = outchans;
+    sys_setchsr(audio_nextinchans, audio_nextoutchans, rate);
     sys_save_audio_params(nrealindev, realindev, realinchans,
-        nrealoutdev, realoutdev, realoutchans, rate, advance, callback);
+        nrealoutdev, realoutdev, realoutchans, rate, advance, callback,
+            blocksize);
 }
 
 void sys_close_audio(void)
@@ -389,9 +408,10 @@ void sys_reopen_audio( void)
 {
     int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
     int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
-    int rate, advance, callback, outcome = 0;
+    int rate, advance, callback, blocksize, outcome = 0;
     sys_get_audio_params(&naudioindev, audioindev, chindev,
-        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
+        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback,
+            &blocksize);
     sys_setchsr(audio_nextinchans, audio_nextoutchans, rate);
     if (!naudioindev && !naudiooutdev)
     {
@@ -429,7 +449,8 @@ void sys_reopen_audio( void)
         be open for both input and output. */
     if (sys_audioapi == API_ALSA)
         outcome = alsa_open_audio(naudioindev, audioindev, naudioindev,
-            chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate);
+            chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate,
+                audio_blocksize);
     else 
 #endif
 #ifdef USEAPI_MMIO
@@ -660,7 +681,7 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform)
         audioinchan1, audioinchan2, audioinchan3, audioinchan4,
         audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4,
         audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4;
-    int rate, advance, callback;
+    int rate, advance, callback, blocksize;
         /* these are all the devices on your system: */
     char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
     int nindevs = 0, noutdevs = 0, canmulti = 0, cancallback = 0, i;
@@ -679,7 +700,8 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform)
             outdevlist + i * DEVDESCSIZE);
 
     sys_get_audio_params(&naudioindev, audioindev, chindev,
-        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
+        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback,
+            &blocksize);
 
 #ifdef USEAPI_JACK
     if (sys_audioapiopened == API_JACK)
@@ -719,7 +741,7 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform)
         audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4,
         audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4, 
         rate, advance, canmulti, (cancallback ? callback : -1),
-        (flongform != 0));
+        (flongform != 0), blocksize);
     gfxstub_deleteforkey(0);
     gfxstub_new(&glob_pdobject, (void *)glob_audio_properties, buf);
 }
@@ -728,13 +750,17 @@ extern int pa_foo;
     /* new values from dialog window */
 void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
 {
-    int i, nindev, noutdev;
+    int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
+    int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
+    int rate, advance, audioon, i, nindev, noutdev;
+    int audioindev1, audioinchan1, audiooutdev1, audiooutchan1;
     int newaudioindev[4], newaudioinchan[4],
         newaudiooutdev[4], newaudiooutchan[4];
         /* the new values the dialog came back with: */
     int newrate = atom_getintarg(16, argc, argv);
     int newadvance = atom_getintarg(17, argc, argv);
     int newcallback = atom_getintarg(18, argc, argv);
+    int newblocksize = atom_getintarg(19, argc, argv);
 
     for (i = 0; i < 4; i++)
     {
@@ -767,14 +793,28 @@ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
         }
     }
     
-    if (newcallback < 0)
-        newcallback = 0;
-    if (!audio_callback_is_open && !newcallback)
-        sys_close_audio();
-    sys_set_audio_settings(nindev, newaudioindev, nindev, newaudioinchan,
+    sys_set_audio_settings_reopen(nindev, newaudioindev, nindev, newaudioinchan,
         noutdev, newaudiooutdev, noutdev, newaudiooutchan,
-        newrate, newadvance, (newcallback >= 0 ? newcallback : 0));
-    if (!audio_callback_is_open && !newcallback)
+        newrate, newadvance, newcallback, newblocksize);
+}
+
+
+void sys_set_audio_settings_reopen(int naudioindev, int *audioindev, int nchindev,
+    int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
+    int *choutdev, int rate, int advance, int callback, int newblocksize)
+{
+    if (callback < 0)
+        callback = 0;
+    if (newblocksize != (1<<ilog2(newblocksize)) ||
+        newblocksize < DEFDACBLKSIZE || newblocksize > 2048)
+            newblocksize = DEFDACBLKSIZE;
+    
+    if (!audio_callback_is_open && !callback)
+        sys_close_audio();
+    sys_set_audio_settings(naudioindev, audioindev, nchindev, chindev,
+        naudiooutdev, audiooutdev, nchoutdev, choutdev,
+        rate, advance, (callback >= 0 ? callback : 0), newblocksize);
+    if (!audio_callback_is_open && !callback)
         sys_reopen_audio();
     else sched_reopenmeplease();
 }
@@ -946,3 +986,62 @@ void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv)
     }
 #endif
 }
+
+/* convert a device name to a (1-based) device number.  (Output device if
+'output' parameter is true, otherwise input device).  Negative on failure. */
+
+int sys_audiodevnametonumber(int output, const char *name)
+{
+    char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
+    int nindevs = 0, noutdevs = 0, i, canmulti, cancallback;
+
+    sys_get_audio_devs(indevlist, &nindevs, outdevlist, &noutdevs,
+        &canmulti, &cancallback, MAXNDEV, DEVDESCSIZE);
+
+    if (output)
+    {
+        for (i = 0; i < noutdevs; i++)
+        {
+            unsigned int comp = strlen(name);
+            if (comp > strlen(outdevlist + i * DEVDESCSIZE))
+                comp = strlen(outdevlist + i * DEVDESCSIZE);
+            if (!strncmp(name, outdevlist + i * DEVDESCSIZE, comp))
+                return (i);
+        }
+    }
+    else
+    {
+        for (i = 0; i < nindevs; i++)
+        {
+            unsigned int comp = strlen(name);
+            if (comp > strlen(indevlist + i * DEVDESCSIZE))
+                comp = strlen(indevlist + i * DEVDESCSIZE);
+            if (!strncmp(name, indevlist + i * DEVDESCSIZE, comp))
+                return (i);
+        }
+    }
+    return (-1);
+}
+
+/* convert a (1-based) device number to a device name.  (Output device if
+'output' parameter is true, otherwise input device).  Empty string on failure.
+*/
+
+void sys_audiodevnumbertoname(int output, int devno, char *name, int namesize)
+{
+    char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
+    int nindevs = 0, noutdevs = 0, i, canmulti, cancallback;
+    if (devno < 0)
+    {
+        *name = 0;
+        return;
+    }
+    sys_get_audio_devs(indevlist, &nindevs, outdevlist, &noutdevs,
+        &canmulti, &cancallback, MAXNDEV, DEVDESCSIZE);
+    if (output && (devno < noutdevs))
+        strncpy(name, outdevlist + devno * DEVDESCSIZE, namesize);
+    else if (!output && (devno < nindevs))
+        strncpy(name, indevlist + devno * DEVDESCSIZE, namesize);
+    else *name = 0;
+    name[namesize-1] = 0;
+}
diff --git a/pd/src/s_audio_alsa.c b/pd/src/s_audio_alsa.c
index 91fc385fe19b4a07d9c4f8c243650321ab1e2ad7..06e889cda5fcf6425d7ea5e2cdc04b7c07f16289 100644
--- a/pd/src/s_audio_alsa.c
+++ b/pd/src/s_audio_alsa.c
@@ -233,12 +233,14 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate,
     /* return 0 on success */
 int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
     int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
-    int *choutdev, int rate)
+    int *choutdev, int rate, int blocksize)
 {
     int err, inchans = 0, outchans = 0, subunitdir;
     char devname[512];
-    int frag_size = (sys_blocksize ? sys_blocksize : ALSA_DEFFRAGSIZE);
+    snd_output_t* out;
+    int frag_size = (blocksize ? blocksize : ALSA_DEFFRAGSIZE);
     int nfrags, i, iodev, dev2;
+    int wantinchans, wantoutchans, device;
 
     nfrags = sys_schedadvance * (float)rate / (1e6 * frag_size);
         /* save our belief as to ALSA's buffer size for later */
@@ -254,7 +256,7 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
         alsa_numbertoname(audioindev[iodev], devname, 512);
         err = snd_pcm_open(&alsa_indev[alsa_nindev].a_handle, devname,
             SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
-        check_error(err, "snd_pcm_open (input)");
+        check_error(err, "snd_pcm_open");
         if (err < 0)
             continue;
         alsa_indev[alsa_nindev].a_devno = audioindev[iodev];
@@ -268,7 +270,7 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
         alsa_numbertoname(audiooutdev[iodev], devname, 512);
         err = snd_pcm_open(&alsa_outdev[alsa_noutdev].a_handle, devname,
             SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
-        check_error(err, "snd_pcm_open (output)");
+        check_error(err, "snd_pcm_open");
         if (err < 0)
             continue;
         alsa_outdev[alsa_noutdev].a_devno = audiooutdev[iodev];
@@ -290,7 +292,7 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
     if (alsa_usemmap)
     {
         post("using mmap audio interface");
-        if (alsamm_open_audio(rate))
+        if (alsamm_open_audio(rate, blocksize))
             goto blewit;
         else return (0);
     }
@@ -336,7 +338,8 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
         check_error(err, "snd_pcm_status_malloc");
     }
 
-        /* fill the buffer with silence */
+        /* fill the buffer with silence and prime the output FIFOs.  This
+        should automatically start the output devices. */
     memset(alsa_snd_buf, 0, alsa_snd_bufsize);
 
     if (outchans)
@@ -349,11 +352,15 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
                     DEFDACBLKSIZE);
         }
     }
-    else if (inchans)
+    if (inchans)
     {
+            /* some of the ADC devices might already have been started by
+            starting the outputs above, but others might still need it. */
         for (iodev = 0; iodev < alsa_nindev; iodev++)
-            if ((err = snd_pcm_start(alsa_indev[iodev].a_handle)) < 0)
-                check_error(err, "input start failed\n");
+            if (snd_pcm_state(alsa_indev[iodev].a_handle)
+                != SND_PCM_STATE_RUNNING)
+                    if ((err = snd_pcm_start(alsa_indev[iodev].a_handle)) < 0)
+                        check_error(err, "input start failed");
     }
     return (0);
 blewit:
diff --git a/pd/src/s_audio_alsamm.c b/pd/src/s_audio_alsamm.c
index 9401d20a5d3cfa07744292086f194ee733109562..fe5d48650f5ac00961e0fa1b6fe90143358b9a45 100644
--- a/pd/src/s_audio_alsamm.c
+++ b/pd/src/s_audio_alsamm.c
@@ -175,17 +175,24 @@ static void check_error(int err, const char *why)
         error("%s: %s\n", why, snd_strerror(err));
 }
 
-int alsamm_open_audio(int rate)
+int alsamm_open_audio(int rate, int blocksize)
 {
-  int err, i;
+  int err;
+  char devname[80];
+  char *cardname;
   snd_pcm_hw_params_t* hw_params;
   snd_pcm_sw_params_t* sw_params;
 
+
   /* fragsize is an old concept now use periods, used to be called fragments. */
   /* Be aware in ALSA periodsize can be in bytes, where buffersize is in frames, 
      but sometimes buffersize is in bytes and periods in frames, crazy alsa...      
      ...we use periodsize and buffersize in frames */
 
+  int i;
+  short* tmp_buf;
+  unsigned int tmp_uint;
+
   snd_pcm_hw_params_alloca(&hw_params);
   snd_pcm_sw_params_alloca(&sw_params);
   
@@ -224,16 +231,16 @@ int alsamm_open_audio(int rate)
   
   /* set the asked buffer time (alsa buffertime in us)*/  
   alsamm_buffertime = alsamm_buffersize = 0;
-  if(sys_blocksize == 0)
+  if(blocksize == 0)
     alsamm_buffertime = sys_schedadvance;
   else
-    alsamm_buffersize = sys_blocksize;
+    alsamm_buffersize = blocksize;
    
   if(sys_verbose)
     post("syschedadvance=%d us(%d Samples)so buffertime max should be this=%d" 
          "or sys_blocksize=%d (samples) to use buffersize=%d",
          sys_schedadvance,sys_advance_samples,alsamm_buffertime,
-         sys_blocksize,alsamm_buffersize);
+         blocksize,alsamm_buffersize);
   
   alsamm_periods = 0; /* no one wants periods setting from command line ;-) */
 
@@ -308,6 +315,8 @@ int alsamm_open_audio(int rate)
   /* check for linked handles of input for each output*/
   
   for(i=0; i<(alsa_noutdev < alsa_nindev ? alsa_noutdev:alsa_nindev); i++){
+    t_alsa_dev *ad = &alsa_outdev[i];
+
     if (alsa_outdev[i].a_devno == alsa_indev[i].a_devno){
       if ((err = snd_pcm_link (alsa_indev[i].a_handle,
                                alsa_outdev[i].a_handle)) == 0){
diff --git a/pd/src/s_file.c b/pd/src/s_file.c
index cc27cb2e8046a6daa26e58327d891cd3ce118a77..7c12da3b22291d3b5a441b8bc6f75bc00e4a49c3 100644
--- a/pd/src/s_file.c
+++ b/pd/src/s_file.c
@@ -321,7 +321,8 @@ void sys_loadpreferences( void)
     int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
     int nmidiindev, midiindev[MAXMIDIINDEV];
     int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
-    int i, rate = 0, advance = 0, callback = 0, api, nolib, maxi;
+    int i, rate = 0, advance = -1, callback = 0, blocksize = 0,
+        api, nolib, maxi;
     char prefbuf[MAXPDSTRING], keybuf[80];
 
     sys_initloadpreferences();
@@ -374,7 +375,7 @@ void sys_loadpreferences( void)
         sscanf(prefbuf, "%d", &callback);
     sys_set_audio_settings(naudioindev, audioindev, naudioindev, chindev,
         naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance,
-        callback);
+        callback, blocksize);
         
         /* load MIDI preferences */
         /* JMZ/MB: brackets for initializing */
@@ -459,7 +460,7 @@ void glob_savepreferences(t_pd *dummy)
 {
     int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
     int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
-    int i, rate, advance, callback;
+    int i, rate, advance, callback, blocksize;
     char buf1[MAXPDSTRING], buf2[MAXPDSTRING];
     int nmidiindev, midiindev[MAXMIDIINDEV];
     int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
@@ -472,7 +473,8 @@ void glob_savepreferences(t_pd *dummy)
     sys_putpreference("audioapi", buf1);
 
     sys_get_audio_params(&naudioindev, audioindev, chindev,
-        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
+        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback,
+            &blocksize);
 
     sys_putpreference("noaudioin", (naudioindev <= 0 ? "True" : "False"));
     for (i = 0; i < naudioindev; i++)
@@ -498,6 +500,9 @@ void glob_savepreferences(t_pd *dummy)
     sprintf(buf1, "%d", callback);
     sys_putpreference("callback", buf1);
 
+    sprintf(buf1, "%d", blocksize);
+    sys_putpreference("blocksize", buf1);
+
         /* MIDI settings */
     sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev);
     sys_putpreference("nomidiin", (nmidiindev <= 0 ? "True" : "False"));
diff --git a/pd/src/s_main.c b/pd/src/s_main.c
index e00b17d703c4c891653829f3194905bb252cf043..1949d76b1d0db431c0b8165dfbd07bb5e9205d06 100644
--- a/pd/src/s_main.c
+++ b/pd/src/s_main.c
@@ -79,6 +79,7 @@ char sys_fontweight[] = "normal"; /* currently only used for iemguis */
 static int sys_main_srate;
 static int sys_main_advance;
 static int sys_main_callback;
+static int sys_main_blocksize;
 static int sys_listplease;
 
 int sys_externalschedlib;
@@ -1019,7 +1020,7 @@ static void sys_afterargparse(void)
     int i;
     int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
     int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
-    int nchindev, nchoutdev, rate, advance, callback;
+    int nchindev, nchoutdev, rate, advance, callback, blocksize;
     int nmidiindev = 0, midiindev[MAXMIDIINDEV];
     int nmidioutdev = 0, midioutdev[MAXMIDIOUTDEV];
             /* add "extra" library to path */
@@ -1055,7 +1056,8 @@ static void sys_afterargparse(void)
             else are the default.  Overwrite them with any results
             of argument parsing, and store them again. */
     sys_get_audio_params(&naudioindev, audioindev, chindev,
-        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
+        &naudiooutdev, audiooutdev, choutdev, &rate, &advance,
+            &callback, &blocksize);
     if (sys_nchin >= 0)
     {
         nchindev = sys_nchin;
@@ -1103,9 +1105,11 @@ static void sys_afterargparse(void)
         rate = sys_main_srate;
     if (sys_main_callback)
         callback = sys_main_callback;
+    if (sys_main_blocksize)
+        blocksize = sys_main_blocksize;
     sys_set_audio_settings(naudioindev, audioindev, nchindev, chindev,
         naudiooutdev, audiooutdev, nchoutdev, choutdev, rate, advance, 
-        callback);
+        callback, blocksize);
     sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 0);
 }
 
diff --git a/pd/src/s_stuff.h b/pd/src/s_stuff.h
index 862b2a44ce81a9f880fefd2404fbf94149b2aece..3af586934da524f7909961f8ee50459c08af2e85 100644
--- a/pd/src/s_stuff.h
+++ b/pd/src/s_stuff.h
@@ -81,12 +81,23 @@ extern int sys_blocksize;       /* audio I/O block size in sample frames */
 extern t_float sys_dacsr;
 extern int sys_schedadvance;
 extern int sys_sleepgrain;
-void sys_set_audio_settings(int naudioindev, int *audioindev,
+EXTERN void sys_set_audio_settings(int naudioindev, int *audioindev,
     int nchindev, int *chindev,
     int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
-    int srate, int advance, int callback);
+    int srate, int advance, int callback, int blocksize);
+/* the same as above, but reopens the audio subsystem if needed */
+EXTERN void sys_set_audio_settings_reopen(int naudioindev, int *audioindev,
+    int nchindev, int *chindev,
+    int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
+    int srate, int advance, int callback, int blocksize);
 void sys_reopen_audio( void);
 void sys_close_audio(void);
+    /* return true if the interface prefers always being open (ala jack) : */
+EXTERN int audio_shouldkeepopen( void);
+EXTERN int audio_isopen( void);     /* true if audio interface is open */
+EXTERN int sys_audiodevnametonumber(int output, const char *name);
+EXTERN void sys_audiodevnumbertoname(int output, int devno, char *name,
+    int namesize);
 
 
 int sys_send_dacs(void);
@@ -260,7 +271,7 @@ void oss_getdevs(char *indevlist, int *nindevs,
 
 int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
     int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
-    int *choutdev, int rate);
+    int *choutdev, int rate, int blocksize);
 void alsa_close_audio(void);
 int alsa_send_dacs(void);
 void alsa_reportidle(void);
@@ -298,14 +309,14 @@ void sys_set_audio_state(int onoff);
 void oss_set32bit( void);
 void linux_alsa_devname(char *devname);
 
-void sys_get_audio_params(
+EXTERN void sys_get_audio_params(
     int *pnaudioindev, int *paudioindev, int *chindev,
     int *pnaudiooutdev, int *paudiooutdev, int *choutdev,
-    int *prate, int *padvance, int *callback);
+    int *prate, int *padvance, int *callback, int *blocksize);
 void sys_save_audio_params(
     int naudioindev, int *audioindev, int *chindev,
     int naudiooutdev, int *audiooutdev, int *choutdev,
-    int rate, int advance, int callback);
+    int rate, int advance, int callback, int blocksize);
 
 /* s_file.c */
 
diff --git a/pd/src/x_interface.c b/pd/src/x_interface.c
index 479da8f4c0b10ec63f535fdfbb0a2161f40f86ad..bae50d480b7d4c2a16478f71e3318ad360a4c6b0 100644
--- a/pd/src/x_interface.c
+++ b/pd/src/x_interface.c
@@ -577,9 +577,9 @@ void pdinfo_audio_dev(t_pdinfo *x, t_symbol *s, int argc, t_atom *argv)
     else devno = 0;
     int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
     int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
-    int rate, advance, callback;
+    int rate, advance, callback, blocksize;
     sys_get_audio_params(&naudioindev, audioindev, chindev,
-        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
+        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, &blocksize);
     int *dev, *chan, ndev;
     if (s == gensym("audio-indev"))
         dev = audioindev, chan = chindev, ndev = naudioindev;
@@ -675,9 +675,9 @@ void pdinfo_audio_outdev(t_pdinfo *x, t_symbol *s, int argc, t_atom *argv)
     else devno = 0;
     int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
     int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
-    int rate, advance, callback;
+    int rate, advance, callback, blocksize;
     sys_get_audio_params(&naudioindev, audioindev, chindev,
-        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
+        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, &blocksize);
     if (devno >= 0 && devno < naudioindev)
     {
         t_atom at[2];