On Tue, Oct 28, 2008 at 03:31:38AM +0000, Jacob Meuser wrote:
> 
> this adds playback and recording backends using libsndio.  gstreamer
> will use them by default.

any objections to this going in?

> please test with any and all ports that use gstreamer for audio i/o.
> I only use this with gnash.  grepping ports/INDEX suggests these:
> 
> rhythmbox-0.11.5
> subtitleeditor-0.13.6p1
> gcompris-8.4.4p2
> swfdec-0.6.8
> py-gstreamer-0.10.11p0
> oggconvert-0.3.0
> emesene-1.0
> farsight-0.1.25p2
> gnash-0.8.3p1
> gnome-applets2-2.20.0p5
> gnomebaker-0.6.4
> control-center2-2.20.3p6
> gnome-media-2.20.1p4
> totem-2.22.2p2
> kdemultimedia-3.5.10
> 
> patch also available at
> http://jakemsr.trancell.org/plugins-good-libsndio.diff
> 
> if this works for people, I suggest removing the patches/modules for
> OSS and audio(4) and quit trying to maintain them ... same for SDL.
> 
> and I will of course push this upstream if people like it.
> 
> -- 
> [EMAIL PROTECTED]
> SDF Public Access UNIX System - http://sdf.lonestar.org
> 
> Index: Makefile
> ===================================================================
> RCS file: 
> /home2/cvs/OpenBSD/ports/multimedia/gstreamer-0.10/plugins-good/Makefile,v
> retrieving revision 1.24
> diff -u -r1.24 Makefile
> --- Makefile  24 Sep 2008 23:01:32 -0000      1.24
> +++ Makefile  28 Oct 2008 03:09:03 -0000
> @@ -18,7 +18,7 @@
>  
>  V =                  0.10.8
>  DISTNAME =           gst-plugins-good-$V
> -PKGNAME-main =               gstreamer-plugins-good-$Vp4
> +PKGNAME-main =               gstreamer-plugins-good-$Vp5
>  PKGNAME-aalib =              gstreamer-aalib-$Vp0
>  PKGNAME-cairo =              gstreamer-cairo-$Vp1
>  PKGNAME-gconf =              gstreamer-confelements-$Vp0
> @@ -50,7 +50,7 @@
>  LIB_DEPENDS =                gstreamer-0.10:gstreamer->=0.10:$P/core
>  
>  WANTLIB-main =               ${WANTLIB} \
> -                     ICE SM X11 Xdamage Xext Xfixes ossaudio \
> +                     ICE SM X11 Xdamage Xext Xfixes ossaudio sndio \
>                       gstcontroller-0.10 gstbase-0.10 Xau Xdmcp
>  LIB_DEPENDS-main =   ${LIB_DEPENDS} \
>                       oil-0.3::devel/liboil \
> @@ -148,6 +148,10 @@
>  LIB_DEPENDS-soup =   ${LIB_DEPENDS} \
>                       soup-2.4::devel/libsoup
>  
> +BUILD_DEPENDS +=     ${MODGNU_AUTOCONF_DEPENDS} \
> +                     ${MODGNU_AUTOMAKE_DEPENDS} 
> +AUTOMAKE_VERSION =   1.9
> +CONFIGURE_STYLE =    gnu
>  CONFIGURE_ARGS +=    --with-aalib-prefix=${LOCALBASE} \
>                       --disable-cdio \
>                       --disable-dv1394 \
> @@ -156,9 +160,16 @@
>                       --disable-schemas-install \
>                       --enable-experimental \
>                       --enable-gst_v4l2 \
> -                     --with-default-audiosink=osssink \
> -                     --with-default-audiosrc=osssrc \
> +                     --with-default-audiosink=libsndiosink \
> +                     --with-default-audiosrc=libsndiosrc \
>                       --with-default-videosink=xvimagesink \
>                       --with-default-videosrc=v4l2src
> +
> +post-extract:
> +     cp -R ${FILESDIR} ${WRKSRC}/ext/libsndio
> +
> +pre-configure:
> +     cd ${WRKSRC} && AUTOCONF_VERSION=${AUTOCONF_VERSION} \
> +             AUTOMAKE_VERSION=${AUTOMAKE_VERSION} NOCONFIGURE="true" 
> ./autogen.sh
>  
>  .include <bsd.port.mk>
> Index: files/Makefile.am
> ===================================================================
> RCS file: files/Makefile.am
> diff -N files/Makefile.am
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ files/Makefile.am 28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,11 @@
> +plugin_LTLIBRARIES = libgstlibsndio.la
> +
> +libgstlibsndio_la_SOURCES = gstlibsndio.c libsndiosink.c libsndiosrc.c 
> +libgstlibsndio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
> +libgstlibsndio_la_LIBADD = \
> +     $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) \
> +     $(LIBSNDIO_LIBS)
> +libgstlibsndio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
> +
> +noinst_HEADERS = libsndiosink.h libsndiosrc.h
> +EXTRA_DIST =
> Index: files/gstlibsndio.c
> ===================================================================
> RCS file: files/gstlibsndio.c
> diff -N files/gstlibsndio.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ files/gstlibsndio.c       28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,54 @@
> +/* GStreamer
> + * Copyright (C) <2008> Jacob Meuser <[EMAIL PROTECTED]>
> + *
> + * 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., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +#include "libsndiosink.h"
> +#include "libsndiosrc.h"
> +
> +#include "gst/gst-i18n-plugin.h"
> +
> +GST_DEBUG_CATEGORY (libsndio_debug);
> +
> +static gboolean
> +plugin_init (GstPlugin * plugin)
> +{
> +  if (!gst_element_register (plugin, "libsndiosrc", GST_RANK_PRIMARY,
> +          GST_TYPE_LIBSNDIOSRC) ||
> +      !gst_element_register (plugin, "libsndiosink", GST_RANK_PRIMARY,
> +          GST_TYPE_LIBSNDIOSINK)) {
> +    return FALSE;
> +  }
> +
> +  GST_DEBUG_CATEGORY_INIT (libsndio_debug, "libsndio", 0, "libsndio 
> elements");
> +
> +#ifdef ENABLE_NLS
> +  setlocale (LC_ALL, "");
> +  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
> +#endif /* ENABLE_NLS */
> +
> +  return TRUE;
> +}
> +
> +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
> +    GST_VERSION_MINOR,
> +    "libsndio",
> +    "libsndio support for GStreamer",
> +    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
> Index: files/libsndiosink.c
> ===================================================================
> RCS file: files/libsndiosink.c
> diff -N files/libsndiosink.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ files/libsndiosink.c      28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,536 @@
> +/* GStreamer
> + * Copyright (C) <2008> Jacob Meuser <[EMAIL PROTECTED]>
> + *
> + * libsndiosink.c: libsndio audio sink
> + *
> + * 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., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +/**
> + * SECTION:element-libsndiosink
> + * @see_also: #GstAutoAudioSink
> + *
> + * <refsect2>
> + * <para>
> + * This element outputs sound to a sound card using libsndio.
> + * </para>
> + * <para>
> + * Simple example pipeline that plays an Ogg/Vorbis file via libsndio:
> + * <programlisting>
> + * gst-launch -v filesrc location=foo.ogg ! decodebin ! audioconvert ! 
> audioresample ! libsndiosink
> + * </programlisting>
> + * </para>
> + * </refsect2>
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include "libsndiosink.h"
> +#include <unistd.h>
> +#include <errno.h>
> +
> +#include <gst/gst-i18n-plugin.h>
> +
> +GST_DEBUG_CATEGORY_EXTERN (libsndio_debug);
> +#define GST_CAT_DEFAULT libsndio_debug
> +
> +/* elementfactory information */
> +static const GstElementDetails libsndiosink_details =
> +GST_ELEMENT_DETAILS ("Libsndio audio sink",
> +    "Sink/Audio",
> +    "Plays audio through libsndio",
> +    "Jacob Meuser <[EMAIL PROTECTED]>");
> +
> +enum
> +{
> +  PROP_0,
> +  PROP_HOST
> +};
> +
> +static GstStaticPadTemplate libsndio_sink_factory =
> +    GST_STATIC_PAD_TEMPLATE ("sink",
> +    GST_PAD_SINK,
> +    GST_PAD_ALWAYS,
> +    GST_STATIC_CAPS ("audio/x-raw-int, "
> +        "endianness = (int) { 1234, 4321 }, "
> +        "signed = (boolean) { TRUE, FALSE }, "
> +        "width = (int) { 8, 16, 24, 32 }, "
> +        "depth = (int) { 8, 16, 24, 32 }, "
> +        "rate = (int) [ 8000, 192000 ], "
> +        "channels = (int) [ 1, 16 ] ")
> +    );
> +
> +static void gst_libsndiosink_finalize (GObject * object);
> +
> +static GstCaps *gst_libsndiosink_getcaps (GstBaseSink * bsink);
> +
> +static gboolean gst_libsndiosink_open (GstAudioSink * asink);
> +static gboolean gst_libsndiosink_close (GstAudioSink * asink);
> +static gboolean gst_libsndiosink_prepare (GstAudioSink * asink,
> +    GstRingBufferSpec * spec);
> +static gboolean gst_libsndiosink_unprepare (GstAudioSink * asink);
> +static guint gst_libsndiosink_write (GstAudioSink * asink, gpointer data,
> +    guint length);
> +static guint gst_libsndiosink_delay (GstAudioSink * asink);
> +static void gst_libsndiosink_reset (GstAudioSink * asink);
> +
> +static void gst_libsndiosink_set_property (GObject * object, guint prop_id,
> +    const GValue * value, GParamSpec * pspec);
> +static void gst_libsndiosink_get_property (GObject * object, guint prop_id,
> +    GValue * value, GParamSpec * pspec);
> +static void gst_libsndiosink_cb(void * addr, int delta);
> +
> +GST_BOILERPLATE (GstLibsndioSink, gst_libsndiosink, GstAudioSink, 
> GST_TYPE_AUDIO_SINK);
> +
> +static void
> +gst_libsndiosink_base_init (gpointer g_class)
> +{
> +  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
> +
> +  gst_element_class_set_details (element_class, &libsndiosink_details);
> +
> +  gst_element_class_add_pad_template (element_class,
> +      gst_static_pad_template_get (&libsndio_sink_factory));
> +}
> +
> +static void
> +gst_libsndiosink_class_init (GstLibsndioSinkClass * klass)
> +{
> +  GObjectClass *gobject_class;
> +  GstBaseSinkClass *gstbasesink_class;
> +  GstBaseAudioSinkClass *gstbaseaudiosink_class;
> +  GstAudioSinkClass *gstaudiosink_class;
> +
> +  gobject_class = (GObjectClass *) klass;
> +  gstbasesink_class = (GstBaseSinkClass *) klass;
> +  gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
> +  gstaudiosink_class = (GstAudioSinkClass *) klass;
> +
> +  parent_class = g_type_class_peek_parent (klass);
> +
> +  gobject_class->finalize = gst_libsndiosink_finalize;
> +
> +  gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_libsndiosink_getcaps);
> +
> +  gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_libsndiosink_open);
> +  gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_libsndiosink_close);
> +  gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_libsndiosink_prepare);
> +  gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR 
> (gst_libsndiosink_unprepare);
> +  gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_libsndiosink_write);
> +  gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_libsndiosink_delay);
> +  gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_libsndiosink_reset);
> +
> +  gobject_class->set_property = gst_libsndiosink_set_property;
> +  gobject_class->get_property = gst_libsndiosink_get_property;
> +
> +  /* default value is filled in the _init method */
> +  g_object_class_install_property (gobject_class, PROP_HOST,
> +      g_param_spec_string ("host", "Host",
> +          "Device or socket libsndio will access", NULL, G_PARAM_READWRITE));
> +}
> +
> +static void
> +gst_libsndiosink_init (GstLibsndioSink * libsndiosink, GstLibsndioSinkClass 
> * klass)
> +{
> +  libsndiosink->hdl = NULL;
> +  libsndiosink->host = g_strdup (g_getenv ("AUDIODEVICE"));
> +}
> +
> +static void
> +gst_libsndiosink_finalize (GObject * object)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (object);
> +
> +  gst_caps_replace (&libsndiosink->cur_caps, NULL);
> +  g_free (libsndiosink->host);
> +
> +  G_OBJECT_CLASS (parent_class)->finalize (object);
> +}
> +
> +static GstCaps *
> +gst_libsndiosink_getcaps (GstBaseSink * bsink)
> +{
> +  GstLibsndioSink *libsndiosink;
> +
> +  libsndiosink = GST_LIBSNDIOSINK (bsink);
> +
> +  /* no hdl, we're done with the template caps */
> +  if (libsndiosink->cur_caps == NULL) {
> +    GST_LOG_OBJECT (libsndiosink, "getcaps called, returning template caps");
> +    return NULL;
> +  }
> +
> +  GST_LOG_OBJECT (libsndiosink, "returning %" GST_PTR_FORMAT, 
> libsndiosink->cur_caps);
> +
> +  return gst_caps_ref (libsndiosink->cur_caps);
> +}
> +
> +static gboolean
> +gst_libsndiosink_open (GstAudioSink * asink)
> +{
> +  GstPadTemplate *pad_template;
> +  GstLibsndioSink *libsndiosink;
> +  struct sio_par par;
> +  struct sio_cap cap;
> +  GArray *rates, *chans;
> +  GValue rates_v = { 0 };
> +  GValue chans_v = { 0 };
> +  GValue value = { 0 };
> +  struct sio_enc enc;
> +  struct sio_conf conf;
> +  int confs[SIO_NCONF];
> +  int rate, chan;
> +  int i, j, k;
> +  int nconfs;
> +
> +
> +  libsndiosink = GST_LIBSNDIOSINK (asink);
> +
> +  GST_DEBUG_OBJECT (libsndiosink, "open");
> +
> +  /* conect */
> +  libsndiosink->hdl = sio_open (libsndiosink->host, SIO_PLAY, 0);
> +
> +  if (libsndiosink->hdl == NULL)
> +    goto couldnt_connect;
> +
> +  /* Use libsndio defaults as the only encodings, but get the supported
> +   * sample rates and number of channels.
> +   */
> +
> +  if (!sio_getpar(libsndiosink->hdl, &par))
> +    goto no_server_info;
> +
> +  if (!sio_getcap(libsndiosink->hdl, &cap))
> +    goto no_server_info;
> +
> +  rates = g_array_new(FALSE, FALSE, sizeof(int));
> +  chans = g_array_new(FALSE, FALSE, sizeof(int));
> +
> +  /* find confs that have the default encoding */
> +  nconfs = 0;
> +  for (i = 0; i < cap.nconf; i++) {
> +    for (j = 0; j < SIO_NENC; j++) {
> +      if (cap.confs[i].enc & (1 << j)) {
> +        enc = cap.enc[j];
> +        if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
> +            confs[nconfs] = i;
> +            nconfs++;
> +            break;
> +        }
> +      }
> +    }
> +  }
> +
> +  /* find the rates and channels of the confs that have the default encoding 
> */
> +  for (i = 0; i < nconfs; i++) {
> +    conf = cap.confs[confs[i]];
> +    /* rates */
> +    for (j = 0; j < SIO_NRATE; j++) {
> +      if (conf.rate & (1 << j)) {
> +        rate = cap.rate[j];
> +        for (k = 0; k < rates->len && rate; k++) {
> +          if (rate == g_array_index(rates, int, k))
> +            rate = 0;
> +        }
> +        /* add in ascending order */
> +        if (rate) {
> +          for (k = 0; k < rates->len; k++) {
> +            if (rate < g_array_index(rates, int, k)) {
> +              g_array_insert_val(rates, k, rate);
> +              break;
> +            }
> +          }
> +          if (k == rates->len)
> +            g_array_append_val(rates, rate);
> +        }
> +      }
> +    }
> +    /* channels */
> +    for (j = 0; j < SIO_NCHAN; j++) {
> +      if (conf.pchan & (1 << j)) {
> +        chan = cap.pchan[j];
> +        for (k = 0; k < chans->len && chan; k++) {
> +          if (chan == g_array_index(chans, int, k))
> +            chan = 0;
> +        }
> +        /* add in ascending order */
> +        if (chan) {
> +          for (k = 0; k < chans->len; k++) {
> +            if (chan < g_array_index(chans, int, k)) {
> +              g_array_insert_val(chans, k, chan);
> +              break;
> +            }
> +          }
> +          if (k == chans->len)
> +            g_array_append_val(chans, chan);
> +        }
> +      }
> +    }
> +  }
> +  /* not sure how this can happen, but it might */
> +  if (cap.nconf == 0) {
> +    g_array_append_val(rates, par.rate);
> +    g_array_append_val(chans, par.pchan);
> +  }
> +
> +  g_value_init(&rates_v, GST_TYPE_LIST);
> +  g_value_init(&chans_v, GST_TYPE_LIST);
> +  g_value_init(&value, G_TYPE_INT);
> +
> +  for (i = 0; i < rates->len; i++) {
> +    g_value_set_int(&value, g_array_index(rates, int, i));
> +    gst_value_list_append_value(&rates_v, &value);
> +  }
> +  for (i = 0; i < chans->len; i++) {
> +    g_value_set_int(&value, g_array_index(chans, int, i));
> +    gst_value_list_append_value(&chans_v, &value);
> +  }
> +
> +  g_array_free(rates, TRUE);
> +  g_array_free(chans, TRUE);
> +
> +  pad_template = gst_static_pad_template_get (&libsndio_sink_factory);
> +  libsndiosink->cur_caps = gst_caps_copy (gst_pad_template_get_caps 
> (pad_template));
> +  gst_object_unref (pad_template);
> +
> +  for (i = 0; i < libsndiosink->cur_caps->structs->len; i++) {
> +    GstStructure *s;
> +
> +    s = gst_caps_get_structure (libsndiosink->cur_caps, i);
> +    gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, 
> NULL);
> +    gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE, 
> NULL);
> +    gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
> +    // gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX 
> */
> +    gst_structure_set_value (s, "rate", &rates_v);
> +    gst_structure_set_value (s, "channels", &chans_v);
> +  }
> +
> +  return TRUE;
> +
> +  /* ERRORS */
> +couldnt_connect:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
> +        (_("Could not establish connection to libsndio")),
> +        ("can't open connection to libsndio"));
> +    return FALSE;
> +  }
> +no_server_info:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
> +        (_("Failed to query libsndio capabilities")),
> +        ("couldn't get libsndio info!"));
> +    return FALSE;
> +  }
> +}
> +
> +static gboolean
> +gst_libsndiosink_close (GstAudioSink * asink)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
> +
> +  GST_DEBUG_OBJECT (libsndiosink, "close");
> +
> +  gst_caps_replace (&libsndiosink->cur_caps, NULL);
> +  sio_close (libsndiosink->hdl);
> +  libsndiosink->hdl = NULL;
> +
> +  return TRUE;
> +}
> +
> +static void
> +gst_libsndiosink_cb(void *addr, int delta)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK ((GstAudioSink *)addr);
> +
> +  libsndiosink->realpos += delta;
> +
> +  if (libsndiosink->realpos >= libsndiosink->playpos)
> +    libsndiosink->latency = 0;
> +  else
> +    libsndiosink->latency = libsndiosink->playpos - libsndiosink->realpos;
> +}
> +
> +static gboolean
> +gst_libsndiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
> +  struct sio_par par;
> +  int spec_bpf;
> +
> +  GST_DEBUG_OBJECT (libsndiosink, "prepare");
> +
> +  libsndiosink->playpos = libsndiosink->realpos = libsndiosink->latency = 0;
> +
> +  sio_initpar(&par);
> +  par.sig = spec->sign;
> +  par.le = !spec->bigend;
> +  par.bits = spec->width;
> +  // par.bps = spec->depth / 8;  /* XXX */
> +  par.rate = spec->rate;
> +  par.pchan = spec->channels;
> +
> +  spec_bpf = ((spec->width / 8) * spec->channels);
> +
> +  par.bufsz = (spec->segsize * spec->segtotal) / spec_bpf;
> +
> +  if (!sio_setpar(libsndiosink->hdl, &par))
> +    goto cannot_configure;
> +
> +  sio_getpar(libsndiosink->hdl, &par);
> +
> +  spec->sign = par.sig;
> +  spec->bigend = !par.le;
> +  spec->width = par.bits;
> +  // spec->depth = par.bps * 8;  /* XXX */
> +  spec->rate = par.rate;
> +  spec->channels = par.pchan;
> +
> +  libsndiosink->bpf = par.bps * par.pchan;
> +
> +  spec->segsize = par.round * par.pchan * par.bps;
> +  spec->segtotal = par.bufsz / par.round;
> +
> +  /* FIXME: this is wrong for signed ints (and the
> +   * audioringbuffers should do it for us anyway) */
> +  spec->silence_sample[0] = 0;
> +  spec->silence_sample[1] = 0;
> +  spec->silence_sample[2] = 0;
> +  spec->silence_sample[3] = 0;
> +
> +  sio_onmove(libsndiosink->hdl, gst_libsndiosink_cb, libsndiosink);
> +
> +  if (!sio_start(libsndiosink->hdl))
> +    goto cannot_start;
> +
> +  GST_INFO_OBJECT (libsndiosink, "successfully opened connection to 
> libsndio");
> +
> +  return TRUE;
> +
> +  /* ERRORS */
> +cannot_configure:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
> +        (_("Could not configure libsndio")),
> +        ("can't configure libsndio"));
> +    return FALSE;
> +  }
> +cannot_start:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosink, RESOURCE, OPEN_WRITE,
> +        (_("Could not start libsndio")),
> +        ("can't start libsndio"));
> +    return FALSE;
> +  }
> +}
> +
> +static gboolean
> +gst_libsndiosink_unprepare (GstAudioSink * asink)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
> +
> +  if (libsndiosink->hdl == NULL)
> +    return TRUE;
> +
> +  sio_stop(libsndiosink->hdl);
> +
> +  return TRUE;
> +}
> +
> +
> +static guint
> +gst_libsndiosink_write (GstAudioSink * asink, gpointer data, guint length)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
> +  guint done;
> +
> +  done = sio_write (libsndiosink->hdl, data, length);
> +
> +  if (done == 0)
> +    goto write_error;
> +
> +  libsndiosink->playpos += (done / libsndiosink->bpf);
> +
> +  data = (char *) data + done;
> +
> +  return done;
> +
> +  /* ERRORS */
> +write_error:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosink, RESOURCE, WRITE,
> +        ("Failed to write data to libsndio"), GST_ERROR_SYSTEM);
> +    return 0;
> +  }
> +}
> +
> +static guint
> +gst_libsndiosink_delay (GstAudioSink * asink)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (asink);
> +
> +  if (libsndiosink->latency == (guint) - 1) {
> +    GST_WARNING_OBJECT (asink, "couldn't get latency");
> +    return 0;
> +  }
> +
> +  GST_DEBUG_OBJECT (asink, "got latency: %u", libsndiosink->latency);
> +
> +  return libsndiosink->latency;
> +}
> +
> +static void
> +gst_libsndiosink_reset (GstAudioSink * asink)
> +{
> +  /* no way to flush the buffers with libsndio ? */
> +
> +  GST_DEBUG_OBJECT (asink, "reset called");
> +}
> +
> +static void
> +gst_libsndiosink_set_property (GObject * object, guint prop_id, const GValue 
> * value,
> +    GParamSpec * pspec)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (object);
> +
> +  switch (prop_id) {
> +    case PROP_HOST:
> +      g_free (libsndiosink->host);
> +      libsndiosink->host = g_value_dup_string (value);
> +      break;
> +    default:
> +      break;
> +  }
> +}
> +
> +static void
> +gst_libsndiosink_get_property (GObject * object, guint prop_id, GValue * 
> value,
> +    GParamSpec * pspec)
> +{
> +  GstLibsndioSink *libsndiosink = GST_LIBSNDIOSINK (object);
> +
> +  switch (prop_id) {
> +    case PROP_HOST:
> +      g_value_set_string (value, libsndiosink->host);
> +      break;
> +    default:
> +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> +      break;
> +  }
> +}
> Index: files/libsndiosink.h
> ===================================================================
> RCS file: files/libsndiosink.h
> diff -N files/libsndiosink.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ files/libsndiosink.h      28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,72 @@
> +/* GStreamer
> + * Copyright (C) <2008> Jacob Meuser <[EMAIL PROTECTED]>
> + *
> + * libsndiosink.h: libsndio audio sink
> + *
> + * 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., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +
> +#ifndef __GST_LIBSNDIOSINK_H__
> +#define __GST_LIBSNDIOSINK_H__
> +
> +#include <sndio.h>
> +
> +#include <gst/gst.h>
> +#include <gst/audio/gstaudiosink.h>
> +
> +G_BEGIN_DECLS
> +
> +#define GST_TYPE_LIBSNDIOSINK \
> +  (gst_libsndiosink_get_type())
> +#define GST_LIBSNDIOSINK(obj) \
> +  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LIBSNDIOSINK,GstLibsndioSink))
> +#define GST_LIBSNDIOSINK_CLASS(klass) \
> +  
> (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LIBSNDIOSINK,GstLibsndioSinkClass))
> +#define GST_IS_LIBSNDIOSINK(obj) \
> +  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LIBSNDIOSINK))
> +#define GST_IS_LIBSNDIOSINK_CLASS(klass) \
> +  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LIBSNDIOSINK))
> +
> +typedef struct _GstLibsndioSink GstLibsndioSink;
> +typedef struct _GstLibsndioSinkClass GstLibsndioSinkClass;
> +
> +struct _GstLibsndioSink {
> +  GstAudioSink   sink;
> +
> +  struct sio_hdl *hdl;
> +  gchar    *host;
> +
> +  /* bytes per frame */
> +  int bpf;
> +
> +  /* frames counts */
> +  volatile long long realpos;
> +  volatile long long playpos;
> +  volatile guint latency;
> +
> +  GstCaps  *cur_caps;
> +};
> +
> +struct _GstLibsndioSinkClass {
> +  GstAudioSinkClass parent_class;
> +};
> +
> +GType gst_libsndiosink_get_type (void);
> +
> +G_END_DECLS
> +
> +#endif /* __GST_LIBSNDIOSINK_H__ */
> Index: files/libsndiosrc.c
> ===================================================================
> RCS file: files/libsndiosrc.c
> diff -N files/libsndiosrc.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ files/libsndiosrc.c       28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,536 @@
> +/* GStreamer
> + * Copyright (C) <2008> Jacob Meuser <[EMAIL PROTECTED]>
> + *
> + * libsndiosrc.c: libsndio audio source
> + *
> + * 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., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +/**
> + * SECTION:element-libsndiosrc
> + * @see_also: #GstAutoAudioSrc
> + *
> + * <refsect2>
> + * <para>
> + * This element retrieves samples from a sound card using libsndio.
> + * </para>
> + * <para>
> + * Simple example pipeline that plays an Ogg/Vorbis file via libsndio:
> + * <programlisting>
> + * gst-launch -v libsndiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink 
> location=foo.ogg 
> + * </programlisting>
> + * </para>
> + * </refsect2>
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include "libsndiosrc.h"
> +#include <unistd.h>
> +#include <errno.h>
> +
> +#include <gst/gst-i18n-plugin.h>
> +
> +GST_DEBUG_CATEGORY_EXTERN (libsndio_debug);
> +#define GST_CAT_DEFAULT libsndio_debug
> +
> +/* elementfactory information */
> +static const GstElementDetails libsndiosrc_details =
> +GST_ELEMENT_DETAILS ("Libsndio audio source",
> +    "Source/Audio",
> +    "Records audio through libsndio",
> +    "Jacob Meuser <[EMAIL PROTECTED]>");
> +
> +enum
> +{
> +  PROP_0,
> +  PROP_HOST
> +};
> +
> +static GstStaticPadTemplate libsndio_src_factory =
> +    GST_STATIC_PAD_TEMPLATE ("src",
> +    GST_PAD_SRC,
> +    GST_PAD_ALWAYS,
> +    GST_STATIC_CAPS ("audio/x-raw-int, "
> +        "endianness = (int) { 1234, 4321 }, "
> +        "signed = (boolean) { TRUE, FALSE }, "
> +        "width = (int) { 8, 16, 24, 32 }, "
> +        "depth = (int) { 8, 16, 24, 32 }, "
> +        "rate = (int) [ 8000, 192000 ], "
> +        "channels = (int) [ 1, 16 ] ")
> +    );
> +
> +static void gst_libsndiosrc_finalize (GObject * object);
> +
> +static GstCaps *gst_libsndiosrc_getcaps (GstBaseSrc * bsrc);
> +
> +static gboolean gst_libsndiosrc_open (GstAudioSrc * asrc);
> +static gboolean gst_libsndiosrc_close (GstAudioSrc * asrc);
> +static gboolean gst_libsndiosrc_prepare (GstAudioSrc * asrc,
> +    GstRingBufferSpec * spec);
> +static gboolean gst_libsndiosrc_unprepare (GstAudioSrc * asrc);
> +static guint gst_libsndiosrc_read (GstAudioSrc * asrc, gpointer data,
> +    guint length);
> +static guint gst_libsndiosrc_delay (GstAudioSrc * asrc);
> +static void gst_libsndiosrc_reset (GstAudioSrc * asrc);
> +
> +static void gst_libsndiosrc_set_property (GObject * object, guint prop_id,
> +    const GValue * value, GParamSpec * pspec);
> +static void gst_libsndiosrc_get_property (GObject * object, guint prop_id,
> +    GValue * value, GParamSpec * pspec);
> +static void gst_libsndiosrc_cb(void * addr, int delta);
> +
> +GST_BOILERPLATE (GstLibsndioSrc, gst_libsndiosrc, GstAudioSrc, 
> GST_TYPE_AUDIO_SRC);
> +
> +static void
> +gst_libsndiosrc_base_init (gpointer g_class)
> +{
> +  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
> +
> +  gst_element_class_set_details (element_class, &libsndiosrc_details);
> +
> +  gst_element_class_add_pad_template (element_class,
> +      gst_static_pad_template_get (&libsndio_src_factory));
> +}
> +
> +static void
> +gst_libsndiosrc_class_init (GstLibsndioSrcClass * klass)
> +{
> +  GObjectClass *gobject_class;
> +  GstBaseSrcClass *gstbasesrc_class;
> +  GstBaseAudioSrcClass *gstbaseaudiosrc_class;
> +  GstAudioSrcClass *gstaudiosrc_class;
> +
> +  gobject_class = (GObjectClass *) klass;
> +  gstbasesrc_class = (GstBaseSrcClass *) klass;
> +  gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
> +  gstaudiosrc_class = (GstAudioSrcClass *) klass;
> +
> +  parent_class = g_type_class_peek_parent (klass);
> +
> +  gobject_class->finalize = gst_libsndiosrc_finalize;
> +
> +  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_libsndiosrc_getcaps);
> +
> +  gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_libsndiosrc_open);
> +  gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_libsndiosrc_close);
> +  gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_libsndiosrc_prepare);
> +  gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR 
> (gst_libsndiosrc_unprepare);
> +  gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_libsndiosrc_read);
> +  gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_libsndiosrc_delay);
> +  gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_libsndiosrc_reset);
> +
> +  gobject_class->set_property = gst_libsndiosrc_set_property;
> +  gobject_class->get_property = gst_libsndiosrc_get_property;
> +
> +  /* default value is filled in the _init method */
> +  g_object_class_install_property (gobject_class, PROP_HOST,
> +      g_param_spec_string ("host", "Host",
> +          "Device or socket libsndio will access", NULL, G_PARAM_READWRITE));
> +}
> +
> +static void
> +gst_libsndiosrc_init (GstLibsndioSrc * libsndiosrc, GstLibsndioSrcClass * 
> klass)
> +{
> +  libsndiosrc->hdl = NULL;
> +  libsndiosrc->host = g_strdup (g_getenv ("AUDIODEVICE"));
> +}
> +
> +static void
> +gst_libsndiosrc_finalize (GObject * object)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (object);
> +
> +  gst_caps_replace (&libsndiosrc->cur_caps, NULL);
> +  g_free (libsndiosrc->host);
> +
> +  G_OBJECT_CLASS (parent_class)->finalize (object);
> +}
> +
> +static GstCaps *
> +gst_libsndiosrc_getcaps (GstBaseSrc * bsrc)
> +{
> +  GstLibsndioSrc *libsndiosrc;
> +
> +  libsndiosrc = GST_LIBSNDIOSRC (bsrc);
> +
> +  /* no hdl, we're done with the template caps */
> +  if (libsndiosrc->cur_caps == NULL) {
> +    GST_LOG_OBJECT (libsndiosrc, "getcaps called, returning template caps");
> +    return NULL;
> +  }
> +
> +  GST_LOG_OBJECT (libsndiosrc, "returning %" GST_PTR_FORMAT, 
> libsndiosrc->cur_caps);
> +
> +  return gst_caps_ref (libsndiosrc->cur_caps);
> +}
> +
> +static gboolean
> +gst_libsndiosrc_open (GstAudioSrc * asrc)
> +{
> +  GstPadTemplate *pad_template;
> +  GstLibsndioSrc *libsndiosrc;
> +  struct sio_par par;
> +  struct sio_cap cap;
> +  GArray *rates, *chans;
> +  GValue rates_v = { 0 };
> +  GValue chans_v = { 0 };
> +  GValue value = { 0 };
> +  struct sio_enc enc;
> +  struct sio_conf conf;
> +  int confs[SIO_NCONF];
> +  int rate, chan;
> +  int i, j, k;
> +  int nconfs;
> +
> +  libsndiosrc = GST_LIBSNDIOSRC (asrc);
> +
> +  GST_DEBUG_OBJECT (libsndiosrc, "open");
> +
> +  /* connect */
> +  libsndiosrc->hdl = sio_open (libsndiosrc->host, SIO_REC, 0);
> +
> +  if (libsndiosrc->hdl == NULL)
> +    goto couldnt_connect;
> +
> +  /* Use libsndio defaults as the only encodings, but get the supported
> +   * sample rates and number of channels.
> +   */
> +
> +  if (!sio_getpar(libsndiosrc->hdl, &par))
> +    goto no_server_info;
> +
> +  if (!sio_getcap(libsndiosrc->hdl, &cap))
> +    goto no_server_info;
> +
> +  rates = g_array_new(FALSE, FALSE, sizeof(int));
> +  chans = g_array_new(FALSE, FALSE, sizeof(int));
> +
> +  /* find confs that have the default encoding */
> +  nconfs = 0;
> +  for (i = 0; i < cap.nconf; i++) {
> +    for (j = 0; j < SIO_NENC; j++) {
> +      if (cap.confs[i].enc & (1 << j)) {
> +        enc = cap.enc[j];
> +        if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
> +            confs[nconfs] = i;
> +            nconfs++;
> +            break;
> +        }
> +      }
> +    }
> +  }
> +
> +  /* find the rates and channels of the confs that have the default encoding 
> */
> +  for (i = 0; i < nconfs; i++) {
> +    conf = cap.confs[confs[i]];
> +    /* rates */
> +    for (j = 0; j < SIO_NRATE; j++) {
> +      if (conf.rate & (1 << j)) {
> +        rate = cap.rate[j];
> +        for (k = 0; k < rates->len && rate; k++) {
> +          if (rate == g_array_index(rates, int, k))
> +            rate = 0;
> +        }
> +        /* add in ascending order */
> +        if (rate) {
> +          for (k = 0; k < rates->len; k++) {
> +            if (rate < g_array_index(rates, int, k)) {
> +              g_array_insert_val(rates, k, rate);
> +              break;
> +            }
> +          }
> +          if (k == rates->len)
> +            g_array_append_val(rates, rate);
> +        }
> +      }
> +    }
> +    /* channels */
> +    for (j = 0; j < SIO_NCHAN; j++) {
> +      if (conf.rchan & (1 << j)) {
> +        chan = cap.rchan[j];
> +        for (k = 0; k < chans->len && chan; k++) {
> +          if (chan == g_array_index(chans, int, k))
> +            chan = 0;
> +        }
> +        /* add in ascending order */
> +        if (chan) {
> +          for (k = 0; k < chans->len; k++) {
> +            if (chan < g_array_index(chans, int, k)) {
> +              g_array_insert_val(chans, k, chan);
> +              break;
> +            }
> +          }
> +          if (k == chans->len)
> +            g_array_append_val(chans, chan);
> +        }
> +      }
> +    }
> +  }
> +  /* not sure how this can happen, but it might */
> +  if (cap.nconf == 0) {
> +    g_array_append_val(rates, par.rate);
> +    g_array_append_val(chans, par.rchan);
> +  }
> +
> +  g_value_init(&rates_v, GST_TYPE_LIST);
> +  g_value_init(&chans_v, GST_TYPE_LIST);
> +  g_value_init(&value, G_TYPE_INT);
> +
> +  for (i = 0; i < rates->len; i++) {
> +    g_value_set_int(&value, g_array_index(rates, int, i));
> +    gst_value_list_append_value(&rates_v, &value);
> +  }
> +  for (i = 0; i < chans->len; i++) {
> +    g_value_set_int(&value, g_array_index(chans, int, i));
> +    gst_value_list_append_value(&chans_v, &value);
> +  }
> +
> +  g_array_free(rates, TRUE);
> +  g_array_free(chans, TRUE);
> +
> +  pad_template = gst_static_pad_template_get (&libsndio_src_factory);
> +  libsndiosrc->cur_caps = gst_caps_copy (gst_pad_template_get_caps 
> (pad_template));
> +  gst_object_unref (pad_template);
> +
> +  for (i = 0; i < libsndiosrc->cur_caps->structs->len; i++) {
> +    GstStructure *s;
> +
> +    s = gst_caps_get_structure (libsndiosrc->cur_caps, i);
> +    gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, 
> NULL);
> +    gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE, 
> NULL);
> +    gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
> +    // gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX 
> */
> +    gst_structure_set_value (s, "rate", &rates_v);
> +    gst_structure_set_value (s, "channels", &chans_v);
> +  }
> +
> +  return TRUE;
> +
> +  /* ERRORS */
> +couldnt_connect:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
> +        (_("Could not establish connection to libsndio")),
> +        ("can't open connection to libsndio"));
> +    return FALSE;
> +  }
> +no_server_info:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
> +        (_("Failed to query libsndio capabilities")),
> +        ("couldn't get libsndio info!"));
> +    return FALSE;
> +  }
> +}
> +
> +static gboolean
> +gst_libsndiosrc_close (GstAudioSrc * asrc)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
> +
> +  GST_DEBUG_OBJECT (libsndiosrc, "close");
> +
> +  gst_caps_replace (&libsndiosrc->cur_caps, NULL);
> +  sio_close (libsndiosrc->hdl);
> +  libsndiosrc->hdl = NULL;
> +
> +  return TRUE;
> +}
> +
> +static void
> +gst_libsndiosrc_cb(void *addr, int delta)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC ((GstAudioSrc *)addr);
> +
> +  libsndiosrc->realpos += delta;
> +
> +  if (libsndiosrc->readpos >= libsndiosrc->realpos)
> +    libsndiosrc->latency = 0;
> +  else
> +    libsndiosrc->latency = libsndiosrc->realpos - libsndiosrc->readpos;
> +}
> +
> +static gboolean
> +gst_libsndiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
> +  struct sio_par par;
> +  int spec_bpf;
> +
> +  GST_DEBUG_OBJECT (libsndiosrc, "prepare");
> +
> +  libsndiosrc->readpos = libsndiosrc->realpos = libsndiosrc->latency = 0;
> +
> +  sio_initpar(&par);
> +  par.sig = spec->sign;
> +  par.le = !spec->bigend;
> +  par.bits = spec->width;
> +  // par.bps = spec->depth / 8;  /* XXX */
> +  par.rate = spec->rate;
> +  par.rchan = spec->channels;
> +
> +  spec_bpf = ((spec->width / 8) * spec->channels);
> +
> +  par.round = spec->segsize / spec_bpf;
> +  par.bufsz = (spec->segsize * spec->segtotal) / spec_bpf;
> +
> +  if (!sio_setpar(libsndiosrc->hdl, &par))
> +    goto cannot_configure;
> +
> +  sio_getpar(libsndiosrc->hdl, &par);
> +
> +  spec->sign = par.sig;
> +  spec->bigend = !par.le;
> +  spec->width = par.bits;
> +  // spec->depth = par.bps * 8;  /* XXX */
> +  spec->rate = par.rate;
> +  spec->channels = par.rchan;
> +
> +  libsndiosrc->bpf = par.bps * par.rchan;
> +
> +  spec->segsize = par.round * par.rchan * par.bps;
> +  spec->segtotal = par.bufsz / par.round;
> +
> +  /* FIXME: this is wrong for signed ints (and the
> +   * audioringbuffers should do it for us anyway) */
> +  spec->silence_sample[0] = 0;
> +  spec->silence_sample[1] = 0;
> +  spec->silence_sample[2] = 0;
> +  spec->silence_sample[3] = 0;
> +
> +  sio_onmove(libsndiosrc->hdl, gst_libsndiosrc_cb, libsndiosrc);
> +
> +  if (!sio_start(libsndiosrc->hdl))
> +    goto cannot_start;
> +
> +  GST_INFO_OBJECT (libsndiosrc, "successfully opened connection to 
> libsndio");
> +
> +  return TRUE;
> +
> +  /* ERRORS */
> +cannot_configure:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
> +        (_("Could not configure libsndio")),
> +        ("can't configure libsndio"));
> +    return FALSE;
> +  }
> +cannot_start:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, OPEN_READ,
> +        (_("Could not start libsndio")),
> +        ("can't start libsndio"));
> +    return FALSE;
> +  }
> +}
> +
> +static gboolean
> +gst_libsndiosrc_unprepare (GstAudioSrc * asrc)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
> +
> +  if (libsndiosrc->hdl == NULL)
> +    return TRUE;
> +
> +  sio_stop(libsndiosrc->hdl);
> +
> +  return TRUE;
> +}
> +
> +
> +static guint
> +gst_libsndiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
> +  guint done;
> +
> +  done = sio_read (libsndiosrc->hdl, data, length);
> +
> +  if (done == 0)
> +    goto read_error;
> +
> +  libsndiosrc->readpos += (done / libsndiosrc->bpf);
> +
> +  data = (char *) data + done;
> +
> +  return done;
> +
> +  /* ERRORS */
> +read_error:
> +  {
> +    GST_ELEMENT_ERROR (libsndiosrc, RESOURCE, READ,
> +        ("Failed to read data from libsndio"), GST_ERROR_SYSTEM);
> +    return 0;
> +  }
> +}
> +
> +static guint
> +gst_libsndiosrc_delay (GstAudioSrc * asrc)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (asrc);
> +
> +  if (libsndiosrc->latency == (guint) - 1) {
> +    GST_WARNING_OBJECT (asrc, "couldn't get latency");
> +    return 0;
> +  }
> +
> +  GST_DEBUG_OBJECT (asrc, "got latency: %u", libsndiosrc->latency);
> +
> +  return libsndiosrc->latency;
> +}
> +
> +static void
> +gst_libsndiosrc_reset (GstAudioSrc * asrc)
> +{
> +  /* no way to flush the buffers with libsndio ? */
> +
> +  GST_DEBUG_OBJECT (asrc, "reset called");
> +}
> +
> +static void
> +gst_libsndiosrc_set_property (GObject * object, guint prop_id, const GValue 
> * value,
> +    GParamSpec * pspec)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (object);
> +
> +  switch (prop_id) {
> +    case PROP_HOST:
> +      g_free (libsndiosrc->host);
> +      libsndiosrc->host = g_value_dup_string (value);
> +      break;
> +    default:
> +      break;
> +  }
> +}
> +
> +static void
> +gst_libsndiosrc_get_property (GObject * object, guint prop_id, GValue * 
> value,
> +    GParamSpec * pspec)
> +{
> +  GstLibsndioSrc *libsndiosrc = GST_LIBSNDIOSRC (object);
> +
> +  switch (prop_id) {
> +    case PROP_HOST:
> +      g_value_set_string (value, libsndiosrc->host);
> +      break;
> +    default:
> +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> +      break;
> +  }
> +}
> Index: files/libsndiosrc.h
> ===================================================================
> RCS file: files/libsndiosrc.h
> diff -N files/libsndiosrc.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ files/libsndiosrc.h       28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,72 @@
> +/* GStreamer
> + * Copyright (C) <2008> Jacob Meuser <[EMAIL PROTECTED]>
> + *
> + * libsndiosrc.h: libsndio audio source
> + *
> + * 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., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +
> +#ifndef __GST_LIBSNDIOSRC_H__
> +#define __GST_LIBSNDIOSRC_H__
> +
> +#include <sndio.h>
> +
> +#include <gst/gst.h>
> +#include <gst/audio/gstaudiosrc.h>
> +
> +G_BEGIN_DECLS
> +
> +#define GST_TYPE_LIBSNDIOSRC \
> +  (gst_libsndiosrc_get_type())
> +#define GST_LIBSNDIOSRC(obj) \
> +  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LIBSNDIOSRC,GstLibsndioSrc))
> +#define GST_LIBSNDIOSRC_CLASS(klass) \
> +  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LIBSNDIOSRC,GstLibsndioSrcClass))
> +#define GST_IS_LIBSNDIOSRC(obj) \
> +  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LIBSNDIOSRC))
> +#define GST_IS_LIBSNDIOSRC_CLASS(klass) \
> +  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LIBSNDIOSRC))
> +
> +typedef struct _GstLibsndioSrc GstLibsndioSrc;
> +typedef struct _GstLibsndioSrcClass GstLibsndioSrcClass;
> +
> +struct _GstLibsndioSrc {
> +  GstAudioSrc   src;
> +
> +  struct sio_hdl *hdl;
> +  gchar    *host;
> +
> +  /* bytes per frame */
> +  int bpf;
> +
> +  /* frames counts */
> +  volatile long long realpos;
> +  volatile long long readpos;
> +  volatile guint latency;
> +
> +  GstCaps  *cur_caps;
> +};
> +
> +struct _GstLibsndioSrcClass {
> +  GstAudioSrcClass parent_class;
> +};
> +
> +GType gst_libsndiosrc_get_type (void);
> +
> +G_END_DECLS
> +
> +#endif /* __GST_LIBSNDIOSRC_H__ */
> Index: patches/patch-configure_ac
> ===================================================================
> RCS file: 
> /home2/cvs/OpenBSD/ports/multimedia/gstreamer-0.10/plugins-good/patches/patch-configure_ac,v
> retrieving revision 1.5
> diff -u -r1.5 patch-configure_ac
> --- patches/patch-configure_ac        16 May 2008 14:24:01 -0000      1.5
> +++ patches/patch-configure_ac        28 Oct 2008 03:09:03 -0000
> @@ -1,6 +1,6 @@
>  $OpenBSD: patch-configure_ac,v 1.5 2008/05/16 14:24:01 ajacoutot Exp $
> ---- configure.ac.orig        Wed Apr 23 03:55:55 2008
> -+++ configure.ac     Wed May 14 12:28:02 2008
> +--- configure.ac.orig        Tue Apr 22 18:55:55 2008
> ++++ configure.ac     Mon Oct 27 01:45:57 2008
>  @@ -488,6 +488,8 @@ AG_GST_CHECK_FEATURE(GST_V4L2, [Video 4 Linux 2], v4l2
>   #ifdef __sun /* Solaris */
>   #include <sys/types.h>
> @@ -19,7 +19,29 @@
>   #else /* Linux */
>   #include <linux/types.h>
>   #define _LINUX_TIME_H
> -@@ -699,7 +703,7 @@ AG_GST_CHECK_FEATURE(FLAC, [FLAC lossless audio], flac
> +@@ -676,6 +680,21 @@ AG_GST_CHECK_FEATURE(ESD, [ESounD sound daemon], esdsi
> +   fi
> + ])
> + 
> ++dnl *** libsndio ***
> ++translit(dnm, m, l) AM_CONDITIONAL(USE_LIBSNDIO, true)
> ++AG_GST_CHECK_FEATURE(LIBSNDIO, [libsndio audio], libsndioaudio, [
> ++  AC_CHECK_HEADER(sndio.h, HAVE_LIBSNDIO="yes", HAVE_LIBSNDIO="no")
> ++  if test $HAVE_LIBSNDIO = yes
> ++  then
> ++    AC_CHECK_LIB(sndio, sio_open, HAVE_LIBSNDIO="yes", HAVE_LIBSNDIO="no", 
> [])
> ++    if test $HAVE_LIBSNDIO = yes
> ++    then
> ++      LIBSNDIO_LIBS=-lsndio
> ++      AC_SUBST(LIBSNDIO_LIBS)
> ++    fi
> ++  fi
> ++])
> ++
> + dnl *** FLAC ***
> + translit(dnm, m, l) AM_CONDITIONAL(USE_FLAC, true)
> + AC_TRY_COMPILE([#include <FLAC/export.h>], [
> +@@ -699,7 +718,7 @@ AG_GST_CHECK_FEATURE(FLAC, [FLAC lossless audio], flac
>   ])
>   else
>   AG_GST_CHECK_FEATURE(FLAC, [FLAC lossless audio], flac, [
> @@ -28,7 +50,7 @@
>     dnl API change in FLAC 1.1.3, so require that...
>     if test x$HAVE_FLAC = xyes; then
>       AC_CHECK_DECL(FLAC__STREAM_ENCODER_TELL_STATUS_ERROR,
> -@@ -773,7 +777,7 @@ AG_GST_CHECK_FEATURE(LIBDV, [libdv DV demuxer/decoder]
> +@@ -773,7 +792,7 @@ AG_GST_CHECK_FEATURE(LIBDV, [libdv DV demuxer/decoder]
>   dnl *** libpng ***
>   translit(dnm, m, l) AM_CONDITIONAL(USE_LIBPNG, true)
>   AG_GST_CHECK_FEATURE(LIBPNG, [Portable Network Graphics library], png, [
> @@ -37,3 +59,19 @@
>   ])
>   
>   dnl *** dv1394 ***
> +@@ -947,6 +966,7 @@ AM_CONDITIONAL(USE_ANNODEX, false)
> + AM_CONDITIONAL(USE_CAIRO, false)
> + AM_CONDITIONAL(USE_CDIO, false)
> + AM_CONDITIONAL(USE_ESD, false)
> ++AM_CONDITIONAL(USE_LIBSNDIO, false)
> + AM_CONDITIONAL(USE_FLAC, false)
> + AM_CONDITIONAL(USE_GCONF, false)
> + AM_CONDITIONAL(USE_GDK_PIXBUF, false)
> +@@ -1066,6 +1086,7 @@ ext/cairo/Makefile
> + ext/cdio/Makefile
> + ext/dv/Makefile
> + ext/esd/Makefile
> ++ext/libsndio/Makefile
> + ext/flac/Makefile
> + ext/gconf/Makefile
> + ext/gdk_pixbuf/Makefile
> Index: patches/patch-ext_Makefile_am
> ===================================================================
> RCS file: patches/patch-ext_Makefile_am
> diff -N patches/patch-ext_Makefile_am
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-ext_Makefile_am     28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,32 @@
> +$OpenBSD$
> +--- ext/Makefile.am.orig     Fri Sep 26 02:05:28 2008
> ++++ ext/Makefile.am  Fri Sep 26 02:07:07 2008
> +@@ -82,6 +82,12 @@ else
> + LIBPNG_DIR =
> + endif
> + 
> ++if USE_LIBSNDIO
> ++LIBSNDIO_DIR = libsndio
> ++else
> ++LIBSNDIO_DIR =
> ++endif
> ++
> + # if USE_MIKMOD
> + # MIKMOD_DIR = mikmod
> + # else
> +@@ -140,6 +146,7 @@ SUBDIRS = \
> +     $(LIBDV_DIR) \
> +     $(LIBMNG_DIR) \
> +     $(LIBPNG_DIR) \
> ++    $(LIBSNDIO_DIR) \
> +     $(MIKMOD_DIR) \
> +     $(SHOUT2_DIR) \
> +     $(SOUP_DIR) \
> +@@ -162,6 +169,7 @@ DIST_SUBDIRS = \
> +     ladspa \
> +     libcaca \
> +     libpng \
> ++    libsndio \
> +     raw1394 \
> +     shout2 \
> +     soup \
> Index: patches/patch-sys_oss_Makefile_am
> ===================================================================
> RCS file: patches/patch-sys_oss_Makefile_am
> diff -N patches/patch-sys_oss_Makefile_am
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-sys_oss_Makefile_am 28 Oct 2008 03:09:03 -0000
> @@ -0,0 +1,13 @@
> +$OpenBSD$
> +--- sys/oss/Makefile.am.orig Fri Sep 26 02:07:41 2008
> ++++ sys/oss/Makefile.am      Fri Sep 26 02:08:01 2008
> +@@ -13,7 +13,8 @@ libgstossaudio_la_LIBADD = \
> +     $(GST_PLUGINS_BASE_LIBS) \
> +         -lgstinterfaces-$(GST_MAJORMINOR) \
> +     -lgstaudio-$(GST_MAJORMINOR) \
> +-    $(GST_LIBS)
> ++    $(GST_LIBS) \
> ++    -lossaudio
> + libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) 
> + 
> + noinst_HEADERS = common.h            \
> Index: patches/patch-sys_oss_Makefile_in
> ===================================================================
> RCS file: patches/patch-sys_oss_Makefile_in
> diff -N patches/patch-sys_oss_Makefile_in
> --- patches/patch-sys_oss_Makefile_in 13 May 2008 15:11:51 -0000      1.2
> +++ /dev/null 1 Jan 1970 00:00:00 -0000
> @@ -1,13 +0,0 @@
> -$OpenBSD: patch-sys_oss_Makefile_in,v 1.2 2008/05/13 15:11:51 espie Exp $
> ---- sys/oss/Makefile.in.orig Thu Apr 24 00:39:31 2008
> -+++ sys/oss/Makefile.in      Mon May 12 14:28:03 2008
> -@@ -521,7 +521,8 @@ libgstossaudio_la_LIBADD = \
> -     $(GST_PLUGINS_BASE_LIBS) \
> -         -lgstinterfaces-$(GST_MAJORMINOR) \
> -     -lgstaudio-$(GST_MAJORMINOR) \
> --    $(GST_LIBS)
> -+    $(GST_LIBS) \
> -+    -lossaudio
> - 
> - libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) 
> - 
> Index: pkg/PLIST-main
> ===================================================================
> RCS file: 
> /home2/cvs/OpenBSD/ports/multimedia/gstreamer-0.10/plugins-good/pkg/PLIST-main,v
> retrieving revision 1.8
> diff -u -r1.8 PLIST-main
> --- pkg/PLIST-main    18 May 2008 13:37:22 -0000      1.8
> +++ pkg/PLIST-main    28 Oct 2008 03:09:03 -0000
> @@ -36,6 +36,8 @@
>  lib/gstreamer-${VERSION}/libgstid3demux.so
>  lib/gstreamer-${VERSION}/libgstlevel.la
>  lib/gstreamer-${VERSION}/libgstlevel.so
> +lib/gstreamer-${VERSION}/libgstlibsndio.la
> +lib/gstreamer-${VERSION}/libgstlibsndio.so
>  lib/gstreamer-${VERSION}/libgstmatroska.la
>  lib/gstreamer-${VERSION}/libgstmatroska.so
>  lib/gstreamer-${VERSION}/libgstmonoscope.la
> 

-- 
[EMAIL PROTECTED]
SDF Public Access UNIX System - http://sdf.lonestar.org

Reply via email to