ext/alsa/: Port to 0.9.
authorAndy Wingo <wingo@pobox.com>
Fri, 19 Aug 2005 16:13:54 +0000 (16:13 +0000)
committerAndy Wingo <wingo@pobox.com>
Fri, 19 Aug 2005 16:13:54 +0000 (16:13 +0000)
Original commit message from CVS:
2005-08-19  Andy Wingo  <wingo@pobox.com>

* ext/alsa/gstalsamixertrack.h:
* ext/alsa/gstalsamixertrack.c:
* ext/alsa/gstalsamixeroptions.h:
* ext/alsa/gstalsamixeroptions.c:
* ext/alsa/gstalsamixer.h:
* ext/alsa/gstalsamixer.c: Port to 0.9.

* ext/alsa/Makefile.am: Build mixer, mixeroptions, mixertracks.
Remove gstalsa.c and alsaclock. No more cruft here.

ChangeLog
ext/alsa/Makefile.am
ext/alsa/gstalsa.c [deleted file]
ext/alsa/gstalsa.h
ext/alsa/gstalsaclock.c [deleted file]
ext/alsa/gstalsaclock.h [deleted file]
ext/alsa/gstalsamixer.c
ext/alsa/gstalsamixer.h
ext/alsa/gstalsamixeroptions.h
ext/alsa/gstalsamixertrack.h
ext/alsa/gstalsaplugin.c

index 293cbcc..dfcb5dd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2005-08-19  Andy Wingo  <wingo@pobox.com>
+
+       * ext/alsa/gstalsamixertrack.h:
+       * ext/alsa/gstalsamixertrack.c:
+       * ext/alsa/gstalsamixeroptions.h:
+       * ext/alsa/gstalsamixeroptions.c:
+       * ext/alsa/gstalsamixer.h:
+       * ext/alsa/gstalsamixer.c: Port to 0.9.
+
+       * ext/alsa/Makefile.am: Build mixer, mixeroptions, mixertracks.
+       Remove gstalsa.c and alsaclock. No more cruft here.
+       
 2005-08-18  Wim Taymans  <wim@fluendo.com>
 
        * gst-libs/gst/rtp/gstbasertpdepayload.c:
index 050828c..d0f533a 100644 (file)
@@ -2,16 +2,11 @@ plugin_LTLIBRARIES = libgstalsa.la
 
 libgstalsa_la_SOURCES = \
        gstalsaplugin.c \
-       gstalsasink.c   \
-       gstalsasrc.c
-
-# port alsa stuff then add the _SOURCES above
-EXTRA_DIST = \
-       gstalsamixer.c \
+       gstalsamixer.c  \
        gstalsamixertrack.c \
        gstalsamixeroptions.c \
-       gstalsa.c \
-       gstalsaclock.c 
+       gstalsasink.c   \
+       gstalsasrc.c
 
 libgstalsa_la_CFLAGS = $(GST_CFLAGS) $(ALSA_CFLAGS)
 libgstalsa_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
@@ -22,7 +17,6 @@ libgstalsa_la_LIBADD = \
 
 noinst_HEADERS = \
        gstalsa.h \
-       gstalsaclock.h \
        gstalsasink.h \
        gstalsasrc.h \
        gstalsamixer.h \
diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c
deleted file mode 100644 (file)
index 5d80de5..0000000
+++ /dev/null
@@ -1,2125 +0,0 @@
-/*
- * Copyright (C) 2001 CodeFactory AB
- * Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se>
- * Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu>
- * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/time.h>
-
-#include "gst/gst-i18n-plugin.h"
-#include <gst/audio/multichannel.h>
-#include "gst/propertyprobe/propertyprobe.h"
-#include "gstalsa.h"
-#include "gstalsaclock.h"
-#include "gstalsamixer.h"
-
-/* all this ifdef'ed stuff causes segfaults because of alsa bug 389, see
- * https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000389
- */
-#ifdef ALSA_BUG_389_FIXED
-#define ALSA_DEBUG_FLUSH(this) G_STMT_START{ \
-  gchar *__str; \
-  size_t __size; \
-  __size = snd_output_buffer_string (this->out, &__str); \
-  if (__size > 0) { \
-    GST_DEBUG_OBJECT (this, "%*s", __size, __str); \
-    if (snd_output_flush (this->out) != 0) \
-      GST_ERROR_OBJECT (this, "error flushing output buffer"); \
-  } \
-}G_STMT_END
-#endif
-
-/* GObject functions */
-static void gst_alsa_class_init (gpointer g_class, gpointer class_data);
-static void gst_alsa_init (GstAlsa * this);
-static void gst_alsa_dispose (GObject * object);
-static void gst_alsa_finalize (GObject * object);
-static void gst_alsa_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_alsa_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-
-/* interface */
-static void gst_alsa_probe_interface_init (GstPropertyProbeInterface * iface);
-
-/* GStreamer functions for pads and state changing */
-static GstPad *gst_alsa_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
-static GstElementStateReturn gst_alsa_change_state (GstElement * element);
-static GstClock *gst_alsa_get_clock (GstElement * element);
-static void gst_alsa_set_clock (GstElement * element, GstClock * clock);
-
-/* ALSA setup / start / stop functions */
-static gboolean gst_alsa_probe_hw_params (GstAlsa * this,
-    GstAlsaFormat * format);
-static gboolean gst_alsa_set_hw_params (GstAlsa * this);
-static gboolean gst_alsa_set_sw_params (GstAlsa * this);
-
-static gboolean gst_alsa_open_audio (GstAlsa * this);
-static gboolean gst_alsa_start_audio (GstAlsa * this);
-static gboolean gst_alsa_drain_audio (GstAlsa * this);
-static gboolean gst_alsa_stop_audio (GstAlsa * this);
-static gboolean gst_alsa_close_audio (GstAlsa * this);
-
-/* GStreamer querying, conversion, and format functions */
-static const GstFormat *gst_alsa_get_formats (GstPad * pad);
-static gboolean gst_alsa_convert (GstAlsa * this,
-    GstFormat src_format,
-    gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
-static gboolean gst_alsa_pad_convert (GstPad * pad,
-    GstFormat src_format,
-    gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
-static const GstQueryType *gst_alsa_get_query_types (GstPad * pad);
-static gboolean gst_alsa_query_func (GstElement * element,
-    GstQueryType type, GstFormat * format, gint64 * value);
-static gboolean gst_alsa_query (GstElement * element,
-    GstQueryType type, GstFormat * format, gint64 * value);
-static gboolean gst_alsa_pad_query (GstPad * pad,
-    GstQueryType type, GstFormat * format, gint64 * value);
-
-/* TYPE FUNCTIONS ***********************************************************/
-
-GType
-gst_alsa_get_type (void)
-{
-  static GType alsa_type = 0;
-
-  if (!alsa_type) {
-    static const GTypeInfo alsa_info = {
-      sizeof (GstAlsaClass),
-      NULL,
-      NULL,
-      gst_alsa_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAlsa),
-      0,
-      (GInstanceInitFunc) gst_alsa_init,
-    };
-    static const GInterfaceInfo alsa_probe_info = {
-      (GInterfaceInitFunc) gst_alsa_probe_interface_init,
-      NULL,
-      NULL
-    };
-
-    alsa_type =
-        g_type_register_static (GST_TYPE_ELEMENT, "GstAlsa", &alsa_info, 0);
-
-    g_type_add_interface_static (alsa_type,
-        GST_TYPE_PROPERTY_PROBE, &alsa_probe_info);
-  }
-
-  return alsa_type;
-}
-
-/* GOBJECT FUNCTIONS ********************************************************/
-
-enum
-{
-  ARG_0,
-  ARG_DEVICE,
-  ARG_DEVICE_NAME,
-  ARG_PERIODCOUNT,
-  ARG_PERIODSIZE,
-  ARG_BUFFERSIZE,
-  ARG_AUTORECOVER,
-  ARG_MMAP,
-  ARG_MAXDISCONT
-};
-
-static GstElement *parent_class = NULL;
-
-static void
-gst_alsa_class_init (gpointer g_class, gpointer class_data)
-{
-  GObjectClass *object_class;
-  GstElementClass *element_class;
-  GstAlsaClass *klass;
-
-  klass = (GstAlsaClass *) g_class;
-  object_class = (GObjectClass *) g_class;
-  element_class = (GstElementClass *) g_class;
-
-  if (parent_class == NULL)
-    parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
-  object_class->dispose = gst_alsa_dispose;
-  object_class->finalize = gst_alsa_finalize;
-  object_class->get_property = gst_alsa_get_property;
-  object_class->set_property = gst_alsa_set_property;
-
-  g_object_class_install_property (object_class, ARG_DEVICE,
-      g_param_spec_string ("device", "Device",
-          "ALSA device, as defined in an asoundrc",
-          "default", G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, ARG_DEVICE_NAME,
-      g_param_spec_string ("device_name", "Device name",
-          "Name of the device", NULL, G_PARAM_READABLE));
-  g_object_class_install_property (object_class, ARG_PERIODCOUNT,
-      g_param_spec_int ("period-count", "Period count",
-          "Number of hardware buffers to use",
-          GST_ALSA_MIN_PERIOD_CNT, GST_ALSA_MAX_PERIOD_CNT,
-          GST_ALSA_MIN_PERIOD_CNT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-  g_object_class_install_property (object_class, ARG_PERIODSIZE,
-      g_param_spec_int ("period-size", "Period size",
-          "Number of frames (samples on each channel) in one hardware period",
-          GST_ALSA_MIN_PERIOD_SZ, GST_ALSA_MAX_PERIOD_SZ,
-          GST_ALSA_MAX_PERIOD_SZ, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-  g_object_class_install_property (object_class, ARG_BUFFERSIZE,
-      g_param_spec_int ("buffer-size", "Buffer size",
-          "Number of frames the hardware buffer can hold",
-          GST_ALSA_MIN_BUFFER_SZ, GST_ALSA_MAX_BUFFER_SZ,
-          GST_ALSA_MIN_PERIOD_CNT * GST_ALSA_MAX_PERIOD_SZ, G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, ARG_AUTORECOVER,
-      g_param_spec_boolean ("autorecover", "Automatic xrun recovery",
-          "When TRUE tries to reduce processor load on xruns", TRUE,
-          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-  g_object_class_install_property (object_class, ARG_MMAP,
-      g_param_spec_boolean ("mmap", "Use mmap'ed access",
-          "Wether to use mmap (faster) or standard read/write (more compatible)",
-          TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-  g_object_class_install_property (object_class, ARG_MAXDISCONT,
-      g_param_spec_uint64 ("max-discont", "Maximum Discontinuity",
-          "GStreamer timeunits before the timestamp syncing starts dropping/inserting samples",
-          /* rounding errors */ 1000, GST_SECOND, GST_ALSA_DEFAULT_DISCONT,
-          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-  element_class->change_state = GST_DEBUG_FUNCPTR (gst_alsa_change_state);
-  element_class->query = GST_DEBUG_FUNCPTR (gst_alsa_query);
-  element_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_alsa_request_new_pad);
-  element_class->set_clock = GST_DEBUG_FUNCPTR (gst_alsa_set_clock);
-  element_class->get_clock = GST_DEBUG_FUNCPTR (gst_alsa_get_clock);
-}
-
-static void
-gst_alsa_init (GstAlsa * this)
-{
-  this->device = g_strdup ("default");
-  this->cached_caps = NULL;
-}
-
-static void
-gst_alsa_dispose (GObject * object)
-{
-  GstAlsa *this = GST_ALSA (object);
-
-  if (this->clock) {
-    gst_object_unparent (GST_OBJECT (this->clock));
-    this->clock = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_alsa_finalize (GObject * object)
-{
-  GstAlsa *this = GST_ALSA (object);
-
-  g_free (this->device);
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_alsa_set_property (GObject * object, guint prop_id, const GValue * value,
-    GParamSpec * pspec)
-{
-  GstAlsa *this;
-  gint buffer_size;
-
-  this = (GstAlsa *) object;
-  switch (prop_id) {
-    case ARG_DEVICE:
-      if (this->device)
-        g_free (this->device);
-      this->device = g_strdup (g_value_get_string (value));
-      break;
-    case ARG_PERIODCOUNT:
-      g_return_if_fail (!GST_FLAG_IS_SET (this, GST_ALSA_RUNNING));
-      this->period_count = g_value_get_int (value);
-      break;
-    case ARG_PERIODSIZE:
-      g_return_if_fail (!GST_FLAG_IS_SET (this, GST_ALSA_RUNNING));
-      this->period_size = g_value_get_int (value);
-      break;
-    case ARG_BUFFERSIZE:
-      g_return_if_fail (!GST_FLAG_IS_SET (this, GST_ALSA_RUNNING));
-      buffer_size = g_value_get_int (value);
-      this->period_count = buffer_size / this->period_size;
-      break;
-    case ARG_AUTORECOVER:
-      this->autorecover = g_value_get_boolean (value);
-      return;
-    case ARG_MMAP:
-      this->mmap = g_value_get_boolean (value);
-      return;
-    case ARG_MAXDISCONT:
-      this->max_discont = (GstClockTime) g_value_get_uint64 (value);
-      return;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      return;
-  }
-
-  if (GST_STATE (this) == GST_STATE_NULL)
-    return;
-
-  if (GST_FLAG_IS_SET (this, GST_ALSA_RUNNING)) {
-    gst_alsa_stop_audio (this);
-    gst_alsa_start_audio (this);
-  }
-}
-
-static void
-gst_alsa_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
-{
-  GstAlsa *this;
-
-  this = (GstAlsa *) object;
-
-  switch (prop_id) {
-    case ARG_DEVICE:
-      g_value_set_string (value, this->device);
-      break;
-    case ARG_DEVICE_NAME:
-      g_value_set_string (value, this->cardname);
-      break;
-    case ARG_PERIODCOUNT:
-      g_value_set_int (value, this->period_count);
-      break;
-    case ARG_PERIODSIZE:
-      g_value_set_int (value, this->period_size);
-      break;
-    case ARG_BUFFERSIZE:
-      g_value_set_int (value, this->period_size * this->period_count);
-      break;
-    case ARG_AUTORECOVER:
-      g_value_set_boolean (value, this->autorecover);
-      break;
-    case ARG_MMAP:
-      g_value_set_boolean (value, this->mmap);
-      break;
-    case ARG_MAXDISCONT:
-      g_value_set_uint64 (value, (guint64) this->max_discont);
-      return;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static const GList *
-gst_alsa_probe_get_properties (GstPropertyProbe * probe)
-{
-  GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
-  static GList *list = NULL;
-
-  if (!list) {
-    list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
-  }
-
-  return list;
-}
-
-static void
-device_list (snd_pcm_stream_t stream, GstAlsaClass * klass)
-{
-  snd_ctl_t *handle;
-  int card, err, dev;
-  snd_ctl_card_info_t *info;
-  snd_pcm_info_t *pcminfo;
-  gboolean mixer = (stream == -1);
-
-  if (stream == -1)
-    stream = 0;
-
-  snd_ctl_card_info_alloca (&info);
-  snd_pcm_info_alloca (&pcminfo);
-  card = -1;
-
-  if (snd_card_next (&card) < 0 || card < 0) {
-    /* no soundcard found */
-    return;
-  }
-  while (card >= 0) {
-    char name[32];
-
-    sprintf (name, "hw:%d", card);
-    if ((err = snd_ctl_open (&handle, name, 0)) < 0) {
-      goto next_card;
-    }
-    if ((err = snd_ctl_card_info (handle, info)) < 0) {
-      snd_ctl_close (handle);
-      goto next_card;
-    }
-
-    if (mixer) {
-      klass->devices = g_list_append (klass->devices, g_strdup (name));
-    } else {
-      dev = -1;
-      while (1) {
-        gchar *gst_device;
-
-        snd_ctl_pcm_next_device (handle, &dev);
-
-        if (dev < 0)
-          break;
-        snd_pcm_info_set_device (pcminfo, dev);
-        snd_pcm_info_set_subdevice (pcminfo, 0);
-        snd_pcm_info_set_stream (pcminfo, stream);
-        if ((err = snd_ctl_pcm_info (handle, pcminfo)) < 0) {
-          continue;
-        }
-
-        gst_device = g_strdup_printf ("hw:%d,%d", card, dev);
-        klass->devices = g_list_append (klass->devices, gst_device);
-      }
-    }
-    snd_ctl_close (handle);
-  next_card:
-    if (snd_card_next (&card) < 0) {
-      break;
-    }
-  }
-}
-
-static gboolean
-gst_alsa_class_probe_devices (GstAlsaClass * klass, gboolean check)
-{
-  static gboolean init = FALSE;
-
-  /* I'm pretty sure ALSA has a good way to do this. However, their cool
-   * auto-generated documentation is pretty much useless if you try to
-   * do function-wise look-ups. */
-
-  if (!init && !check) {
-    snd_pcm_stream_t mode = -1;
-    const GList *templates;
-
-    /* we assume one pad template at max [zero=mixer] */
-    templates =
-        gst_element_class_get_pad_template_list (GST_ELEMENT_CLASS (klass));
-    if (templates) {
-      if (GST_PAD_TEMPLATE_DIRECTION (templates->data) == GST_PAD_SRC)
-        mode = SND_PCM_STREAM_CAPTURE;
-      else
-        mode = SND_PCM_STREAM_PLAYBACK;
-    }
-
-    device_list (mode, klass);
-
-    init = TRUE;
-  }
-
-  return init;
-}
-
-static GValueArray *
-gst_alsa_class_list_devices (GstAlsaClass * klass)
-{
-  GValueArray *array;
-  GValue value = { 0 };
-  GList *item;
-
-  if (!klass->devices)
-    return NULL;
-
-  array = g_value_array_new (g_list_length (klass->devices));
-  g_value_init (&value, G_TYPE_STRING);
-  for (item = klass->devices; item != NULL; item = item->next) {
-    g_value_set_string (&value, item->data);
-    g_value_array_append (array, &value);
-  }
-  g_value_unset (&value);
-
-  return array;
-
-}
-
-static void
-gst_alsa_probe_probe_property (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
-{
-  GstAlsaClass *klass = GST_ALSA_GET_CLASS (probe);
-
-  switch (prop_id) {
-    case ARG_DEVICE:
-      gst_alsa_class_probe_devices (klass, FALSE);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_alsa_probe_needs_probe (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
-{
-  GstAlsaClass *klass = GST_ALSA_GET_CLASS (probe);
-  gboolean ret = FALSE;
-
-  switch (prop_id) {
-    case ARG_DEVICE:
-      ret = !gst_alsa_class_probe_devices (klass, TRUE);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
-      break;
-  }
-
-  return ret;
-}
-
-static GValueArray *
-gst_alsa_probe_get_values (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
-{
-  GstAlsaClass *klass = GST_ALSA_GET_CLASS (probe);
-  GValueArray *array = NULL;
-
-  switch (prop_id) {
-    case ARG_DEVICE:
-      array = gst_alsa_class_list_devices (klass);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
-      break;
-  }
-
-  return array;
-}
-
-static void
-gst_alsa_probe_interface_init (GstPropertyProbeInterface * iface)
-{
-  iface->get_properties = gst_alsa_probe_get_properties;
-  iface->probe_property = gst_alsa_probe_probe_property;
-  iface->needs_probe = gst_alsa_probe_needs_probe;
-  iface->get_values = gst_alsa_probe_get_values;
-}
-
-/* GSTREAMER PAD / QUERY / CONVERSION / STATE FUNCTIONS *********************/
-
-static GstPad *
-gst_alsa_request_new_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * name)
-{
-  GstAlsa *this;
-  gint track = 0;
-
-  g_return_val_if_fail (GST_IS_ALSA (element), NULL);
-  g_return_val_if_fail (!GST_FLAG_IS_SET (element, GST_ALSA_RUNNING), NULL);
-  this = GST_ALSA (element);
-
-  if (name) {
-    /* locate the track number in the requested pad name. */
-    track = (gint) strtol (name + (strchr (templ->name_template, '%') -
-            templ->name_template), NULL, 0);
-    if (track < 1 || track >= GST_ALSA_MAX_TRACKS) {
-      GST_INFO_OBJECT (this, "invalid track requested. (%d)", track);
-      return NULL;
-    }
-  }
-
-  /* make sure the requested track is free. */
-  if (track > 0 || this->pad[track] != NULL) {
-    GST_INFO_OBJECT (this, "requested track %d already in use.", track);
-    return NULL;
-  }
-
-  /* if the user doesn't care, use the lowest available track number */
-  if (track == 0) {
-    for (track = 1; track < GST_ALSA_MAX_TRACKS; track++) {
-      if (this->pad[track] != NULL)
-        goto found_track;
-    }
-    return NULL;
-  }
-
-found_track:
-  this->pad[track] = gst_pad_new_from_template (templ, name);
-
-  gst_pad_set_link_function (this->pad[track], gst_alsa_link);
-  gst_pad_set_getcaps_function (this->pad[track], gst_alsa_get_caps);
-  gst_pad_set_fixate_function (this->pad[track], gst_alsa_fixate);
-
-  gst_element_add_pad (GST_ELEMENT (this), this->pad[track]);
-
-  gst_pad_set_convert_function (this->pad[track], gst_alsa_pad_convert);
-  gst_pad_set_query_function (this->pad[track], gst_alsa_pad_query);
-  gst_pad_set_query_type_function (this->pad[track], gst_alsa_get_query_types);
-  gst_pad_set_formats_function (this->pad[track], gst_alsa_get_formats);
-
-  return this->pad[track];
-}
-
-/* gets the matching alsa format or NULL if none matches */
-static GstAlsaFormat *
-gst_alsa_get_format (const GstStructure * structure)
-{
-  const gchar *mimetype;
-  GstAlsaFormat *ret;
-
-  if (!(ret = g_new (GstAlsaFormat, 1)))
-    return NULL;
-
-  /* we have to differentiate between int and float formats */
-  mimetype = gst_structure_get_name (structure);
-
-  if (!strncmp (mimetype, "audio/x-raw-int", 15)) {
-    gboolean sign;
-    gint width, depth, endianness;
-
-    /* extract the needed information from the cap */
-    if (!(gst_structure_get_int (structure, "width", &width) &&
-            gst_structure_get_int (structure, "depth", &depth) &&
-            gst_structure_get_boolean (structure, "signed", &sign)))
-      goto error;
-
-    /* extract endianness if needed */
-    if (width > 8) {
-      if (!gst_structure_get_int (structure, "endianness", &endianness))
-        goto error;
-    } else {
-      endianness = G_BYTE_ORDER;
-    }
-
-    ret->format =
-        snd_pcm_build_linear_format (depth, width, sign ? 0 : 1,
-        endianness == G_LITTLE_ENDIAN ? 0 : 1);
-
-  } else if (!strncmp (mimetype, "audio/x-raw-float", 17)) {
-    gint width;
-
-    /* get layout */
-    if (!gst_structure_get_int (structure, "width", &width))
-      goto error;
-
-    /* match layout to format wrt to endianness */
-    if (width == 32) {
-      if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
-        ret->format = SND_PCM_FORMAT_FLOAT_LE;
-      } else if (G_BYTE_ORDER == G_BIG_ENDIAN) {
-        ret->format = SND_PCM_FORMAT_FLOAT_BE;
-      } else {
-        ret->format = SND_PCM_FORMAT_FLOAT;
-      }
-    } else if (width == 64) {
-      if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
-        ret->format = SND_PCM_FORMAT_FLOAT64_LE;
-      } else if (G_BYTE_ORDER == G_BIG_ENDIAN) {
-        ret->format = SND_PCM_FORMAT_FLOAT64_BE;
-      } else {
-        ret->format = SND_PCM_FORMAT_FLOAT64;
-      }
-    } else {
-      goto error;
-    }
-  } else if (!strncmp (mimetype, "audio/x-alaw", 12)) {
-    ret->format = SND_PCM_FORMAT_A_LAW;
-  } else if (!strncmp (mimetype, "audio/x-mulaw", 13)) {
-    ret->format = SND_PCM_FORMAT_MU_LAW;
-  }
-
-  /* get rate and channels */
-  if (!(gst_structure_get_int (structure, "rate", &ret->rate) &&
-          gst_structure_get_int (structure, "channels", &ret->channels)))
-    goto error;
-
-  return ret;
-
-error:
-  g_free (ret);
-  return NULL;
-}
-
-static inline gboolean
-gst_alsa_formats_match (GstAlsaFormat * one, GstAlsaFormat * two)
-{
-  if (one == two)
-    return TRUE;
-  if (one == NULL || two == NULL)
-    return FALSE;
-  return (one->format == two->format) &&
-      (one->rate == two->rate) && (one->channels == two->channels);
-}
-
-/* get props for a spec */
-static GstCaps *
-gst_alsa_get_caps_internal (snd_pcm_format_t format)
-{
-  if (format == SND_PCM_FORMAT_A_LAW) {
-    return gst_caps_new_simple ("audio/x-alaw", NULL);
-  } else if (format == SND_PCM_FORMAT_MU_LAW) {
-    return gst_caps_new_simple ("audio/x-mulaw", NULL);
-  } else if (snd_pcm_format_linear (format)) {
-    /* int */
-    GstStructure *structure = gst_structure_new ("audio/x-raw-int",
-        "width", G_TYPE_INT, (gint) snd_pcm_format_physical_width (format),
-        "depth", G_TYPE_INT, (gint) snd_pcm_format_width (format),
-        "signed", G_TYPE_BOOLEAN,
-        snd_pcm_format_signed (format) == 1 ? TRUE : FALSE,
-        NULL);
-
-    /* endianness */
-    if (snd_pcm_format_physical_width (format) > 8) {
-      switch (snd_pcm_format_little_endian (format)) {
-        case 0:
-          gst_structure_set (structure, "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-              NULL);
-          break;
-        case 1:
-          gst_structure_set (structure, "endianness", G_TYPE_INT,
-              G_LITTLE_ENDIAN, NULL);
-          break;
-        default:
-          GST_WARNING
-              ("Unknown byte order in sound driver. Continuing by assuming system byte order.");
-          gst_structure_set (structure, "endianness", G_TYPE_INT, G_BYTE_ORDER,
-              NULL);
-          break;
-      }
-    }
-    return gst_caps_new_full (structure, NULL);
-  } else if (snd_pcm_format_float (format)) {
-    /* no float with non-platform endianness */
-    if (!snd_pcm_format_cpu_endian (format))
-      return NULL;
-
-    return gst_caps_new_simple ("audio/x-raw-float",
-        "buffer-frames", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-        "width", G_TYPE_INT, (gint) snd_pcm_format_width (format),
-        "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
-  }
-  return NULL;
-}
-
-static inline void
-add_rates (GstStructure * structure, gint min_rate, gint max_rate)
-{
-  if (min_rate < 0) {
-    min_rate = GST_ALSA_MIN_RATE;
-    max_rate = GST_ALSA_MAX_RATE;
-  }
-  if (max_rate < 0 || min_rate == max_rate) {
-    gst_structure_set (structure, "rate", G_TYPE_INT, min_rate, NULL);
-  } else {
-    /* just to be sure */
-    if (min_rate > max_rate) {
-      gint temp;
-
-      GST_ERROR
-          ("minimum rate > maximum rate (%d > %d), please fix your soundcard drivers",
-          min_rate, max_rate);
-      temp = min_rate;
-      min_rate = max_rate;
-      max_rate = temp;
-    }
-    gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, min_rate,
-        max_rate, NULL);
-  }
-}
-
-static inline void
-add_channels (GstStructure * structure, gint min_channels, gint max_channels)
-{
-  if (min_channels < 0) {
-    min_channels = 1;
-    max_channels = GST_ALSA_MAX_CHANNELS;
-  }
-  if (max_channels < 0 || min_channels == max_channels) {
-    gst_structure_set (structure, "channels", G_TYPE_INT, min_channels, NULL);
-  } else {
-    /* just to be sure */
-    if (min_channels > max_channels) {
-      gint temp;
-
-      GST_ERROR
-          ("minimum channels > maximum channels (%d > %d), please fix your soundcard drivers",
-          min_channels, max_channels);
-      temp = min_channels;
-      min_channels = max_channels;
-      max_channels = temp;
-    }
-    gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE,
-        min_channels, max_channels, NULL);
-  }
-}
-
-/*
- * Get all available caps.
- * @format: SND_PCM_FORMAT_UNKNOWN for all formats, desired format else
- * @rate: allowed rates if < 0, else desired rate
- * @channels: all allowed values for channels if < 0, else desired channels
- */
-GstCaps *
-gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
-{
-  GstCaps *ret_caps;
-
-  if (format != SND_PCM_FORMAT_UNKNOWN) {
-    /* there are some caps set already */
-    ret_caps = gst_alsa_get_caps_internal (format);
-
-    /* we can never use a format we can't set caps for */
-    g_assert (ret_caps != NULL);
-    g_assert (gst_caps_get_size (ret_caps) == 1);
-
-    add_rates (gst_caps_get_structure (ret_caps, 0), rate, -1);
-    add_channels (gst_caps_get_structure (ret_caps, 0), channels, -1);
-  } else {
-    int i;
-    GstCaps *temp;
-
-    ret_caps = gst_caps_new_empty ();
-    for (i = 0; i <= SND_PCM_FORMAT_LAST; i++) {
-      temp = gst_alsa_get_caps_internal (i);
-
-      /* can be NULL, because not all alsa formats can be specified as caps */
-      if (temp != NULL) {
-        g_assert (gst_caps_get_size (temp) == 1);
-        add_rates (gst_caps_get_structure (temp, 0), rate, -1);
-        add_channels (gst_caps_get_structure (temp, 0), channels, -1);
-        gst_caps_append (ret_caps, temp);
-      }
-    }
-  }
-
-  gst_caps_do_simplify (ret_caps);
-  return ret_caps;
-}
-
-
-static int
-gst_alsa_check_sample_rates (snd_pcm_t * device_handle,
-    snd_pcm_hw_params_t * hw_params, unsigned int *tested_rates,
-    GValue * supported_rates)
-{
-  int i;
-  char init_done = 0;
-
-  GValue value = { 0 };
-  g_value_init (&value, G_TYPE_INT);
-
-  for (i = 0; tested_rates[i] != 0; i++) {
-    if (!snd_pcm_hw_params_test_rate (device_handle, hw_params, tested_rates[i],
-            0)) {
-      if (!init_done) {
-        /* at least one sample rate supported */
-        g_value_init (supported_rates, GST_TYPE_LIST);
-        init_done = 1;
-      }
-
-      g_value_set_int (&value, tested_rates[i]);
-      gst_value_list_append_value (supported_rates, &value);
-    }
-  }
-
-// only one -> G_TYPE_INT
-
-  g_value_unset (&value);
-
-  return init_done;
-}
-
-static int
-gst_alsa_rates_probe (snd_pcm_t * device_handle,
-    snd_pcm_hw_params_t * hw_params, GValue * supported_rates)
-{
-  int n;
-  gboolean min_found = FALSE, max_found = FALSE;
-  unsigned int common_rates[] =
-      { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 88200,
-    96000, 192000, 0, 0, 0
-  };
-  /* this dummy sample rate should only be supported by a software device.
-   * you need two, because one could be dmix... */
-  unsigned int uncommon_rates[] = { 12345, 45678, 0 };
-
-  int ret;
-  int dir;
-  unsigned int min_rate, max_rate;
-
-  /* Get MIN/MAX supported rate */
-  snd_pcm_hw_params_get_rate_min (hw_params, &min_rate, &dir);
-  min_rate =
-      min_rate <
-      GST_ALSA_MIN_RATE ? GST_ALSA_MIN_RATE : (min_rate +
-      GST_ALSA_DIR_MIN (dir));
-  snd_pcm_hw_params_get_rate_max (hw_params, &max_rate, &dir);
-  max_rate =
-      max_rate >
-      GST_ALSA_MAX_RATE ? GST_ALSA_MAX_RATE : (max_rate +
-      GST_ALSA_DIR_MAX (dir));
-  for (n = 0; common_rates[n] != 0; n++) {
-    if (common_rates[n] == min_rate)
-      min_found = TRUE;
-    if (common_rates[n] == max_rate)
-      max_found = TRUE;
-  }
-  if (!min_found)
-    common_rates[12] = min_rate;
-  if (!max_found && min_rate != max_rate)
-    common_rates[13] = max_rate;
-
-  ret =
-      gst_alsa_check_sample_rates (device_handle, hw_params, uncommon_rates,
-      supported_rates);
-  if (ret) {
-    /* Uncommon sample rates supported, it is certainly a
-     * "software"/dummy device */
-    g_value_unset (supported_rates);
-    g_value_init (supported_rates, GST_TYPE_INT_RANGE);
-
-    if (min_rate != max_rate) {
-      gst_value_set_int_range (supported_rates, min_rate, max_rate);
-    } else {
-      /* Only one supported */
-      g_value_unset (supported_rates);
-      g_value_init (supported_rates, G_TYPE_INT);
-      g_value_set_int (supported_rates, min_rate);
-    }
-  } else {
-    /* Check common sample rates for real hardware support */
-    ret =
-        gst_alsa_check_sample_rates (device_handle, hw_params, common_rates,
-        supported_rates);
-    if (ret) {
-      if (gst_value_list_get_size (supported_rates) == 1) {
-        /* Only one supported */
-        GValue *rate = (GValue *) gst_value_list_get_value (supported_rates, 0);
-
-        min_rate = g_value_get_int (rate);
-        g_value_unset (supported_rates);
-        g_value_init (supported_rates, G_TYPE_INT);
-        g_value_set_int (supported_rates, min_rate);
-      }
-    } else {
-      GST_WARNING ("No supported samplerates found for %d-%d range",
-          min_rate, max_rate);
-      gst_value_set_int_range (supported_rates, min_rate, max_rate);
-    }
-  }
-
-  return 0;
-}
-
-
-/* Return better caps when device is open */
-GstCaps *
-gst_alsa_get_caps (GstPad * pad)
-{
-  GstAlsa *this;
-  snd_pcm_hw_params_t *hw_params;
-  snd_pcm_format_mask_t *mask;
-  int i;
-  GValue supported_rates = { 0 };
-  unsigned int min_period_cnt, max_period_cnt;
-  snd_pcm_uframes_t min_period_sz, max_period_sz;
-  snd_pcm_uframes_t min_buffer_sz, max_buffer_sz;
-  gint buffer_size;
-  gint min_channels, max_channels;
-  GstCaps *ret = NULL;
-
-  g_return_val_if_fail (pad != NULL, NULL);
-
-  this = GST_ALSA (gst_pad_get_parent (pad));
-
-  if (!GST_FLAG_IS_SET (this, GST_ALSA_OPEN))
-    return gst_caps_copy (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)));
-  if (this->cached_caps)
-    return gst_caps_copy (this->cached_caps);
-
-  snd_pcm_hw_params_alloca (&hw_params);
-  ERROR_CHECK (snd_pcm_hw_params_any (this->handle, hw_params),
-      "Broken configuration for this PCM: %s");
-
-  if (((GstElement *) this)->numpads > 1) {
-    min_channels = 1;
-    max_channels = -1;
-  } else {
-    ERROR_CHECK (snd_pcm_hw_params_get_channels_min (hw_params, &min_channels),
-        "Couldn't get minimum channel count for device %s: %s", this->device);
-    ERROR_CHECK (snd_pcm_hw_params_get_channels_max (hw_params, &max_channels),
-        "Couldn't get maximum channel count for device %s: %s", this->device);
-    min_channels = min_channels < 1 ? 1 : min_channels;
-    max_channels =
-        max_channels >
-        GST_ALSA_MAX_CHANNELS ? GST_ALSA_MAX_CHANNELS : max_channels;
-  }
-
-  /* Check available sample rates */
-  if (!gst_alsa_rates_probe (this->handle, hw_params, &supported_rates)) {
-    ;
-  }
-
-  /* Probe period_count and adjust default/user provided value against probed MIN/MAX */
-  ERROR_CHECK (snd_pcm_hw_params_get_periods_min (hw_params, &min_period_cnt,
-          &i), "Couldn't get minimum period_count for device %s: %s",
-      this->device);
-  min_period_cnt =
-      min_period_cnt <
-      GST_ALSA_MIN_PERIOD_CNT ? GST_ALSA_MIN_PERIOD_CNT : (min_period_cnt +
-      GST_ALSA_DIR_MIN (i));
-  if (this->period_count < min_period_cnt) {
-    this->period_count = min_period_cnt;
-  };
-  ERROR_CHECK (snd_pcm_hw_params_get_periods_max (hw_params, &max_period_cnt,
-          &i), "Couldn't get maximum period_count for device %s: %s",
-      this->device);
-  max_period_cnt =
-      max_period_cnt >
-      GST_ALSA_MAX_PERIOD_CNT ? GST_ALSA_MAX_PERIOD_CNT : (max_period_cnt +
-      GST_ALSA_DIR_MAX (i));
-  if (this->period_count > max_period_cnt) {
-    this->period_count = max_period_cnt;
-  };
-
-  /* Probe period_size and adjust default/user provided value against probed MIN/MAX */
-  ERROR_CHECK (snd_pcm_hw_params_get_period_size_min (hw_params, &min_period_sz,
-          &i), "Couldn't get minimum period_size for device %s: %s",
-      this->device);
-  min_period_sz =
-      min_period_sz <
-      GST_ALSA_MIN_PERIOD_SZ ? GST_ALSA_MIN_PERIOD_SZ : (min_period_sz +
-      GST_ALSA_DIR_MIN (i));
-  if (this->period_size < min_period_sz) {
-    this->period_size = min_period_sz;
-  };
-  ERROR_CHECK (snd_pcm_hw_params_get_period_size_max (hw_params, &max_period_sz,
-          &i), "Couldn't get maximum period_size for device %s: %s",
-      this->device);
-  max_period_sz =
-      max_period_sz >
-      GST_ALSA_MAX_PERIOD_SZ ? GST_ALSA_MAX_PERIOD_SZ : (max_period_sz +
-      GST_ALSA_DIR_MAX (i));
-  if (this->period_size > max_period_sz) {
-    this->period_size = max_period_sz;
-  };
-
-  /* Probe buffer_size MIN/MAX */
-  buffer_size = this->period_count * this->period_size;
-  ERROR_CHECK (snd_pcm_hw_params_get_buffer_size_min (hw_params,
-          &min_buffer_sz), "Couldn't get minimum buffer_size for device %s: %s",
-      this->device);
-  min_buffer_sz =
-      min_buffer_sz <
-      GST_ALSA_MIN_BUFFER_SZ ? GST_ALSA_MIN_BUFFER_SZ : min_buffer_sz;
-  if (buffer_size < min_buffer_sz) {
-    buffer_size = min_buffer_sz;
-    this->period_size = GST_ALSA_MIN_BUFFER_SZ / this->period_count;
-  };
-  ERROR_CHECK (snd_pcm_hw_params_get_buffer_size_max (hw_params,
-          &max_buffer_sz), "Couldn't get maximum buffer_size for device %s: %s",
-      this->device);
-  max_buffer_sz =
-      max_buffer_sz >
-      GST_ALSA_MAX_BUFFER_SZ ? GST_ALSA_MAX_BUFFER_SZ : max_buffer_sz;
-  if (buffer_size > max_buffer_sz) {
-    buffer_size = max_buffer_sz;
-    this->period_size = GST_ALSA_MAX_BUFFER_SZ / this->period_count;
-  };
-
-
-  snd_pcm_format_mask_alloca (&mask);
-  snd_pcm_hw_params_get_format_mask (hw_params, mask);
-  for (i = 0; i <= SND_PCM_FORMAT_LAST; i++) {
-    if (snd_pcm_format_mask_test (mask, i)) {
-      GstCaps *caps = gst_alsa_get_caps_internal (i);
-
-      /* we can never use a format we can't set caps for */
-      if (caps != NULL) {
-        gint n;
-
-        g_assert (gst_caps_get_size (caps) == 1);
-
-        gst_structure_set_value (gst_caps_get_structure (caps, 0), "rate",
-            &supported_rates);
-
-        add_channels (gst_caps_get_structure (caps, 0), min_channels,
-            max_channels);
-
-        /* channel configuration */
-        /* MIN used to spped up because we don't support more than 8 channels */
-        for (n = min_channels; n <= MIN (8, max_channels); n++) {
-          if (snd_pcm_hw_params_test_channels (this->handle, hw_params, n) == 0) {
-            GstStructure *str;
-            GstAudioChannelPosition pos[8] = {
-              GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
-              GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
-              GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
-              GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
-              GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
-              GST_AUDIO_CHANNEL_POSITION_LFE,
-              GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
-              GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
-            };
-
-            switch (n) {
-              case 1:
-                pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
-                break;
-              case 2:
-              case 4:
-              case 6:
-              case 8:
-                /* keep above */
-                break;
-              default:
-                /* unsupported */
-                pos[0] = GST_AUDIO_CHANNEL_POSITION_INVALID;
-                break;
-            }
-
-            if (pos[0] != GST_AUDIO_CHANNEL_POSITION_INVALID) {
-              str = gst_structure_copy (gst_caps_get_structure (caps, 0));
-              gst_structure_set (str, "channels", G_TYPE_INT, n, NULL);
-              if (n > 2) {
-                gst_audio_set_channel_positions (str, pos);
-              }
-              if (!ret) {
-                ret = gst_caps_new_empty ();
-              }
-              gst_caps_append_structure (ret, str);
-            }
-          }
-        }
-        gst_caps_unref (caps);
-      }
-    }
-  }
-
-  if (ret == NULL) {
-    GST_WARNING_OBJECT (this, "no supported caps found, returning empty caps");
-    ret = gst_caps_new_empty ();
-  }
-  gst_caps_do_simplify (ret);
-  GST_LOG_OBJECT (this, "get_caps returns %P", ret);
-
-  g_value_unset (&supported_rates);
-
-  this->cached_caps = gst_caps_copy (ret);
-  return ret;
-}
-
-static GstCaps *
-gst_alsa_fixate_to_mimetype (const GstCaps * caps, const gchar * mime)
-{
-  GstCaps *try, *result;
-
-  try = gst_caps_new_simple (mime, NULL);
-  result = gst_caps_intersect (try, caps);
-  gst_caps_unref (try);
-  if (gst_caps_is_empty (result)) {
-    gst_caps_unref (result);
-    return NULL;
-  }
-  if (gst_caps_is_subset (caps, result)) {
-    /* we didn't reduce caps */
-    gst_caps_unref (result);
-    return NULL;
-  }
-  return result;
-}
-
-static GstCaps *
-gst_alsa_fixate_field_nearest_int (const GstCaps * caps,
-    const gchar * field_name, gint target)
-{
-  guint i;
-  GstCaps *result;
-  GstCaps *smaller = gst_caps_new_empty ();
-  GstCaps *equal = gst_caps_new_empty ();
-  GstCaps *bigger = gst_caps_new_empty ();
-
-  /* works like this: we fixate every structure and put them into one of those 
-   * caps depending on what we fixated to. We then return the best caps that is 
-   * not empty in the following order: equal, bigger, smaller 
-   * We also make sure the caps were really reduced.
-   */
-  for (i = 0; i < gst_caps_get_size (caps); i++) {
-    gint fixated_to;
-    GstStructure *copy = gst_structure_copy (gst_caps_get_structure (caps, i));
-
-    gst_caps_structure_fixate_field_nearest_int (copy, field_name, target);
-    if (gst_structure_get_int (copy, field_name, &fixated_to)) {
-      if (fixated_to == target) {
-        gst_caps_append_structure (equal, copy);
-      } else if (fixated_to > target) {
-        gst_caps_append_structure (bigger, copy);
-      } else {
-        gst_caps_append_structure (smaller, copy);
-      }
-    } else {
-      /* FIXME: what do we do here? Add to all or throw an error? */
-      g_return_val_if_reached (NULL);
-    }
-  }
-  if (!gst_caps_is_empty (equal)) {
-    gst_caps_unref (bigger);
-    gst_caps_unref (smaller);
-    result = equal;
-  } else {
-    gst_caps_unref (equal);
-    if (!gst_caps_is_empty (bigger)) {
-      gst_caps_unref (smaller);
-      result = bigger;
-    } else {
-      gst_caps_unref (bigger);
-      if (gst_caps_is_empty (smaller)) {
-        gst_caps_unref (smaller);
-        return NULL;
-      }
-      result = smaller;
-    }
-  }
-  if (gst_caps_is_subset (caps, result)) {
-    /* we didn't reduce caps */
-    gst_caps_unref (result);
-    return NULL;
-  }
-  return result;
-}
-
-GstCaps *
-gst_alsa_fixate (GstPad * pad, const GstCaps * caps)
-{
-  GstCaps *result;
-  const gchar *mime;
-
-  if ((result = gst_alsa_fixate_to_mimetype (caps, "audio/x-raw-int")))
-    return result;
-  if ((result = gst_alsa_fixate_to_mimetype (caps, "audio/x-raw-float")))
-    return result;
-  if ((result = gst_alsa_fixate_to_mimetype (caps, "audio/x-alaw")))
-    return result;
-  if ((result = gst_alsa_fixate_to_mimetype (caps, "audio/x-mulaw")))
-    return result;
-
-  /* now we know there's only one mimetype in the caps */
-  /* FIXME: I should check this to be really sure I didn't mess up somewhere */
-
-  if ((result = gst_alsa_fixate_field_nearest_int (caps, "rate", 44100)))
-    return result;
-  if ((result = gst_alsa_fixate_field_nearest_int (caps, "channels", 2)))
-    return result;
-
-  mime = gst_structure_get_name (gst_caps_get_structure (caps, 0));
-  if (g_str_equal (mime, "audio/x-raw-int")) {
-    if ((result = gst_alsa_fixate_field_nearest_int (caps, "width", 16)))
-      return result;
-    if ((result = gst_alsa_fixate_field_nearest_int (caps, "depth", 16)))
-      return result;
-  } else if (g_str_equal (mime, "audio/x-raw-float")) {
-    if ((result = gst_alsa_fixate_field_nearest_int (caps, "width", 32)))
-      return result;
-  }
-
-  return NULL;
-}
-
-/* Negotiates the caps */
-GstPadLinkReturn
-gst_alsa_link (GstPad * pad, const GstCaps * caps)
-{
-  GstAlsa *this;
-  GstAlsaFormat *format;
-  GstPadLinkReturn ret;
-  gint old_rate = 0;
-
-  g_return_val_if_fail (caps != NULL, GST_PAD_LINK_REFUSED);
-  g_return_val_if_fail (pad != NULL, GST_PAD_LINK_REFUSED);
-
-  this = GST_ALSA (gst_pad_get_parent (pad));
-
-  if (this->handle == NULL)
-    if (!gst_alsa_open_audio (this))
-      return GST_PAD_LINK_REFUSED;
-
-  format = gst_alsa_get_format (gst_caps_get_structure (caps, 0));
-  if (format == NULL)
-    return GST_PAD_LINK_REFUSED;
-
-  GST_DEBUG ("found format %s", snd_pcm_format_name (format->format));
-
-  if (!GST_FLAG_IS_SET (this, GST_ALSA_CAPS_NEGO)) {
-    gint i;
-
-    GST_FLAG_SET (this, GST_ALSA_CAPS_NEGO);
-
-    if (gst_alsa_formats_match (this->format, format)) {
-      ret = GST_PAD_LINK_OK;
-      goto out;
-    }
-
-    if (!gst_alsa_probe_hw_params (this, format)) {
-      ret = GST_PAD_LINK_REFUSED;
-      goto out;
-    }
-
-    for (i = 0; i < ((GstElement *) this)->numpads; i++) {
-      g_assert (this->pad[i] != NULL);
-      if (this->pad[i] == pad)
-        continue;
-      if (gst_pad_try_set_caps (this->pad[i], caps) == GST_PAD_LINK_REFUSED) {
-        if (this->format) {
-          GstCaps *old =
-              gst_alsa_caps (this->format->format, this->format->rate,
-              this->format->channels);
-
-          for (--i; i >= 0; i--) {
-            if (gst_pad_try_set_caps (this->pad[i],
-                    old) == GST_PAD_LINK_REFUSED) {
-              GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
-                  ("could not reset caps to a sane value"));
-              gst_caps_unref (old);
-              break;
-            } else {
-              /* FIXME: unset caps on pads somehow */
-            }
-          }
-          gst_caps_unref (old);
-          ret = GST_PAD_LINK_REFUSED;
-          goto out;
-        }
-      }
-    }
-
-    GST_FLAG_UNSET (this, GST_ALSA_CAPS_NEGO);
-
-    /* sync the params */
-    if (GST_FLAG_IS_SET (this, GST_ALSA_RUNNING))
-      gst_alsa_stop_audio (this);
-    if (this->format)
-      old_rate = this->format->rate;
-    g_free (this->format);
-    this->format = format;
-    if (this->played && old_rate)
-      this->played = this->played * this->format->rate / old_rate;
-    if (!gst_alsa_start_audio (this)) {
-      GST_ELEMENT_ERROR (this, RESOURCE, SETTINGS, (NULL), (NULL));
-      return GST_PAD_LINK_REFUSED;
-    }
-
-    return GST_PAD_LINK_OK;
-  }
-
-  return GST_PAD_LINK_DELAYED;
-
-out:
-  g_free (format);
-  GST_FLAG_UNSET (this, GST_ALSA_CAPS_NEGO);
-  return ret;
-}
-
-static GstElementStateReturn
-gst_alsa_change_state (GstElement * element)
-{
-  int err = 0;
-  GstAlsa *this;
-
-  g_return_val_if_fail (element != NULL, FALSE);
-  this = GST_ALSA (element);
-
-  switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_NULL_TO_READY:
-      if (!(GST_FLAG_IS_SET (element, GST_ALSA_OPEN) ||
-              gst_alsa_open_audio (this)))
-        return GST_STATE_FAILURE;
-      break;
-    case GST_STATE_READY_TO_PAUSED:
-      this->played = 0;
-      this->captured = 0;
-      break;
-    case GST_STATE_PAUSED_TO_PLAYING:
-      if (snd_pcm_state (this->handle) == SND_PCM_STATE_PAUSED) {
-        if ((err = snd_pcm_pause (this->handle, 0)) < 0) {
-          GST_ERROR_OBJECT (this, "Error unpausing sound: %s",
-              snd_strerror (err));
-          return GST_STATE_FAILURE;
-        }
-      }
-      /* If we were already negotiated, but we are not running, then
-       * we stopped (probably because we paused), so re-start. If
-       * there's no format, we didn't negotiate yet so don't do
-       * anything because ALSA will crash (#151288, #153227, etc.). */
-      else if (this->format != NULL &&
-          !GST_FLAG_IS_SET (element, GST_ALSA_RUNNING) &&
-          !gst_alsa_start_audio (this)) {
-        return GST_STATE_FAILURE;
-      }
-      gst_alsa_clock_start (this->clock);
-      break;
-    case GST_STATE_PLAYING_TO_PAUSED:
-      if (GST_ALSA_CAPS_IS_SET (this, GST_ALSA_CAPS_PAUSE)) {
-        if (snd_pcm_state (this->handle) == SND_PCM_STATE_RUNNING) {
-          if ((err = snd_pcm_pause (this->handle, 1)) < 0) {
-            GST_ERROR_OBJECT (this, "Error pausing sound: %s",
-                snd_strerror (err));
-            GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_PAUSE, 0);
-            goto cant_pause;
-          }
-        }
-      } else {
-      cant_pause:
-        /* if device doesn't know how to pause, we just stop */
-        if (GST_FLAG_IS_SET (element, GST_ALSA_RUNNING))
-          gst_alsa_stop_audio (this);
-      }
-      gst_alsa_clock_stop (this->clock);
-      break;
-    case GST_STATE_PAUSED_TO_READY:
-      if (GST_FLAG_IS_SET (element, GST_ALSA_RUNNING))
-        gst_alsa_stop_audio (this);
-      g_free (this->format);
-      this->format = NULL;
-      this->played = 0;
-      this->captured = 0;
-      break;
-    case GST_STATE_READY_TO_NULL:
-      if (GST_FLAG_IS_SET (element, GST_ALSA_OPEN))
-        gst_alsa_close_audio (this);
-      break;
-
-    default:
-      break;
-  }
-
-  if (GST_ELEMENT_CLASS (parent_class)->change_state)
-    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
-
-  return GST_STATE_SUCCESS;
-}
-
-static GstClock *
-gst_alsa_get_clock (GstElement * element)
-{
-  return GST_CLOCK (GST_ALSA (element)->clock);
-}
-
-static void
-gst_alsa_set_clock (GstElement * element, GstClock * clock)
-{
-  /* we need this function just so everybody knows we use a clock */
-  GST_ALSA (element)->ext_clock = clock;
-}
-
-/* AUDIO PROCESSING *********************************************************/
-
-inline snd_pcm_sframes_t
-gst_alsa_update_avail (GstAlsa * this)
-{
-  snd_pcm_sframes_t avail = snd_pcm_avail_update (this->handle);
-
-  if (avail < 0) {
-    if (avail == -EPIPE) {
-      gst_alsa_xrun_recovery (this);
-    } else {
-      GST_WARNING_OBJECT (this, "unknown ALSA avail_update return value (%d)",
-          (int) avail);
-    }
-  }
-  return avail;
-}
-
-/* returns TRUE, if the loop should go on */
-inline gboolean
-gst_alsa_pcm_wait (GstAlsa * this)
-{
-  int err;
-  snd_pcm_state_t state = snd_pcm_state (this->handle);
-
-  if (state == SND_PCM_STATE_RUNNING) {
-    if ((err = snd_pcm_wait (this->handle, 1000)) < 0) {
-      if (err == EINTR) {
-        /* happens mostly when run under gdb, or when exiting due to a signal */
-        GST_DEBUG ("got interrupted while waiting");
-        if (gst_element_interrupt (GST_ELEMENT (this))) {
-          return TRUE;
-        } else {
-          return FALSE;
-        }
-      }
-      if (!gst_alsa_xrun_recovery (this)) {
-        GST_ERROR_OBJECT (this, "error waiting for alsa pcm: (%d: %s)", err,
-            snd_strerror (err));
-        return FALSE;
-      }
-    }
-  } else {
-    GST_INFO_OBJECT (this, "in state %s, not waiting",
-        snd_pcm_state_name (state));
-  }
-  return TRUE;
-}
-
-/*
- * error out or make sure we're in SND_PCM_STATE_RUNNING afterwards
- * return FALSE if we're not
- */
-inline gboolean
-gst_alsa_start (GstAlsa * this)
-{
-  GST_DEBUG ("Setting state to RUNNING");
-
-  switch (snd_pcm_state (this->handle)) {
-    case SND_PCM_STATE_XRUN:
-      gst_alsa_xrun_recovery (this);
-      return gst_alsa_start (this);
-    case SND_PCM_STATE_SETUP:
-      ERROR_CHECK (snd_pcm_prepare (this->handle), "error preparing: %s");
-    case SND_PCM_STATE_SUSPENDED:
-    case SND_PCM_STATE_PREPARED:
-      this->captured = 0;
-      ERROR_CHECK (snd_pcm_start (this->handle), "error starting playback: %s");
-      break;
-    case SND_PCM_STATE_PAUSED:
-      ERROR_CHECK (snd_pcm_pause (this->handle, 0), "error unpausing: %s");
-      break;
-    case SND_PCM_STATE_RUNNING:
-      break;
-    case SND_PCM_STATE_DRAINING:
-    case SND_PCM_STATE_OPEN:
-      /* this probably happens when someone replugged a pipeline and we're in a
-         really weird state because our cothread wasn't busted */
-      return FALSE;
-    default:
-      /* it's a bug when we get here */
-      g_assert_not_reached ();
-      break;
-  }
-  return TRUE;
-}
-
-gboolean
-gst_alsa_xrun_recovery (GstAlsa * this)
-{
-  snd_pcm_status_t *status;
-  gint err;
-
-  snd_pcm_status_alloca (&status);
-
-  if ((err = snd_pcm_status (this->handle, status)) < 0)
-    GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
-
-  if (snd_pcm_status_get_state (status) == SND_PCM_STATE_XRUN) {
-    struct timeval now, diff, tstamp;
-
-    gettimeofday (&now, 0);
-    snd_pcm_status_get_trigger_tstamp (status, &tstamp);
-    timersub (&now, &tstamp, &diff);
-
-    /* if we're allowed to recover, ... */
-    if (this->autorecover) {
-      /* ... then increase the period size or buffer size / period count to
-         prevent further xruns (at the cost of increased latency and memory
-         usage). */
-      if (this->period_count >= 4) {
-        this->period_size *= 2;
-        this->period_count /= 2;
-      } else {
-        this->period_count *= 2;
-      }
-    }
-    if (!(gst_alsa_stop_audio (this) && gst_alsa_start_audio (this))) {
-      GST_ELEMENT_ERROR (this, RESOURCE, FAILED, (NULL),
-          ("Error restarting audio after xrun"));
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-}
-
-/* AUDIO SETUP / START / STOP ***********************************************/
-
-void
-gst_alsa_set_eos (GstAlsa * this)
-{
-  gst_alsa_drain_audio (this);
-  gst_element_set_eos (GST_ELEMENT (this));
-}
-
-static gboolean
-gst_alsa_open_audio (GstAlsa * this)
-{
-  snd_pcm_info_t *info;
-  int ret;
-
-  g_assert (this != NULL);
-  g_assert (this->handle == NULL);
-
-  /* If we have no pads, then we're apparently a mixer object,
-   * and that doesn't need a handle to the actual audio device. */
-  if (!gst_element_get_pad_list (GST_ELEMENT (this)))
-    return TRUE;
-
-  GST_INFO ("Opening alsa device \"%s\"...", this->device);
-
-#ifdef ALSA_BUG_389_FIXED
-  ERROR_CHECK (snd_output_buffer_open (&this->out),
-      "error opening log output: %s");
-#endif
-
-  if ((ret = snd_pcm_open (&this->handle, this->device,
-              GST_ALSA_GET_CLASS (this)->stream, SND_PCM_NONBLOCK)) < 0) {
-    /* ALSA inverts standard errno.h error codes */
-    switch (-ret) {
-      case EBUSY:
-        GST_ELEMENT_ERROR (GST_ELEMENT (this), RESOURCE, BUSY,
-            (_("ALSA device \"%s\" is already in use by another program."),
-                this->device), (NULL));
-        break;
-      case EACCES:
-      case ETXTBSY:
-        GST_ELEMENT_ERROR (GST_ELEMENT (this), RESOURCE, OPEN_READ_WRITE,
-            (_("Could not access ALSA device \"%s\", check its permissions."),
-                this->device), GST_ERROR_SYSTEM);
-        break;
-
-      case ENXIO:
-      case ENODEV:
-      case ENOENT:
-        GST_ELEMENT_ERROR (GST_ELEMENT (this), RESOURCE, BUSY,
-            (_("ALSA device \"%s\" does not exist."), this->device), (NULL));
-        break;
-      default:
-        GST_ELEMENT_ERROR (GST_ELEMENT (this), RESOURCE, BUSY,
-            (_("ALSA device \"%s\" had an error."),
-                this->device), ("ALSA error %d: %s", ret, snd_strerror (ret)));
-        break;
-    }
-    return FALSE;
-  }
-
-  snd_pcm_info_malloc (&info);
-  snd_pcm_info (this->handle, info);
-  this->cardname = g_strdup (snd_pcm_info_get_name (info));
-  snd_pcm_info_free (info);
-
-  GST_FLAG_SET (this, GST_ALSA_OPEN);
-  return TRUE;
-}
-
-void
-gst_alsa_sw_params_dump (GstAlsa * this, snd_pcm_sw_params_t * sw_params)
-{
-#ifdef ALSA_BUG_389_FIXED
-  snd_pcm_sw_params_dump (sw_params, this->out);
-  ALSA_DEBUG_FLUSH (this);
-#endif
-}
-
-void
-gst_alsa_hw_params_dump (GstAlsa * this, snd_pcm_hw_params_t * hw_params)
-{
-#ifdef ALSA_BUG_389_FIXED
-  snd_pcm_hw_params_dump (hw_params, this->out);
-  ALSA_DEBUG_FLUSH (this);
-#endif
-}
-
-/* if someone finds an easy way to merge this with _set_hw_params, go ahead */
-static gboolean
-gst_alsa_probe_hw_params (GstAlsa * this, GstAlsaFormat * format)
-{
-  snd_pcm_hw_params_t *hw_params;
-  snd_pcm_uframes_t period_size;
-  unsigned int period_count;
-  unsigned int rate;
-
-  g_return_val_if_fail (this != NULL, FALSE);
-  g_return_val_if_fail (format != NULL, FALSE);
-
-  GST_INFO ("Probing format: %s %dHz, %d channels",
-      snd_pcm_format_name (format->format), format->rate, format->channels);
-
-  snd_pcm_hw_params_alloca (&hw_params);
-  SIMPLE_ERROR_CHECK (snd_pcm_hw_params_any (this->handle, hw_params));
-
-  gst_alsa_hw_params_dump (this, hw_params);
-
-  if (GST_ELEMENT (this)->numpads == 1) {
-    SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_access (this->handle,
-            hw_params, this->
-            mmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED :
-            SND_PCM_ACCESS_RW_INTERLEAVED));
-  } else {
-    SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_access (this->handle,
-            hw_params, this->
-            mmap ? SND_PCM_ACCESS_MMAP_NONINTERLEAVED :
-            SND_PCM_ACCESS_RW_NONINTERLEAVED));
-  }
-
-  SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_format (this->handle, hw_params,
-          format->format));
-  SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_channels (this->handle, hw_params,
-          format->channels));
-  /* FIXME: We should use snd_pcm_hw_params_set_rate instead of 
-   * snd_pcm_hw_params_set_rate_near here. Unfortunately alsa fails in that case
-   * far more often and seems to handle this quite well. (Example: ENS1371 
-   * driver on alsalib 1.0.5, kernel 2.6.6-mm5). If it sets far too wrong sample
-   * rates, we need to revert back to snd_pcm_hw_params_set_rate or check the
-   * rate that was set.
-   */
-  rate = format->rate;
-  SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_rate_near (this->handle, hw_params,
-          &rate, 0));
-  if (rate != format->rate)
-    GST_WARNING_OBJECT (this, "set rate (%u) differs from desired rate (%u)",
-        rate, format->rate);
-
-  period_count = this->period_count;
-  SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_periods_near (this->handle,
-          hw_params, &period_count, 0));
-  period_size = this->period_size;
-  SIMPLE_ERROR_CHECK (snd_pcm_hw_params_set_period_size_near (this->handle,
-          hw_params, &period_size, 0));
-
-  return TRUE;
-}
-
-/*
- * You must set all hw parameters at once and can't use already set params and
- * change them.
- * Thx ALSA for not documenting this
- */
-static gboolean
-gst_alsa_set_hw_params (GstAlsa * this)
-{
-  snd_pcm_hw_params_t *hw_params;
-  unsigned int rate;
-
-  g_return_val_if_fail (this != NULL, FALSE);
-  g_return_val_if_fail (this->handle != NULL, FALSE);
-
-  snd_pcm_hw_params_alloca (&hw_params);
-  ERROR_CHECK (snd_pcm_hw_params_any (this->handle, hw_params),
-      "Broken configuration for this PCM: %s");
-
-  if (this->format) {
-    GST_INFO ("Preparing format: %s %dHz, %d channels",
-        snd_pcm_format_name (this->format->format), this->format->rate,
-        this->format->channels);
-
-    if (GST_ELEMENT (this)->numpads == 1) {
-      ERROR_CHECK (snd_pcm_hw_params_set_access (this->handle, hw_params, this->
-              mmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED :
-              SND_PCM_ACCESS_RW_INTERLEAVED),
-          "This plugin does not support your harware: %s");
-    } else {
-      ERROR_CHECK (snd_pcm_hw_params_set_access (this->handle, hw_params, this->
-              mmap ? SND_PCM_ACCESS_MMAP_NONINTERLEAVED :
-              SND_PCM_ACCESS_RW_NONINTERLEAVED),
-          "This plugin does not support your harware: %s");
-    }
-
-    ERROR_CHECK (snd_pcm_hw_params_set_format (this->handle, hw_params,
-            this->format->format), "Sample format (%s) not available: %s",
-        snd_pcm_format_name (this->format->format));
-    ERROR_CHECK (snd_pcm_hw_params_set_channels (this->handle, hw_params,
-            this->format->channels), "Channels count (%d) not available: %s",
-        this->format->channels);
-    /* FIXME: We should use snd_pcm_hw_params_set_rate instead of 
-     * snd_pcm_hw_params_set_rate_near here. Unfortunately alsa fails in that case
-     * far more often and seems to handle this quite well. (Example: ENS1371 
-     * driver on alsalib 1.0.5, kernel 2.6.6-mm5). If it sets far too wrong sample
-     * rates, we need to revert back to snd_pcm_hw_params_set_rate or check the
-     * rate that was set.
-     */
-    rate = this->format->rate;
-    ERROR_CHECK (snd_pcm_hw_params_set_rate_near (this->handle, hw_params,
-            &rate, 0), "error setting rate (%d): %s", this->format->rate);
-    if (rate != this->format->rate)
-      GST_WARNING_OBJECT (this, "set rate (%u) differs from desired rate (%u)",
-          rate, this->format->rate);
-    ERROR_CHECK (snd_pcm_hw_params_set_periods_near (this->handle, hw_params,
-            &this->period_count, 0), "error setting period count to %u: %s",
-        (guint) this->period_count);
-    ERROR_CHECK (snd_pcm_hw_params_set_period_size_near (this->handle,
-            hw_params, &this->period_size, 0),
-        "error setting period size to %u frames: %s",
-        (guint) this->period_size);
-  } else {
-    GST_INFO_OBJECT (this, "Preparing format: (none)");
-  }
-  gst_alsa_hw_params_dump (this, hw_params);
-
-
-  ERROR_CHECK (snd_pcm_hw_params (this->handle, hw_params),
-      "Could not set hardware parameters: %s");
-
-  /* now get the pcm caps */
-  GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_PAUSE,
-      snd_pcm_hw_params_can_pause (hw_params));
-  GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_RESUME,
-      snd_pcm_hw_params_can_resume (hw_params));
-  GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_SYNC_START,
-      snd_pcm_hw_params_can_sync_start (hw_params));
-
-  if (this->mmap) {
-    this->transmit = GST_ALSA_GET_CLASS (this)->transmit_mmap;
-  } else {
-    this->transmit = GST_ALSA_GET_CLASS (this)->transmit_rw;
-  }
-
-  return TRUE;
-}
-
-static gboolean
-gst_alsa_set_sw_params (GstAlsa * this)
-{
-  snd_pcm_sw_params_t *sw_params;
-
-  if (!this->format) {
-    GST_LOG_OBJECT (this, "not setting sw params, we're not negotiated yet");
-    return TRUE;
-  }
-
-  snd_pcm_sw_params_alloca (&sw_params);
-  ERROR_CHECK (snd_pcm_sw_params_current (this->handle, sw_params),
-      "Could not get current software parameters: %s");
-
-  gst_alsa_sw_params_dump (this, sw_params);
-
-  ERROR_CHECK (snd_pcm_sw_params_set_silence_size (this->handle, sw_params, 0),
-      "could not set silence size: %s");
-  ERROR_CHECK (snd_pcm_sw_params_set_silence_threshold (this->handle, sw_params,
-          0), "could not set silence threshold: %s");
-  ERROR_CHECK (snd_pcm_sw_params_set_avail_min (this->handle, sw_params,
-          this->period_size), "could not set avail min: %s");
-  /* we start explicitly */
-  ERROR_CHECK (snd_pcm_sw_params_set_start_threshold (this->handle, sw_params,
-          this->period_size * this->period_count + 1),
-      "could not set start mode: %s");
-  ERROR_CHECK (snd_pcm_sw_params_set_stop_threshold (this->handle, sw_params,
-          this->period_size * this->period_count),
-      "could not set stop mode: %s");
-  ERROR_CHECK (snd_pcm_sw_params_set_xfer_align (this->handle, sw_params, 1),
-      "Unable to set transfer align for playback: %s");
-  ERROR_CHECK (snd_pcm_sw_params (this->handle, sw_params),
-      "could not set sw_params: %s");
-  return TRUE;
-}
-
-static gboolean
-gst_alsa_start_audio (GstAlsa * this)
-{
-  g_assert (GST_FLAG_IS_SET (this, GST_ALSA_OPEN));
-
-  if (!gst_alsa_set_hw_params (this))
-    return FALSE;
-  if (!gst_alsa_set_sw_params (this))
-    GST_WARNING_OBJECT (this,
-        "setting software parameters failed, we'll trust the defaults");
-
-  GST_FLAG_SET (this, GST_ALSA_RUNNING);
-  return TRUE;
-}
-
-static gboolean
-gst_alsa_drain_audio (GstAlsa * this)
-{
-  g_assert (this != NULL);
-  g_return_val_if_fail (this->handle != NULL, FALSE);
-
-  GST_DEBUG ("stopping alsa");
-
-  switch (snd_pcm_state (this->handle)) {
-    case SND_PCM_STATE_XRUN:
-    case SND_PCM_STATE_RUNNING:
-      /* fall through - clock is already stopped when paused */
-    case SND_PCM_STATE_PAUSED:
-      /* snd_pcm_drain only works in blocking mode */
-      ERROR_CHECK (snd_pcm_nonblock (this->handle, 0),
-          "couldn't set blocking mode: %s");
-      ERROR_CHECK (snd_pcm_drain (this->handle),
-          "couldn't stop and drain buffer: %s");
-      ERROR_CHECK (snd_pcm_nonblock (this->handle, 1),
-          "couldn't set non-blocking mode: %s");
-      break;
-    default:
-      break;
-  }
-
-  GST_DEBUG ("stopped alsa");
-  GST_FLAG_UNSET (this, GST_ALSA_RUNNING);
-  return TRUE;
-}
-
-static gboolean
-gst_alsa_stop_audio (GstAlsa * this)
-{
-  g_assert (this != NULL);
-  g_return_val_if_fail (this->handle != NULL, FALSE);
-
-  GST_DEBUG ("stopping alsa, skipping pending frames");
-
-  switch (snd_pcm_state (this->handle)) {
-    case SND_PCM_STATE_XRUN:
-    case SND_PCM_STATE_RUNNING:
-      /* fall through - clock is already stopped when paused */
-    case SND_PCM_STATE_PAUSED:
-      ERROR_CHECK (snd_pcm_drop (this->handle),
-          "couldn't stop (dropping frames): %s");
-      break;
-    default:
-      break;
-  }
-
-  GST_FLAG_UNSET (this, GST_ALSA_RUNNING);
-  return TRUE;
-}
-
-static gboolean
-gst_alsa_close_audio (GstAlsa * this)
-{
-#ifdef ALSA_BUG_389_FIXED
-  gint err;
-#endif
-
-  /* if there's no pads, we never open. So we don't close either. */
-  if (!gst_element_get_pad_list (GST_ELEMENT (this)))
-    return TRUE;
-
-  g_return_val_if_fail (this != NULL, FALSE);
-  g_return_val_if_fail (this->handle != NULL, FALSE);
-
-#ifdef ALSA_BUG_389_FIXED
-  ALSA_DEBUG_FLUSH (this);
-  err = snd_output_close (this->out);
-  if (err != 0)
-    GST_ERROR_OBJECT (this, "failed to close debugging output: %s",
-        snd_strerror (err));
-#endif
-  ERROR_CHECK (snd_pcm_close (this->handle), "Error closing device: %s");
-
-  this->handle = NULL;
-  if (this->cardname) {
-    g_free (this->cardname);
-    this->cardname = NULL;
-  }
-  GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_PAUSE, 0);
-  GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_RESUME, 0);
-  GST_ALSA_CAPS_SET (this, GST_ALSA_CAPS_SYNC_START, 0);
-  GST_FLAG_UNSET (this, GST_ALSA_OPEN);
-  if (this->cached_caps) {
-    gst_caps_unref (this->cached_caps);
-    this->cached_caps = NULL;
-  }
-
-  return TRUE;
-}
-
-/* QUERYING/FORMAT/CONVERSION FUNCTIONS *************************************/
-
-static const GstFormat *
-gst_alsa_get_formats (GstPad * pad)
-{
-  static const GstFormat formats[] = {
-    GST_FORMAT_TIME,
-    GST_FORMAT_DEFAULT,
-    GST_FORMAT_BYTES,
-    0
-  };
-
-  return formats;
-}
-
-static gboolean
-gst_alsa_pad_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
-    GstFormat * dest_format, gint64 * dest_value)
-{
-  return gst_alsa_convert (GST_ALSA (GST_PAD_PARENT (pad)), src_format,
-      src_value, dest_format, dest_value);
-}
-
-static gboolean
-gst_alsa_convert (GstAlsa * this, GstFormat src_format, gint64 src_value,
-    GstFormat * dest_format, gint64 * dest_value)
-{
-  gboolean res = TRUE;
-
-  if (src_format == *dest_format) {
-    *dest_value = src_value;
-    return TRUE;
-  }
-  if (this->format == NULL)
-    return FALSE;
-
-  switch (src_format) {
-    case GST_FORMAT_BYTES:
-      switch (*dest_format) {
-        case GST_FORMAT_DEFAULT:
-          *dest_value = gst_alsa_bytes_to_samples (this, (guint) src_value);
-          break;
-        case GST_FORMAT_TIME:
-          *dest_value = gst_alsa_bytes_to_timestamp (this, (guint) src_value);
-          break;
-        default:
-          res = FALSE;
-          break;
-      }
-      break;
-    case GST_FORMAT_TIME:
-      switch (*dest_format) {
-        case GST_FORMAT_DEFAULT:
-          *dest_value =
-              gst_alsa_timestamp_to_samples (this, (GstClockTime) src_value);
-          break;
-        case GST_FORMAT_BYTES:
-          *dest_value =
-              gst_alsa_timestamp_to_bytes (this, (GstClockTime) src_value);
-          break;
-        default:
-          res = FALSE;
-          break;
-      }
-      break;
-    case GST_FORMAT_DEFAULT:
-      switch (*dest_format) {
-        case GST_FORMAT_TIME:
-          *dest_value = gst_alsa_samples_to_timestamp (this, (guint) src_value);
-          break;
-        case GST_FORMAT_BYTES:
-          *dest_value = gst_alsa_samples_to_bytes (this, (guint) src_value);
-          break;
-        case GST_FORMAT_DEFAULT:
-          g_assert_not_reached ();
-          /* fall through */
-        default:
-          res = FALSE;
-          break;
-      }
-      break;
-    default:
-      res = FALSE;
-  }
-
-  return res;
-}
-
-static const GstQueryType *
-gst_alsa_get_query_types (GstPad * pad)
-{
-  static const GstQueryType query_types[] = {
-    GST_QUERY_LATENCY,
-    GST_QUERY_POSITION,
-    0,
-  };
-
-  return query_types;
-}
-
-static gboolean
-gst_alsa_query_func (GstElement * element, GstQueryType type,
-    GstFormat * format, gint64 * value)
-{
-  gboolean res = FALSE;
-  GstAlsa *this = GST_ALSA (element);
-
-  switch (type) {
-    case GST_QUERY_LATENCY:{
-      snd_pcm_sframes_t delay;
-
-      ERROR_CHECK (snd_pcm_delay (this->handle, &delay),
-          "Error getting delay: %s");
-      res =
-          gst_alsa_convert (this, GST_FORMAT_DEFAULT, (gint64) delay, format,
-          value);
-      break;
-    }
-    case GST_QUERY_POSITION:
-      res =
-          gst_alsa_convert (this, GST_FORMAT_TIME,
-          gst_element_get_time (GST_ELEMENT (this)), format, value);
-      break;
-    default:
-      break;
-  }
-
-  return res;
-}
-
-static gboolean
-gst_alsa_query (GstElement * element, GstQueryType type, GstFormat * format,
-    gint64 * value)
-{
-  return gst_alsa_pad_query (GST_ALSA (element)->pad[0], type, format, value);
-}
-
-static gboolean
-gst_alsa_pad_query (GstPad * pad, GstQueryType type, GstFormat * format,
-    gint64 * value)
-{
-  if (gst_alsa_query_func (GST_PAD_PARENT (pad), type, format, value))
-    return TRUE;
-
-  if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK
-      && gst_pad_query (gst_pad_get_peer (pad), type, format, value))
-    return TRUE;
-
-  return FALSE;
-}
-
-inline snd_pcm_uframes_t
-gst_alsa_timestamp_to_samples (GstAlsa * this, GstClockTime time)
-{
-  return (snd_pcm_uframes_t) ((time * this->format->rate +
-          this->format->rate / 2) / GST_SECOND);
-}
-
-inline GstClockTime
-gst_alsa_samples_to_timestamp (GstAlsa * this, snd_pcm_uframes_t samples)
-{
-  return ((GstClockTime) samples) * GST_SECOND / this->format->rate;
-}
-
-inline snd_pcm_uframes_t
-gst_alsa_bytes_to_samples (GstAlsa * this, guint bytes)
-{
-  return bytes / (snd_pcm_format_physical_width (this->format->format) / 8) /
-      (GST_ELEMENT (this)->numpads == 1 ? this->format->channels : 1);
-}
-
-inline guint
-gst_alsa_samples_to_bytes (GstAlsa * this, snd_pcm_uframes_t samples)
-{
-  return samples * snd_pcm_format_physical_width (this->format->format) / 8 *
-      (GST_ELEMENT (this)->numpads == 1 ? this->format->channels : 1);
-}
-
-inline GstClockTime
-gst_alsa_bytes_to_timestamp (GstAlsa * this, guint bytes)
-{
-  return gst_alsa_samples_to_timestamp (this, gst_alsa_bytes_to_samples (this,
-          bytes));
-}
-
-inline guint
-gst_alsa_timestamp_to_bytes (GstAlsa * this, GstClockTime time)
-{
-  return gst_alsa_samples_to_bytes (this, gst_alsa_timestamp_to_samples (this,
-          time));
-}
index 74dd2c8..a38f22b 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 #ifndef __GST_ALSA_H__
 #define __GST_ALSA_H__
 
+
 #define ALSA_PCM_NEW_HW_PARAMS_API
 #define ALSA_PCM_NEW_SW_PARAMS_API
 
 #include <gst/gst.h>
 
 
-GST_DEBUG_CATEGORY_EXTERN (alsa_debug);
-#define GST_CAT_DEFAULT alsa_debug
-
-
-/* error checking for standard alsa functions */
-/* NOTE: these functions require a GObject *this and can only be used in 
-   functions that return TRUE on success and FALSE on error */
-#define SIMPLE_ERROR_CHECK(value) G_STMT_START{ \
-  int err = (value); \
-  if (err < 0) { \
-    GST_WARNING_OBJECT (this, "\"" #value "\": %s", snd_strerror (err)); \
-    return FALSE; \
-  } \
-}G_STMT_END
-
-
-#ifdef G_HAVE_ISO_VARARGS
-#define ERROR_CHECK(value, ...) G_STMT_START{ \
-  int err = (value); \
-  if (err < 0) { \
-    GST_WARNING_OBJECT (this, __VA_ARGS__, snd_strerror (err)); \
-    return FALSE; \
-  } \
-}G_STMT_END
-
-#elif defined(G_HAVE_GNUC_VARARGS)
-#define ERROR_CHECK(value, args...) G_STMT_START{ \
-  int err = (value); \
-  if (err < 0) { \
-    GST_WARNING_OBJECT (this, ## args, snd_strerror (err)); \
-    return FALSE; \
-  } \
-}G_STMT_END
-
-#else
-#define ERROR_CHECK(value, args...) G_STMT_START{ \
-  int err = (value); \
-  if (err < 0) { \
-    GST_WARNING_OBJECT (this, snd_strerror (err)); \
-    return FALSE; \
-  } \
-}G_STMT_END
-#endif
-
-
-#define GST_ALSA_MIN_RATE      8000
-#define GST_ALSA_MAX_RATE      192000
-#define GST_ALSA_MIN_PERIOD_CNT        2
-#define GST_ALSA_MAX_PERIOD_CNT        64
-#define GST_ALSA_MIN_PERIOD_SZ 2
-#define GST_ALSA_MAX_PERIOD_SZ 8192
-#define GST_ALSA_MIN_BUFFER_SZ GST_ALSA_MIN_PERIOD_CNT*GST_ALSA_MIN_PERIOD_SZ
-#define GST_ALSA_MAX_BUFFER_SZ 65536
-#define GST_ALSA_MAX_TRACKS    64 /* we don't support more than 64 tracks */
-#define GST_ALSA_MAX_CHANNELS  32 /* tracks can have up to 32 channels */
-
-/* a few alsa functions return an int value and a 'direction', -1, 0 or +1
-  0 = exact value
- -1 = real value is up to 1 before given value
- +1 = real value is up to 1 after given value
-*/
-#define GST_ALSA_DIR_MIN(i) ((i == 1) ? 1 : 0)
-#define GST_ALSA_DIR_MAX(i) ((i ==-1) ?-1 : 0)
-
-/* Mono is 1 channel ; the 5.1 standard is 6 channels. The value for
-   GST_ALSA_MAX_CHANNELS comes from alsa/mixer.h. */
-
-/* Max allowed discontinuity in time units between timestamp and playback
-   pointer before killing/inserting samples. This should be big enough to allow
-   smoothing errors on different video formats. */
-#define GST_ALSA_DEFAULT_DISCONT (GST_SECOND / 10)
-
-G_BEGIN_DECLS
-
-#define GST_ALSA(obj)                  (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA, GstAlsa))
-#define GST_ALSA_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA, GstAlsaClass))
-#define GST_ALSA_GET_CLASS(obj)                (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ALSA, GstAlsaClass))
-#define GST_IS_ALSA(obj)               (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA))
-#define GST_IS_ALSA_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA))
-#define GST_TYPE_ALSA                  (gst_alsa_get_type())
-
-enum {
-  GST_ALSA_OPEN = GST_ELEMENT_FLAG_LAST,
-  GST_ALSA_RUNNING,
-  GST_ALSA_CAPS_NEGO,
-  GST_ALSA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 3
-};
-
-typedef enum {
-  GST_ALSA_CAPS_PAUSE = 0,
-  GST_ALSA_CAPS_RESUME,
-  GST_ALSA_CAPS_SYNC_START
-  /* add more */
-} GstAlsaPcmCaps;
-
-#define GST_ALSA_CAPS_IS_SET(obj, flag) (GST_ALSA (obj)->pcm_caps & (1<<(flag)))
-#define GST_ALSA_CAPS_SET(obj, flag, set) G_STMT_START{  \
-  if (set) { (GST_ALSA (obj)->pcm_caps |=  (1<<(flag))); } \
-  else     { (GST_ALSA (obj)->pcm_caps &= ~(1<<(flag))); } \
-}G_STMT_END
-
-typedef struct _GstAlsaClock GstAlsaClock;
-typedef struct _GstAlsaClockClass GstAlsaClockClass;
-
-typedef struct _GstAlsa GstAlsa;
-typedef struct _GstAlsaClass GstAlsaClass;
-
-typedef int (*GstAlsaTransmitFunction) (GstAlsa *this, snd_pcm_sframes_t *avail);
-
-typedef struct {
-  snd_pcm_format_t     format;
-  guint                        rate;
-  gint                 channels;
-} GstAlsaFormat;
-
-struct _GstAlsa {
-  GstElement                   parent;
-
-  /* array of GstAlsaPads */
-  GstPad *                     pad[GST_ALSA_MAX_TRACKS];
-
-  gchar *                      device;
-  gchar *                       cardname;
-  snd_pcm_t *                  handle;
-  guint                                pcm_caps;       /* capabilities of the pcm device, see GstAlsaPcmCaps */
-  snd_output_t *               out;
-
-  GstAlsaFormat *              format;         /* NULL if undefined */
-  gboolean                     mmap;           /* use mmap transmit (fast) or read/write (sloooow) */
-  GstAlsaTransmitFunction      transmit;
-  GstCaps *                    cached_caps;    /* we cache caps to speed up get_caps */
-
-  /* latency / performance parameters */
-  snd_pcm_uframes_t            period_size;
-  unsigned int                 period_count;
-
-  gboolean                     autorecover;
-
-  /* clocking */
-  GstAlsaClock *               clock;          /* our provided clock */
-  GstClock *                   ext_clock;      /* externally set clock. */
-  snd_pcm_uframes_t            played;         /* samples transmitted since last sync 
-                                                  This thing actually is our master clock.
-                                                  We will event insert silent samples or
-                                                  drop some to sync to incoming timestamps.
-                                                */
-  snd_pcm_uframes_t            captured;
-  GstClockTime                 max_discont;    /* max difference between current
-                                                  playback timestamp and buffers timestamps
-                                                */
-};
-
-struct _GstAlsaClass {
-  GstElementClass              parent_class;
-
-  snd_pcm_stream_t             stream;
-
-  /* different transmit functions */
-  GstAlsaTransmitFunction      transmit_mmap;
-  GstAlsaTransmitFunction      transmit_rw;
-
-  /* autodetected devices available */
-  GList *devices;
-};
-
-GType gst_alsa_get_type (void);
-
-void                   gst_alsa_set_eos        (GstAlsa *              this);
-GstPadLinkReturn       gst_alsa_link           (GstPad *               pad,
-                                                const GstCaps *        caps);
-GstCaps *              gst_alsa_get_caps       (GstPad *               pad);
-GstCaps *              gst_alsa_fixate         (GstPad *               pad,
-                                                 const GstCaps *        caps);
-GstCaps *              gst_alsa_caps           (snd_pcm_format_t       format,
-                                                gint                   rate,
-                                                gint                   channels);
-
-/* audio processing functions */
-inline snd_pcm_sframes_t       gst_alsa_update_avail   (GstAlsa * this);
-inline gboolean                        gst_alsa_pcm_wait       (GstAlsa * this);
-inline gboolean                        gst_alsa_start          (GstAlsa * this);
-gboolean                       gst_alsa_xrun_recovery  (GstAlsa * this);
-
-/* format conversions */
-inline snd_pcm_uframes_t       gst_alsa_timestamp_to_samples   (GstAlsa *              this,
-                                                                GstClockTime           time);
-inline GstClockTime            gst_alsa_samples_to_timestamp   (GstAlsa *              this,
-                                                                snd_pcm_uframes_t      samples);
-inline snd_pcm_uframes_t       gst_alsa_bytes_to_samples       (GstAlsa *              this,
-                                                                guint                  bytes);
-inline guint                   gst_alsa_samples_to_bytes       (GstAlsa *              this,
-                                                                snd_pcm_uframes_t      samples);
-inline GstClockTime            gst_alsa_bytes_to_timestamp     (GstAlsa *              this,
-                                                                guint                  bytes);
-inline guint                   gst_alsa_timestamp_to_bytes     (GstAlsa *              this,
-                                                                GstClockTime           time);
-
-/* debugging functions (useful in gdb) - require running with --gst-debug=alsa:4 or better */
-void                           gst_alsa_sw_params_dump         (GstAlsa *              this, 
-                                                                snd_pcm_sw_params_t *  sw_params);
-void                           gst_alsa_hw_params_dump         (GstAlsa *              this, 
-                                                                snd_pcm_hw_params_t *  hw_params);
-
-
-G_END_DECLS
-
 #endif /* __GST_ALSA_H__ */
diff --git a/ext/alsa/gstalsaclock.c b/ext/alsa/gstalsaclock.c
deleted file mode 100644 (file)
index beb502f..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2001 CodeFactory AB
- * Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se>
- * Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu>
- * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstalsaclock.h"
-
-/* clock functions */
-static void gst_alsa_clock_class_init (gpointer g_class, gpointer class_data);
-static void gst_alsa_clock_init (GstAlsaClock * clock);
-
-static GstClockTime gst_alsa_clock_get_internal_time (GstClock * clock);
-static guint64 gst_alsa_clock_get_resolution (GstClock * clock);
-static GstClockEntryStatus gst_alsa_clock_wait (GstClock * clock,
-    GstClockEntry * entry);
-static void gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry);
-
-static GstClockClass *clock_parent_class = NULL;
-
-/* static guint gst_alsa_clock_signals[LAST_SIGNAL] = { 0 }; */
-
-GType
-gst_alsa_clock_get_type (void)
-{
-  static GType clock_type = 0;
-
-  if (!clock_type) {
-    static const GTypeInfo clock_info = {
-      sizeof (GstAlsaClockClass),
-      NULL,
-      NULL,
-      gst_alsa_clock_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAlsaClock),
-      4,
-      (GInstanceInitFunc) gst_alsa_clock_init,
-      NULL
-    };
-
-    clock_type = g_type_register_static (GST_TYPE_CLOCK, "GstAlsaClock",
-        &clock_info, 0);
-  }
-  return clock_type;
-}
-static void
-gst_alsa_clock_class_init (gpointer g_class, gpointer class_data)
-{
-  GObjectClass *gobject_class;
-  GstObjectClass *gstobject_class;
-  GstClockClass *gstclock_class;
-  GstAlsaClockClass *klass;
-
-  klass = (GstAlsaClockClass *) g_class;
-  gobject_class = (GObjectClass *) klass;
-  gstobject_class = (GstObjectClass *) klass;
-  gstclock_class = (GstClockClass *) klass;
-
-  clock_parent_class = g_type_class_ref (GST_TYPE_CLOCK);
-
-  gstclock_class->get_internal_time = gst_alsa_clock_get_internal_time;
-  gstclock_class->get_resolution = gst_alsa_clock_get_resolution;
-  gstclock_class->wait = gst_alsa_clock_wait;
-  gstclock_class->unlock = gst_alsa_clock_unlock;
-}
-static void
-gst_alsa_clock_init (GstAlsaClock * clock)
-{
-  gst_object_set_name (GST_OBJECT (clock), "GstAlsaClock");
-
-  clock->start_time = GST_CLOCK_TIME_NONE;
-}
-
-GstAlsaClock *
-gst_alsa_clock_new (gchar * name, GstAlsaClockGetTimeFunc get_time,
-    GstAlsa * owner)
-{
-  GstAlsaClock *alsa_clock =
-      GST_ALSA_CLOCK (g_object_new (GST_TYPE_ALSA_CLOCK, NULL));
-
-  g_assert (alsa_clock);
-
-  alsa_clock->get_time = get_time;
-  alsa_clock->owner = owner;
-  alsa_clock->adjust = 0;
-
-  gst_object_set_name (GST_OBJECT (alsa_clock), name);
-  gst_object_set_parent (GST_OBJECT (alsa_clock), GST_OBJECT (owner));
-
-  return alsa_clock;
-}
-
-void
-gst_alsa_clock_start (GstAlsaClock * clock)
-{
-  g_assert (!GST_CLOCK_TIME_IS_VALID (clock->start_time));
-
-  if (clock->owner->format) {
-    clock->start_time = gst_clock_get_event_time (GST_CLOCK (clock))
-        - clock->get_time (clock->owner);
-  } else {
-    clock->start_time = gst_clock_get_event_time (GST_CLOCK (clock));
-  }
-}
-void
-gst_alsa_clock_stop (GstAlsaClock * clock)
-{
-  GTimeVal timeval;
-
-  g_get_current_time (&timeval);
-
-  g_assert (GST_CLOCK_TIME_IS_VALID (clock->start_time));
-
-  clock->adjust +=
-      GST_TIMEVAL_TO_TIME (timeval) -
-      gst_clock_get_event_time (GST_CLOCK (clock));
-  clock->start_time = GST_CLOCK_TIME_NONE;
-}
-
-static GstClockTime
-gst_alsa_clock_get_internal_time (GstClock * clock)
-{
-  GstAlsaClock *alsa_clock = GST_ALSA_CLOCK (clock);
-
-  if (GST_CLOCK_TIME_IS_VALID (alsa_clock->start_time)) {
-    return alsa_clock->get_time (alsa_clock->owner) + alsa_clock->start_time;
-  } else {
-    GTimeVal timeval;
-
-    g_get_current_time (&timeval);
-    return GST_TIMEVAL_TO_TIME (timeval) + alsa_clock->adjust;
-  }
-}
-static guint64
-gst_alsa_clock_get_resolution (GstClock * clock)
-{
-  GstAlsaClock *this = GST_ALSA_CLOCK (clock);
-
-  if (this->owner->format) {
-    return GST_SECOND / this->owner->format->rate;
-  } else {
-    /* FIXME: is there an "unknown" value? We just return the sysclock's time by default */
-    return 1 * GST_USECOND;
-  }
-}
-static GstClockEntryStatus
-gst_alsa_clock_wait (GstClock * clock, GstClockEntry * entry)
-{
-  GstClockTime target, entry_time, glib_start, glib_cur;
-  GstClockTimeDiff diff;
-  GstAlsaClock *this = GST_ALSA_CLOCK (clock);
-  GTimeVal t;
-
-  entry_time = gst_alsa_clock_get_internal_time (clock);
-  diff = GST_CLOCK_ENTRY_TIME (entry) - gst_clock_get_time (clock);
-
-  if (diff < 0)
-    return GST_CLOCK_ENTRY_EARLY;
-
-  if (diff > clock->max_diff) {
-    GST_INFO_OBJECT (this,
-        "GstAlsaClock: abnormal clock request diff: %" GST_TIME_FORMAT ") >"
-        "  %" GST_TIME_FORMAT, GST_TIME_ARGS (diff),
-        GST_TIME_ARGS (clock->max_diff));
-    return GST_CLOCK_ENTRY_EARLY;
-  }
-
-  target = entry_time + diff;
-
-  GST_DEBUG_OBJECT (this, "real_target %" GST_TIME_FORMAT
-      " target %" GST_TIME_FORMAT
-      " now %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (target), GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry)),
-      GST_TIME_ARGS (entry_time));
-
-  g_get_current_time (&t);
-  glib_cur = glib_start = GST_TIMEVAL_TO_TIME (t);
-  while (gst_alsa_clock_get_internal_time (clock) < target &&
-      this->last_unlock < entry_time && glib_start + diff * 1.5 > glib_cur) {
-    g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC /
-        GST_SECOND);
-    g_get_current_time (&t);
-    glib_cur = GST_TIMEVAL_TO_TIME (t);
-  }
-
-  return entry->status;
-}
-static void
-gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry)
-{
-  GstAlsaClock *this = GST_ALSA_CLOCK (clock);
-
-  this->last_unlock = this->get_time (this->owner);
-}
diff --git a/ext/alsa/gstalsaclock.h b/ext/alsa/gstalsaclock.h
deleted file mode 100644 (file)
index 4629289..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2001 CodeFactory AB
- * Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se>
- * Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu>
- * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __GST_ALSA_CLOCK_H__
-#define __GST_ALSA_CLOCK_H__
-
-#include "gstalsa.h"
-
-G_BEGIN_DECLS
-
-#define GST_ALSA_CLOCK(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_CLOCK,GstAlsaClock))
-#define GST_ALSA_CLOCK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_CLOCK,GstAlsaClockClass))
-#define GST_IS_ALSA_CLOCK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_CLOCK))
-#define GST_IS_ALSA_CLOCK_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_CLOCK))
-#define GST_TYPE_ALSA_CLOCK            (gst_alsa_clock_get_type())
-
-typedef GstClockTime (*GstAlsaClockGetTimeFunc) (GstAlsa *);
-
-struct _GstAlsaClock {
-  GstSystemClock               parent;
-
-  GstAlsaClockGetTimeFunc      get_time;
-  GstAlsa *                    owner;
-
-  GstClockTimeDiff             adjust;         /* adjustment to real clock (recalculated when stopping) */
-  GstClockTime                 start_time;     /* time when the stream started (NONE when stopped) */
-  GstClockTime                 last_unlock;    /* time of last unlock request */
-};
-
-struct _GstAlsaClockClass {
-  GstSystemClockClass parent_class;
-};
-
-GType          gst_alsa_clock_get_type (void);
-GstAlsaClock * gst_alsa_clock_new      (gchar *                        name,
-                                        GstAlsaClockGetTimeFunc        func,
-                                        GstAlsa *                      owner);
-
-void   gst_alsa_clock_start    (GstAlsaClock * clock);
-void   gst_alsa_clock_stop     (GstAlsaClock * clock);
-
-G_END_DECLS
-
-#endif /* __GST_ALSA_CLOCK_H__ */
index d66dda1..65db1d0 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "gstalsamixer.h"
 
-/* elementfactory information */
+
 static GstElementDetails gst_alsa_mixer_details =
 GST_ELEMENT_DETAILS ("Alsa Mixer",
     "Generic/Audio",
     "Control sound input and output levels with ALSA",
     "Leif Johnson <leif@ambient.2y.net>");
 
-static void gst_alsa_interface_init (GstImplementsInterfaceClass * klass);
 
-static void gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data);
-static void gst_alsa_mixer_init (GstAlsaMixer * mixer);
-static void gst_alsa_mixer_interface_init (GstMixerClass * klass);
-static gboolean gst_alsa_mixer_supported (GstImplementsInterface * iface,
-    GType iface_type);
+#define GST_BOILERPLATE_WITH_INTERFACE(type, type_as_function, parent_type,             \
+    parent_type_as_macro, interface_type, interface_type_as_macro,                      \
+    interface_as_function)                                                              \
+                                                                                        \
+static void interface_as_function ## _interface_init (interface_type ## Class *klass);  \
+static gboolean interface_as_function ## _supported (type *object, GType iface_type);   \
+                                                                                        \
+static void                                                                             \
+type_as_function ## _implements_interface_init (GstImplementsInterfaceClass *klass)     \
+{                                                                                       \
+  klass->supported = (gpointer)interface_as_function ## _supported;                     \
+}                                                                                       \
+                                                                                        \
+static void                                                                             \
+type_as_function ## _init_interfaces (GType type)                                       \
+{                                                                                       \
+  static const GInterfaceInfo implements_iface_info = {                                 \
+    (GInterfaceInitFunc) type_as_function ## _implements_interface_init,                \
+    NULL,                                                                               \
+    NULL,                                                                               \
+  };                                                                                    \
+  static const GInterfaceInfo iface_info = {                                            \
+    (GInterfaceInitFunc) interface_as_function ## _interface_init,                      \
+    NULL,                                                                               \
+    NULL,                                                                               \
+  };                                                                                    \
+                                                                                        \
+  g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,                     \
+      &implements_iface_info);                                                          \
+  g_type_add_interface_static (type, interface_type_as_macro, &iface_info);             \
+}                                                                                       \
+                                                                                        \
+GST_BOILERPLATE_FULL (type, type_as_function, parent_type,                              \
+    parent_type_as_macro, type_as_function ## _init_interfaces)
+
+GST_BOILERPLATE_WITH_INTERFACE (GstAlsaMixer, gst_alsa_mixer, GstElement,
+    GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, gst_alsa_mixer);
 
-/* GStreamer stuff */
 static GstElementStateReturn gst_alsa_mixer_change_state (GstElement * element);
 
-static void gst_alsa_mixer_build_list (GstAlsaMixer * mixer);
-static void gst_alsa_mixer_free_list (GstAlsaMixer * mixer);
-
-/* interface implementation */
+/* GstMixer */
 static const GList *gst_alsa_mixer_list_tracks (GstMixer * mixer);
-
 static void gst_alsa_mixer_set_volume (GstMixer * mixer,
     GstMixerTrack * track, gint * volumes);
 static void gst_alsa_mixer_get_volume (GstMixer * mixer,
     GstMixerTrack * track, gint * volumes);
-
 static void gst_alsa_mixer_set_record (GstMixer * mixer,
     GstMixerTrack * track, gboolean record);
 static void gst_alsa_mixer_set_mute (GstMixer * mixer,
     GstMixerTrack * track, gboolean mute);
-
 static void gst_alsa_mixer_set_option (GstMixer * mixer,
     GstMixerOptions * opts, gchar * value);
 static const gchar *gst_alsa_mixer_get_option (GstMixer * mixer,
     GstMixerOptions * opts);
 
-/*** GOBJECT STUFF ************************************************************/
-
-static GstAlsa *parent_class = NULL;
-
-GType
-gst_alsa_mixer_get_type (void)
+static void
+gst_alsa_mixer_base_init (gpointer klass)
 {
-  static GType alsa_mixer_type = 0;
-
-  if (!alsa_mixer_type) {
-    static const GTypeInfo alsa_mixer_info = {
-      sizeof (GstAlsaMixerClass),
-      NULL,
-      NULL,
-      gst_alsa_mixer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAlsaMixer),
-      0,
-      (GInstanceInitFunc) gst_alsa_mixer_init,
-    };
-    static const GInterfaceInfo alsa_iface_info = {
-      (GInterfaceInitFunc) gst_alsa_interface_init,
-      NULL,
-      NULL,
-    };
-    static const GInterfaceInfo alsa_mixer_iface_info = {
-      (GInterfaceInitFunc) gst_alsa_mixer_interface_init,
-      NULL,
-      NULL,
-    };
-
-    alsa_mixer_type =
-        g_type_register_static (GST_TYPE_ALSA, "GstAlsaMixer", &alsa_mixer_info,
-        0);
-
-    g_type_add_interface_static (alsa_mixer_type, GST_TYPE_IMPLEMENTS_INTERFACE,
-        &alsa_iface_info);
-    g_type_add_interface_static (alsa_mixer_type, GST_TYPE_MIXER,
-        &alsa_mixer_iface_info);
-  }
-
-  return alsa_mixer_type;
+  gst_element_class_set_details (GST_ELEMENT_CLASS (klass),
+      &gst_alsa_mixer_details);
 }
 
 static void
-gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data)
+gst_alsa_mixer_class_init (GstAlsaMixerClass * klass)
 {
-  GObjectClass *object_class;
   GstElementClass *element_class;
-  GstAlsaClass *klass;
-
-  klass = (GstAlsaClass *) g_class;
-  object_class = (GObjectClass *) g_class;
-  element_class = (GstElementClass *) g_class;
 
-  if (parent_class == NULL)
-    parent_class = g_type_class_ref (GST_TYPE_ALSA);
+  element_class = (GstElementClass *) klass;
 
   element_class->change_state = gst_alsa_mixer_change_state;
-
-  gst_element_class_set_details (element_class, &gst_alsa_mixer_details);
 }
 
 static void
@@ -136,10 +114,9 @@ static gboolean
 gst_alsa_mixer_open (GstAlsaMixer * mixer)
 {
   gint err, device;
-  GstAlsa *alsa = GST_ALSA (mixer);
   gchar *nocomma = NULL;
 
-  mixer->mixer_handle = NULL;
+  g_return_val_if_fail (mixer->mixer_handle == NULL, FALSE);
 
   /* open and initialize the mixer device */
   err = snd_mixer_open (&mixer->mixer_handle, 0);
@@ -148,6 +125,8 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
     mixer->mixer_handle = NULL;
     return FALSE;
   }
+#if 0
+  GstAlsa *alsa = GST_ALSA (mixer);
 
   if (!strncmp (alsa->device, "hw:", 3))
     nocomma = g_strdup (alsa->device);
@@ -155,6 +134,9 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
     nocomma = g_strdup (alsa->device + 4);
   else
     goto error;
+#else
+  nocomma = g_strdup ("hw:0");
+#endif
 
   if (strchr (nocomma, ','))
     strchr (nocomma, ',')[0] = '\0';
@@ -181,7 +163,7 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
     gchar *name;
 
     if (!snd_card_get_name (device, &name))
-      alsa->cardname = name;
+      mixer->cardname = name;
   }
 
   g_free (nocomma);
@@ -198,49 +180,19 @@ error:
 static void
 gst_alsa_mixer_close (GstAlsaMixer * mixer)
 {
-  GstAlsa *alsa = GST_ALSA (mixer);
-
   if (mixer->mixer_handle == NULL)
     return;
 
-  if (alsa->cardname) {
-    g_free (alsa->cardname);
-    alsa->cardname = NULL;
+  if (mixer->cardname) {
+    free (mixer->cardname);
+    mixer->cardname = NULL;
   }
+
   snd_mixer_close (mixer->mixer_handle);
   mixer->mixer_handle = NULL;
 }
 
 static void
-gst_alsa_interface_init (GstImplementsInterfaceClass * klass)
-{
-  klass->supported = gst_alsa_mixer_supported;
-}
-
-static void
-gst_alsa_mixer_interface_init (GstMixerClass * klass)
-{
-  GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE;
-
-  /* set up the interface hooks */
-  klass->list_tracks = gst_alsa_mixer_list_tracks;
-  klass->set_volume = gst_alsa_mixer_set_volume;
-  klass->get_volume = gst_alsa_mixer_get_volume;
-  klass->set_mute = gst_alsa_mixer_set_mute;
-  klass->set_record = gst_alsa_mixer_set_record;
-  klass->set_option = gst_alsa_mixer_set_option;
-  klass->get_option = gst_alsa_mixer_get_option;
-}
-
-gboolean
-gst_alsa_mixer_supported (GstImplementsInterface * iface, GType iface_type)
-{
-  g_assert (iface_type == GST_TYPE_MIXER);
-
-  return (GST_ALSA_MIXER (iface)->mixer_handle != NULL);
-}
-
-static void
 gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
 {
   gint i, count;
@@ -349,8 +301,6 @@ gst_alsa_mixer_free_list (GstAlsaMixer * mixer)
   mixer->tracklist = NULL;
 }
 
-/*** GSTREAMER FUNCTIONS ******************************************************/
-
 static GstElementStateReturn
 gst_alsa_mixer_change_state (GstElement * element)
 {
@@ -382,6 +332,29 @@ gst_alsa_mixer_change_state (GstElement * element)
 
 /*** INTERFACE IMPLEMENTATION *************************************************/
 
+static void
+gst_alsa_mixer_interface_init (GstMixerClass * klass)
+{
+  GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE;
+
+  /* set up the interface hooks */
+  klass->list_tracks = gst_alsa_mixer_list_tracks;
+  klass->set_volume = gst_alsa_mixer_set_volume;
+  klass->get_volume = gst_alsa_mixer_get_volume;
+  klass->set_mute = gst_alsa_mixer_set_mute;
+  klass->set_record = gst_alsa_mixer_set_record;
+  klass->set_option = gst_alsa_mixer_set_option;
+  klass->get_option = gst_alsa_mixer_get_option;
+}
+
+gboolean
+gst_alsa_mixer_supported (GstAlsaMixer * object, GType iface_type)
+{
+  g_assert (iface_type == GST_TYPE_MIXER);
+
+  return (object->mixer_handle != NULL);
+}
+
 static const GList *
 gst_alsa_mixer_list_tracks (GstMixer * mixer)
 {
@@ -559,13 +532,16 @@ static const gchar *
 gst_alsa_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
 {
   GstAlsaMixerOptions *alsa_opts = (GstAlsaMixerOptions *) opts;
-  gint idx = -1;
+  gint ret;
+  guint idx;
 
   g_return_val_if_fail (GST_ALSA_MIXER (mixer)->mixer_handle != NULL, NULL);
 
   gst_alsa_mixer_update (GST_ALSA_MIXER (mixer), NULL);
 
-  snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
-
-  return g_list_nth_data (opts->values, idx);
+  ret = snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
+  if (ret == 0)
+    return g_list_nth_data (opts->values, idx);
+  else
+    return snd_strerror (ret);  /* feeble attempt at error handling */
 }
index 1f98566..9c983df 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 #ifndef __GST_ALSA_MIXER_H__
 #define __GST_ALSA_MIXER_H__
 
+
 #include "gstalsa.h"
+#include <gst/interfaces/mixer.h>
+
 #include "gstalsamixeroptions.h"
 #include "gstalsamixertrack.h"
-#include <gst/interfaces/mixer.h>
+
 
 G_BEGIN_DECLS
 
+
 #define GST_ALSA_MIXER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER,GstAlsaMixer))
 #define GST_ALSA_MIXER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER,GstAlsaMixerClass))
 #define GST_IS_ALSA_MIXER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER))
 #define GST_IS_ALSA_MIXER_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER))
 #define GST_TYPE_ALSA_MIXER            (gst_alsa_mixer_get_type())
 
+
 typedef struct _GstAlsaMixer GstAlsaMixer;
 typedef struct _GstAlsaMixerClass GstAlsaMixerClass;
 
+
 struct _GstAlsaMixer {
-  GstAlsa      parent;
-  GList *      tracklist;      /* list of available tracks */
-  snd_mixer_t *        mixer_handle;
+  GstElement           parent;
+
+  GList *              tracklist;      /* list of available tracks */
+
+  snd_mixer_t *                mixer_handle;
+
+  gchar *              cardname;
 };
 
 struct _GstAlsaMixerClass {
-  GstAlsaClass parent;
+  GstElementClass      parent;
 };
 
+
 GType          gst_alsa_mixer_get_type         (void);
 
+
 G_END_DECLS
 
+
 #endif /* __GST_ALSA_MIXER_H__ */
index 0595a2c..af909df 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 #ifndef __GST_ALSA_MIXER_OPTIONS_H__
 #define __GST_ALSA_MIXER_OPTIONS_H__
 
+
 #include "gstalsa.h"
 #include <gst/interfaces/mixeroptions.h>
 
+
 G_BEGIN_DECLS
 
+
 #define GST_ALSA_MIXER_OPTIONS_TYPE            (gst_alsa_mixer_options_get_type ())
 #define GST_ALSA_MIXER_OPTIONS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptions))
 #define GST_ALSA_MIXER_OPTIONS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptionsClass))
@@ -31,9 +35,11 @@ G_BEGIN_DECLS
 #define GST_IS_ALSA_MIXER_OPTIONS_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER_OPTIONS))
 #define GST_TYPE_ALSA_MIXER_OPTIONS            (gst_alsa_mixer_options_get_type())
 
+
 typedef struct _GstAlsaMixerOptions GstAlsaMixerOptions;
 typedef struct _GstAlsaMixerOptionsClass GstAlsaMixerOptionsClass;
 
+
 struct _GstAlsaMixerOptions {
   GstMixerOptions       parent;
   snd_mixer_elem_t     *element; /* the ALSA mixer element for this track */
@@ -44,10 +50,13 @@ struct _GstAlsaMixerOptionsClass {
   GstMixerOptionsClass parent;
 };
 
+
 GType          gst_alsa_mixer_options_get_type (void);
 GstMixerOptions *gst_alsa_mixer_options_new    (snd_mixer_elem_t *     element,
                                                 gint                   track_num);
 
+
 G_END_DECLS
 
+
 #endif /* __GST_ALSA_MIXER_OPTIONS_H__ */
index 1bba405..ee5dff9 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 #ifndef __GST_ALSA_MIXER_TRACK_H__
 #define __GST_ALSA_MIXER_TRACK_H__
 
+
 #include "gstalsa.h"
 #include <gst/interfaces/mixertrack.h>
 
+
 G_BEGIN_DECLS
 
+
 #define GST_ALSA_MIXER_TRACK_TYPE              (gst_alsa_mixer_track_get_type ())
 #define GST_ALSA_MIXER_TRACK(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrack))
 #define GST_ALSA_MIXER_TRACK_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrackClass))
@@ -37,6 +41,7 @@ typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass;
 #define GST_ALSA_MIXER_TRACK_CAPTURE  (1<<0)
 #define GST_ALSA_MIXER_TRACK_PLAYBACK (1<<1)
 
+#define GST_ALSA_MAX_CHANNELS  32 /* tracks can have up to 32 channels */
 struct _GstAlsaMixerTrack {
   GstMixerTrack                 parent;
   snd_mixer_elem_t     *element; /* the ALSA mixer element for this track */
@@ -57,6 +62,8 @@ GstMixerTrack *       gst_alsa_mixer_track_new        (snd_mixer_elem_t *     element,
                                                 gint                   flags,
                                                 gint                   alsa_flags);
 
+
 G_END_DECLS
 
+
 #endif /* __GST_ALSA_MIXER_TRACK_H__ */
index 029ca8b..5fe1c36 100644 (file)
@@ -56,11 +56,9 @@ plugin_init (GstPlugin * plugin)
 {
   int err;
 
-  /*
-     if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
-     GST_TYPE_ALSA_MIXER))
-     return FALSE;
-   */
+  if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
+          GST_TYPE_ALSA_MIXER))
+    return FALSE;
   if (!gst_element_register (plugin, "alsasrc", GST_RANK_PRIMARY,
           GST_TYPE_ALSA_SRC))
     return FALSE;