From 6d1d64ebacc156f4df5401dac427b316dd22265d Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Wed, 9 Mar 2011 11:28:09 -0800
Subject: audio: moved alsa support files into subdirectory

---
 gr-audio/lib/Makefile.am               |  18 +-
 gr-audio/lib/alsa/audio_alsa_sink.cc   | 548 +++++++++++++++++++++++++++++++++
 gr-audio/lib/alsa/audio_alsa_sink.h    | 104 +++++++
 gr-audio/lib/alsa/audio_alsa_source.cc | 505 ++++++++++++++++++++++++++++++
 gr-audio/lib/alsa/audio_alsa_source.h  | 106 +++++++
 gr-audio/lib/alsa/gr-audio-alsa.conf   |  11 +
 gr-audio/lib/alsa/gri_alsa.cc          | 175 +++++++++++
 gr-audio/lib/alsa/gri_alsa.h           |  44 +++
 gr-audio/lib/audio_alsa_sink.cc        | 548 ---------------------------------
 gr-audio/lib/audio_alsa_sink.h         | 104 -------
 gr-audio/lib/audio_alsa_source.cc      | 505 ------------------------------
 gr-audio/lib/audio_alsa_source.h       | 106 -------
 gr-audio/lib/gr-audio-alsa.conf        |  11 -
 gr-audio/lib/gri_alsa.cc               | 175 -----------
 gr-audio/lib/gri_alsa.h                |  44 ---
 15 files changed, 1503 insertions(+), 1501 deletions(-)
 create mode 100644 gr-audio/lib/alsa/audio_alsa_sink.cc
 create mode 100644 gr-audio/lib/alsa/audio_alsa_sink.h
 create mode 100644 gr-audio/lib/alsa/audio_alsa_source.cc
 create mode 100644 gr-audio/lib/alsa/audio_alsa_source.h
 create mode 100644 gr-audio/lib/alsa/gr-audio-alsa.conf
 create mode 100644 gr-audio/lib/alsa/gri_alsa.cc
 create mode 100644 gr-audio/lib/alsa/gri_alsa.h
 delete mode 100644 gr-audio/lib/audio_alsa_sink.cc
 delete mode 100644 gr-audio/lib/audio_alsa_sink.h
 delete mode 100644 gr-audio/lib/audio_alsa_source.cc
 delete mode 100644 gr-audio/lib/audio_alsa_source.h
 delete mode 100644 gr-audio/lib/gr-audio-alsa.conf
 delete mode 100644 gr-audio/lib/gri_alsa.cc
 delete mode 100644 gr-audio/lib/gri_alsa.h

(limited to 'gr-audio/lib')

diff --git a/gr-audio/lib/Makefile.am b/gr-audio/lib/Makefile.am
index 7d9e419a8b..995cfec885 100644
--- a/gr-audio/lib/Makefile.am
+++ b/gr-audio/lib/Makefile.am
@@ -47,20 +47,22 @@ dist_etc_DATA = gr-audio.conf
 ########################################################################
 if GR_AUDIO_ALSA_SUPPORT
 
-AM_CPPFLAGS += $(ALSA_CPPFLAGS)
+AM_CPPFLAGS += \
+	-I$(srcdir)/alsa \
+	$(ALSA_CPPFLAGS)
 
 libgnuradio_audio_la_LIBADD += $(ALSA_LIBS)
 
 libgnuradio_audio_la_SOURCES += \
-	gri_alsa.cc \
-	audio_alsa_source.cc \
-	audio_alsa_sink.cc
+	alsa/gri_alsa.cc \
+	alsa/audio_alsa_source.cc \
+	alsa/audio_alsa_sink.cc
 
 noinst_HEADERS += \
-	gri_alsa.h \
-	audio_alsa_source.h \
-	audio_alsa_sink.h
+	alsa/gri_alsa.h \
+	alsa/audio_alsa_source.h \
+	alsa/audio_alsa_sink.h
 
-dist_etc_DATA += gr-audio-alsa.conf
+dist_etc_DATA += alsa/gr-audio-alsa.conf
 
 endif
diff --git a/gr-audio/lib/alsa/audio_alsa_sink.cc b/gr-audio/lib/alsa/audio_alsa_sink.cc
new file mode 100644
index 0000000000..af5cc02be9
--- /dev/null
+++ b/gr-audio/lib/alsa/audio_alsa_sink.cc
@@ -0,0 +1,548 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2011 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gr_audio_registry.h"
+#include <audio_alsa_sink.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_alsa.h>
+
+AUDIO_REGISTER_SINK(alsa)(
+    int sampling_rate, const std::string &device_name, bool ok_to_block
+){
+    return audio_sink::sptr(new audio_alsa_sink(sampling_rate, device_name, ok_to_block));
+}
+
+static bool CHATTY_DEBUG = false;
+
+
+static snd_pcm_format_t acceptable_formats[] = {
+  // these are in our preferred order...
+  SND_PCM_FORMAT_S32,
+  SND_PCM_FORMAT_S16
+};
+
+#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_alsa", "default_output_device", "hw:0,0");
+}
+
+static double
+default_period_time ()
+{
+  return std::max(0.001, gr_prefs::singleton()->get_double("audio_alsa", "period_time", 0.010));
+}
+
+static int
+default_nperiods ()
+{
+  return std::max(2L, gr_prefs::singleton()->get_long("audio_alsa", "nperiods", 4));
+}
+
+// ----------------------------------------------------------------
+
+audio_alsa_sink::audio_alsa_sink (int sampling_rate,
+				  const std::string device_name,
+				  bool ok_to_block)
+  : audio_sink ("audio_alsa_sink",
+		   gr_make_io_signature (0, 0, 0),
+		   gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_pcm_handle (0),
+    d_hw_params ((snd_pcm_hw_params_t *)(new char[snd_pcm_hw_params_sizeof()])),
+    d_sw_params ((snd_pcm_sw_params_t *)(new char[snd_pcm_sw_params_sizeof()])),
+    d_nperiods (default_nperiods()),
+    d_period_time_us ((unsigned int) (default_period_time() * 1e6)),
+    d_period_size (0),
+    d_buffer_size_bytes (0), d_buffer (0),
+    d_worker (0), d_special_case_mono_to_stereo (false),
+    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block)
+{
+  CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
+
+  int  	error;
+  int	dir;
+
+  // open the device for playback
+  error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
+		       SND_PCM_STREAM_PLAYBACK, 0);
+  if (ok_to_block == false)
+    snd_pcm_nonblock(d_pcm_handle, !ok_to_block);
+  if (error < 0){
+    fprintf (stderr, "audio_alsa_sink[%s]: %s\n",
+	     d_device_name.c_str(), snd_strerror(error));
+    throw std::runtime_error ("audio_alsa_sink");
+  }
+
+  // Fill params with a full configuration space for a PCM.
+  error = snd_pcm_hw_params_any(d_pcm_handle, d_hw_params);
+  if (error < 0)
+    bail ("broken configuration for playback", error);
+
+
+  if (CHATTY_DEBUG)
+    gri_alsa_dump_hw_params (d_pcm_handle, d_hw_params, stdout);
+
+
+  // now that we know how many channels the h/w can handle, set input signature
+  unsigned int umin_chan, umax_chan;
+  snd_pcm_hw_params_get_channels_min (d_hw_params, &umin_chan);
+  snd_pcm_hw_params_get_channels_max (d_hw_params, &umax_chan);
+  int min_chan = std::min (umin_chan, 1000U);
+  int max_chan = std::min (umax_chan, 1000U);
+
+  // As a special case, if the hw's min_chan is two, we'll accept
+  // a single input and handle the duplication ourselves.
+
+  if (min_chan == 2){
+    min_chan = 1;
+    d_special_case_mono_to_stereo = true;
+  }
+  set_input_signature (gr_make_io_signature (min_chan, max_chan,
+					     sizeof (float)));
+  
+  // fill in portions of the d_hw_params that we know now...
+
+  // Specify the access methods we implement
+  // For now, we only handle RW_INTERLEAVED...
+  snd_pcm_access_mask_t *access_mask;
+  snd_pcm_access_mask_t **access_mask_ptr = &access_mask; // FIXME: workaround for compiler warning
+  snd_pcm_access_mask_alloca (access_mask_ptr);
+  snd_pcm_access_mask_none (access_mask);
+  snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_INTERLEAVED);
+  // snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED);
+
+  if ((error = snd_pcm_hw_params_set_access_mask (d_pcm_handle,
+						  d_hw_params, access_mask)) < 0)
+    bail ("failed to set access mask", error);
+
+
+  // set sample format
+  if (!gri_alsa_pick_acceptable_format (d_pcm_handle, d_hw_params,
+					acceptable_formats,
+					NELEMS (acceptable_formats),
+					&d_format,
+					"audio_alsa_sink",
+					CHATTY_DEBUG))
+    throw std::runtime_error ("audio_alsa_sink");
+  
+
+  // sampling rate
+  unsigned int orig_sampling_rate = d_sampling_rate;
+  if ((error = snd_pcm_hw_params_set_rate_near (d_pcm_handle, d_hw_params,
+						&d_sampling_rate, 0)) < 0)
+    bail ("failed to set rate near", error);
+  
+  if (orig_sampling_rate != d_sampling_rate){
+    fprintf (stderr, "audio_alsa_sink[%s]: unable to support sampling rate %d\n",
+	     snd_pcm_name (d_pcm_handle), orig_sampling_rate);
+    fprintf (stderr, "  card requested %d instead.\n", d_sampling_rate);
+  }
+
+  /*
+   * ALSA transfers data in units of "periods".
+   * We indirectly determine the underlying buffersize by specifying
+   * the number of periods we want (typically 4) and the length of each
+   * period in units of time (typically 1ms).
+   */
+  unsigned int min_nperiods, max_nperiods;
+  snd_pcm_hw_params_get_periods_min (d_hw_params, &min_nperiods, &dir);
+  snd_pcm_hw_params_get_periods_max (d_hw_params, &max_nperiods, &dir);
+  //fprintf (stderr, "alsa_sink: min_nperiods = %d, max_nperiods = %d\n",
+  // min_nperiods, max_nperiods);
+
+  unsigned int orig_nperiods = d_nperiods;
+  d_nperiods = std::min (std::max (min_nperiods, d_nperiods), max_nperiods);
+
+  // adjust period time so that total buffering remains more-or-less constant
+  d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods;
+
+  error = snd_pcm_hw_params_set_periods (d_pcm_handle, d_hw_params,
+					 d_nperiods, 0);
+  if (error < 0)
+    bail ("set_periods failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_set_period_time_near (d_pcm_handle, d_hw_params,
+						  &d_period_time_us, &dir);
+  if (error < 0)
+    bail ("set_period_time_near failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_get_period_size (d_hw_params,
+					     &d_period_size, &dir);
+  if (error < 0)
+    bail ("get_period_size failed", error);
+  
+  set_output_multiple (d_period_size);
+}
+
+
+bool
+audio_alsa_sink::check_topology (int ninputs, int noutputs)
+{
+  // ninputs is how many channels the user has connected.
+  // Now we can finish up setting up the hw params...
+
+  int nchan = ninputs;
+  int err;
+
+  // Check the state of the stream
+  // Ensure that the pcm is in a state where we can still mess with the hw_params
+  snd_pcm_state_t state;
+  state=snd_pcm_state(d_pcm_handle);
+  if ( state== SND_PCM_STATE_RUNNING)
+    return true;  // If stream is running, don't change any parameters
+  else if(state == SND_PCM_STATE_XRUN )
+    snd_pcm_prepare ( d_pcm_handle ); // Prepare stream on underrun, and we can set parameters;
+  
+  bool special_case = nchan == 1 && d_special_case_mono_to_stereo;
+  if (special_case)
+    nchan = 2;
+  
+  err = snd_pcm_hw_params_set_channels (d_pcm_handle, d_hw_params, nchan);
+
+  if (err < 0){
+    output_error_msg ("set_channels failed", err);
+    return false;
+  }
+
+  // set the parameters into the driver...
+  err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
+  if (err < 0){
+    output_error_msg ("snd_pcm_hw_params failed", err);
+    return false;
+  }
+
+  // get current s/w params
+  err = snd_pcm_sw_params_current (d_pcm_handle, d_sw_params);
+  if (err < 0)
+    bail ("snd_pcm_sw_params_current", err);
+  
+  // Tell the PCM device to wait to start until we've filled
+  // it's buffers half way full.  This helps avoid audio underruns.
+
+  err = snd_pcm_sw_params_set_start_threshold(d_pcm_handle,
+					      d_sw_params,
+					      d_nperiods * d_period_size / 2);
+  if (err < 0)
+    bail ("snd_pcm_sw_params_set_start_threshold", err);
+
+  // store the s/w params
+  err = snd_pcm_sw_params (d_pcm_handle, d_sw_params);
+  if (err < 0)
+    bail ("snd_pcm_sw_params", err);
+
+  d_buffer_size_bytes =
+    d_period_size * nchan * snd_pcm_format_size (d_format, 1);
+
+  d_buffer = new char [d_buffer_size_bytes];
+
+  if (CHATTY_DEBUG)
+    fprintf (stdout, "audio_alsa_sink[%s]: sample resolution = %d bits\n",
+	     snd_pcm_name (d_pcm_handle),
+	     snd_pcm_hw_params_get_sbits (d_hw_params));
+
+  switch (d_format){
+  case SND_PCM_FORMAT_S16:
+    if (special_case)
+      d_worker = &audio_alsa_sink::work_s16_1x2;
+    else
+      d_worker = &audio_alsa_sink::work_s16;
+    break;
+
+  case SND_PCM_FORMAT_S32:
+    if (special_case)
+      d_worker = &audio_alsa_sink::work_s32_1x2;
+    else
+      d_worker = &audio_alsa_sink::work_s32;
+    break;
+
+  default:
+    assert (0);
+  }
+  return true;
+}
+
+audio_alsa_sink::~audio_alsa_sink ()
+{
+  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
+    snd_pcm_drop (d_pcm_handle);
+
+  snd_pcm_close(d_pcm_handle);
+  delete [] ((char *) d_hw_params);
+  delete [] ((char *) d_sw_params);
+  delete [] d_buffer;
+}
+
+int
+audio_alsa_sink::work (int noutput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items)
+{
+  assert ((noutput_items % d_period_size) == 0);
+
+  // this is a call through a pointer to a method...
+  return (this->*d_worker)(noutput_items, input_items, output_items);
+}
+
+/*
+ * Work function that deals with float to S16 conversion
+ */
+int
+audio_alsa_sink::work_s16 (int noutput_items,
+			   gr_vector_const_void_star &input_items,
+			   gr_vector_void_star &output_items)
+{
+  typedef gr_int16	sample_t;	// the type of samples we're creating
+  static const int NBITS = 16;		// # of bits in a sample
+  
+  unsigned int nchan = input_items.size ();
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      for (unsigned int chan = 0; chan < nchan; chan++){
+	buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1));
+      }
+    }
+
+    // update src pointers
+    for (unsigned int chan = 0; chan < nchan; chan++)
+      in[chan] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;	// No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+
+/*
+ * Work function that deals with float to S32 conversion
+ */
+int
+audio_alsa_sink::work_s32 (int noutput_items,
+			   gr_vector_const_void_star &input_items,
+			   gr_vector_void_star &output_items)
+{
+  typedef gr_int32	sample_t;	// the type of samples we're creating
+  static const int NBITS = 32;		// # of bits in a sample
+  
+  unsigned int nchan = input_items.size ();
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      for (unsigned int chan = 0; chan < nchan; chan++){
+	buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1));
+      }
+    }
+
+    // update src pointers
+    for (unsigned int chan = 0; chan < nchan; chan++)
+      in[chan] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;	// No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+/*
+ * Work function that deals with float to S16 conversion and
+ * mono to stereo kludge.
+ */
+int
+audio_alsa_sink::work_s16_1x2 (int noutput_items,
+			       gr_vector_const_void_star &input_items,
+			       gr_vector_void_star &output_items)
+{
+  typedef gr_int16	sample_t;	// the type of samples we're creating
+  static const int NBITS = 16;		// # of bits in a sample
+  
+  assert (input_items.size () == 1);
+  static const unsigned int nchan = 2;
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1));
+      buf[bi++] = t;
+      buf[bi++] = t;
+    }
+
+    // update src pointers
+    in[0] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;	// No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+/*
+ * Work function that deals with float to S32 conversion and
+ * mono to stereo kludge.
+ */
+int
+audio_alsa_sink::work_s32_1x2 (int noutput_items,
+			       gr_vector_const_void_star &input_items,
+			       gr_vector_void_star &output_items)
+{
+  typedef gr_int32	sample_t;	// the type of samples we're creating
+  static const int NBITS = 32;		// # of bits in a sample
+  
+  assert (input_items.size () == 1);
+  static unsigned int nchan = 2;
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1));
+      buf[bi++] = t;
+      buf[bi++] = t;
+    }
+
+    // update src pointers
+    in[0] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;	// No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+bool
+audio_alsa_sink::write_buffer (const void *vbuffer,
+			       unsigned nframes, unsigned sizeof_frame)
+{
+  const unsigned char *buffer = (const unsigned char *) vbuffer;
+
+  while (nframes > 0){
+    int r = snd_pcm_writei (d_pcm_handle, buffer, nframes);
+    if (r == -EAGAIN)
+    {
+      if (d_ok_to_block == true)
+	continue;		// try again
+      
+      break;
+    }
+
+    else if (r == -EPIPE){	// underrun
+      d_nunderuns++;
+      fputs ("aU", stderr);
+      if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){
+	output_error_msg ("snd_pcm_prepare failed. Can't recover from underrun", r);
+	return false;
+      }
+      continue;			// try again
+    }
+
+    else if (r == -ESTRPIPE){	// h/w is suspended (whatever that means)
+				// This is apparently related to power management
+      d_nsuspends++;
+      if ((r = snd_pcm_resume (d_pcm_handle)) < 0){
+	output_error_msg ("failed to resume from suspend", r);
+	return false;
+      }
+      continue;			// try again
+    }
+
+    else if (r < 0){
+      output_error_msg ("snd_pcm_writei failed", r);
+      return false;
+    }
+
+    nframes -= r;
+    buffer += r * sizeof_frame;
+  }
+
+  return true;
+}
+
+
+void
+audio_alsa_sink::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_alsa_sink[%s]: %s: %s\n",
+	   snd_pcm_name (d_pcm_handle), msg,  snd_strerror (err));
+}
+
+void
+audio_alsa_sink::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_alsa_sink");
+}
diff --git a/gr-audio/lib/alsa/audio_alsa_sink.h b/gr-audio/lib/alsa/audio_alsa_sink.h
new file mode 100644
index 0000000000..23e406d6b4
--- /dev/null
+++ b/gr-audio/lib/alsa/audio_alsa_sink.h
@@ -0,0 +1,104 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2011 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_AUDIO_ALSA_SINK_H
+#define INCLUDED_AUDIO_ALSA_SINK_H
+
+// use new ALSA API
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+
+#include <gr_audio_sink.h>
+#include <string>
+#include <alsa/asoundlib.h>
+#include <stdexcept>
+
+/*!
+ * \brief audio sink using ALSA
+ *
+ * The sink has N input streams of floats, where N depends
+ * on the hardware characteristics of the selected device.
+ *
+ * Input samples must be in the range [-1,1].
+ */
+class audio_alsa_sink : public audio_sink {
+  // typedef for pointer to class work method
+  typedef int (audio_alsa_sink::*work_t)(int noutput_items,
+					 gr_vector_const_void_star &input_items,
+					 gr_vector_void_star &output_items);
+
+  unsigned int		d_sampling_rate;
+  std::string		d_device_name;
+  snd_pcm_t            *d_pcm_handle;
+  snd_pcm_hw_params_t  *d_hw_params;
+  snd_pcm_sw_params_t  *d_sw_params;
+  snd_pcm_format_t	d_format;
+  unsigned int		d_nperiods;
+  unsigned int		d_period_time_us;	// microseconds
+  snd_pcm_uframes_t	d_period_size;		// in frames
+  unsigned int		d_buffer_size_bytes;	// sizeof of d_buffer
+  char		       *d_buffer;
+  work_t	        d_worker;		// the work method to use
+  bool			d_special_case_mono_to_stereo;
+
+  // random stats
+  int			d_nunderuns;		// count of underruns
+  int			d_nsuspends;		// count of suspends
+  bool			d_ok_to_block;      // defaults to "true", controls blocking/non-block I/O
+
+  void output_error_msg (const char *msg, int err);
+  void bail (const char *msg, int err) throw (std::runtime_error);
+
+public:
+  audio_alsa_sink (int sampling_rate, const std::string device_name,
+		   bool ok_to_block);
+
+  ~audio_alsa_sink ();
+  
+  bool check_topology (int ninputs, int noutputs);
+
+  int work (int noutput_items,
+	    gr_vector_const_void_star &input_items,
+	    gr_vector_void_star &output_items);
+
+
+protected:
+  bool write_buffer (const void *buffer, unsigned nframes, unsigned sizeof_frame);
+
+  int work_s16 (int noutput_items,
+		gr_vector_const_void_star &input_items,
+		gr_vector_void_star &output_items);
+
+  int work_s16_1x2 (int noutput_items,
+		    gr_vector_const_void_star &input_items,
+		    gr_vector_void_star &output_items);
+
+  int work_s32 (int noutput_items,
+		gr_vector_const_void_star &input_items,
+		gr_vector_void_star &output_items);
+
+  int work_s32_1x2 (int noutput_items,
+		    gr_vector_const_void_star &input_items,
+		    gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_AUDIO_ALSA_SINK_H */
diff --git a/gr-audio/lib/alsa/audio_alsa_source.cc b/gr-audio/lib/alsa/audio_alsa_source.cc
new file mode 100644
index 0000000000..a8667361e2
--- /dev/null
+++ b/gr-audio/lib/alsa/audio_alsa_source.cc
@@ -0,0 +1,505 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2011 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gr_audio_registry.h"
+#include <audio_alsa_source.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_alsa.h>
+
+AUDIO_REGISTER_SOURCE(alsa)(
+    int sampling_rate, const std::string &device_name, bool ok_to_block
+){
+    return audio_source::sptr(new audio_alsa_source(sampling_rate, device_name, ok_to_block));
+}
+
+static bool CHATTY_DEBUG = false;
+
+static snd_pcm_format_t acceptable_formats[] = {
+  // these are in our preferred order...
+  SND_PCM_FORMAT_S32,
+  SND_PCM_FORMAT_S16
+};
+
+#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_alsa", "default_input_device", "hw:0,0");
+}
+
+static double
+default_period_time ()
+{
+  return std::max(0.001, gr_prefs::singleton()->get_double("audio_alsa", "period_time", 0.010));
+}
+
+static int
+default_nperiods ()
+{
+  return std::max(2L, gr_prefs::singleton()->get_long("audio_alsa", "nperiods", 4));
+}
+
+// ----------------------------------------------------------------
+
+audio_alsa_source::audio_alsa_source (int sampling_rate,
+				      const std::string device_name,
+				      bool ok_to_block)
+  : audio_source ("audio_alsa_source",
+		   gr_make_io_signature (0, 0, 0),
+		   gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_pcm_handle (0),
+    d_hw_params ((snd_pcm_hw_params_t *)(new char[snd_pcm_hw_params_sizeof()])),
+    d_sw_params ((snd_pcm_sw_params_t *)(new char[snd_pcm_sw_params_sizeof()])),
+    d_nperiods (default_nperiods()),
+    d_period_time_us ((unsigned int) (default_period_time() * 1e6)),
+    d_period_size (0),
+    d_buffer_size_bytes (0), d_buffer (0),
+    d_worker (0), d_hw_nchan (0),
+    d_special_case_stereo_to_mono (false),
+    d_noverruns (0), d_nsuspends (0)
+{
+
+  CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
+
+  int  	error;
+  int	dir;
+
+  // open the device for capture
+  error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
+		       SND_PCM_STREAM_CAPTURE, 0);
+  if (error < 0){
+    fprintf (stderr, "audio_alsa_source[%s]: %s\n",
+	     d_device_name.c_str(), snd_strerror(error));
+    throw std::runtime_error ("audio_alsa_source");
+  }
+
+  // Fill params with a full configuration space for a PCM.
+  error = snd_pcm_hw_params_any(d_pcm_handle, d_hw_params);
+  if (error < 0)
+    bail ("broken configuration for playback", error);
+
+  if (CHATTY_DEBUG)
+    gri_alsa_dump_hw_params (d_pcm_handle, d_hw_params, stdout);
+
+  // now that we know how many channels the h/w can handle, set output signature
+  unsigned int umax_chan;
+  unsigned int umin_chan;
+  snd_pcm_hw_params_get_channels_min (d_hw_params, &umin_chan);
+  snd_pcm_hw_params_get_channels_max (d_hw_params, &umax_chan);
+  int min_chan = std::min (umin_chan, 1000U);
+  int max_chan = std::min (umax_chan, 1000U);
+
+  // As a special case, if the hw's min_chan is two, we'll accept
+  // a single output and handle the demux ourselves.
+
+  if (min_chan == 2){
+    min_chan = 1;
+    d_special_case_stereo_to_mono = true;
+  }
+  
+  set_output_signature (gr_make_io_signature (min_chan, max_chan,
+					      sizeof (float)));
+  
+  // fill in portions of the d_hw_params that we know now...
+
+  // Specify the access methods we implement
+  // For now, we only handle RW_INTERLEAVED...
+  snd_pcm_access_mask_t *access_mask;
+  snd_pcm_access_mask_t **access_mask_ptr = &access_mask; // FIXME: workaround for compiler warning
+  snd_pcm_access_mask_alloca (access_mask_ptr);
+  snd_pcm_access_mask_none (access_mask);
+  snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_INTERLEAVED);
+  // snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED);
+
+  if ((error = snd_pcm_hw_params_set_access_mask (d_pcm_handle,
+						  d_hw_params, access_mask)) < 0)
+    bail ("failed to set access mask", error);
+
+
+  // set sample format
+  if (!gri_alsa_pick_acceptable_format (d_pcm_handle, d_hw_params,
+					acceptable_formats,
+					NELEMS (acceptable_formats),
+					&d_format,
+					"audio_alsa_source",
+					CHATTY_DEBUG))
+    throw std::runtime_error ("audio_alsa_source");
+  
+
+  // sampling rate
+  unsigned int orig_sampling_rate = d_sampling_rate;
+  if ((error = snd_pcm_hw_params_set_rate_near (d_pcm_handle, d_hw_params,
+						&d_sampling_rate, 0)) < 0)
+    bail ("failed to set rate near", error);
+  
+  if (orig_sampling_rate != d_sampling_rate){
+    fprintf (stderr, "audio_alsa_source[%s]: unable to support sampling rate %d\n",
+	     snd_pcm_name (d_pcm_handle), orig_sampling_rate);
+    fprintf (stderr, "  card requested %d instead.\n", d_sampling_rate);
+  }
+
+  /*
+   * ALSA transfers data in units of "periods".
+   * We indirectly determine the underlying buffersize by specifying
+   * the number of periods we want (typically 4) and the length of each
+   * period in units of time (typically 1ms).
+   */
+  unsigned int min_nperiods, max_nperiods;
+  snd_pcm_hw_params_get_periods_min (d_hw_params, &min_nperiods, &dir);
+  snd_pcm_hw_params_get_periods_max (d_hw_params, &max_nperiods, &dir);
+  //fprintf (stderr, "alsa_source: min_nperiods = %d, max_nperiods = %d\n",
+  // min_nperiods, max_nperiods);
+
+
+  unsigned int orig_nperiods = d_nperiods;
+  d_nperiods = std::min (std::max (min_nperiods, d_nperiods), max_nperiods);
+
+  // adjust period time so that total buffering remains more-or-less constant
+  d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods;
+
+  error = snd_pcm_hw_params_set_periods (d_pcm_handle, d_hw_params,
+					 d_nperiods, 0);
+  if (error < 0)
+    bail ("set_periods failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_set_period_time_near (d_pcm_handle, d_hw_params,
+						  &d_period_time_us, &dir);
+  if (error < 0)
+    bail ("set_period_time_near failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_get_period_size (d_hw_params,
+					     &d_period_size, &dir);
+  if (error < 0)
+    bail ("get_period_size failed", error);
+  
+  set_output_multiple (d_period_size);
+}
+
+bool
+audio_alsa_source::check_topology (int ninputs, int noutputs)
+{
+  // noutputs is how many channels the user has connected.
+  // Now we can finish up setting up the hw params...
+
+  unsigned int nchan = noutputs;
+  int err;
+
+  // FIXME check_topology may be called more than once.
+  // Ensure that the pcm is in a state where we can still mess with the hw_params
+
+  bool special_case = nchan == 1 && d_special_case_stereo_to_mono;
+  if (special_case)
+    nchan = 2;
+
+  d_hw_nchan = nchan;
+  err = snd_pcm_hw_params_set_channels (d_pcm_handle, d_hw_params, d_hw_nchan);
+  if (err < 0){
+    output_error_msg ("set_channels failed", err);
+    return false;
+  }
+
+  // set the parameters into the driver...
+  err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
+  if (err < 0){
+    output_error_msg ("snd_pcm_hw_params failed", err);
+    return false;
+  }
+
+  d_buffer_size_bytes =
+    d_period_size * d_hw_nchan * snd_pcm_format_size (d_format, 1);
+
+  d_buffer = new char [d_buffer_size_bytes];
+
+  if (CHATTY_DEBUG)
+    fprintf (stdout, "audio_alsa_source[%s]: sample resolution = %d bits\n",
+	     snd_pcm_name (d_pcm_handle),
+	     snd_pcm_hw_params_get_sbits (d_hw_params));
+
+  switch (d_format){
+  case SND_PCM_FORMAT_S16:
+    if (special_case)
+      d_worker = &audio_alsa_source::work_s16_2x1;
+    else
+      d_worker = &audio_alsa_source::work_s16;
+    break;
+
+  case SND_PCM_FORMAT_S32:
+    if (special_case)
+      d_worker = &audio_alsa_source::work_s32_2x1;
+    else
+      d_worker = &audio_alsa_source::work_s32;
+    break;
+
+  default:
+    assert (0);
+  }
+
+  return true;
+}
+
+audio_alsa_source::~audio_alsa_source ()
+{
+  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
+    snd_pcm_drop (d_pcm_handle);
+
+  snd_pcm_close(d_pcm_handle);
+  delete [] ((char *) d_hw_params);
+  delete [] ((char *) d_sw_params);
+  delete [] d_buffer;
+}
+
+int
+audio_alsa_source::work (int noutput_items,
+			 gr_vector_const_void_star &input_items,
+			 gr_vector_void_star &output_items)
+{
+  assert ((noutput_items % d_period_size) == 0);
+  assert (noutput_items != 0);
+
+  // this is a call through a pointer to a method...
+  return (this->*d_worker)(noutput_items, input_items, output_items);
+}
+
+/*
+ * Work function that deals with float to S16 conversion
+ */
+int
+audio_alsa_source::work_s16 (int noutput_items,
+			     gr_vector_const_void_star &input_items,
+			     gr_vector_void_star &output_items)
+{
+  typedef gr_int16	sample_t;	// the type of samples we're creating
+  static const int NBITS = 16;		// # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;		// No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    for (unsigned int chan = 0; chan < nchan; chan++){
+      out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+    }
+  }
+
+  return d_period_size;
+}
+
+/*
+ * Work function that deals with float to S16 conversion
+ * and stereo to mono kludge...
+ */
+int
+audio_alsa_source::work_s16_2x1 (int noutput_items,
+				 gr_vector_const_void_star &input_items,
+				 gr_vector_void_star &output_items)
+{
+  typedef gr_int16	sample_t;	// the type of samples we're creating
+  static const int NBITS = 16;		// # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  assert (nchan == 1);
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;		// No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    int t = (buf[bi] + buf[bi+1]) / 2;
+    bi += 2;
+    out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+  }
+
+  return d_period_size;
+}
+
+/*
+ * Work function that deals with float to S32 conversion
+ */
+int
+audio_alsa_source::work_s32 (int noutput_items,
+			     gr_vector_const_void_star &input_items,
+			     gr_vector_void_star &output_items)
+{
+  typedef gr_int32	sample_t;	// the type of samples we're creating
+  static const int NBITS = 32;		// # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;		// No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    for (unsigned int chan = 0; chan < nchan; chan++){
+      out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+    }
+  }
+
+  return d_period_size;
+}
+
+/*
+ * Work function that deals with float to S32 conversion
+ * and stereo to mono kludge...
+ */
+int
+audio_alsa_source::work_s32_2x1 (int noutput_items,
+				 gr_vector_const_void_star &input_items,
+				 gr_vector_void_star &output_items)
+{
+  typedef gr_int32	sample_t;	// the type of samples we're creating
+  static const int NBITS = 32;		// # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  assert (nchan == 1);
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;		// No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    int t = (buf[bi] + buf[bi+1]) / 2;
+    bi += 2;
+    out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+  }
+
+  return d_period_size;
+}
+
+bool
+audio_alsa_source::read_buffer (void *vbuffer, unsigned nframes, unsigned sizeof_frame)
+{
+  unsigned char *buffer = (unsigned char *) vbuffer;
+
+  while (nframes > 0){
+    int r = snd_pcm_readi (d_pcm_handle, buffer, nframes);
+    if (r == -EAGAIN)
+      continue;			// try again
+
+    else if (r == -EPIPE){	// overrun
+      d_noverruns++;
+      fputs ("aO", stderr);
+      if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){
+	output_error_msg ("snd_pcm_prepare failed. Can't recover from overrun", r);
+	return false;
+      }
+      continue;			// try again
+    }
+
+    else if (r == -ESTRPIPE){	// h/w is suspended (whatever that means)
+				// This is apparently related to power management
+      d_nsuspends++;
+      if ((r = snd_pcm_resume (d_pcm_handle)) < 0){
+	output_error_msg ("failed to resume from suspend", r);
+	return false;
+      }
+      continue;			// try again
+    }
+
+    else if (r < 0){
+      output_error_msg ("snd_pcm_readi failed", r);
+      return false;
+    }
+
+    nframes -= r;
+    buffer += r * sizeof_frame;
+  }
+
+  return true;
+}
+
+
+void
+audio_alsa_source::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_alsa_source[%s]: %s: %s\n",
+	   snd_pcm_name (d_pcm_handle), msg,  snd_strerror (err));
+}
+
+void
+audio_alsa_source::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_alsa_source");
+}
diff --git a/gr-audio/lib/alsa/audio_alsa_source.h b/gr-audio/lib/alsa/audio_alsa_source.h
new file mode 100644
index 0000000000..e38af38724
--- /dev/null
+++ b/gr-audio/lib/alsa/audio_alsa_source.h
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2011 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_AUDIO_ALSA_SOURCE_H
+#define INCLUDED_AUDIO_ALSA_SOURCE_H
+
+// use new ALSA API
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+
+#include <gr_audio_source.h>
+#include <string>
+#include <alsa/asoundlib.h>
+#include <stdexcept>
+
+class audio_alsa_source;
+typedef boost::shared_ptr<audio_alsa_source> audio_alsa_source_sptr;
+
+/*!
+ * \brief audio source using ALSA
+ *
+ * The source has between 1 and N input streams of floats, where N is
+ * depends on the hardware characteristics of the selected device.
+ *
+ * Output samples will be in the range [-1,1].
+ */
+class audio_alsa_source : public audio_source {
+  // typedef for pointer to class work method
+  typedef int (audio_alsa_source::*work_t)(int noutput_items,
+					   gr_vector_const_void_star &input_items,
+					   gr_vector_void_star &output_items);
+
+  unsigned int		d_sampling_rate;
+  std::string		d_device_name;
+  snd_pcm_t            *d_pcm_handle;
+  snd_pcm_hw_params_t  *d_hw_params;
+  snd_pcm_sw_params_t  *d_sw_params;
+  snd_pcm_format_t	d_format;
+  unsigned int		d_nperiods;
+  unsigned int		d_period_time_us;	// microseconds
+  snd_pcm_uframes_t	d_period_size;		// in frames
+  unsigned int		d_buffer_size_bytes;	// sizeof of d_buffer
+  char		       *d_buffer;
+  work_t	        d_worker;		// the work method to use
+  unsigned int		d_hw_nchan;		// # of configured h/w channels
+  bool			d_special_case_stereo_to_mono;
+
+  // random stats
+  int			d_noverruns;		// count of overruns
+  int			d_nsuspends;		// count of suspends
+
+  void output_error_msg (const char *msg, int err);
+  void bail (const char *msg, int err) throw (std::runtime_error);
+
+public:
+  audio_alsa_source (int sampling_rate, const std::string device_name,
+		     bool ok_to_block);
+
+  ~audio_alsa_source ();
+  
+  bool check_topology (int ninputs, int noutputs);
+
+  int work (int noutput_items,
+	    gr_vector_const_void_star &input_items,
+	    gr_vector_void_star &output_items);
+
+protected:
+  bool read_buffer (void *buffer, unsigned nframes, unsigned sizeof_frame);
+
+  int work_s16 (int noutput_items,
+		gr_vector_const_void_star &input_items,
+		gr_vector_void_star &output_items);
+
+  int work_s16_2x1 (int noutput_items,
+		    gr_vector_const_void_star &input_items,
+		    gr_vector_void_star &output_items);
+
+  int work_s32 (int noutput_items,
+		gr_vector_const_void_star &input_items,
+		gr_vector_void_star &output_items);
+
+  int work_s32_2x1 (int noutput_items,
+		    gr_vector_const_void_star &input_items,
+		    gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_AUDIO_ALSA_SOURCE_H */
diff --git a/gr-audio/lib/alsa/gr-audio-alsa.conf b/gr-audio/lib/alsa/gr-audio-alsa.conf
new file mode 100644
index 0000000000..5cec63e7ab
--- /dev/null
+++ b/gr-audio/lib/alsa/gr-audio-alsa.conf
@@ -0,0 +1,11 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[audio_alsa]
+
+default_input_device = hw:0,0
+default_output_device = hw:0,0
+period_time = 0.010                      # in seconds
+nperiods = 4				 # total buffering = period_time * nperiods
+verbose = false
diff --git a/gr-audio/lib/alsa/gri_alsa.cc b/gr-audio/lib/alsa/gri_alsa.cc
new file mode 100644
index 0000000000..d9fda0f7d4
--- /dev/null
+++ b/gr-audio/lib/alsa/gri_alsa.cc
@@ -0,0 +1,175 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_alsa.h>
+#include <algorithm>
+
+static snd_pcm_access_t access_types[] = {
+  SND_PCM_ACCESS_MMAP_INTERLEAVED,
+  SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
+  SND_PCM_ACCESS_MMAP_COMPLEX,
+  SND_PCM_ACCESS_RW_INTERLEAVED,
+  SND_PCM_ACCESS_RW_NONINTERLEAVED
+};
+
+static snd_pcm_format_t format_types[] = {
+  // SND_PCM_FORMAT_UNKNOWN,
+  SND_PCM_FORMAT_S8,
+  SND_PCM_FORMAT_U8,
+  SND_PCM_FORMAT_S16_LE,
+  SND_PCM_FORMAT_S16_BE,
+  SND_PCM_FORMAT_U16_LE,
+  SND_PCM_FORMAT_U16_BE,
+  SND_PCM_FORMAT_S24_LE,
+  SND_PCM_FORMAT_S24_BE,
+  SND_PCM_FORMAT_U24_LE,
+  SND_PCM_FORMAT_U24_BE,
+  SND_PCM_FORMAT_S32_LE,
+  SND_PCM_FORMAT_S32_BE,
+  SND_PCM_FORMAT_U32_LE,
+  SND_PCM_FORMAT_U32_BE,
+  SND_PCM_FORMAT_FLOAT_LE,
+  SND_PCM_FORMAT_FLOAT_BE,
+  SND_PCM_FORMAT_FLOAT64_LE,
+  SND_PCM_FORMAT_FLOAT64_BE,
+  SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+  SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+  SND_PCM_FORMAT_MU_LAW,
+  SND_PCM_FORMAT_A_LAW,
+  SND_PCM_FORMAT_IMA_ADPCM,
+  SND_PCM_FORMAT_MPEG,
+  SND_PCM_FORMAT_GSM,
+  SND_PCM_FORMAT_SPECIAL,
+  SND_PCM_FORMAT_S24_3LE,
+  SND_PCM_FORMAT_S24_3BE,
+  SND_PCM_FORMAT_U24_3LE,
+  SND_PCM_FORMAT_U24_3BE,
+  SND_PCM_FORMAT_S20_3LE,
+  SND_PCM_FORMAT_S20_3BE,
+  SND_PCM_FORMAT_U20_3LE,
+  SND_PCM_FORMAT_U20_3BE,
+  SND_PCM_FORMAT_S18_3LE,
+  SND_PCM_FORMAT_S18_3BE,
+  SND_PCM_FORMAT_U18_3LE,
+  SND_PCM_FORMAT_U18_3BE
+};
+
+static unsigned int test_rates[] = {
+  8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000
+};
+
+#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+void
+gri_alsa_dump_hw_params (snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, FILE *fp)
+{
+  fprintf (fp, "PCM name: %s\n", snd_pcm_name (pcm));
+  
+  fprintf (fp, "Access types:\n");
+  for (unsigned i = 0; i < NELEMS (access_types); i++){
+    snd_pcm_access_t	at = access_types[i];
+    fprintf (fp, "    %-20s %s\n",
+	     snd_pcm_access_name (at),
+	     snd_pcm_hw_params_test_access (pcm, hwparams, at) == 0 ? "YES" : "NO");
+  }
+
+  fprintf (fp, "Formats:\n");
+  for (unsigned i = 0; i < NELEMS (format_types); i++){
+    snd_pcm_format_t	ft = format_types[i];
+    if (0)
+      fprintf (fp, "    %-20s %s\n",
+	       snd_pcm_format_name (ft),
+	       snd_pcm_hw_params_test_format (pcm, hwparams, ft) == 0 ? "YES" : "NO");
+    else {
+      if (snd_pcm_hw_params_test_format (pcm, hwparams, ft) == 0)
+	fprintf (fp, "    %-20s YES\n", snd_pcm_format_name (ft));
+    }
+  }
+
+  fprintf (fp, "Number of channels\n");
+  unsigned int min_chan, max_chan;
+  snd_pcm_hw_params_get_channels_min (hwparams, &min_chan);
+  snd_pcm_hw_params_get_channels_max (hwparams, &max_chan);
+  fprintf (fp, "    min channels: %d\n", min_chan);
+  fprintf (fp, "    max channels: %d\n", max_chan);
+  unsigned int chan;
+  max_chan = std::min (max_chan, 16U);	// truncate display...
+  for (chan = min_chan; chan <= max_chan; chan++){
+    fprintf (fp, "    %d channels\t%s\n", chan,
+	     snd_pcm_hw_params_test_channels (pcm, hwparams, chan) == 0 ? "YES" : "NO");
+  }
+
+  fprintf (fp, "Sample Rates:\n");
+  unsigned int min_rate, max_rate;
+  int	min_dir, max_dir;
+
+  snd_pcm_hw_params_get_rate_min (hwparams, &min_rate, &min_dir);
+  snd_pcm_hw_params_get_rate_max (hwparams, &max_rate, &max_dir);
+  fprintf (fp, "    min rate: %7d (dir = %d)\n", min_rate, min_dir);
+  fprintf (fp, "    max rate: %7d (dir = %d)\n", max_rate, max_dir);
+  for (unsigned i = 0; i < NELEMS (test_rates); i++){
+    unsigned int rate = test_rates[i];
+    fprintf (fp, "    %6u  %s\n", rate,
+	     snd_pcm_hw_params_test_rate (pcm, hwparams, rate, 0) == 0 ? "YES" : "NO");
+  }
+
+  fflush (fp);
+}
+
+bool
+gri_alsa_pick_acceptable_format (snd_pcm_t *pcm,
+				 snd_pcm_hw_params_t *hwparams,
+				 snd_pcm_format_t acceptable_formats[],
+				 unsigned nacceptable_formats,
+				 snd_pcm_format_t *selected_format,
+				 const char *error_msg_tag,
+				 bool verbose)
+{
+  int err;
+
+  // pick a format that we like...
+  for (unsigned i = 0; i < nacceptable_formats; i++){
+    if (snd_pcm_hw_params_test_format (pcm, hwparams,
+				       acceptable_formats[i]) == 0){
+      err = snd_pcm_hw_params_set_format (pcm, hwparams, acceptable_formats[i]);
+      if (err < 0){
+	fprintf (stderr, "%s[%s]: failed to set format: %s\n",
+		 error_msg_tag, snd_pcm_name (pcm), snd_strerror (err));
+	return false;
+      }
+      if (verbose)
+	fprintf (stdout, "%s[%s]: using %s\n",
+		 error_msg_tag, snd_pcm_name (pcm),
+		 snd_pcm_format_name (acceptable_formats[i]));
+      *selected_format = acceptable_formats[i];
+      return true;
+    }
+  }
+  
+  fprintf (stderr, "%s[%s]: failed to find acceptable format",
+	   error_msg_tag, snd_pcm_name (pcm));
+  return false;
+}
diff --git a/gr-audio/lib/alsa/gri_alsa.h b/gr-audio/lib/alsa/gri_alsa.h
new file mode 100644
index 0000000000..3d72fd950e
--- /dev/null
+++ b/gr-audio/lib/alsa/gri_alsa.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_ALSA_H
+#define INCLUDED_GRI_ALSA_H
+
+#include <stdio.h>
+#include <alsa/asoundlib.h>
+
+void 
+gri_alsa_dump_hw_params (snd_pcm_t *pcm,
+			 snd_pcm_hw_params_t *hwparams,
+			 FILE *fp);
+
+bool
+gri_alsa_pick_acceptable_format (snd_pcm_t *pcm,
+				 snd_pcm_hw_params_t *hwparams,
+				 snd_pcm_format_t acceptable_formats[],
+				 unsigned nacceptable_formats,
+				 snd_pcm_format_t *selected_format,
+				 const char *error_msg_tag,
+				 bool verbose);
+
+
+#endif /* INCLUDED_GRI_ALSA_H */
diff --git a/gr-audio/lib/audio_alsa_sink.cc b/gr-audio/lib/audio_alsa_sink.cc
deleted file mode 100644
index af5cc02be9..0000000000
--- a/gr-audio/lib/audio_alsa_sink.cc
+++ /dev/null
@@ -1,548 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004-2011 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gr_audio_registry.h"
-#include <audio_alsa_sink.h>
-#include <gr_io_signature.h>
-#include <gr_prefs.h>
-#include <stdio.h>
-#include <iostream>
-#include <stdexcept>
-#include <gri_alsa.h>
-
-AUDIO_REGISTER_SINK(alsa)(
-    int sampling_rate, const std::string &device_name, bool ok_to_block
-){
-    return audio_sink::sptr(new audio_alsa_sink(sampling_rate, device_name, ok_to_block));
-}
-
-static bool CHATTY_DEBUG = false;
-
-
-static snd_pcm_format_t acceptable_formats[] = {
-  // these are in our preferred order...
-  SND_PCM_FORMAT_S32,
-  SND_PCM_FORMAT_S16
-};
-
-#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
-
-
-static std::string 
-default_device_name ()
-{
-  return gr_prefs::singleton()->get_string("audio_alsa", "default_output_device", "hw:0,0");
-}
-
-static double
-default_period_time ()
-{
-  return std::max(0.001, gr_prefs::singleton()->get_double("audio_alsa", "period_time", 0.010));
-}
-
-static int
-default_nperiods ()
-{
-  return std::max(2L, gr_prefs::singleton()->get_long("audio_alsa", "nperiods", 4));
-}
-
-// ----------------------------------------------------------------
-
-audio_alsa_sink::audio_alsa_sink (int sampling_rate,
-				  const std::string device_name,
-				  bool ok_to_block)
-  : audio_sink ("audio_alsa_sink",
-		   gr_make_io_signature (0, 0, 0),
-		   gr_make_io_signature (0, 0, 0)),
-    d_sampling_rate (sampling_rate),
-    d_device_name (device_name.empty() ? default_device_name() : device_name),
-    d_pcm_handle (0),
-    d_hw_params ((snd_pcm_hw_params_t *)(new char[snd_pcm_hw_params_sizeof()])),
-    d_sw_params ((snd_pcm_sw_params_t *)(new char[snd_pcm_sw_params_sizeof()])),
-    d_nperiods (default_nperiods()),
-    d_period_time_us ((unsigned int) (default_period_time() * 1e6)),
-    d_period_size (0),
-    d_buffer_size_bytes (0), d_buffer (0),
-    d_worker (0), d_special_case_mono_to_stereo (false),
-    d_nunderuns (0), d_nsuspends (0), d_ok_to_block(ok_to_block)
-{
-  CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
-
-  int  	error;
-  int	dir;
-
-  // open the device for playback
-  error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
-		       SND_PCM_STREAM_PLAYBACK, 0);
-  if (ok_to_block == false)
-    snd_pcm_nonblock(d_pcm_handle, !ok_to_block);
-  if (error < 0){
-    fprintf (stderr, "audio_alsa_sink[%s]: %s\n",
-	     d_device_name.c_str(), snd_strerror(error));
-    throw std::runtime_error ("audio_alsa_sink");
-  }
-
-  // Fill params with a full configuration space for a PCM.
-  error = snd_pcm_hw_params_any(d_pcm_handle, d_hw_params);
-  if (error < 0)
-    bail ("broken configuration for playback", error);
-
-
-  if (CHATTY_DEBUG)
-    gri_alsa_dump_hw_params (d_pcm_handle, d_hw_params, stdout);
-
-
-  // now that we know how many channels the h/w can handle, set input signature
-  unsigned int umin_chan, umax_chan;
-  snd_pcm_hw_params_get_channels_min (d_hw_params, &umin_chan);
-  snd_pcm_hw_params_get_channels_max (d_hw_params, &umax_chan);
-  int min_chan = std::min (umin_chan, 1000U);
-  int max_chan = std::min (umax_chan, 1000U);
-
-  // As a special case, if the hw's min_chan is two, we'll accept
-  // a single input and handle the duplication ourselves.
-
-  if (min_chan == 2){
-    min_chan = 1;
-    d_special_case_mono_to_stereo = true;
-  }
-  set_input_signature (gr_make_io_signature (min_chan, max_chan,
-					     sizeof (float)));
-  
-  // fill in portions of the d_hw_params that we know now...
-
-  // Specify the access methods we implement
-  // For now, we only handle RW_INTERLEAVED...
-  snd_pcm_access_mask_t *access_mask;
-  snd_pcm_access_mask_t **access_mask_ptr = &access_mask; // FIXME: workaround for compiler warning
-  snd_pcm_access_mask_alloca (access_mask_ptr);
-  snd_pcm_access_mask_none (access_mask);
-  snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_INTERLEAVED);
-  // snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED);
-
-  if ((error = snd_pcm_hw_params_set_access_mask (d_pcm_handle,
-						  d_hw_params, access_mask)) < 0)
-    bail ("failed to set access mask", error);
-
-
-  // set sample format
-  if (!gri_alsa_pick_acceptable_format (d_pcm_handle, d_hw_params,
-					acceptable_formats,
-					NELEMS (acceptable_formats),
-					&d_format,
-					"audio_alsa_sink",
-					CHATTY_DEBUG))
-    throw std::runtime_error ("audio_alsa_sink");
-  
-
-  // sampling rate
-  unsigned int orig_sampling_rate = d_sampling_rate;
-  if ((error = snd_pcm_hw_params_set_rate_near (d_pcm_handle, d_hw_params,
-						&d_sampling_rate, 0)) < 0)
-    bail ("failed to set rate near", error);
-  
-  if (orig_sampling_rate != d_sampling_rate){
-    fprintf (stderr, "audio_alsa_sink[%s]: unable to support sampling rate %d\n",
-	     snd_pcm_name (d_pcm_handle), orig_sampling_rate);
-    fprintf (stderr, "  card requested %d instead.\n", d_sampling_rate);
-  }
-
-  /*
-   * ALSA transfers data in units of "periods".
-   * We indirectly determine the underlying buffersize by specifying
-   * the number of periods we want (typically 4) and the length of each
-   * period in units of time (typically 1ms).
-   */
-  unsigned int min_nperiods, max_nperiods;
-  snd_pcm_hw_params_get_periods_min (d_hw_params, &min_nperiods, &dir);
-  snd_pcm_hw_params_get_periods_max (d_hw_params, &max_nperiods, &dir);
-  //fprintf (stderr, "alsa_sink: min_nperiods = %d, max_nperiods = %d\n",
-  // min_nperiods, max_nperiods);
-
-  unsigned int orig_nperiods = d_nperiods;
-  d_nperiods = std::min (std::max (min_nperiods, d_nperiods), max_nperiods);
-
-  // adjust period time so that total buffering remains more-or-less constant
-  d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods;
-
-  error = snd_pcm_hw_params_set_periods (d_pcm_handle, d_hw_params,
-					 d_nperiods, 0);
-  if (error < 0)
-    bail ("set_periods failed", error);
-
-  dir = 0;
-  error = snd_pcm_hw_params_set_period_time_near (d_pcm_handle, d_hw_params,
-						  &d_period_time_us, &dir);
-  if (error < 0)
-    bail ("set_period_time_near failed", error);
-
-  dir = 0;
-  error = snd_pcm_hw_params_get_period_size (d_hw_params,
-					     &d_period_size, &dir);
-  if (error < 0)
-    bail ("get_period_size failed", error);
-  
-  set_output_multiple (d_period_size);
-}
-
-
-bool
-audio_alsa_sink::check_topology (int ninputs, int noutputs)
-{
-  // ninputs is how many channels the user has connected.
-  // Now we can finish up setting up the hw params...
-
-  int nchan = ninputs;
-  int err;
-
-  // Check the state of the stream
-  // Ensure that the pcm is in a state where we can still mess with the hw_params
-  snd_pcm_state_t state;
-  state=snd_pcm_state(d_pcm_handle);
-  if ( state== SND_PCM_STATE_RUNNING)
-    return true;  // If stream is running, don't change any parameters
-  else if(state == SND_PCM_STATE_XRUN )
-    snd_pcm_prepare ( d_pcm_handle ); // Prepare stream on underrun, and we can set parameters;
-  
-  bool special_case = nchan == 1 && d_special_case_mono_to_stereo;
-  if (special_case)
-    nchan = 2;
-  
-  err = snd_pcm_hw_params_set_channels (d_pcm_handle, d_hw_params, nchan);
-
-  if (err < 0){
-    output_error_msg ("set_channels failed", err);
-    return false;
-  }
-
-  // set the parameters into the driver...
-  err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
-  if (err < 0){
-    output_error_msg ("snd_pcm_hw_params failed", err);
-    return false;
-  }
-
-  // get current s/w params
-  err = snd_pcm_sw_params_current (d_pcm_handle, d_sw_params);
-  if (err < 0)
-    bail ("snd_pcm_sw_params_current", err);
-  
-  // Tell the PCM device to wait to start until we've filled
-  // it's buffers half way full.  This helps avoid audio underruns.
-
-  err = snd_pcm_sw_params_set_start_threshold(d_pcm_handle,
-					      d_sw_params,
-					      d_nperiods * d_period_size / 2);
-  if (err < 0)
-    bail ("snd_pcm_sw_params_set_start_threshold", err);
-
-  // store the s/w params
-  err = snd_pcm_sw_params (d_pcm_handle, d_sw_params);
-  if (err < 0)
-    bail ("snd_pcm_sw_params", err);
-
-  d_buffer_size_bytes =
-    d_period_size * nchan * snd_pcm_format_size (d_format, 1);
-
-  d_buffer = new char [d_buffer_size_bytes];
-
-  if (CHATTY_DEBUG)
-    fprintf (stdout, "audio_alsa_sink[%s]: sample resolution = %d bits\n",
-	     snd_pcm_name (d_pcm_handle),
-	     snd_pcm_hw_params_get_sbits (d_hw_params));
-
-  switch (d_format){
-  case SND_PCM_FORMAT_S16:
-    if (special_case)
-      d_worker = &audio_alsa_sink::work_s16_1x2;
-    else
-      d_worker = &audio_alsa_sink::work_s16;
-    break;
-
-  case SND_PCM_FORMAT_S32:
-    if (special_case)
-      d_worker = &audio_alsa_sink::work_s32_1x2;
-    else
-      d_worker = &audio_alsa_sink::work_s32;
-    break;
-
-  default:
-    assert (0);
-  }
-  return true;
-}
-
-audio_alsa_sink::~audio_alsa_sink ()
-{
-  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
-    snd_pcm_drop (d_pcm_handle);
-
-  snd_pcm_close(d_pcm_handle);
-  delete [] ((char *) d_hw_params);
-  delete [] ((char *) d_sw_params);
-  delete [] d_buffer;
-}
-
-int
-audio_alsa_sink::work (int noutput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items)
-{
-  assert ((noutput_items % d_period_size) == 0);
-
-  // this is a call through a pointer to a method...
-  return (this->*d_worker)(noutput_items, input_items, output_items);
-}
-
-/*
- * Work function that deals with float to S16 conversion
- */
-int
-audio_alsa_sink::work_s16 (int noutput_items,
-			   gr_vector_const_void_star &input_items,
-			   gr_vector_void_star &output_items)
-{
-  typedef gr_int16	sample_t;	// the type of samples we're creating
-  static const int NBITS = 16;		// # of bits in a sample
-  
-  unsigned int nchan = input_items.size ();
-  const float **in = (const float **) &input_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-  int n;
-
-  unsigned int sizeof_frame = nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  for (n = 0; n < noutput_items; n += d_period_size){
-
-    // process one period of data
-    bi = 0;
-    for (unsigned int i = 0; i < d_period_size; i++){
-      for (unsigned int chan = 0; chan < nchan; chan++){
-	buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1));
-      }
-    }
-
-    // update src pointers
-    for (unsigned int chan = 0; chan < nchan; chan++)
-      in[chan] += d_period_size;
-
-    if (!write_buffer (buf, d_period_size, sizeof_frame))  
-      return -1;	// No fixing this problem.  Say we're done.
-  }
-
-  return n;
-}
-
-
-/*
- * Work function that deals with float to S32 conversion
- */
-int
-audio_alsa_sink::work_s32 (int noutput_items,
-			   gr_vector_const_void_star &input_items,
-			   gr_vector_void_star &output_items)
-{
-  typedef gr_int32	sample_t;	// the type of samples we're creating
-  static const int NBITS = 32;		// # of bits in a sample
-  
-  unsigned int nchan = input_items.size ();
-  const float **in = (const float **) &input_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-  int n;
-
-  unsigned int sizeof_frame = nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  for (n = 0; n < noutput_items; n += d_period_size){
-
-    // process one period of data
-    bi = 0;
-    for (unsigned int i = 0; i < d_period_size; i++){
-      for (unsigned int chan = 0; chan < nchan; chan++){
-	buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1));
-      }
-    }
-
-    // update src pointers
-    for (unsigned int chan = 0; chan < nchan; chan++)
-      in[chan] += d_period_size;
-
-    if (!write_buffer (buf, d_period_size, sizeof_frame))  
-      return -1;	// No fixing this problem.  Say we're done.
-  }
-
-  return n;
-}
-
-/*
- * Work function that deals with float to S16 conversion and
- * mono to stereo kludge.
- */
-int
-audio_alsa_sink::work_s16_1x2 (int noutput_items,
-			       gr_vector_const_void_star &input_items,
-			       gr_vector_void_star &output_items)
-{
-  typedef gr_int16	sample_t;	// the type of samples we're creating
-  static const int NBITS = 16;		// # of bits in a sample
-  
-  assert (input_items.size () == 1);
-  static const unsigned int nchan = 2;
-  const float **in = (const float **) &input_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-  int n;
-
-  unsigned int sizeof_frame = nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  for (n = 0; n < noutput_items; n += d_period_size){
-
-    // process one period of data
-    bi = 0;
-    for (unsigned int i = 0; i < d_period_size; i++){
-      sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1));
-      buf[bi++] = t;
-      buf[bi++] = t;
-    }
-
-    // update src pointers
-    in[0] += d_period_size;
-
-    if (!write_buffer (buf, d_period_size, sizeof_frame))  
-      return -1;	// No fixing this problem.  Say we're done.
-  }
-
-  return n;
-}
-
-/*
- * Work function that deals with float to S32 conversion and
- * mono to stereo kludge.
- */
-int
-audio_alsa_sink::work_s32_1x2 (int noutput_items,
-			       gr_vector_const_void_star &input_items,
-			       gr_vector_void_star &output_items)
-{
-  typedef gr_int32	sample_t;	// the type of samples we're creating
-  static const int NBITS = 32;		// # of bits in a sample
-  
-  assert (input_items.size () == 1);
-  static unsigned int nchan = 2;
-  const float **in = (const float **) &input_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-  int n;
-
-  unsigned int sizeof_frame = nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  for (n = 0; n < noutput_items; n += d_period_size){
-
-    // process one period of data
-    bi = 0;
-    for (unsigned int i = 0; i < d_period_size; i++){
-      sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1));
-      buf[bi++] = t;
-      buf[bi++] = t;
-    }
-
-    // update src pointers
-    in[0] += d_period_size;
-
-    if (!write_buffer (buf, d_period_size, sizeof_frame))  
-      return -1;	// No fixing this problem.  Say we're done.
-  }
-
-  return n;
-}
-
-bool
-audio_alsa_sink::write_buffer (const void *vbuffer,
-			       unsigned nframes, unsigned sizeof_frame)
-{
-  const unsigned char *buffer = (const unsigned char *) vbuffer;
-
-  while (nframes > 0){
-    int r = snd_pcm_writei (d_pcm_handle, buffer, nframes);
-    if (r == -EAGAIN)
-    {
-      if (d_ok_to_block == true)
-	continue;		// try again
-      
-      break;
-    }
-
-    else if (r == -EPIPE){	// underrun
-      d_nunderuns++;
-      fputs ("aU", stderr);
-      if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){
-	output_error_msg ("snd_pcm_prepare failed. Can't recover from underrun", r);
-	return false;
-      }
-      continue;			// try again
-    }
-
-    else if (r == -ESTRPIPE){	// h/w is suspended (whatever that means)
-				// This is apparently related to power management
-      d_nsuspends++;
-      if ((r = snd_pcm_resume (d_pcm_handle)) < 0){
-	output_error_msg ("failed to resume from suspend", r);
-	return false;
-      }
-      continue;			// try again
-    }
-
-    else if (r < 0){
-      output_error_msg ("snd_pcm_writei failed", r);
-      return false;
-    }
-
-    nframes -= r;
-    buffer += r * sizeof_frame;
-  }
-
-  return true;
-}
-
-
-void
-audio_alsa_sink::output_error_msg (const char *msg, int err)
-{
-  fprintf (stderr, "audio_alsa_sink[%s]: %s: %s\n",
-	   snd_pcm_name (d_pcm_handle), msg,  snd_strerror (err));
-}
-
-void
-audio_alsa_sink::bail (const char *msg, int err) throw (std::runtime_error)
-{
-  output_error_msg (msg, err);
-  throw std::runtime_error ("audio_alsa_sink");
-}
diff --git a/gr-audio/lib/audio_alsa_sink.h b/gr-audio/lib/audio_alsa_sink.h
deleted file mode 100644
index 23e406d6b4..0000000000
--- a/gr-audio/lib/audio_alsa_sink.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004-2011 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_AUDIO_ALSA_SINK_H
-#define INCLUDED_AUDIO_ALSA_SINK_H
-
-// use new ALSA API
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#define ALSA_PCM_NEW_SW_PARAMS_API
-
-#include <gr_audio_sink.h>
-#include <string>
-#include <alsa/asoundlib.h>
-#include <stdexcept>
-
-/*!
- * \brief audio sink using ALSA
- *
- * The sink has N input streams of floats, where N depends
- * on the hardware characteristics of the selected device.
- *
- * Input samples must be in the range [-1,1].
- */
-class audio_alsa_sink : public audio_sink {
-  // typedef for pointer to class work method
-  typedef int (audio_alsa_sink::*work_t)(int noutput_items,
-					 gr_vector_const_void_star &input_items,
-					 gr_vector_void_star &output_items);
-
-  unsigned int		d_sampling_rate;
-  std::string		d_device_name;
-  snd_pcm_t            *d_pcm_handle;
-  snd_pcm_hw_params_t  *d_hw_params;
-  snd_pcm_sw_params_t  *d_sw_params;
-  snd_pcm_format_t	d_format;
-  unsigned int		d_nperiods;
-  unsigned int		d_period_time_us;	// microseconds
-  snd_pcm_uframes_t	d_period_size;		// in frames
-  unsigned int		d_buffer_size_bytes;	// sizeof of d_buffer
-  char		       *d_buffer;
-  work_t	        d_worker;		// the work method to use
-  bool			d_special_case_mono_to_stereo;
-
-  // random stats
-  int			d_nunderuns;		// count of underruns
-  int			d_nsuspends;		// count of suspends
-  bool			d_ok_to_block;      // defaults to "true", controls blocking/non-block I/O
-
-  void output_error_msg (const char *msg, int err);
-  void bail (const char *msg, int err) throw (std::runtime_error);
-
-public:
-  audio_alsa_sink (int sampling_rate, const std::string device_name,
-		   bool ok_to_block);
-
-  ~audio_alsa_sink ();
-  
-  bool check_topology (int ninputs, int noutputs);
-
-  int work (int noutput_items,
-	    gr_vector_const_void_star &input_items,
-	    gr_vector_void_star &output_items);
-
-
-protected:
-  bool write_buffer (const void *buffer, unsigned nframes, unsigned sizeof_frame);
-
-  int work_s16 (int noutput_items,
-		gr_vector_const_void_star &input_items,
-		gr_vector_void_star &output_items);
-
-  int work_s16_1x2 (int noutput_items,
-		    gr_vector_const_void_star &input_items,
-		    gr_vector_void_star &output_items);
-
-  int work_s32 (int noutput_items,
-		gr_vector_const_void_star &input_items,
-		gr_vector_void_star &output_items);
-
-  int work_s32_1x2 (int noutput_items,
-		    gr_vector_const_void_star &input_items,
-		    gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_AUDIO_ALSA_SINK_H */
diff --git a/gr-audio/lib/audio_alsa_source.cc b/gr-audio/lib/audio_alsa_source.cc
deleted file mode 100644
index a8667361e2..0000000000
--- a/gr-audio/lib/audio_alsa_source.cc
+++ /dev/null
@@ -1,505 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004-2011 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gr_audio_registry.h"
-#include <audio_alsa_source.h>
-#include <gr_io_signature.h>
-#include <gr_prefs.h>
-#include <stdio.h>
-#include <iostream>
-#include <stdexcept>
-#include <gri_alsa.h>
-
-AUDIO_REGISTER_SOURCE(alsa)(
-    int sampling_rate, const std::string &device_name, bool ok_to_block
-){
-    return audio_source::sptr(new audio_alsa_source(sampling_rate, device_name, ok_to_block));
-}
-
-static bool CHATTY_DEBUG = false;
-
-static snd_pcm_format_t acceptable_formats[] = {
-  // these are in our preferred order...
-  SND_PCM_FORMAT_S32,
-  SND_PCM_FORMAT_S16
-};
-
-#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
-
-
-static std::string 
-default_device_name ()
-{
-  return gr_prefs::singleton()->get_string("audio_alsa", "default_input_device", "hw:0,0");
-}
-
-static double
-default_period_time ()
-{
-  return std::max(0.001, gr_prefs::singleton()->get_double("audio_alsa", "period_time", 0.010));
-}
-
-static int
-default_nperiods ()
-{
-  return std::max(2L, gr_prefs::singleton()->get_long("audio_alsa", "nperiods", 4));
-}
-
-// ----------------------------------------------------------------
-
-audio_alsa_source::audio_alsa_source (int sampling_rate,
-				      const std::string device_name,
-				      bool ok_to_block)
-  : audio_source ("audio_alsa_source",
-		   gr_make_io_signature (0, 0, 0),
-		   gr_make_io_signature (0, 0, 0)),
-    d_sampling_rate (sampling_rate),
-    d_device_name (device_name.empty() ? default_device_name() : device_name),
-    d_pcm_handle (0),
-    d_hw_params ((snd_pcm_hw_params_t *)(new char[snd_pcm_hw_params_sizeof()])),
-    d_sw_params ((snd_pcm_sw_params_t *)(new char[snd_pcm_sw_params_sizeof()])),
-    d_nperiods (default_nperiods()),
-    d_period_time_us ((unsigned int) (default_period_time() * 1e6)),
-    d_period_size (0),
-    d_buffer_size_bytes (0), d_buffer (0),
-    d_worker (0), d_hw_nchan (0),
-    d_special_case_stereo_to_mono (false),
-    d_noverruns (0), d_nsuspends (0)
-{
-
-  CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
-
-  int  	error;
-  int	dir;
-
-  // open the device for capture
-  error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
-		       SND_PCM_STREAM_CAPTURE, 0);
-  if (error < 0){
-    fprintf (stderr, "audio_alsa_source[%s]: %s\n",
-	     d_device_name.c_str(), snd_strerror(error));
-    throw std::runtime_error ("audio_alsa_source");
-  }
-
-  // Fill params with a full configuration space for a PCM.
-  error = snd_pcm_hw_params_any(d_pcm_handle, d_hw_params);
-  if (error < 0)
-    bail ("broken configuration for playback", error);
-
-  if (CHATTY_DEBUG)
-    gri_alsa_dump_hw_params (d_pcm_handle, d_hw_params, stdout);
-
-  // now that we know how many channels the h/w can handle, set output signature
-  unsigned int umax_chan;
-  unsigned int umin_chan;
-  snd_pcm_hw_params_get_channels_min (d_hw_params, &umin_chan);
-  snd_pcm_hw_params_get_channels_max (d_hw_params, &umax_chan);
-  int min_chan = std::min (umin_chan, 1000U);
-  int max_chan = std::min (umax_chan, 1000U);
-
-  // As a special case, if the hw's min_chan is two, we'll accept
-  // a single output and handle the demux ourselves.
-
-  if (min_chan == 2){
-    min_chan = 1;
-    d_special_case_stereo_to_mono = true;
-  }
-  
-  set_output_signature (gr_make_io_signature (min_chan, max_chan,
-					      sizeof (float)));
-  
-  // fill in portions of the d_hw_params that we know now...
-
-  // Specify the access methods we implement
-  // For now, we only handle RW_INTERLEAVED...
-  snd_pcm_access_mask_t *access_mask;
-  snd_pcm_access_mask_t **access_mask_ptr = &access_mask; // FIXME: workaround for compiler warning
-  snd_pcm_access_mask_alloca (access_mask_ptr);
-  snd_pcm_access_mask_none (access_mask);
-  snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_INTERLEAVED);
-  // snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED);
-
-  if ((error = snd_pcm_hw_params_set_access_mask (d_pcm_handle,
-						  d_hw_params, access_mask)) < 0)
-    bail ("failed to set access mask", error);
-
-
-  // set sample format
-  if (!gri_alsa_pick_acceptable_format (d_pcm_handle, d_hw_params,
-					acceptable_formats,
-					NELEMS (acceptable_formats),
-					&d_format,
-					"audio_alsa_source",
-					CHATTY_DEBUG))
-    throw std::runtime_error ("audio_alsa_source");
-  
-
-  // sampling rate
-  unsigned int orig_sampling_rate = d_sampling_rate;
-  if ((error = snd_pcm_hw_params_set_rate_near (d_pcm_handle, d_hw_params,
-						&d_sampling_rate, 0)) < 0)
-    bail ("failed to set rate near", error);
-  
-  if (orig_sampling_rate != d_sampling_rate){
-    fprintf (stderr, "audio_alsa_source[%s]: unable to support sampling rate %d\n",
-	     snd_pcm_name (d_pcm_handle), orig_sampling_rate);
-    fprintf (stderr, "  card requested %d instead.\n", d_sampling_rate);
-  }
-
-  /*
-   * ALSA transfers data in units of "periods".
-   * We indirectly determine the underlying buffersize by specifying
-   * the number of periods we want (typically 4) and the length of each
-   * period in units of time (typically 1ms).
-   */
-  unsigned int min_nperiods, max_nperiods;
-  snd_pcm_hw_params_get_periods_min (d_hw_params, &min_nperiods, &dir);
-  snd_pcm_hw_params_get_periods_max (d_hw_params, &max_nperiods, &dir);
-  //fprintf (stderr, "alsa_source: min_nperiods = %d, max_nperiods = %d\n",
-  // min_nperiods, max_nperiods);
-
-
-  unsigned int orig_nperiods = d_nperiods;
-  d_nperiods = std::min (std::max (min_nperiods, d_nperiods), max_nperiods);
-
-  // adjust period time so that total buffering remains more-or-less constant
-  d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods;
-
-  error = snd_pcm_hw_params_set_periods (d_pcm_handle, d_hw_params,
-					 d_nperiods, 0);
-  if (error < 0)
-    bail ("set_periods failed", error);
-
-  dir = 0;
-  error = snd_pcm_hw_params_set_period_time_near (d_pcm_handle, d_hw_params,
-						  &d_period_time_us, &dir);
-  if (error < 0)
-    bail ("set_period_time_near failed", error);
-
-  dir = 0;
-  error = snd_pcm_hw_params_get_period_size (d_hw_params,
-					     &d_period_size, &dir);
-  if (error < 0)
-    bail ("get_period_size failed", error);
-  
-  set_output_multiple (d_period_size);
-}
-
-bool
-audio_alsa_source::check_topology (int ninputs, int noutputs)
-{
-  // noutputs is how many channels the user has connected.
-  // Now we can finish up setting up the hw params...
-
-  unsigned int nchan = noutputs;
-  int err;
-
-  // FIXME check_topology may be called more than once.
-  // Ensure that the pcm is in a state where we can still mess with the hw_params
-
-  bool special_case = nchan == 1 && d_special_case_stereo_to_mono;
-  if (special_case)
-    nchan = 2;
-
-  d_hw_nchan = nchan;
-  err = snd_pcm_hw_params_set_channels (d_pcm_handle, d_hw_params, d_hw_nchan);
-  if (err < 0){
-    output_error_msg ("set_channels failed", err);
-    return false;
-  }
-
-  // set the parameters into the driver...
-  err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
-  if (err < 0){
-    output_error_msg ("snd_pcm_hw_params failed", err);
-    return false;
-  }
-
-  d_buffer_size_bytes =
-    d_period_size * d_hw_nchan * snd_pcm_format_size (d_format, 1);
-
-  d_buffer = new char [d_buffer_size_bytes];
-
-  if (CHATTY_DEBUG)
-    fprintf (stdout, "audio_alsa_source[%s]: sample resolution = %d bits\n",
-	     snd_pcm_name (d_pcm_handle),
-	     snd_pcm_hw_params_get_sbits (d_hw_params));
-
-  switch (d_format){
-  case SND_PCM_FORMAT_S16:
-    if (special_case)
-      d_worker = &audio_alsa_source::work_s16_2x1;
-    else
-      d_worker = &audio_alsa_source::work_s16;
-    break;
-
-  case SND_PCM_FORMAT_S32:
-    if (special_case)
-      d_worker = &audio_alsa_source::work_s32_2x1;
-    else
-      d_worker = &audio_alsa_source::work_s32;
-    break;
-
-  default:
-    assert (0);
-  }
-
-  return true;
-}
-
-audio_alsa_source::~audio_alsa_source ()
-{
-  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
-    snd_pcm_drop (d_pcm_handle);
-
-  snd_pcm_close(d_pcm_handle);
-  delete [] ((char *) d_hw_params);
-  delete [] ((char *) d_sw_params);
-  delete [] d_buffer;
-}
-
-int
-audio_alsa_source::work (int noutput_items,
-			 gr_vector_const_void_star &input_items,
-			 gr_vector_void_star &output_items)
-{
-  assert ((noutput_items % d_period_size) == 0);
-  assert (noutput_items != 0);
-
-  // this is a call through a pointer to a method...
-  return (this->*d_worker)(noutput_items, input_items, output_items);
-}
-
-/*
- * Work function that deals with float to S16 conversion
- */
-int
-audio_alsa_source::work_s16 (int noutput_items,
-			     gr_vector_const_void_star &input_items,
-			     gr_vector_void_star &output_items)
-{
-  typedef gr_int16	sample_t;	// the type of samples we're creating
-  static const int NBITS = 16;		// # of bits in a sample
-  
-  unsigned int nchan = output_items.size ();
-  float **out = (float **) &output_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-
-  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  // To minimize latency, return at most a single period's worth of samples.
-  // [We could also read the first one in a blocking mode and subsequent
-  //  ones in non-blocking mode, but we'll leave that for later (or never).]
-  
-  if (!read_buffer (buf, d_period_size, sizeof_frame))
-    return -1;		// No fixing this problem.  Say we're done.
-
-  // process one period of data
-  bi = 0;
-  for (unsigned int i = 0; i < d_period_size; i++){
-    for (unsigned int chan = 0; chan < nchan; chan++){
-      out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1));
-    }
-  }
-
-  return d_period_size;
-}
-
-/*
- * Work function that deals with float to S16 conversion
- * and stereo to mono kludge...
- */
-int
-audio_alsa_source::work_s16_2x1 (int noutput_items,
-				 gr_vector_const_void_star &input_items,
-				 gr_vector_void_star &output_items)
-{
-  typedef gr_int16	sample_t;	// the type of samples we're creating
-  static const int NBITS = 16;		// # of bits in a sample
-  
-  unsigned int nchan = output_items.size ();
-  float **out = (float **) &output_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-
-  assert (nchan == 1);
-
-  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  // To minimize latency, return at most a single period's worth of samples.
-  // [We could also read the first one in a blocking mode and subsequent
-  //  ones in non-blocking mode, but we'll leave that for later (or never).]
-  
-  if (!read_buffer (buf, d_period_size, sizeof_frame))
-    return -1;		// No fixing this problem.  Say we're done.
-
-  // process one period of data
-  bi = 0;
-  for (unsigned int i = 0; i < d_period_size; i++){
-    int t = (buf[bi] + buf[bi+1]) / 2;
-    bi += 2;
-    out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1));
-  }
-
-  return d_period_size;
-}
-
-/*
- * Work function that deals with float to S32 conversion
- */
-int
-audio_alsa_source::work_s32 (int noutput_items,
-			     gr_vector_const_void_star &input_items,
-			     gr_vector_void_star &output_items)
-{
-  typedef gr_int32	sample_t;	// the type of samples we're creating
-  static const int NBITS = 32;		// # of bits in a sample
-  
-  unsigned int nchan = output_items.size ();
-  float **out = (float **) &output_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-
-  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  // To minimize latency, return at most a single period's worth of samples.
-  // [We could also read the first one in a blocking mode and subsequent
-  //  ones in non-blocking mode, but we'll leave that for later (or never).]
-  
-  if (!read_buffer (buf, d_period_size, sizeof_frame))
-    return -1;		// No fixing this problem.  Say we're done.
-
-  // process one period of data
-  bi = 0;
-  for (unsigned int i = 0; i < d_period_size; i++){
-    for (unsigned int chan = 0; chan < nchan; chan++){
-      out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1));
-    }
-  }
-
-  return d_period_size;
-}
-
-/*
- * Work function that deals with float to S32 conversion
- * and stereo to mono kludge...
- */
-int
-audio_alsa_source::work_s32_2x1 (int noutput_items,
-				 gr_vector_const_void_star &input_items,
-				 gr_vector_void_star &output_items)
-{
-  typedef gr_int32	sample_t;	// the type of samples we're creating
-  static const int NBITS = 32;		// # of bits in a sample
-  
-  unsigned int nchan = output_items.size ();
-  float **out = (float **) &output_items[0];
-  sample_t *buf = (sample_t *) d_buffer;
-  int bi;
-
-  assert (nchan == 1);
-
-  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
-  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
-
-  // To minimize latency, return at most a single period's worth of samples.
-  // [We could also read the first one in a blocking mode and subsequent
-  //  ones in non-blocking mode, but we'll leave that for later (or never).]
-  
-  if (!read_buffer (buf, d_period_size, sizeof_frame))
-    return -1;		// No fixing this problem.  Say we're done.
-
-  // process one period of data
-  bi = 0;
-  for (unsigned int i = 0; i < d_period_size; i++){
-    int t = (buf[bi] + buf[bi+1]) / 2;
-    bi += 2;
-    out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1));
-  }
-
-  return d_period_size;
-}
-
-bool
-audio_alsa_source::read_buffer (void *vbuffer, unsigned nframes, unsigned sizeof_frame)
-{
-  unsigned char *buffer = (unsigned char *) vbuffer;
-
-  while (nframes > 0){
-    int r = snd_pcm_readi (d_pcm_handle, buffer, nframes);
-    if (r == -EAGAIN)
-      continue;			// try again
-
-    else if (r == -EPIPE){	// overrun
-      d_noverruns++;
-      fputs ("aO", stderr);
-      if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){
-	output_error_msg ("snd_pcm_prepare failed. Can't recover from overrun", r);
-	return false;
-      }
-      continue;			// try again
-    }
-
-    else if (r == -ESTRPIPE){	// h/w is suspended (whatever that means)
-				// This is apparently related to power management
-      d_nsuspends++;
-      if ((r = snd_pcm_resume (d_pcm_handle)) < 0){
-	output_error_msg ("failed to resume from suspend", r);
-	return false;
-      }
-      continue;			// try again
-    }
-
-    else if (r < 0){
-      output_error_msg ("snd_pcm_readi failed", r);
-      return false;
-    }
-
-    nframes -= r;
-    buffer += r * sizeof_frame;
-  }
-
-  return true;
-}
-
-
-void
-audio_alsa_source::output_error_msg (const char *msg, int err)
-{
-  fprintf (stderr, "audio_alsa_source[%s]: %s: %s\n",
-	   snd_pcm_name (d_pcm_handle), msg,  snd_strerror (err));
-}
-
-void
-audio_alsa_source::bail (const char *msg, int err) throw (std::runtime_error)
-{
-  output_error_msg (msg, err);
-  throw std::runtime_error ("audio_alsa_source");
-}
diff --git a/gr-audio/lib/audio_alsa_source.h b/gr-audio/lib/audio_alsa_source.h
deleted file mode 100644
index e38af38724..0000000000
--- a/gr-audio/lib/audio_alsa_source.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004-2011 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_AUDIO_ALSA_SOURCE_H
-#define INCLUDED_AUDIO_ALSA_SOURCE_H
-
-// use new ALSA API
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#define ALSA_PCM_NEW_SW_PARAMS_API
-
-#include <gr_audio_source.h>
-#include <string>
-#include <alsa/asoundlib.h>
-#include <stdexcept>
-
-class audio_alsa_source;
-typedef boost::shared_ptr<audio_alsa_source> audio_alsa_source_sptr;
-
-/*!
- * \brief audio source using ALSA
- *
- * The source has between 1 and N input streams of floats, where N is
- * depends on the hardware characteristics of the selected device.
- *
- * Output samples will be in the range [-1,1].
- */
-class audio_alsa_source : public audio_source {
-  // typedef for pointer to class work method
-  typedef int (audio_alsa_source::*work_t)(int noutput_items,
-					   gr_vector_const_void_star &input_items,
-					   gr_vector_void_star &output_items);
-
-  unsigned int		d_sampling_rate;
-  std::string		d_device_name;
-  snd_pcm_t            *d_pcm_handle;
-  snd_pcm_hw_params_t  *d_hw_params;
-  snd_pcm_sw_params_t  *d_sw_params;
-  snd_pcm_format_t	d_format;
-  unsigned int		d_nperiods;
-  unsigned int		d_period_time_us;	// microseconds
-  snd_pcm_uframes_t	d_period_size;		// in frames
-  unsigned int		d_buffer_size_bytes;	// sizeof of d_buffer
-  char		       *d_buffer;
-  work_t	        d_worker;		// the work method to use
-  unsigned int		d_hw_nchan;		// # of configured h/w channels
-  bool			d_special_case_stereo_to_mono;
-
-  // random stats
-  int			d_noverruns;		// count of overruns
-  int			d_nsuspends;		// count of suspends
-
-  void output_error_msg (const char *msg, int err);
-  void bail (const char *msg, int err) throw (std::runtime_error);
-
-public:
-  audio_alsa_source (int sampling_rate, const std::string device_name,
-		     bool ok_to_block);
-
-  ~audio_alsa_source ();
-  
-  bool check_topology (int ninputs, int noutputs);
-
-  int work (int noutput_items,
-	    gr_vector_const_void_star &input_items,
-	    gr_vector_void_star &output_items);
-
-protected:
-  bool read_buffer (void *buffer, unsigned nframes, unsigned sizeof_frame);
-
-  int work_s16 (int noutput_items,
-		gr_vector_const_void_star &input_items,
-		gr_vector_void_star &output_items);
-
-  int work_s16_2x1 (int noutput_items,
-		    gr_vector_const_void_star &input_items,
-		    gr_vector_void_star &output_items);
-
-  int work_s32 (int noutput_items,
-		gr_vector_const_void_star &input_items,
-		gr_vector_void_star &output_items);
-
-  int work_s32_2x1 (int noutput_items,
-		    gr_vector_const_void_star &input_items,
-		    gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_AUDIO_ALSA_SOURCE_H */
diff --git a/gr-audio/lib/gr-audio-alsa.conf b/gr-audio/lib/gr-audio-alsa.conf
deleted file mode 100644
index 5cec63e7ab..0000000000
--- a/gr-audio/lib/gr-audio-alsa.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file contains system wide configuration data for GNU Radio.
-# You may override any setting on a per-user basis by editing
-# ~/.gnuradio/config.conf
-
-[audio_alsa]
-
-default_input_device = hw:0,0
-default_output_device = hw:0,0
-period_time = 0.010                      # in seconds
-nperiods = 4				 # total buffering = period_time * nperiods
-verbose = false
diff --git a/gr-audio/lib/gri_alsa.cc b/gr-audio/lib/gri_alsa.cc
deleted file mode 100644
index d9fda0f7d4..0000000000
--- a/gr-audio/lib/gri_alsa.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gri_alsa.h>
-#include <algorithm>
-
-static snd_pcm_access_t access_types[] = {
-  SND_PCM_ACCESS_MMAP_INTERLEAVED,
-  SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
-  SND_PCM_ACCESS_MMAP_COMPLEX,
-  SND_PCM_ACCESS_RW_INTERLEAVED,
-  SND_PCM_ACCESS_RW_NONINTERLEAVED
-};
-
-static snd_pcm_format_t format_types[] = {
-  // SND_PCM_FORMAT_UNKNOWN,
-  SND_PCM_FORMAT_S8,
-  SND_PCM_FORMAT_U8,
-  SND_PCM_FORMAT_S16_LE,
-  SND_PCM_FORMAT_S16_BE,
-  SND_PCM_FORMAT_U16_LE,
-  SND_PCM_FORMAT_U16_BE,
-  SND_PCM_FORMAT_S24_LE,
-  SND_PCM_FORMAT_S24_BE,
-  SND_PCM_FORMAT_U24_LE,
-  SND_PCM_FORMAT_U24_BE,
-  SND_PCM_FORMAT_S32_LE,
-  SND_PCM_FORMAT_S32_BE,
-  SND_PCM_FORMAT_U32_LE,
-  SND_PCM_FORMAT_U32_BE,
-  SND_PCM_FORMAT_FLOAT_LE,
-  SND_PCM_FORMAT_FLOAT_BE,
-  SND_PCM_FORMAT_FLOAT64_LE,
-  SND_PCM_FORMAT_FLOAT64_BE,
-  SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
-  SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
-  SND_PCM_FORMAT_MU_LAW,
-  SND_PCM_FORMAT_A_LAW,
-  SND_PCM_FORMAT_IMA_ADPCM,
-  SND_PCM_FORMAT_MPEG,
-  SND_PCM_FORMAT_GSM,
-  SND_PCM_FORMAT_SPECIAL,
-  SND_PCM_FORMAT_S24_3LE,
-  SND_PCM_FORMAT_S24_3BE,
-  SND_PCM_FORMAT_U24_3LE,
-  SND_PCM_FORMAT_U24_3BE,
-  SND_PCM_FORMAT_S20_3LE,
-  SND_PCM_FORMAT_S20_3BE,
-  SND_PCM_FORMAT_U20_3LE,
-  SND_PCM_FORMAT_U20_3BE,
-  SND_PCM_FORMAT_S18_3LE,
-  SND_PCM_FORMAT_S18_3BE,
-  SND_PCM_FORMAT_U18_3LE,
-  SND_PCM_FORMAT_U18_3BE
-};
-
-static unsigned int test_rates[] = {
-  8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000
-};
-
-#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
-
-void
-gri_alsa_dump_hw_params (snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, FILE *fp)
-{
-  fprintf (fp, "PCM name: %s\n", snd_pcm_name (pcm));
-  
-  fprintf (fp, "Access types:\n");
-  for (unsigned i = 0; i < NELEMS (access_types); i++){
-    snd_pcm_access_t	at = access_types[i];
-    fprintf (fp, "    %-20s %s\n",
-	     snd_pcm_access_name (at),
-	     snd_pcm_hw_params_test_access (pcm, hwparams, at) == 0 ? "YES" : "NO");
-  }
-
-  fprintf (fp, "Formats:\n");
-  for (unsigned i = 0; i < NELEMS (format_types); i++){
-    snd_pcm_format_t	ft = format_types[i];
-    if (0)
-      fprintf (fp, "    %-20s %s\n",
-	       snd_pcm_format_name (ft),
-	       snd_pcm_hw_params_test_format (pcm, hwparams, ft) == 0 ? "YES" : "NO");
-    else {
-      if (snd_pcm_hw_params_test_format (pcm, hwparams, ft) == 0)
-	fprintf (fp, "    %-20s YES\n", snd_pcm_format_name (ft));
-    }
-  }
-
-  fprintf (fp, "Number of channels\n");
-  unsigned int min_chan, max_chan;
-  snd_pcm_hw_params_get_channels_min (hwparams, &min_chan);
-  snd_pcm_hw_params_get_channels_max (hwparams, &max_chan);
-  fprintf (fp, "    min channels: %d\n", min_chan);
-  fprintf (fp, "    max channels: %d\n", max_chan);
-  unsigned int chan;
-  max_chan = std::min (max_chan, 16U);	// truncate display...
-  for (chan = min_chan; chan <= max_chan; chan++){
-    fprintf (fp, "    %d channels\t%s\n", chan,
-	     snd_pcm_hw_params_test_channels (pcm, hwparams, chan) == 0 ? "YES" : "NO");
-  }
-
-  fprintf (fp, "Sample Rates:\n");
-  unsigned int min_rate, max_rate;
-  int	min_dir, max_dir;
-
-  snd_pcm_hw_params_get_rate_min (hwparams, &min_rate, &min_dir);
-  snd_pcm_hw_params_get_rate_max (hwparams, &max_rate, &max_dir);
-  fprintf (fp, "    min rate: %7d (dir = %d)\n", min_rate, min_dir);
-  fprintf (fp, "    max rate: %7d (dir = %d)\n", max_rate, max_dir);
-  for (unsigned i = 0; i < NELEMS (test_rates); i++){
-    unsigned int rate = test_rates[i];
-    fprintf (fp, "    %6u  %s\n", rate,
-	     snd_pcm_hw_params_test_rate (pcm, hwparams, rate, 0) == 0 ? "YES" : "NO");
-  }
-
-  fflush (fp);
-}
-
-bool
-gri_alsa_pick_acceptable_format (snd_pcm_t *pcm,
-				 snd_pcm_hw_params_t *hwparams,
-				 snd_pcm_format_t acceptable_formats[],
-				 unsigned nacceptable_formats,
-				 snd_pcm_format_t *selected_format,
-				 const char *error_msg_tag,
-				 bool verbose)
-{
-  int err;
-
-  // pick a format that we like...
-  for (unsigned i = 0; i < nacceptable_formats; i++){
-    if (snd_pcm_hw_params_test_format (pcm, hwparams,
-				       acceptable_formats[i]) == 0){
-      err = snd_pcm_hw_params_set_format (pcm, hwparams, acceptable_formats[i]);
-      if (err < 0){
-	fprintf (stderr, "%s[%s]: failed to set format: %s\n",
-		 error_msg_tag, snd_pcm_name (pcm), snd_strerror (err));
-	return false;
-      }
-      if (verbose)
-	fprintf (stdout, "%s[%s]: using %s\n",
-		 error_msg_tag, snd_pcm_name (pcm),
-		 snd_pcm_format_name (acceptable_formats[i]));
-      *selected_format = acceptable_formats[i];
-      return true;
-    }
-  }
-  
-  fprintf (stderr, "%s[%s]: failed to find acceptable format",
-	   error_msg_tag, snd_pcm_name (pcm));
-  return false;
-}
diff --git a/gr-audio/lib/gri_alsa.h b/gr-audio/lib/gri_alsa.h
deleted file mode 100644
index 3d72fd950e..0000000000
--- a/gr-audio/lib/gri_alsa.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GRI_ALSA_H
-#define INCLUDED_GRI_ALSA_H
-
-#include <stdio.h>
-#include <alsa/asoundlib.h>
-
-void 
-gri_alsa_dump_hw_params (snd_pcm_t *pcm,
-			 snd_pcm_hw_params_t *hwparams,
-			 FILE *fp);
-
-bool
-gri_alsa_pick_acceptable_format (snd_pcm_t *pcm,
-				 snd_pcm_hw_params_t *hwparams,
-				 snd_pcm_format_t acceptable_formats[],
-				 unsigned nacceptable_formats,
-				 snd_pcm_format_t *selected_format,
-				 const char *error_msg_tag,
-				 bool verbose);
-
-
-#endif /* INCLUDED_GRI_ALSA_H */
-- 
cgit v1.2.3