summaryrefslogtreecommitdiff
path: root/sys/sunaudio
diff options
context:
space:
mode:
authorjk7744.park <jk7744.park@samsung.com>2015-10-24 16:49:08 +0900
committerjk7744.park <jk7744.park@samsung.com>2015-10-24 16:49:08 +0900
commit32e864f0f32b7628d995e84d07646b01dc5bf2d5 (patch)
tree27f97eaa1ca7e171815e4f88b348448b05f02748 /sys/sunaudio
parent9093d777f57b3f1dc62010bb8e0c7ed3d72a76d2 (diff)
downloadgst-plugins-good-accepted/tizen_2.4_mobile.tar.gz
gst-plugins-good-accepted/tizen_2.4_mobile.tar.bz2
gst-plugins-good-accepted/tizen_2.4_mobile.zip
Diffstat (limited to 'sys/sunaudio')
-rw-r--r--sys/sunaudio/Makefile.am26
-rwxr-xr-xsys/sunaudio/Makefile.in963
-rw-r--r--sys/sunaudio/gstsunaudio.c62
-rw-r--r--sys/sunaudio/gstsunaudiomixer.c104
-rw-r--r--sys/sunaudio/gstsunaudiomixer.h51
-rw-r--r--sys/sunaudio/gstsunaudiomixerctrl.c585
-rw-r--r--sys/sunaudio/gstsunaudiomixerctrl.h189
-rw-r--r--sys/sunaudio/gstsunaudiomixeroptions.c157
-rw-r--r--sys/sunaudio/gstsunaudiomixeroptions.h65
-rw-r--r--sys/sunaudio/gstsunaudiomixertrack.c158
-rw-r--r--sys/sunaudio/gstsunaudiomixertrack.h78
-rw-r--r--sys/sunaudio/gstsunaudiosink.c651
-rw-r--r--sys/sunaudio/gstsunaudiosink.h78
-rw-r--r--sys/sunaudio/gstsunaudiosrc.c423
-rw-r--r--sys/sunaudio/gstsunaudiosrc.h67
15 files changed, 3657 insertions, 0 deletions
diff --git a/sys/sunaudio/Makefile.am b/sys/sunaudio/Makefile.am
new file mode 100644
index 0000000..86b62da
--- /dev/null
+++ b/sys/sunaudio/Makefile.am
@@ -0,0 +1,26 @@
+plugin_LTLIBRARIES = libgstsunaudio.la
+
+libgstsunaudio_la_SOURCES = gstsunaudio.c \
+ gstsunaudiosink.c \
+ gstsunaudiomixerctrl.c \
+ gstsunaudiomixer.c \
+ gstsunaudiomixertrack.c \
+ gstsunaudiomixeroptions.c \
+ gstsunaudiosrc.c
+
+libgstsunaudio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+libgstsunaudio_la_LIBADD = \
+ -lgstinterfaces-@GST_API_VERSION@ \
+ -lgstaudio-@GST_API_VERSION@ \
+ $(GST_PLUGINS_BASE_LIBS) \
+ $(GST_LIBS)
+libgstsunaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstsunaudio_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
+
+noinst_HEADERS = gstsunaudiosink.h \
+ gstsunaudiomixer.h \
+ gstsunaudiomixerctrl.h \
+ gstsunaudiomixertrack.h \
+ gstsunaudiomixeroptions.h \
+ gstsunaudiosrc.h
+
diff --git a/sys/sunaudio/Makefile.in b/sys/sunaudio/Makefile.in
new file mode 100755
index 0000000..cae0342
--- /dev/null
+++ b/sys/sunaudio/Makefile.in
@@ -0,0 +1,963 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = sys/sunaudio
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
+ $(top_srcdir)/common/m4/as-auto-alt.m4 \
+ $(top_srcdir)/common/m4/as-compiler-flag.m4 \
+ $(top_srcdir)/common/m4/as-gcc-inline-assembly.m4 \
+ $(top_srcdir)/common/m4/as-libtool.m4 \
+ $(top_srcdir)/common/m4/as-version.m4 \
+ $(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+ $(top_srcdir)/common/m4/gst-arch.m4 \
+ $(top_srcdir)/common/m4/gst-args.m4 \
+ $(top_srcdir)/common/m4/gst-check.m4 \
+ $(top_srcdir)/common/m4/gst-default.m4 \
+ $(top_srcdir)/common/m4/gst-dowhile.m4 \
+ $(top_srcdir)/common/m4/gst-error.m4 \
+ $(top_srcdir)/common/m4/gst-feature.m4 \
+ $(top_srcdir)/common/m4/gst-gettext.m4 \
+ $(top_srcdir)/common/m4/gst-glib2.m4 \
+ $(top_srcdir)/common/m4/gst-package-release-datetime.m4 \
+ $(top_srcdir)/common/m4/gst-platform.m4 \
+ $(top_srcdir)/common/m4/gst-plugin-docs.m4 \
+ $(top_srcdir)/common/m4/gst-plugindir.m4 \
+ $(top_srcdir)/common/m4/gst-x11.m4 \
+ $(top_srcdir)/common/m4/gst.m4 \
+ $(top_srcdir)/common/m4/gtk-doc.m4 \
+ $(top_srcdir)/common/m4/orc.m4 $(top_srcdir)/common/m4/pkg.m4 \
+ $(top_srcdir)/m4/aalib.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/gst-fionread.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libgstsunaudio_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libgstsunaudio_la_OBJECTS = libgstsunaudio_la-gstsunaudio.lo \
+ libgstsunaudio_la-gstsunaudiosink.lo \
+ libgstsunaudio_la-gstsunaudiomixerctrl.lo \
+ libgstsunaudio_la-gstsunaudiomixer.lo \
+ libgstsunaudio_la-gstsunaudiomixertrack.lo \
+ libgstsunaudio_la-gstsunaudiomixeroptions.lo \
+ libgstsunaudio_la-gstsunaudiosrc.lo
+libgstsunaudio_la_OBJECTS = $(am_libgstsunaudio_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libgstsunaudio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) \
+ $(libgstsunaudio_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libgstsunaudio_la_SOURCES)
+DIST_SOURCES = $(libgstsunaudio_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+AALIB_CFLAGS = @AALIB_CFLAGS@
+AALIB_CONFIG = @AALIB_CONFIG@
+AALIB_LIBS = @AALIB_LIBS@
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BZ2_LIBS = @BZ2_LIBS@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_AUDIOSINK = @DEFAULT_AUDIOSINK@
+DEFAULT_AUDIOSRC = @DEFAULT_AUDIOSRC@
+DEFAULT_VIDEOSINK = @DEFAULT_VIDEOSINK@
+DEFAULT_VIDEOSRC = @DEFAULT_VIDEOSRC@
+DEFAULT_VISUALIZER = @DEFAULT_VISUALIZER@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DEPRECATED_CFLAGS = @DEPRECATED_CFLAGS@
+DIRECTSOUND_CFLAGS = @DIRECTSOUND_CFLAGS@
+DIRECTSOUND_LDFLAGS = @DIRECTSOUND_LDFLAGS@
+DIRECTSOUND_LIBS = @DIRECTSOUND_LIBS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DV1394_CFLAGS = @DV1394_CFLAGS@
+DV1394_LIBS = @DV1394_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ERROR_CFLAGS = @ERROR_CFLAGS@
+ERROR_CXXFLAGS = @ERROR_CXXFLAGS@
+ERROR_OBJCFLAGS = @ERROR_OBJCFLAGS@
+EXEEXT = @EXEEXT@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+FLAC_CFLAGS = @FLAC_CFLAGS@
+FLAC_LIBS = @FLAC_LIBS@
+GCOV = @GCOV@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LIBS = @GCOV_LIBS@
+GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
+GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LDFLAGS = @GIO_LDFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GLIB_PREFIX = @GLIB_PREFIX@
+GLIB_REQ = @GLIB_REQ@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+GSTPB_PLUGINS_DIR = @GSTPB_PLUGINS_DIR@
+GSTPB_PREFIX = @GSTPB_PREFIX@
+GST_AGE = @GST_AGE@
+GST_ALL_LDFLAGS = @GST_ALL_LDFLAGS@
+GST_API_VERSION = @GST_API_VERSION@
+GST_BASE_CFLAGS = @GST_BASE_CFLAGS@
+GST_BASE_LIBS = @GST_BASE_LIBS@
+GST_CFLAGS = @GST_CFLAGS@
+GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@
+GST_CHECK_LIBS = @GST_CHECK_LIBS@
+GST_CONTROLLER_CFLAGS = @GST_CONTROLLER_CFLAGS@
+GST_CONTROLLER_LIBS = @GST_CONTROLLER_LIBS@
+GST_CURRENT = @GST_CURRENT@
+GST_CXXFLAGS = @GST_CXXFLAGS@
+GST_LEVEL_DEFAULT = @GST_LEVEL_DEFAULT@
+GST_LIBS = @GST_LIBS@
+GST_LIBVERSION = @GST_LIBVERSION@
+GST_LICENSE = @GST_LICENSE@
+GST_LT_LDFLAGS = @GST_LT_LDFLAGS@
+GST_NET_CFLAGS = @GST_NET_CFLAGS@
+GST_NET_LIBS = @GST_NET_LIBS@
+GST_OBJCFLAGS = @GST_OBJCFLAGS@
+GST_OPTION_CFLAGS = @GST_OPTION_CFLAGS@
+GST_OPTION_CXXFLAGS = @GST_OPTION_CXXFLAGS@
+GST_OPTION_OBJCFLAGS = @GST_OPTION_OBJCFLAGS@
+GST_PACKAGE_NAME = @GST_PACKAGE_NAME@
+GST_PACKAGE_ORIGIN = @GST_PACKAGE_ORIGIN@
+GST_PLUGINS_ALL = @GST_PLUGINS_ALL@
+GST_PLUGINS_BASE_CFLAGS = @GST_PLUGINS_BASE_CFLAGS@
+GST_PLUGINS_BASE_DIR = @GST_PLUGINS_BASE_DIR@
+GST_PLUGINS_BASE_LIBS = @GST_PLUGINS_BASE_LIBS@
+GST_PLUGINS_DIR = @GST_PLUGINS_DIR@
+GST_PLUGINS_NONPORTED = @GST_PLUGINS_NONPORTED@
+GST_PLUGINS_SELECTED = @GST_PLUGINS_SELECTED@
+GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
+GST_PLUGIN_LIBTOOLFLAGS = @GST_PLUGIN_LIBTOOLFLAGS@
+GST_PREFIX = @GST_PREFIX@
+GST_REVISION = @GST_REVISION@
+GST_TOOLS_DIR = @GST_TOOLS_DIR@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_X11_CFLAGS = @GTK_X11_CFLAGS@
+GTK_X11_LIBS = @GTK_X11_LIBS@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HAVE_AVC1394 = @HAVE_AVC1394@
+HAVE_CXX = @HAVE_CXX@
+HAVE_DIRECTSOUND = @HAVE_DIRECTSOUND@
+HAVE_ROM1394 = @HAVE_ROM1394@
+HAVE_SPEEX = @HAVE_SPEEX@
+HAVE_X = @HAVE_X@
+HAVE_XSHM = @HAVE_XSHM@
+HAVE_ZLIB = @HAVE_ZLIB@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+JACK_0_120_1_CFLAGS = @JACK_0_120_1_CFLAGS@
+JACK_0_120_1_LIBS = @JACK_0_120_1_LIBS@
+JACK_1_9_7_CFLAGS = @JACK_1_9_7_CFLAGS@
+JACK_1_9_7_LIBS = @JACK_1_9_7_LIBS@
+JACK_CFLAGS = @JACK_CFLAGS@
+JACK_LIBS = @JACK_LIBS@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBCACA_CFLAGS = @LIBCACA_CFLAGS@
+LIBCACA_LIBS = @LIBCACA_LIBS@
+LIBDV_CFLAGS = @LIBDV_CFLAGS@
+LIBDV_LIBS = @LIBDV_LIBS@
+LIBICONV = @LIBICONV@
+LIBIEC61883_CFLAGS = @LIBIEC61883_CFLAGS@
+LIBIEC61883_LIBS = @LIBIEC61883_LIBS@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBPNG_CFLAGS = @LIBPNG_CFLAGS@
+LIBPNG_LIBS = @LIBPNG_LIBS@
+LIBRT = @LIBRT@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBV4L2_CFLAGS = @LIBV4L2_CFLAGS@
+LIBV4L2_LIBS = @LIBV4L2_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJC = @OBJC@
+OBJCDEPMODE = @OBJCDEPMODE@
+OBJCFLAGS = @OBJCFLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ORCC = @ORCC@
+ORCC_FLAGS = @ORCC_FLAGS@
+ORC_CFLAGS = @ORC_CFLAGS@
+ORC_LIBS = @ORC_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MICRO = @PACKAGE_VERSION_MICRO@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_NANO = @PACKAGE_VERSION_NANO@
+PACKAGE_VERSION_RELEASE = @PACKAGE_VERSION_RELEASE@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PLUGINDIR = @PLUGINDIR@
+POSUB = @POSUB@
+PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+RAW1394_CFLAGS = @RAW1394_CFLAGS@
+RAW1394_LIBS = @RAW1394_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHOUT2_CFLAGS = @SHOUT2_CFLAGS@
+SHOUT2_LIBS = @SHOUT2_LIBS@
+SOUP_CFLAGS = @SOUP_CFLAGS@
+SOUP_LIBS = @SOUP_LIBS@
+SPEEX_CFLAGS = @SPEEX_CFLAGS@
+SPEEX_LIBS = @SPEEX_LIBS@
+STRIP = @STRIP@
+TAGLIB_CFLAGS = @TAGLIB_CFLAGS@
+TAGLIB_CXXFLAGS = @TAGLIB_CXXFLAGS@
+TAGLIB_LIBS = @TAGLIB_LIBS@
+USE_NLS = @USE_NLS@
+VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
+VALGRIND_LIBS = @VALGRIND_LIBS@
+VALGRIND_PATH = @VALGRIND_PATH@
+VERSION = @VERSION@
+VPX_130_CFLAGS = @VPX_130_CFLAGS@
+VPX_130_LIBS = @VPX_130_LIBS@
+VPX_CFLAGS = @VPX_CFLAGS@
+VPX_LIBS = @VPX_LIBS@
+WARNING_CFLAGS = @WARNING_CFLAGS@
+WARNING_CXXFLAGS = @WARNING_CXXFLAGS@
+WARNING_OBJCFLAGS = @WARNING_OBJCFLAGS@
+WAVPACK_CFLAGS = @WAVPACK_CFLAGS@
+WAVPACK_LIBS = @WAVPACK_LIBS@
+XDAMAGE_CFLAGS = @XDAMAGE_CFLAGS@
+XDAMAGE_LIBS = @XDAMAGE_LIBS@
+XFIXES_CFLAGS = @XFIXES_CFLAGS@
+XFIXES_LIBS = @XFIXES_LIBS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMKMF = @XMKMF@
+XSHM_LIBS = @XSHM_LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_OBJC = @ac_ct_OBJC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+plugin_LTLIBRARIES = libgstsunaudio.la
+libgstsunaudio_la_SOURCES = gstsunaudio.c \
+ gstsunaudiosink.c \
+ gstsunaudiomixerctrl.c \
+ gstsunaudiomixer.c \
+ gstsunaudiomixertrack.c \
+ gstsunaudiomixeroptions.c \
+ gstsunaudiosrc.c
+
+libgstsunaudio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+libgstsunaudio_la_LIBADD = \
+ -lgstinterfaces-@GST_API_VERSION@ \
+ -lgstaudio-@GST_API_VERSION@ \
+ $(GST_PLUGINS_BASE_LIBS) \
+ $(GST_LIBS)
+
+libgstsunaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstsunaudio_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
+noinst_HEADERS = gstsunaudiosink.h \
+ gstsunaudiomixer.h \
+ gstsunaudiomixerctrl.h \
+ gstsunaudiomixertrack.h \
+ gstsunaudiomixeroptions.h \
+ gstsunaudiosrc.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu sys/sunaudio/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu sys/sunaudio/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libgstsunaudio.la: $(libgstsunaudio_la_OBJECTS) $(libgstsunaudio_la_DEPENDENCIES) $(EXTRA_libgstsunaudio_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libgstsunaudio_la_LINK) -rpath $(plugindir) $(libgstsunaudio_la_OBJECTS) $(libgstsunaudio_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudiomixer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudiomixerctrl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudiomixeroptions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudiomixertrack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudiosink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstsunaudio_la-gstsunaudiosrc.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libgstsunaudio_la-gstsunaudio.lo: gstsunaudio.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudio.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudio.Tpo -c -o libgstsunaudio_la-gstsunaudio.lo `test -f 'gstsunaudio.c' || echo '$(srcdir)/'`gstsunaudio.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudio.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudio.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudio.c' object='libgstsunaudio_la-gstsunaudio.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudio.lo `test -f 'gstsunaudio.c' || echo '$(srcdir)/'`gstsunaudio.c
+
+libgstsunaudio_la-gstsunaudiosink.lo: gstsunaudiosink.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudiosink.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudiosink.Tpo -c -o libgstsunaudio_la-gstsunaudiosink.lo `test -f 'gstsunaudiosink.c' || echo '$(srcdir)/'`gstsunaudiosink.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudiosink.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudiosink.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudiosink.c' object='libgstsunaudio_la-gstsunaudiosink.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudiosink.lo `test -f 'gstsunaudiosink.c' || echo '$(srcdir)/'`gstsunaudiosink.c
+
+libgstsunaudio_la-gstsunaudiomixerctrl.lo: gstsunaudiomixerctrl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudiomixerctrl.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixerctrl.Tpo -c -o libgstsunaudio_la-gstsunaudiomixerctrl.lo `test -f 'gstsunaudiomixerctrl.c' || echo '$(srcdir)/'`gstsunaudiomixerctrl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixerctrl.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixerctrl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudiomixerctrl.c' object='libgstsunaudio_la-gstsunaudiomixerctrl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudiomixerctrl.lo `test -f 'gstsunaudiomixerctrl.c' || echo '$(srcdir)/'`gstsunaudiomixerctrl.c
+
+libgstsunaudio_la-gstsunaudiomixer.lo: gstsunaudiomixer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudiomixer.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixer.Tpo -c -o libgstsunaudio_la-gstsunaudiomixer.lo `test -f 'gstsunaudiomixer.c' || echo '$(srcdir)/'`gstsunaudiomixer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixer.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudiomixer.c' object='libgstsunaudio_la-gstsunaudiomixer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudiomixer.lo `test -f 'gstsunaudiomixer.c' || echo '$(srcdir)/'`gstsunaudiomixer.c
+
+libgstsunaudio_la-gstsunaudiomixertrack.lo: gstsunaudiomixertrack.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudiomixertrack.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixertrack.Tpo -c -o libgstsunaudio_la-gstsunaudiomixertrack.lo `test -f 'gstsunaudiomixertrack.c' || echo '$(srcdir)/'`gstsunaudiomixertrack.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixertrack.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixertrack.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudiomixertrack.c' object='libgstsunaudio_la-gstsunaudiomixertrack.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudiomixertrack.lo `test -f 'gstsunaudiomixertrack.c' || echo '$(srcdir)/'`gstsunaudiomixertrack.c
+
+libgstsunaudio_la-gstsunaudiomixeroptions.lo: gstsunaudiomixeroptions.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudiomixeroptions.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixeroptions.Tpo -c -o libgstsunaudio_la-gstsunaudiomixeroptions.lo `test -f 'gstsunaudiomixeroptions.c' || echo '$(srcdir)/'`gstsunaudiomixeroptions.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixeroptions.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudiomixeroptions.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudiomixeroptions.c' object='libgstsunaudio_la-gstsunaudiomixeroptions.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudiomixeroptions.lo `test -f 'gstsunaudiomixeroptions.c' || echo '$(srcdir)/'`gstsunaudiomixeroptions.c
+
+libgstsunaudio_la-gstsunaudiosrc.lo: gstsunaudiosrc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -MT libgstsunaudio_la-gstsunaudiosrc.lo -MD -MP -MF $(DEPDIR)/libgstsunaudio_la-gstsunaudiosrc.Tpo -c -o libgstsunaudio_la-gstsunaudiosrc.lo `test -f 'gstsunaudiosrc.c' || echo '$(srcdir)/'`gstsunaudiosrc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstsunaudio_la-gstsunaudiosrc.Tpo $(DEPDIR)/libgstsunaudio_la-gstsunaudiosrc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstsunaudiosrc.c' object='libgstsunaudio_la-gstsunaudiosrc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstsunaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstsunaudio_la_CFLAGS) $(CFLAGS) -c -o libgstsunaudio_la-gstsunaudiosrc.lo `test -f 'gstsunaudiosrc.c' || echo '$(srcdir)/'`gstsunaudiosrc.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sys/sunaudio/gstsunaudio.c b/sys/sunaudio/gstsunaudio.c
new file mode 100644
index 0000000..633c1f0
--- /dev/null
+++ b/sys/sunaudio/gstsunaudio.c
@@ -0,0 +1,62 @@
+/*
+ * GStreamer - SunAudio plugin
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gst/gst-i18n-plugin.h"
+
+#include "gstsunaudiomixer.h"
+#include "gstsunaudiosink.h"
+#include "gstsunaudiosrc.h"
+
+extern gchar *__gst_oss_plugin_dir;
+
+GST_DEBUG_CATEGORY (sunaudio_debug);
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ if (!gst_element_register (plugin, "sunaudiomixer", GST_RANK_NONE,
+ GST_TYPE_SUNAUDIO_MIXER) ||
+ !gst_element_register (plugin, "sunaudiosink", GST_RANK_SECONDARY,
+ GST_TYPE_SUNAUDIO_SINK) ||
+ !gst_element_register (plugin, "sunaudiosrc", GST_RANK_SECONDARY,
+ GST_TYPE_SUNAUDIO_SRC)) {
+ return FALSE;
+ }
+
+ GST_DEBUG_CATEGORY_INIT (sunaudio_debug, "sunaudio", 0, "sunaudio elements");
+
+#ifdef ENABLE_NLS
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif /* ENABLE_NLS */
+
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ sunaudio,
+ "Sun Audio support for GStreamer",
+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/sys/sunaudio/gstsunaudiomixer.c b/sys/sunaudio/gstsunaudiomixer.c
new file mode 100644
index 0000000..0a431bf
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixer.c
@@ -0,0 +1,104 @@
+/*
+ * GStreamer - SunAudio mixer
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:element-sunaudiomixer
+ *
+ * sunaudiomixer is an mixer that controls the sound input and output
+ * levels with the Sun Audio interface available in Solaris.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstsunaudiomixer.h"
+
+GST_BOILERPLATE_WITH_INTERFACE (GstSunAudioMixer, gst_sunaudiomixer,
+ GstElement, GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, gst_sunaudiomixer);
+
+GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS (GstSunAudioMixer, gst_sunaudiomixer);
+
+static GstStateChangeReturn gst_sunaudiomixer_change_state (GstElement *
+ element, GstStateChange transition);
+
+static void
+gst_sunaudiomixer_base_init (gpointer klass)
+{
+ gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
+ "Sun Audio Mixer", "Generic/Audio",
+ "Control sound input and output levels with Sun Audio",
+ "Brian Cameron <brian.cameron@sun.com>");
+}
+
+static void
+gst_sunaudiomixer_class_init (GstSunAudioMixerClass * klass)
+{
+ GstElementClass *element_class;
+
+ element_class = (GstElementClass *) klass;
+
+ element_class->change_state = gst_sunaudiomixer_change_state;
+}
+
+static void
+gst_sunaudiomixer_init (GstSunAudioMixer * this,
+ GstSunAudioMixerClass * g_class)
+{
+ this->mixer = NULL;
+}
+
+static GstStateChangeReturn
+gst_sunaudiomixer_change_state (GstElement * element, GstStateChange transition)
+{
+ GstSunAudioMixer *this = GST_SUNAUDIO_MIXER (element);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ if (!this->mixer) {
+ const char *audiodev;
+
+ audiodev = g_getenv ("AUDIODEV");
+ if (audiodev == NULL) {
+ this->mixer = gst_sunaudiomixer_ctrl_new ("/dev/audioctl");
+ } else {
+ gchar *device = g_strdup_printf ("%sctl", audiodev);
+
+ this->mixer = gst_sunaudiomixer_ctrl_new (device);
+ g_free (device);
+ }
+ }
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ if (this->mixer) {
+ gst_sunaudiomixer_ctrl_free (this->mixer);
+ this->mixer = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ return GST_STATE_CHANGE_SUCCESS;
+}
diff --git a/sys/sunaudio/gstsunaudiomixer.h b/sys/sunaudio/gstsunaudiomixer.h
new file mode 100644
index 0000000..03292ed
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixer.h
@@ -0,0 +1,51 @@
+/*
+ * GStreamer - SunAudio mixer
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_SUNAUDIO_MIXER_H__
+#define __GST_SUNAUDIO_MIXER_H__
+
+#include "gstsunaudiomixerctrl.h"
+
+G_BEGIN_DECLS
+
+#define GST_SUNAUDIO_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_MIXER,GstSunAudioMixer))
+#define GST_SUNAUDIO_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_MIXER,GstSunAudioMixerClass))
+#define GST_IS_SUNAUDIO_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_MIXER))
+#define GST_IS_SUNAUDIO_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_MIXER))
+#define GST_TYPE_SUNAUDIO_MIXER (gst_sunaudiomixer_get_type())
+
+typedef struct _GstSunAudioMixer GstSunAudioMixer;
+typedef struct _GstSunAudioMixerClass GstSunAudioMixerClass;
+
+struct _GstSunAudioMixer {
+ GstElement parent;
+
+ GstSunAudioMixerCtrl *mixer;
+};
+
+struct _GstSunAudioMixerClass {
+ GstElementClass parent;
+};
+
+GType gst_sunaudiomixer_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_SUNAUDIO_MIXER_H__ */
diff --git a/sys/sunaudio/gstsunaudiomixerctrl.c b/sys/sunaudio/gstsunaudiomixerctrl.c
new file mode 100644
index 0000000..32fc4e2
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixerctrl.c
@@ -0,0 +1,585 @@
+/*
+ * GStreamer - SunAudio mixer interface element
+ * Copyright (C) 2005,2006,2008,2009 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Copyright (C) 2008 Sun Microsystems, Inc.,
+ * Jan Schmidt <jan.schmidt@sun.com>
+ * Copyright (C) 2009 Sun Microsystems, Inc.,
+ * Garrett D'Amore <garrett.damore@sun.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/audio.h>
+#include <sys/mixer.h>
+
+#include <gst/gst-i18n-plugin.h>
+
+#include "gstsunaudiomixerctrl.h"
+#include "gstsunaudiomixertrack.h"
+#include "gstsunaudiomixeroptions.h"
+
+GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
+#define GST_CAT_DEFAULT sunaudio_debug
+
+static gboolean
+gst_sunaudiomixer_ctrl_open (GstSunAudioMixerCtrl * mixer)
+{
+ int fd;
+
+ /* First try to open non-blocking */
+ fd = open (mixer->device, O_RDWR | O_NONBLOCK);
+
+ if (fd >= 0) {
+ close (fd);
+ fd = open (mixer->device, O_WRONLY);
+ }
+
+ if (fd == -1) {
+ GST_DEBUG_OBJECT (mixer,
+ "Failed to open mixer device %s, mixing disabled: %s", mixer->device,
+ strerror (errno));
+
+ return FALSE;
+ }
+ mixer->mixer_fd = fd;
+
+ /* Try to set the multiple open flag if we can, but ignore errors */
+ ioctl (mixer->mixer_fd, AUDIO_MIXER_MULTIPLE_OPEN);
+
+ GST_DEBUG_OBJECT (mixer, "Opened mixer device %s", mixer->device);
+
+ return TRUE;
+}
+
+void
+gst_sunaudiomixer_ctrl_build_list (GstSunAudioMixerCtrl * mixer)
+{
+ GstMixerTrack *track;
+ GstMixerOptions *options;
+
+ struct audio_info audioinfo;
+
+ /*
+ * Do not continue appending the same 3 static tracks onto the list
+ */
+ if (mixer->tracklist == NULL) {
+ g_return_if_fail (mixer->mixer_fd != -1);
+
+ /* query available ports */
+ if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
+ g_warning ("Error getting audio device volume");
+ return;
+ }
+
+ /* Output & should be MASTER when it's the only one. */
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_OUTPUT);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+
+ /* Input */
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_RECORD);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+
+ /* Monitor */
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_MONITOR);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+
+ if (audioinfo.play.avail_ports & AUDIO_SPEAKER) {
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_SPEAKER);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+ }
+ if (audioinfo.play.avail_ports & AUDIO_HEADPHONE) {
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_HP);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+ }
+ if (audioinfo.play.avail_ports & AUDIO_LINE_OUT) {
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_LINEOUT);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+ }
+ if (audioinfo.play.avail_ports & AUDIO_SPDIF_OUT) {
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_SPDIFOUT);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+ }
+ if (audioinfo.play.avail_ports & AUDIO_AUX1_OUT) {
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_AUX1OUT);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+ }
+ if (audioinfo.play.avail_ports & AUDIO_AUX2_OUT) {
+ track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_AUX2OUT);
+ mixer->tracklist = g_list_append (mixer->tracklist, track);
+ }
+
+ if (audioinfo.record.avail_ports != AUDIO_NONE) {
+ options =
+ gst_sunaudiomixer_options_new (mixer, GST_SUNAUDIO_TRACK_RECSRC);
+ mixer->tracklist = g_list_append (mixer->tracklist, options);
+ }
+ }
+}
+
+GstSunAudioMixerCtrl *
+gst_sunaudiomixer_ctrl_new (const char *device)
+{
+ GstSunAudioMixerCtrl *ret = NULL;
+
+ g_return_val_if_fail (device != NULL, NULL);
+
+ ret = g_new0 (GstSunAudioMixerCtrl, 1);
+
+ ret->device = g_strdup (device);
+ ret->mixer_fd = -1;
+ ret->tracklist = NULL;
+
+ if (!gst_sunaudiomixer_ctrl_open (ret))
+ goto error;
+
+ return ret;
+
+error:
+ if (ret)
+ gst_sunaudiomixer_ctrl_free (ret);
+
+ return NULL;
+}
+
+void
+gst_sunaudiomixer_ctrl_free (GstSunAudioMixerCtrl * mixer)
+{
+ g_return_if_fail (mixer != NULL);
+
+ if (mixer->device) {
+ g_free (mixer->device);
+ mixer->device = NULL;
+ }
+
+ if (mixer->tracklist) {
+ g_list_foreach (mixer->tracklist, (GFunc) g_object_unref, NULL);
+ g_list_free (mixer->tracklist);
+ mixer->tracklist = NULL;
+ }
+
+ if (mixer->mixer_fd != -1) {
+ close (mixer->mixer_fd);
+ mixer->mixer_fd = -1;
+ }
+
+ g_free (mixer);
+}
+
+GstMixerFlags
+gst_sunaudiomixer_ctrl_get_mixer_flags (GstSunAudioMixerCtrl * mixer)
+{
+ return GST_MIXER_FLAG_HAS_WHITELIST | GST_MIXER_FLAG_GROUPING;
+}
+
+const GList *
+gst_sunaudiomixer_ctrl_list_tracks (GstSunAudioMixerCtrl * mixer)
+{
+ gst_sunaudiomixer_ctrl_build_list (mixer);
+
+ return (const GList *) mixer->tracklist;
+}
+
+void
+gst_sunaudiomixer_ctrl_get_volume (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track, gint * volumes)
+{
+ gint gain, balance;
+ float ratio;
+ struct audio_info audioinfo;
+ GstSunAudioMixerTrack *sunaudiotrack;
+
+ g_return_if_fail (GST_IS_SUNAUDIO_MIXER_TRACK (track));
+ sunaudiotrack = GST_SUNAUDIO_MIXER_TRACK (track);
+
+ g_return_if_fail (mixer->mixer_fd != -1);
+
+ if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
+ g_warning ("Error getting audio device volume");
+ return;
+ }
+
+ balance = AUDIO_MID_BALANCE;
+ gain = 0;
+
+ switch (sunaudiotrack->track_num) {
+ case GST_SUNAUDIO_TRACK_OUTPUT:
+ gain = (int) audioinfo.play.gain;
+ balance = audioinfo.play.balance;
+ break;
+ case GST_SUNAUDIO_TRACK_RECORD:
+ gain = (int) audioinfo.record.gain;
+ balance = audioinfo.record.balance;
+ break;
+ case GST_SUNAUDIO_TRACK_MONITOR:
+ gain = (int) audioinfo.monitor_gain;
+ balance = audioinfo.record.balance;
+ break;
+ case GST_SUNAUDIO_TRACK_SPEAKER:
+ if (audioinfo.play.port & AUDIO_SPEAKER)
+ gain = AUDIO_MAX_GAIN;
+ break;
+ case GST_SUNAUDIO_TRACK_HP:
+ if (audioinfo.play.port & AUDIO_HEADPHONE)
+ gain = AUDIO_MAX_GAIN;
+ break;
+ case GST_SUNAUDIO_TRACK_LINEOUT:
+ if (audioinfo.play.port & AUDIO_LINE_OUT)
+ gain = AUDIO_MAX_GAIN;
+ break;
+ case GST_SUNAUDIO_TRACK_SPDIFOUT:
+ if (audioinfo.play.port & AUDIO_SPDIF_OUT)
+ gain = AUDIO_MAX_GAIN;
+ break;
+ case GST_SUNAUDIO_TRACK_AUX1OUT:
+ if (audioinfo.play.port & AUDIO_AUX1_OUT)
+ gain = AUDIO_MAX_GAIN;
+ break;
+ case GST_SUNAUDIO_TRACK_AUX2OUT:
+ if (audioinfo.play.port & AUDIO_AUX2_OUT)
+ gain = AUDIO_MAX_GAIN;
+ break;
+ default:
+ break;
+ }
+
+ switch (track->num_channels) {
+ case 2:
+ if (balance == AUDIO_MID_BALANCE) {
+ volumes[0] = gain;
+ volumes[1] = gain;
+ } else if (balance < AUDIO_MID_BALANCE) {
+ volumes[0] = gain;
+ ratio = 1 - (float) (AUDIO_MID_BALANCE - balance) /
+ (float) AUDIO_MID_BALANCE;
+ volumes[1] = (int) ((float) gain * ratio + 0.5);
+ } else {
+ volumes[1] = gain;
+ ratio = 1 - (float) (balance - AUDIO_MID_BALANCE) /
+ (float) AUDIO_MID_BALANCE;
+ volumes[0] = (int) ((float) gain * ratio + 0.5);
+ }
+ break;
+ case 1:
+ volumes[0] = gain;
+ break;
+ }
+
+ /* Likewise reset MUTE */
+ if ((sunaudiotrack->track_num == GST_SUNAUDIO_TRACK_OUTPUT
+ && audioinfo.output_muted == 1)
+ || (sunaudiotrack->track_num != GST_SUNAUDIO_TRACK_OUTPUT && gain == 0)) {
+ /*
+ * If MUTE is set, then gain is always 0, so don't bother
+ * resetting our internal value.
+ */
+ track->flags |= GST_MIXER_TRACK_MUTE;
+ } else {
+ sunaudiotrack->gain = gain;
+ sunaudiotrack->balance = balance;
+ track->flags &= ~GST_MIXER_TRACK_MUTE;
+ }
+}
+
+void
+gst_sunaudiomixer_ctrl_set_volume (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track, gint * volumes)
+{
+ gint gain;
+ gint balance;
+ gint l_real_gain;
+ gint r_real_gain;
+ float ratio;
+ struct audio_info audioinfo;
+ GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIO_MIXER_TRACK (track);
+
+ l_real_gain = volumes[0];
+ r_real_gain = volumes[1];
+
+ if (l_real_gain == r_real_gain) {
+ gain = l_real_gain;
+ balance = AUDIO_MID_BALANCE;
+ } else if (l_real_gain < r_real_gain) {
+ gain = r_real_gain;
+ ratio = (float) l_real_gain / (float) r_real_gain;
+ balance =
+ AUDIO_RIGHT_BALANCE - (int) (ratio * (float) AUDIO_MID_BALANCE + 0.5);
+ } else {
+ gain = l_real_gain;
+ ratio = (float) r_real_gain / (float) l_real_gain;
+ balance =
+ AUDIO_LEFT_BALANCE + (int) (ratio * (float) AUDIO_MID_BALANCE + 0.5);
+ }
+
+ sunaudiotrack->gain = gain;
+ sunaudiotrack->balance = balance;
+
+ if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE)) {
+ if (sunaudiotrack->track_num == GST_SUNAUDIO_TRACK_OUTPUT) {
+ return;
+ } else if (gain == 0) {
+ return;
+ } else {
+ /*
+ * If the volume is set to a non-zero value for LINE_IN
+ * or MONITOR, then unset MUTE.
+ */
+ track->flags &= ~GST_MIXER_TRACK_MUTE;
+ }
+ }
+
+ /* Set the volume */
+ AUDIO_INITINFO (&audioinfo);
+
+ switch (sunaudiotrack->track_num) {
+ case GST_SUNAUDIO_TRACK_OUTPUT:
+ audioinfo.play.gain = gain;
+ audioinfo.play.balance = balance;
+ break;
+ case GST_SUNAUDIO_TRACK_RECORD:
+ audioinfo.record.gain = gain;
+ audioinfo.record.balance = balance;
+ break;
+ case GST_SUNAUDIO_TRACK_MONITOR:
+ audioinfo.monitor_gain = gain;
+ audioinfo.record.balance = balance;
+ break;
+ default:
+ break;
+ }
+
+ g_return_if_fail (mixer->mixer_fd != -1);
+
+ if (ioctl (mixer->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) {
+ g_warning ("Error setting audio device volume");
+ return;
+ }
+}
+
+void
+gst_sunaudiomixer_ctrl_set_mute (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track, gboolean mute)
+{
+ struct audio_info audioinfo;
+ struct audio_info oldinfo;
+ GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIO_MIXER_TRACK (track);
+ gint volume, balance;
+
+ AUDIO_INITINFO (&audioinfo);
+
+ if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &oldinfo) < 0) {
+ g_warning ("Error getting audio device volume");
+ return;
+ }
+
+ if (mute) {
+ volume = 0;
+ track->flags |= GST_MIXER_TRACK_MUTE;
+ } else {
+ volume = sunaudiotrack->gain;
+ track->flags &= ~GST_MIXER_TRACK_MUTE;
+ }
+
+ balance = sunaudiotrack->balance;
+
+ switch (sunaudiotrack->track_num) {
+ case GST_SUNAUDIO_TRACK_OUTPUT:
+ if (mute)
+ audioinfo.output_muted = 1;
+ else
+ audioinfo.output_muted = 0;
+
+ audioinfo.play.gain = volume;
+ audioinfo.play.balance = balance;
+ break;
+ case GST_SUNAUDIO_TRACK_RECORD:
+ audioinfo.record.gain = volume;
+ audioinfo.record.balance = balance;
+ break;
+ case GST_SUNAUDIO_TRACK_MONITOR:
+ audioinfo.monitor_gain = volume;
+ audioinfo.record.balance = balance;
+ break;
+ case GST_SUNAUDIO_TRACK_SPEAKER:
+ if (mute) {
+ audioinfo.play.port = oldinfo.play.port & ~AUDIO_SPEAKER;
+ } else {
+ audioinfo.play.port = oldinfo.play.port | AUDIO_SPEAKER;
+ }
+ break;
+ case GST_SUNAUDIO_TRACK_HP:
+ if (mute) {
+ audioinfo.play.port = oldinfo.play.port & ~AUDIO_HEADPHONE;
+ } else {
+ audioinfo.play.port = oldinfo.play.port | AUDIO_HEADPHONE;
+ }
+ break;
+ case GST_SUNAUDIO_TRACK_LINEOUT:
+ if (mute) {
+ audioinfo.play.port = oldinfo.play.port & ~AUDIO_LINE_OUT;
+ } else {
+ audioinfo.play.port = oldinfo.play.port | AUDIO_LINE_OUT;
+ }
+ break;
+ case GST_SUNAUDIO_TRACK_SPDIFOUT:
+ if (mute) {
+ audioinfo.play.port = oldinfo.play.port & ~AUDIO_SPDIF_OUT;
+ } else {
+ audioinfo.play.port = oldinfo.play.port | AUDIO_SPDIF_OUT;
+ }
+ break;
+ case GST_SUNAUDIO_TRACK_AUX1OUT:
+ if (mute) {
+ audioinfo.play.port = oldinfo.play.port & ~AUDIO_AUX1_OUT;
+ } else {
+ audioinfo.play.port = oldinfo.play.port | AUDIO_AUX1_OUT;
+ }
+ break;
+ case GST_SUNAUDIO_TRACK_AUX2OUT:
+ if (mute) {
+ audioinfo.play.port = oldinfo.play.port & ~AUDIO_AUX2_OUT;
+ } else {
+ audioinfo.play.port = oldinfo.play.port | AUDIO_AUX2_OUT;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (audioinfo.play.port != ((unsigned) ~0)) {
+ /* mask off ports we can't modify. Hack for broken drivers where mod_ports == 0 */
+ if (oldinfo.play.mod_ports != 0) {
+ audioinfo.play.port &= oldinfo.play.mod_ports;
+ /* and add in any that are forced to be on */
+ audioinfo.play.port |= (oldinfo.play.port & ~oldinfo.play.mod_ports);
+ }
+ }
+ g_return_if_fail (mixer->mixer_fd != -1);
+
+ if (audioinfo.play.port != (guint) (-1) &&
+ audioinfo.play.port != oldinfo.play.port)
+ GST_LOG_OBJECT (mixer, "Changing play port mask to 0x%08x",
+ audioinfo.play.port);
+
+ if (ioctl (mixer->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) {
+ g_warning ("Error setting audio settings");
+ return;
+ }
+}
+
+void
+gst_sunaudiomixer_ctrl_set_record (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track, gboolean record)
+{
+}
+
+void
+gst_sunaudiomixer_ctrl_set_option (GstSunAudioMixerCtrl * mixer,
+ GstMixerOptions * options, gchar * value)
+{
+ struct audio_info audioinfo;
+ GstMixerTrack *track;
+ GstSunAudioMixerOptions *opts;
+ GQuark q;
+ int i;
+
+ g_return_if_fail (mixer != NULL);
+ g_return_if_fail (mixer->mixer_fd != -1);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (GST_IS_SUNAUDIO_MIXER_OPTIONS (options));
+
+ track = GST_MIXER_TRACK (options);
+ opts = GST_SUNAUDIO_MIXER_OPTIONS (options);
+
+ if (opts->track_num != GST_SUNAUDIO_TRACK_RECSRC) {
+ g_warning ("set_option not supported on track %s", track->label);
+ return;
+ }
+
+ q = g_quark_try_string (value);
+ if (q == 0) {
+ g_warning ("unknown option '%s'", value);
+ return;
+ }
+
+ for (i = 0; i < 8; i++) {
+ if (opts->names[i] == q) {
+ break;
+ }
+ }
+
+ if (((1 << (i)) & opts->avail) == 0) {
+ g_warning ("Record port %s not available", g_quark_to_string (q));
+ return;
+ }
+
+ AUDIO_INITINFO (&audioinfo);
+ audioinfo.record.port = (1 << (i));
+
+ if (ioctl (mixer->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) {
+ g_warning ("Error setting audio record port");
+ }
+}
+
+const gchar *
+gst_sunaudiomixer_ctrl_get_option (GstSunAudioMixerCtrl * mixer,
+ GstMixerOptions * options)
+{
+ GstMixerTrack *track;
+ GstSunAudioMixerOptions *opts;
+ struct audio_info audioinfo;
+ int i;
+
+ g_return_val_if_fail (mixer != NULL, NULL);
+ g_return_val_if_fail (mixer->fd != -1, NULL);
+ g_return_val_if_fail (GST_IS_SUNAUDIO_MIXER_OPTIONS (options), NULL);
+
+ track = GST_MIXER_TRACK (options);
+ opts = GST_SUNAUDIO_MIXER_OPTIONS (options);
+
+ g_return_val_if_fail (opts->track_num == GST_SUNAUDIO_TRACK_RECSRC, NULL);
+
+ if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
+ g_warning ("Error getting audio device settings");
+ return (NULL);
+ }
+
+ for (i = 0; i < 8; i++) {
+ if ((1 << i) == audioinfo.record.port) {
+ const gchar *s = g_quark_to_string (opts->names[i]);
+ GST_DEBUG_OBJECT (mixer, "Getting value for option %d: %s",
+ opts->track_num, s);
+ return (s);
+ }
+ }
+
+ GST_DEBUG_OBJECT (mixer, "Unable to get value for option %d",
+ opts->track_num);
+
+ g_warning ("Record port value %d seems illegal", audioinfo.record.port);
+ return (NULL);
+}
diff --git a/sys/sunaudio/gstsunaudiomixerctrl.h b/sys/sunaudio/gstsunaudiomixerctrl.h
new file mode 100644
index 0000000..f9aa477
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixerctrl.h
@@ -0,0 +1,189 @@
+/*
+ * GStreamer - SunAudio mixer interface element.
+ * Copyright (C) 2005,2006,2009 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Copyright (C) 2009 Sun Microsystems, Inc.,
+ * Garrett D'Amore <garrett.damore@sun.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_SUNAUDIO_MIXER_CTRL_H
+#define __GST_SUNAUDIO_MIXER_CTRL_H
+
+#include <sys/audioio.h>
+
+#include <gst/gst.h>
+#include <gst/interfaces/mixer.h>
+
+G_BEGIN_DECLS
+
+#define GST_SUNAUDIO_MIXER_CTRL(obj) ((GstSunAudioMixerCtrl*)(obj))
+
+typedef struct _GstSunAudioMixerCtrl GstSunAudioMixerCtrl;
+
+struct _GstSunAudioMixerCtrl {
+ GList * tracklist; /* list of available tracks */
+
+ gint fd;
+ gint mixer_fd;
+
+ gchar * device;
+};
+
+GstSunAudioMixerCtrl* gst_sunaudiomixer_ctrl_new (const gchar *device);
+void gst_sunaudiomixer_ctrl_free (GstSunAudioMixerCtrl *mixer);
+
+const GList* gst_sunaudiomixer_ctrl_list_tracks (GstSunAudioMixerCtrl * mixer);
+void gst_sunaudiomixer_ctrl_set_volume (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track,
+ gint * volumes);
+void gst_sunaudiomixer_ctrl_get_volume (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track,
+ gint * volumes);
+void gst_sunaudiomixer_ctrl_set_record (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track,
+ gboolean record);
+void gst_sunaudiomixer_ctrl_set_mute (GstSunAudioMixerCtrl * mixer,
+ GstMixerTrack * track,
+ gboolean mute);
+void gst_sunaudiomixer_ctrl_set_option (GstSunAudioMixerCtrl * mixer,
+ GstMixerOptions * options,
+ gchar * value);
+const gchar * gst_sunaudiomixer_ctrl_get_option (GstSunAudioMixerCtrl * mixer,
+ GstMixerOptions * options);
+GstMixerFlags gst_sunaudiomixer_ctrl_get_mixer_flags (GstSunAudioMixerCtrl *mixer);
+
+#define GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS(Type, interface_as_function) \
+static gboolean \
+interface_as_function ## _supported (Type *this, GType iface_type) \
+{ \
+ g_assert (iface_type == GST_TYPE_MIXER); \
+ \
+ return (this->mixer != NULL); \
+} \
+ \
+static const GList* \
+interface_as_function ## _list_tracks (GstMixer * mixer) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_val_if_fail (this != NULL, NULL); \
+ g_return_val_if_fail (this->mixer != NULL, NULL); \
+ \
+ return gst_sunaudiomixer_ctrl_list_tracks (this->mixer); \
+} \
+ \
+static void \
+interface_as_function ## _set_volume (GstMixer * mixer, GstMixerTrack * track, \
+ gint * volumes) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_if_fail (this != NULL); \
+ g_return_if_fail (this->mixer != NULL); \
+ \
+ gst_sunaudiomixer_ctrl_set_volume (this->mixer, track, volumes); \
+} \
+ \
+static void \
+interface_as_function ## _get_volume (GstMixer * mixer, GstMixerTrack * track, \
+ gint * volumes) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_if_fail (this != NULL); \
+ g_return_if_fail (this->mixer != NULL); \
+ \
+ gst_sunaudiomixer_ctrl_get_volume (this->mixer, track, volumes); \
+} \
+ \
+static void \
+interface_as_function ## _set_record (GstMixer * mixer, GstMixerTrack * track, \
+ gboolean record) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_if_fail (this != NULL); \
+ g_return_if_fail (this->mixer != NULL); \
+ \
+ gst_sunaudiomixer_ctrl_set_record (this->mixer, track, record); \
+} \
+ \
+static void \
+interface_as_function ## _set_mute (GstMixer * mixer, GstMixerTrack * track, \
+ gboolean mute) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_if_fail (this != NULL); \
+ g_return_if_fail (this->mixer != NULL); \
+ \
+ gst_sunaudiomixer_ctrl_set_mute (this->mixer, track, mute); \
+} \
+ \
+static const gchar * \
+interface_as_function ## _get_option (GstMixer * mixer, GstMixerOptions * opts) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_val_if_fail (this != NULL, NULL); \
+ g_return_val_if_fail (this->mixer != NULL, NULL); \
+ \
+ return gst_sunaudiomixer_ctrl_get_option (this->mixer, opts); \
+} \
+\
+static void \
+interface_as_function ## _set_option (GstMixer * mixer, GstMixerOptions * opts, \
+ gchar * value) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_if_fail (this != NULL); \
+ g_return_if_fail (this->mixer != NULL); \
+ \
+ gst_sunaudiomixer_ctrl_set_option (this->mixer, opts, value); \
+} \
+\
+static GstMixerFlags \
+interface_as_function ## _get_mixer_flags (GstMixer * mixer) \
+{ \
+ Type *this = (Type*) mixer; \
+ \
+ g_return_val_if_fail (this != NULL, GST_MIXER_FLAG_NONE); \
+ g_return_val_if_fail (this->mixer != NULL, GST_MIXER_FLAG_NONE); \
+ \
+ return gst_sunaudiomixer_ctrl_get_mixer_flags (this->mixer); \
+} \
+ \
+static void \
+interface_as_function ## _interface_init (GstMixerInterface * iface) \
+{ \
+ GST_MIXER_TYPE (iface) = GST_MIXER_HARDWARE; \
+ \
+ /* set up the interface hooks */ \
+ iface->list_tracks = interface_as_function ## _list_tracks; \
+ iface->set_volume = interface_as_function ## _set_volume; \
+ iface->get_volume = interface_as_function ## _get_volume; \
+ iface->set_mute = interface_as_function ## _set_mute; \
+ iface->set_record = interface_as_function ## _set_record; \
+ iface->get_option = interface_as_function ## _get_option; \
+ iface->set_option = interface_as_function ## _set_option; \
+ iface->get_mixer_flags = interface_as_function ## _get_mixer_flags; \
+}
+
+G_END_DECLS
+
+#endif
diff --git a/sys/sunaudio/gstsunaudiomixeroptions.c b/sys/sunaudio/gstsunaudiomixeroptions.c
new file mode 100644
index 0000000..4637d82
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixeroptions.c
@@ -0,0 +1,157 @@
+/*
+ * GStreamer SunAudio mixer track implementation
+ * Copyright (C) 2009 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Garrett D'Amore <garrett.damore@sun.com>
+ *
+ * gstsunaudiomixeroptions.c: Sun Audio mixer options object
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/audio.h>
+#include <sys/mixer.h>
+
+#include <gst/gst-i18n-plugin.h>
+
+#include "gstsunaudiomixeroptions.h"
+#include "gstsunaudiomixertrack.h"
+
+GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
+#define GST_CAT_DEFAULT sunaudio_debug
+
+static void gst_sunaudiomixer_options_init (GstSunAudioMixerOptions * sun_opts);
+static void gst_sunaudiomixer_options_class_init (gpointer g_class,
+ gpointer class_data);
+
+static GstMixerOptionsClass *parent_class = NULL;
+
+GType
+gst_sunaudiomixer_options_get_type (void)
+{
+ static GType opts_type = 0;
+
+ if (!opts_type) {
+ static const GTypeInfo opts_info = {
+ sizeof (GstSunAudioMixerOptionsClass),
+ NULL,
+ NULL,
+ gst_sunaudiomixer_options_class_init,
+ NULL,
+ NULL,
+ sizeof (GstSunAudioMixerOptions),
+ 0,
+ (GInstanceInitFunc) gst_sunaudiomixer_options_init,
+ };
+
+ opts_type =
+ g_type_register_static (GST_TYPE_MIXER_OPTIONS,
+ "GstSunAudioMixerOptions", &opts_info, 0);
+ }
+
+ return opts_type;
+}
+
+static void
+gst_sunaudiomixer_options_class_init (gpointer g_class, gpointer class_data)
+{
+ parent_class = g_type_class_peek_parent (g_class);
+}
+
+static void
+gst_sunaudiomixer_options_init (GstSunAudioMixerOptions * sun_opts)
+{
+}
+
+GstMixerOptions *
+gst_sunaudiomixer_options_new (GstSunAudioMixerCtrl * mixer, gint track_num)
+{
+ GstMixerOptions *opts;
+ GstSunAudioMixerOptions *sun_opts;
+ GstMixerTrack *track;
+ const gchar *label;
+ gint i;
+ struct audio_info audioinfo;
+
+ if ((mixer == NULL) || (mixer->mixer_fd == -1)) {
+ g_warning ("mixer not initialized");
+ return NULL;
+ }
+
+ if (track_num != GST_SUNAUDIO_TRACK_RECSRC) {
+ g_warning ("invalid options track");
+ return (NULL);
+ }
+
+ label = N_("Record Source");
+
+ opts = g_object_new (GST_TYPE_SUNAUDIO_MIXER_OPTIONS,
+ "untranslated-label", label, NULL);
+ sun_opts = GST_SUNAUDIO_MIXER_OPTIONS (opts);
+ track = GST_MIXER_TRACK (opts);
+
+ GST_DEBUG_OBJECT (opts, "New mixer options, track %d: %s",
+ track_num, GST_STR_NULL (label));
+
+ /* save off names for the record sources */
+ sun_opts->names[0] = g_quark_from_string (_("Microphone"));
+ sun_opts->names[1] = g_quark_from_string (_("Line In"));
+ sun_opts->names[2] = g_quark_from_string (_("Internal CD"));
+ sun_opts->names[3] = g_quark_from_string (_("SPDIF In"));
+ sun_opts->names[4] = g_quark_from_string (_("AUX 1 In"));
+ sun_opts->names[5] = g_quark_from_string (_("AUX 2 In"));
+ sun_opts->names[6] = g_quark_from_string (_("Codec Loopback"));
+ sun_opts->names[7] = g_quark_from_string (_("SunVTS Loopback"));
+
+ /* set basic information */
+ track->label = g_strdup (_(label));
+ track->num_channels = 0;
+ track->min_volume = 0;
+ track->max_volume = 0;
+ track->flags =
+ GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_WHITELIST |
+ GST_MIXER_TRACK_NO_RECORD;
+
+ if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
+ g_warning ("Error getting audio device settings");
+ g_object_unref (G_OBJECT (sun_opts));
+ return NULL;
+ }
+
+ sun_opts->avail = audioinfo.record.avail_ports;
+ sun_opts->track_num = track_num;
+
+ for (i = 0; i < 8; i++) {
+ if ((1 << i) & audioinfo.record.avail_ports) {
+ const char *s = g_quark_to_string (sun_opts->names[i]);
+ opts->values = g_list_append (opts->values, g_strdup (s));
+ GST_DEBUG_OBJECT (opts, "option for track %d: %s",
+ track_num, GST_STR_NULL (s));
+ }
+ }
+
+ return opts;
+}
diff --git a/sys/sunaudio/gstsunaudiomixeroptions.h b/sys/sunaudio/gstsunaudiomixeroptions.h
new file mode 100644
index 0000000..e27ef21
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixeroptions.h
@@ -0,0 +1,65 @@
+/*
+ * GStreamer SunAudio mixer track implementation
+ * Copyright (C) 2009 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Garrett D'Amore <garrett.damore@sun.com>
+ *
+ * gstsunaudiomixeroptions.h: Sun Audio mixer options object
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ */
+
+#ifndef __GST_SUNAUDIO_MIXER_OPTIONS_H__
+#define __GST_SUNAUDIO_MIXER_OPTIONS_H__
+
+
+#include "gstsunaudiomixer.h"
+#include <gst/interfaces/mixeroptions.h>
+
+
+G_BEGIN_DECLS
+
+
+#define GST_SUNAUDIO_MIXER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_MIXER_OPTIONS, GstSunAudioMixerOptions))
+#define GST_SUNAUDIO_MIXER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_MIXER_OPTIONS, GstSunAudioMixerOptionsClass))
+#define GST_IS_SUNAUDIO_MIXER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_MIXER_OPTIONS))
+#define GST_IS_SUNAUDIO_MIXER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_MIXER_OPTIONS))
+#define GST_TYPE_SUNAUDIO_MIXER_OPTIONS (gst_sunaudiomixer_options_get_type())
+
+
+typedef struct _GstSunAudioMixerOptions GstSunAudioMixerOptions;
+typedef struct _GstSunAudioMixerOptionsClass GstSunAudioMixerOptionsClass;
+
+
+struct _GstSunAudioMixerOptions {
+ GstMixerOptions parent;
+ gint track_num;
+ GQuark names[8]; /* only 8 possible */
+ gint avail; /* mask of avail */
+};
+
+struct _GstSunAudioMixerOptionsClass {
+ GstMixerOptionsClass parent;
+};
+
+
+GType gst_sunaudiomixer_options_get_type (void);
+GstMixerOptions *gst_sunaudiomixer_options_new (GstSunAudioMixerCtrl *mixer, gint track_num);
+
+
+G_END_DECLS
+
+
+#endif /* __GST_SUNAUDIO_MIXER_OPTIONS_H__ */
diff --git a/sys/sunaudio/gstsunaudiomixertrack.c b/sys/sunaudio/gstsunaudiomixertrack.c
new file mode 100644
index 0000000..43bf044
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixertrack.c
@@ -0,0 +1,158 @@
+/*
+ * GStreamer
+ * Copyright (C) 2005,2008, 2009 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Copyright (C) 2009 Sun Microsystems, Inc.,
+ * Garrett D'Amore <garrett.damore@sun.com>
+ *
+ * gstsunaudiomixer.c: mixer interface implementation for OSS
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/audioio.h>
+
+#include <gst/gst-i18n-plugin.h>
+
+#include "gstsunaudiomixertrack.h"
+
+GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
+#define GST_CAT_DEFAULT sunaudio_debug
+
+#define MASK_BIT_IS_SET(mask, bit) \
+ (mask & (1 << bit))
+
+G_DEFINE_TYPE (GstSunAudioMixerTrack, gst_sunaudiomixer_track,
+ GST_TYPE_MIXER_TRACK);
+
+static void
+gst_sunaudiomixer_track_class_init (GstSunAudioMixerTrackClass * klass)
+{
+ /* nop */
+}
+
+static void
+gst_sunaudiomixer_track_init (GstSunAudioMixerTrack * track)
+{
+ track->gain = 0;
+ track->balance = AUDIO_MID_BALANCE;
+ track->track_num = 0;
+}
+
+GstMixerTrack *
+gst_sunaudiomixer_track_new (GstSunAudioTrackType track_num)
+{
+ const gchar *labels[] = { N_("Volume"),
+ N_("Gain"),
+ N_("Monitor"),
+ N_("Built-in Speaker"),
+ N_("Headphone"),
+ N_("Line Out"),
+ N_("SPDIF Out"),
+ N_("AUX 1 Out"),
+ N_("AUX 2 Out"),
+ };
+
+
+ GstSunAudioMixerTrack *sunaudiotrack;
+ GstMixerTrack *track;
+ const gchar *untranslated_label;
+
+ if ((guint) track_num < G_N_ELEMENTS (labels))
+ untranslated_label = labels[track_num];
+ else
+ untranslated_label = NULL;
+
+ sunaudiotrack = g_object_new (GST_TYPE_SUNAUDIO_MIXER_TRACK,
+ "untranslated-label", untranslated_label, NULL);
+
+ GST_DEBUG_OBJECT (sunaudiotrack, "Creating new mixer track of type %d: %s",
+ track_num, GST_STR_NULL (untranslated_label));
+
+ switch (track_num) {
+ case GST_SUNAUDIO_TRACK_OUTPUT:
+ /* these are sliders */
+ track = GST_MIXER_TRACK (sunaudiotrack);
+ track->label = g_strdup (_(untranslated_label));
+ track->num_channels = 2;
+ track->flags = GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_WHITELIST |
+ GST_MIXER_TRACK_MASTER;
+ track->min_volume = 0;
+ track->max_volume = 255;
+ sunaudiotrack->track_num = track_num;
+ sunaudiotrack->gain = (0 & 0xff);
+ sunaudiotrack->balance = AUDIO_MID_BALANCE;
+ break;
+ case GST_SUNAUDIO_TRACK_RECORD:
+ /* these are sliders */
+ track = GST_MIXER_TRACK (sunaudiotrack);
+ track->label = g_strdup (_(untranslated_label));
+ track->num_channels = 2;
+ track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD |
+ GST_MIXER_TRACK_WHITELIST;
+ track->min_volume = 0;
+ track->max_volume = 255;
+ sunaudiotrack->track_num = track_num;
+ sunaudiotrack->gain = (0 & 0xff);
+ sunaudiotrack->balance = AUDIO_MID_BALANCE;
+ break;
+ case GST_SUNAUDIO_TRACK_MONITOR:
+ /* these are sliders */
+ track = GST_MIXER_TRACK (sunaudiotrack);
+ track->label = g_strdup (_(untranslated_label));
+ track->num_channels = 2;
+ track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD;
+ track->min_volume = 0;
+ track->max_volume = 255;
+ sunaudiotrack->track_num = track_num;
+ sunaudiotrack->gain = (0 & 0xff);
+ sunaudiotrack->balance = AUDIO_MID_BALANCE;
+ break;
+ case GST_SUNAUDIO_TRACK_SPEAKER:
+ case GST_SUNAUDIO_TRACK_HP:
+ case GST_SUNAUDIO_TRACK_LINEOUT:
+ case GST_SUNAUDIO_TRACK_SPDIFOUT:
+ case GST_SUNAUDIO_TRACK_AUX1OUT:
+ case GST_SUNAUDIO_TRACK_AUX2OUT:
+ /* these are switches */
+ track = GST_MIXER_TRACK (sunaudiotrack);
+ track->label = g_strdup (_(untranslated_label));
+ track->num_channels = 0;
+ track->flags = GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_WHITELIST;
+ track->min_volume = 0;
+ track->max_volume = 255;
+ sunaudiotrack->track_num = track_num;
+ sunaudiotrack->gain = (0 & 0xff);
+ sunaudiotrack->balance = AUDIO_MID_BALANCE;
+ break;
+ default:
+ g_warning ("Unknown sun audio track num %d", track_num);
+ track = NULL;
+ }
+
+ return track;
+}
diff --git a/sys/sunaudio/gstsunaudiomixertrack.h b/sys/sunaudio/gstsunaudiomixertrack.h
new file mode 100644
index 0000000..278ed81
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiomixertrack.h
@@ -0,0 +1,78 @@
+/*
+ * GStreamer SunAudio mixer track implementation
+ * Copyright (C) 2005,2006,2009 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Copyright (C) 2009 Sun Microsystems, Inc.,
+ * Garrett D'Amore <garrett.damore@sun.com>
+ *
+ * gstsunaudiomixertrack.h: SunAudio mixer tracks
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_SUNAUDIO_MIXER_TRACK_H__
+#define __GST_SUNAUDIO_MIXER_TRACK_H__
+
+#include <gst/gst.h>
+#include <gst/interfaces/mixer.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ GST_SUNAUDIO_TRACK_OUTPUT = 0,
+ GST_SUNAUDIO_TRACK_RECORD,
+ GST_SUNAUDIO_TRACK_MONITOR,
+ GST_SUNAUDIO_TRACK_SPEAKER,
+ GST_SUNAUDIO_TRACK_HP,
+ GST_SUNAUDIO_TRACK_LINEOUT,
+ GST_SUNAUDIO_TRACK_SPDIFOUT,
+ GST_SUNAUDIO_TRACK_AUX1OUT,
+ GST_SUNAUDIO_TRACK_AUX2OUT,
+ GST_SUNAUDIO_TRACK_RECSRC
+} GstSunAudioTrackType;
+
+#define GST_TYPE_SUNAUDIO_MIXER_TRACK \
+ (gst_sunaudiomixer_track_get_type ())
+#define GST_SUNAUDIO_MIXER_TRACK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SUNAUDIO_MIXER_TRACK, \
+ GstSunAudioMixerTrack))
+#define GST_SUNAUDIO_MIXER_TRACK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SUNAUDIO_MIXER_TRACK, \
+ GstSunAudioMixerTrackClass))
+#define GST_IS_SUNAUDIO_MIXER_TRACK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SUNAUDIO_MIXER_TRACK))
+#define GST_IS_SUNAUDIO_MIXER_TRACK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SUNAUDIO_MIXER_TRACK))
+
+typedef struct _GstSunAudioMixerTrack {
+ GstMixerTrack parent;
+
+ gint gain;
+ gint balance;
+ GstSunAudioTrackType track_num;
+} GstSunAudioMixerTrack;
+
+typedef struct _GstSunAudioMixerTrackClass {
+ GstMixerTrackClass parent;
+} GstSunAudioMixerTrackClass;
+
+GType gst_sunaudiomixer_track_get_type (void);
+GstMixerTrack* gst_sunaudiomixer_track_new (GstSunAudioTrackType track_num);
+
+G_END_DECLS
+
+#endif /* __GST_SUNAUDIO_MIXER_TRACK_H__ */
diff --git a/sys/sunaudio/gstsunaudiosink.c b/sys/sunaudio/gstsunaudiosink.c
new file mode 100644
index 0000000..99e08ea
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiosink.c
@@ -0,0 +1,651 @@
+/*
+ * GStreamer - SunAudio sink
+ * Copyright (C) 2004 David A. Schleef <ds@schleef.org>
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Copyright (C) 2006 Jan Schmidt <thaytan@mad.scientist.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:element-sunaudiosink
+ *
+ * sunaudiosink is an audio sink designed to work with the Sun Audio
+ * interface available in Solaris.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch-1.0 audiotestsrc volume=0.5 ! sunaudiosink
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fcntl.h>
+#include <string.h>
+#include <stropts.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "gstsunaudiosink.h"
+
+GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
+#define GST_CAT_DEFAULT sunaudio_debug
+
+static void gst_sunaudiosink_base_init (gpointer g_class);
+static void gst_sunaudiosink_class_init (GstSunAudioSinkClass * klass);
+static void gst_sunaudiosink_init (GstSunAudioSink * filter);
+static void gst_sunaudiosink_dispose (GObject * object);
+static void gst_sunaudiosink_finalize (GObject * object);
+
+static void gst_sunaudiosink_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_sunaudiosink_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_sunaudiosink_getcaps (GstBaseSink * bsink);
+
+static gboolean gst_sunaudiosink_open (GstAudioSink * asink);
+static gboolean gst_sunaudiosink_close (GstAudioSink * asink);
+static gboolean gst_sunaudiosink_prepare (GstAudioSink * asink,
+ GstRingBufferSpec * spec);
+static gboolean gst_sunaudiosink_unprepare (GstAudioSink * asink);
+static guint gst_sunaudiosink_write (GstAudioSink * asink, gpointer data,
+ guint length);
+static guint gst_sunaudiosink_delay (GstAudioSink * asink);
+static void gst_sunaudiosink_reset (GstAudioSink * asink);
+
+#define DEFAULT_DEVICE "/dev/audio"
+enum
+{
+ PROP_0,
+ PROP_DEVICE,
+};
+
+static GstStaticPadTemplate gst_sunaudiosink_factory =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-raw-int, "
+ "endianness = (int) BYTE_ORDER, "
+ "signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16, "
+ /* [5510,48000] seems to be a Solaris limit */
+ "rate = (int) [ 5510, 48000 ], " "channels = (int) [ 1, 2 ]")
+ );
+
+static GstElementClass *parent_class = NULL;
+
+GType
+gst_sunaudiosink_get_type (void)
+{
+ static GType plugin_type = 0;
+
+ if (!plugin_type) {
+ static const GTypeInfo plugin_info = {
+ sizeof (GstSunAudioSinkClass),
+ gst_sunaudiosink_base_init,
+ NULL,
+ (GClassInitFunc) gst_sunaudiosink_class_init,
+ NULL,
+ NULL,
+ sizeof (GstSunAudioSink),
+ 0,
+ (GInstanceInitFunc) gst_sunaudiosink_init,
+ };
+
+ plugin_type = g_type_register_static (GST_TYPE_AUDIO_SINK,
+ "GstSunAudioSink", &plugin_info, 0);
+ }
+ return plugin_type;
+}
+
+static void
+gst_sunaudiosink_dispose (GObject * object)
+{
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_sunaudiosink_finalize (GObject * object)
+{
+ GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (object);
+
+ g_mutex_free (sunaudiosink->write_mutex);
+ g_cond_free (sunaudiosink->sleep_cond);
+
+ g_free (sunaudiosink->device);
+
+ if (sunaudiosink->fd != -1) {
+ close (sunaudiosink->fd);
+ sunaudiosink->fd = -1;
+ }
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_sunaudiosink_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_sunaudiosink_factory));
+ gst_element_class_set_static_metadata (element_class, "Sun Audio Sink",
+ "Sink/Audio",
+ "Audio sink for Sun Audio devices",
+ "David A. Schleef <ds@schleef.org>, "
+ "Brian Cameron <brian.cameron@sun.com>");
+}
+
+static void
+gst_sunaudiosink_class_init (GstSunAudioSinkClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseSinkClass *gstbasesink_class;
+ GstBaseAudioSinkClass *gstbaseaudiosink_class;
+ GstAudioSinkClass *gstaudiosink_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasesink_class = (GstBaseSinkClass *) klass;
+ gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
+ gstaudiosink_class = (GstAudioSinkClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->dispose = gst_sunaudiosink_dispose;
+ gobject_class->finalize = gst_sunaudiosink_finalize;
+
+ gobject_class->set_property = gst_sunaudiosink_set_property;
+ gobject_class->get_property = gst_sunaudiosink_get_property;
+
+ gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sunaudiosink_getcaps);
+
+ gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sunaudiosink_open);
+ gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sunaudiosink_close);
+ gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sunaudiosink_prepare);
+ gstaudiosink_class->unprepare =
+ GST_DEBUG_FUNCPTR (gst_sunaudiosink_unprepare);
+ gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sunaudiosink_write);
+ gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sunaudiosink_delay);
+ gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sunaudiosink_reset);
+
+ g_object_class_install_property (gobject_class, PROP_DEVICE,
+ g_param_spec_string ("device", "Device", "Audio Device (/dev/audio)",
+ DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gst_sunaudiosink_init (GstSunAudioSink * sunaudiosink)
+{
+ const char *audiodev;
+
+ GST_DEBUG_OBJECT (sunaudiosink, "initializing sunaudiosink");
+
+ sunaudiosink->fd = -1;
+
+ audiodev = g_getenv ("AUDIODEV");
+ if (audiodev == NULL)
+ audiodev = DEFAULT_DEVICE;
+ sunaudiosink->device = g_strdup (audiodev);
+
+ /* mutex and gcond used to control the write method */
+ sunaudiosink->write_mutex = g_mutex_new ();
+ sunaudiosink->sleep_cond = g_cond_new ();
+}
+
+static void
+gst_sunaudiosink_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstSunAudioSink *sunaudiosink;
+
+ sunaudiosink = GST_SUNAUDIO_SINK (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ GST_OBJECT_LOCK (sunaudiosink);
+ g_free (sunaudiosink->device);
+ sunaudiosink->device = g_strdup (g_value_get_string (value));
+ GST_OBJECT_UNLOCK (sunaudiosink);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_sunaudiosink_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstSunAudioSink *sunaudiosink;
+
+ sunaudiosink = GST_SUNAUDIO_SINK (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ GST_OBJECT_LOCK (sunaudiosink);
+ g_value_set_string (value, sunaudiosink->device);
+ GST_OBJECT_UNLOCK (sunaudiosink);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GstCaps *
+gst_sunaudiosink_getcaps (GstBaseSink * bsink)
+{
+ GstPadTemplate *pad_template;
+ GstCaps *caps = NULL;
+ GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (bsink);
+
+ GST_DEBUG_OBJECT (sunaudiosink, "getcaps called");
+
+ pad_template = gst_static_pad_template_get (&gst_sunaudiosink_factory);
+ caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
+
+ gst_object_unref (pad_template);
+
+ return caps;
+}
+
+static gboolean
+gst_sunaudiosink_open (GstAudioSink * asink)
+{
+ GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
+ int fd, ret;
+
+ /* First try to open non-blocking */
+ GST_OBJECT_LOCK (sunaudiosink);
+ fd = open (sunaudiosink->device, O_WRONLY | O_NONBLOCK);
+
+ if (fd >= 0) {
+ close (fd);
+ fd = open (sunaudiosink->device, O_WRONLY);
+ }
+
+ if (fd == -1) {
+ GST_OBJECT_UNLOCK (sunaudiosink);
+ goto open_failed;
+ }
+
+ sunaudiosink->fd = fd;
+ GST_OBJECT_UNLOCK (sunaudiosink);
+
+ ret = ioctl (fd, AUDIO_GETDEV, &sunaudiosink->dev);
+ if (ret == -1)
+ goto ioctl_error;
+
+ GST_DEBUG_OBJECT (sunaudiosink, "name %s", sunaudiosink->dev.name);
+ GST_DEBUG_OBJECT (sunaudiosink, "version %s", sunaudiosink->dev.version);
+ GST_DEBUG_OBJECT (sunaudiosink, "config %s", sunaudiosink->dev.config);
+
+ ret = ioctl (fd, AUDIO_GETINFO, &sunaudiosink->info);
+ if (ret == -1)
+ goto ioctl_error;
+
+ GST_DEBUG_OBJECT (sunaudiosink, "monitor_gain %d",
+ sunaudiosink->info.monitor_gain);
+ GST_DEBUG_OBJECT (sunaudiosink, "output_muted %d",
+ sunaudiosink->info.output_muted);
+ GST_DEBUG_OBJECT (sunaudiosink, "hw_features %08x",
+ sunaudiosink->info.hw_features);
+ GST_DEBUG_OBJECT (sunaudiosink, "sw_features %08x",
+ sunaudiosink->info.sw_features);
+ GST_DEBUG_OBJECT (sunaudiosink, "sw_features_enabled %08x",
+ sunaudiosink->info.sw_features_enabled);
+
+ return TRUE;
+
+open_failed:
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, OPEN_WRITE, (NULL),
+ ("can't open connection to Sun Audio device %s", sunaudiosink->device));
+ return FALSE;
+ioctl_error:
+ close (sunaudiosink->fd);
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+}
+
+static gboolean
+gst_sunaudiosink_close (GstAudioSink * asink)
+{
+ GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
+
+ if (sunaudiosink->fd != -1) {
+ close (sunaudiosink->fd);
+ sunaudiosink->fd = -1;
+ }
+ return TRUE;
+}
+
+static gboolean
+gst_sunaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
+{
+ GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
+ audio_info_t ainfo;
+ int ret;
+ int ports;
+
+ ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+
+ if (spec->width != 16)
+ return FALSE;
+
+ ports = ainfo.play.port;
+
+ AUDIO_INITINFO (&ainfo);
+
+ ainfo.play.sample_rate = spec->rate;
+ ainfo.play.channels = spec->channels;
+ ainfo.play.precision = spec->width;
+ ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
+ ainfo.play.port = ports;
+
+ /* buffer_time for playback is not implemented in Solaris at the moment,
+ but at some point in the future, it might be */
+ ainfo.play.buffer_size =
+ gst_util_uint64_scale (spec->rate * spec->bytes_per_sample,
+ spec->buffer_time, GST_SECOND / GST_USECOND);
+
+ spec->silence_sample[0] = 0;
+ spec->silence_sample[1] = 0;
+ spec->silence_sample[2] = 0;
+ spec->silence_sample[3] = 0;
+
+ ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+
+ /* Now read back the info to find out the actual buffer size and set
+ segtotal */
+ AUDIO_INITINFO (&ainfo);
+
+ ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+#if 0
+ /* We don't actually use the buffer_size from the sound device, because
+ * it seems it's just bogus sometimes */
+ sunaudiosink->segtotal = spec->segtotal =
+ ainfo.play.buffer_size / spec->segsize;
+#else
+ sunaudiosink->segtotal = spec->segtotal;
+#endif
+ sunaudiosink->segtotal_samples =
+ spec->segtotal * spec->segsize / spec->bytes_per_sample;
+
+ sunaudiosink->segs_written = (gint) ainfo.play.eof;
+ sunaudiosink->samples_written = ainfo.play.samples;
+ sunaudiosink->bytes_per_sample = spec->bytes_per_sample;
+
+ GST_DEBUG_OBJECT (sunaudiosink, "Got device buffer_size of %u",
+ ainfo.play.buffer_size);
+
+ return TRUE;
+}
+
+static gboolean
+gst_sunaudiosink_unprepare (GstAudioSink * asink)
+{
+ return TRUE;
+}
+
+#define LOOP_WHILE_EINTR(v,func) do { (v) = (func); } \
+ while ((v) == -1 && errno == EINTR);
+
+/* Called with the write_mutex held */
+static void
+gst_sunaudio_sink_do_delay (GstSunAudioSink * sink)
+{
+ GstBaseAudioSink *ba_sink = GST_BASE_AUDIO_SINK (sink);
+ GstClockTime total_sleep;
+ GstClockTime max_sleep;
+ gint sleep_usecs;
+ GTimeVal sleep_end;
+ gint err;
+ audio_info_t ainfo;
+ guint diff;
+
+ /* This code below ensures that we don't race any further than buffer_time
+ * ahead of the audio output, by sleeping if the next write call would cause
+ * us to advance too far in the ring-buffer */
+ LOOP_WHILE_EINTR (err, ioctl (sink->fd, AUDIO_GETINFO, &ainfo));
+ if (err < 0)
+ goto write_error;
+
+ /* Compute our offset from the output (copes with overflow) */
+ diff = (guint) (sink->segs_written) - ainfo.play.eof;
+ if (diff > sink->segtotal) {
+ /* This implies that reset did a flush just as the sound device aquired
+ * some buffers internally, and it causes us to be out of sync with the
+ * eof measure. This corrects it */
+ sink->segs_written = ainfo.play.eof;
+ diff = 0;
+ }
+
+ if (diff + 1 < sink->segtotal)
+ return; /* no need to sleep at all */
+
+ /* Never sleep longer than the initial number of undrained segments in the
+ device plus one */
+ total_sleep = 0;
+ max_sleep = (diff + 1) * (ba_sink->latency_time * GST_USECOND);
+ /* sleep for a segment period between .eof polls */
+ sleep_usecs = ba_sink->latency_time;
+
+ /* Current time is our reference point */
+ g_get_current_time (&sleep_end);
+
+ /* If the next segment would take us too far along the ring buffer,
+ * sleep for a bit to free up a slot. If there were a way to find out
+ * when the eof field actually increments, we could use, but the only
+ * notification mechanism seems to be SIGPOLL, which we can't use from
+ * a support library */
+ while (diff + 1 >= sink->segtotal && total_sleep < max_sleep) {
+ GST_LOG_OBJECT (sink, "need to block to drain segment(s). "
+ "Sleeping for %d us", sleep_usecs);
+
+ g_time_val_add (&sleep_end, sleep_usecs);
+
+ if (g_cond_timed_wait (sink->sleep_cond, sink->write_mutex, &sleep_end)) {
+ GST_LOG_OBJECT (sink, "Waking up early due to reset");
+ return; /* Got told to wake up */
+ }
+ total_sleep += (sleep_usecs * GST_USECOND);
+
+ LOOP_WHILE_EINTR (err, ioctl (sink->fd, AUDIO_GETINFO, &ainfo));
+ if (err < 0)
+ goto write_error;
+
+ /* Compute our (new) offset from the output (copes with overflow) */
+ diff = (guint) g_atomic_int_get (&sink->segs_written) - ainfo.play.eof;
+ }
+
+ return;
+
+write_error:
+ GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
+ ("Playback error on device '%s': %s", sink->device, strerror (errno)));
+ return;
+}
+
+static guint
+gst_sunaudiosink_write (GstAudioSink * asink, gpointer data, guint length)
+{
+ GstSunAudioSink *sink = GST_SUNAUDIO_SINK (asink);
+
+ gint bytes_written, err;
+
+ g_mutex_lock (sink->write_mutex);
+ if (sink->flushing) {
+ /* Exit immediately if reset tells us to */
+ g_mutex_unlock (sink->write_mutex);
+ return length;
+ }
+
+ LOOP_WHILE_EINTR (bytes_written, write (sink->fd, data, length));
+ if (bytes_written < 0) {
+ err = bytes_written;
+ goto write_error;
+ }
+
+ /* Increment our sample counter, for delay calcs */
+ g_atomic_int_add (&sink->samples_written, length / sink->bytes_per_sample);
+
+ /* Don't consider the segment written if we didn't output the whole lot yet */
+ if (bytes_written < length) {
+ g_mutex_unlock (sink->write_mutex);
+ return (guint) bytes_written;
+ }
+
+ /* Write a zero length output to trigger increment of the eof field */
+ LOOP_WHILE_EINTR (err, write (sink->fd, NULL, 0));
+ if (err < 0)
+ goto write_error;
+
+ /* Count this extra segment we've written */
+ sink->segs_written += 1;
+
+ /* Now delay so we don't overrun the ring buffer */
+ gst_sunaudio_sink_do_delay (sink);
+
+ g_mutex_unlock (sink->write_mutex);
+ return length;
+
+write_error:
+ g_mutex_unlock (sink->write_mutex);
+
+ GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
+ ("Playback error on device '%s': %s", sink->device, strerror (errno)));
+ return length; /* Say we wrote the segment to let the ringbuffer exit */
+}
+
+/*
+ * Provide the current number of unplayed samples that have been written
+ * to the device */
+static guint
+gst_sunaudiosink_delay (GstAudioSink * asink)
+{
+ GstSunAudioSink *sink = GST_SUNAUDIO_SINK (asink);
+ audio_info_t ainfo;
+ gint ret;
+ guint offset;
+
+ ret = ioctl (sink->fd, AUDIO_GETINFO, &ainfo);
+ if (G_UNLIKELY (ret == -1))
+ return 0;
+
+ offset = (g_atomic_int_get (&sink->samples_written) - ainfo.play.samples);
+
+ /* If the offset is larger than the total ringbuffer size, then we asked
+ between the write call and when samples_written is updated */
+ if (G_UNLIKELY (offset > sink->segtotal_samples))
+ return 0;
+
+ return offset;
+}
+
+static void
+gst_sunaudiosink_reset (GstAudioSink * asink)
+{
+ /* Get current values */
+ GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
+ audio_info_t ainfo;
+ int ret;
+
+ ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
+ if (ret == -1) {
+ /*
+ * Should never happen, but if we couldn't getinfo, then no point
+ * trying to setinfo
+ */
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return;
+ }
+
+ /*
+ * Pause the audio - so audio stops playing immediately rather than
+ * waiting for the ringbuffer to empty.
+ */
+ ainfo.play.pause = !NULL;
+ ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+
+ /* Flush the audio */
+ ret = ioctl (sunaudiosink->fd, I_FLUSH, FLUSHW);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+
+ /* Now, we take the write_mutex and signal to ensure the write thread
+ * is not busy, and we signal the condition to wake up any sleeper,
+ * then we flush again in case the write wrote something after we flushed,
+ * and finally release the lock and unpause */
+ g_mutex_lock (sunaudiosink->write_mutex);
+ sunaudiosink->flushing = TRUE;
+
+ g_cond_signal (sunaudiosink->sleep_cond);
+
+ ret = ioctl (sunaudiosink->fd, I_FLUSH, FLUSHW);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+
+ /* unpause the audio */
+ ainfo.play.pause = NULL;
+ ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+
+ /* After flushing the audio device, we need to remeasure the sample count
+ * and segments written count so we're in sync with the device */
+
+ sunaudiosink->segs_written = ainfo.play.eof;
+ g_atomic_int_set (&sunaudiosink->samples_written, ainfo.play.samples);
+
+ sunaudiosink->flushing = FALSE;
+ g_mutex_unlock (sunaudiosink->write_mutex);
+}
diff --git a/sys/sunaudio/gstsunaudiosink.h b/sys/sunaudio/gstsunaudiosink.h
new file mode 100644
index 0000000..fb30e6a
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiosink.h
@@ -0,0 +1,78 @@
+/*
+ * GStreamer - SunAudio sink
+ * Copyright (C) 2004 David A. Schleef <ds@schleef.org>
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ * Copyright (C) 2006 Jan Schmidt <thaytan@mad.scientist.com>
+ *
+ * gstsunaudiosink.h:
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_SUNAUDIO_SINK_H__
+#define __GST_SUNAUDIO_SINK_H__
+
+#include <sys/audioio.h>
+#include <gst/gst.h>
+#include <gst/audio/gstaudiosink.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_SUNAUDIO_SINK (gst_sunaudiosink_get_type())
+#define GST_SUNAUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_SINK,GstSunAudioSink))
+#define GST_SUNAUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_SINK,GstSunAudioSinkClass))
+#define GST_IS_SUNAUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_SINK))
+#define GST_IS_SUNAUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_SINK))
+
+typedef struct _GstSunAudioSink GstSunAudioSink;
+typedef struct _GstSunAudioSinkClass GstSunAudioSinkClass;
+
+struct _GstSunAudioSink {
+ GstAudioSink sink;
+
+ gchar *device;
+ gint fd;
+
+ audio_device_t dev;
+ audio_info_t info;
+
+ /* Number of segments the ringbuffer is configured for */
+ guint segtotal;
+ guint segtotal_samples;
+
+ /* Number of segments written to the device */
+ gint segs_written;
+ /* Number of samples written to the device */
+ gint samples_written;
+ guint bytes_per_sample;
+
+ /* mutex and gcond used to control the write method */
+ GMutex *write_mutex;
+ GCond *sleep_cond;
+ gboolean flushing;
+};
+
+struct _GstSunAudioSinkClass {
+ GstAudioSinkClass parent_class;
+};
+
+GType gst_sunaudiosink_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_SUNAUDIO_SINK_H__ */
+
diff --git a/sys/sunaudio/gstsunaudiosrc.c b/sys/sunaudio/gstsunaudiosrc.c
new file mode 100644
index 0000000..ec1d7d7
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiosrc.c
@@ -0,0 +1,423 @@
+/*
+ * GStreamer - SunAudio source
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ *
+ * gstsunaudiosrc.c:
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:element-sunaudiosrc
+ *
+ * sunaudiosrc is an audio source designed to work with the Sun Audio
+ * interface available in Solaris.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch-1.0 sunaudiosrc ! wavenc ! filesink location=audio.wav
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/mixer.h>
+
+#include "gstsunaudiosrc.h"
+
+GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
+#define GST_CAT_DEFAULT sunaudio_debug
+
+static void gst_sunaudiosrc_base_init (gpointer g_class);
+static void gst_sunaudiosrc_class_init (GstSunAudioSrcClass * klass);
+static void gst_sunaudiosrc_init (GstSunAudioSrc * sunaudiosrc,
+ GstSunAudioSrcClass * g_class);
+static void gst_sunaudiosrc_dispose (GObject * object);
+
+static void gst_sunaudiosrc_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_sunaudiosrc_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_sunaudiosrc_getcaps (GstBaseSrc * bsrc);
+
+static gboolean gst_sunaudiosrc_open (GstAudioSrc * asrc);
+static gboolean gst_sunaudiosrc_close (GstAudioSrc * asrc);
+static gboolean gst_sunaudiosrc_prepare (GstAudioSrc * asrc,
+ GstRingBufferSpec * spec);
+static gboolean gst_sunaudiosrc_unprepare (GstAudioSrc * asrc);
+static guint gst_sunaudiosrc_read (GstAudioSrc * asrc, gpointer data,
+ guint length);
+static guint gst_sunaudiosrc_delay (GstAudioSrc * asrc);
+static void gst_sunaudiosrc_reset (GstAudioSrc * asrc);
+
+#define DEFAULT_DEVICE "/dev/audio"
+
+enum
+{
+ PROP_0,
+ PROP_DEVICE
+};
+
+GST_BOILERPLATE_WITH_INTERFACE (GstSunAudioSrc, gst_sunaudiosrc,
+ GstAudioSrc, GST_TYPE_AUDIO_SRC, GstMixer, GST_TYPE_MIXER, gst_sunaudiosrc);
+
+GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS (GstSunAudioSrc, gst_sunaudiosrc);
+
+static GstStaticPadTemplate gst_sunaudiosrc_factory =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-raw-int, "
+ "endianness = (int) BYTE_ORDER, "
+ "signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16, "
+ /* [5510,48000] seems to be a Solaris limit */
+ "rate = (int) [ 5510, 48000 ], " "channels = (int) [ 1, 2 ]")
+ );
+
+static void
+gst_sunaudiosrc_dispose (GObject * object)
+{
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_sunaudiosrc_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_sunaudiosrc_factory));
+ gst_element_class_set_static_metadata (element_class, "Sun Audio Source",
+ "Source/Audio",
+ "Audio source for Sun Audio devices",
+ "Brian Cameron <brian.cameron@sun.com>");
+}
+
+static void
+gst_sunaudiosrc_class_init (GstSunAudioSrcClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseSrcClass *gstbasesrc_class;
+ GstBaseAudioSrcClass *gstbaseaudiosrc_class;
+ GstAudioSrcClass *gstaudiosrc_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasesrc_class = (GstBaseSrcClass *) klass;
+ gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
+ gstaudiosrc_class = (GstAudioSrcClass *) klass;
+
+ gobject_class->dispose = gst_sunaudiosrc_dispose;
+ gobject_class->get_property = gst_sunaudiosrc_get_property;
+ gobject_class->set_property = gst_sunaudiosrc_set_property;
+
+ gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_getcaps);
+
+ gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_open);
+ gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_prepare);
+ gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_unprepare);
+ gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_close);
+ gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_read);
+ gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_delay);
+ gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_reset);
+
+ g_object_class_install_property (gobject_class, PROP_DEVICE,
+ g_param_spec_string ("device", "Device",
+ "SunAudio device (usually /dev/audio)", DEFAULT_DEVICE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gst_sunaudiosrc_init (GstSunAudioSrc * sunaudiosrc,
+ GstSunAudioSrcClass * g_class)
+{
+ const char *audiodev;
+
+ GST_DEBUG_OBJECT (sunaudiosrc, "initializing sunaudiosrc");
+
+ sunaudiosrc->fd = -1;
+
+ audiodev = g_getenv ("AUDIODEV");
+ if (audiodev == NULL)
+ audiodev = DEFAULT_DEVICE;
+ sunaudiosrc->device = g_strdup (audiodev);
+}
+
+static void
+gst_sunaudiosrc_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstSunAudioSrc *sunaudiosrc;
+
+ sunaudiosrc = GST_SUNAUDIO_SRC (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ if (sunaudiosrc->device)
+ g_free (sunaudiosrc->device);
+ sunaudiosrc->device = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_sunaudiosrc_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstSunAudioSrc *sunaudiosrc;
+
+ sunaudiosrc = GST_SUNAUDIO_SRC (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ g_value_set_string (value, sunaudiosrc->device);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GstCaps *
+gst_sunaudiosrc_getcaps (GstBaseSrc * bsrc)
+{
+ GstPadTemplate *pad_template;
+ GstCaps *caps = NULL;
+ GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (bsrc);
+
+ GST_DEBUG_OBJECT (sunaudiosrc, "getcaps called");
+
+ pad_template = gst_static_pad_template_get (&gst_sunaudiosrc_factory);
+ caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
+
+ gst_object_unref (pad_template);
+
+ return caps;
+}
+
+static gboolean
+gst_sunaudiosrc_open (GstAudioSrc * asrc)
+{
+ GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
+ int fd, ret;
+
+ fd = open (sunaudiosrc->device, O_RDONLY);
+
+ if (fd == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, OPEN_READ, (NULL),
+ ("can't open connection to Sun Audio device %s", sunaudiosrc->device));
+
+ return FALSE;
+ }
+
+ sunaudiosrc->fd = fd;
+
+ ret = ioctl (fd, AUDIO_GETDEV, &sunaudiosrc->dev);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+
+ GST_DEBUG_OBJECT (sunaudiosrc, "name %s", sunaudiosrc->dev.name);
+ GST_DEBUG_OBJECT (sunaudiosrc, "version %s", sunaudiosrc->dev.version);
+ GST_DEBUG_OBJECT (sunaudiosrc, "config %s", sunaudiosrc->dev.config);
+
+ ret = ioctl (fd, AUDIO_GETINFO, &sunaudiosrc->info);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+
+ GST_DEBUG_OBJECT (sunaudiosrc, "monitor_gain %d",
+ sunaudiosrc->info.monitor_gain);
+ GST_DEBUG_OBJECT (sunaudiosrc, "output_muted %d",
+ sunaudiosrc->info.output_muted);
+ GST_DEBUG_OBJECT (sunaudiosrc, "hw_features %08x",
+ sunaudiosrc->info.hw_features);
+ GST_DEBUG_OBJECT (sunaudiosrc, "sw_features %08x",
+ sunaudiosrc->info.sw_features);
+ GST_DEBUG_OBJECT (sunaudiosrc, "sw_features_enabled %08x",
+ sunaudiosrc->info.sw_features_enabled);
+
+ if (!sunaudiosrc->mixer) {
+ const char *audiodev;
+
+ audiodev = g_getenv ("AUDIODEV");
+ if (audiodev == NULL) {
+ sunaudiosrc->mixer = gst_sunaudiomixer_ctrl_new ("/dev/audioctl");
+ } else {
+ gchar *device = g_strdup_printf ("%sctl", audiodev);
+
+ sunaudiosrc->mixer = gst_sunaudiomixer_ctrl_new (device);
+ g_free (device);
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gst_sunaudiosrc_close (GstAudioSrc * asrc)
+{
+ GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
+
+ close (sunaudiosrc->fd);
+ sunaudiosrc->fd = -1;
+
+ if (sunaudiosrc->mixer) {
+ gst_sunaudiomixer_ctrl_free (sunaudiosrc->mixer);
+ sunaudiosrc->mixer = NULL;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gst_sunaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
+{
+ GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
+ audio_info_t ainfo;
+ int ret;
+ GstSunAudioMixerCtrl *mixer;
+ struct audio_info audioinfo;
+
+ ret = ioctl (sunaudiosrc->fd, AUDIO_GETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+
+ if (spec->width != 16)
+ return FALSE;
+
+ AUDIO_INITINFO (&ainfo);
+
+ ainfo.record.sample_rate = spec->rate;
+ ainfo.record.precision = spec->width;
+ ainfo.record.channels = spec->channels;
+ ainfo.record.encoding = AUDIO_ENCODING_LINEAR;
+ ainfo.record.buffer_size = spec->buffer_time;
+
+ mixer = sunaudiosrc->mixer;
+
+ if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
+ g_warning ("Error getting audio device volume");
+ }
+ ainfo.record.port = audioinfo.record.port;
+ ainfo.record.gain = audioinfo.record.gain;
+ ainfo.record.balance = audioinfo.record.balance;
+
+ spec->segsize = 128;
+ spec->segtotal = spec->buffer_time / 128;
+
+ spec->silence_sample[0] = 0;
+ spec->silence_sample[1] = 0;
+ spec->silence_sample[2] = 0;
+ spec->silence_sample[3] = 0;
+
+ ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return FALSE;
+ }
+
+
+ ioctl (sunaudiosrc->fd, I_FLUSH, FLUSHR);
+
+ return TRUE;
+}
+
+static gboolean
+gst_sunaudiosrc_unprepare (GstAudioSrc * asrc)
+{
+ return TRUE;
+}
+
+static guint
+gst_sunaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
+{
+ return read (GST_SUNAUDIO_SRC (asrc)->fd, data, length);
+}
+
+static guint
+gst_sunaudiosrc_delay (GstAudioSrc * asrc)
+{
+ return 0;
+}
+
+static void
+gst_sunaudiosrc_reset (GstAudioSrc * asrc)
+{
+ /* Get current values */
+ GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
+ audio_info_t ainfo;
+ int ret;
+
+ ret = ioctl (sunaudiosrc->fd, AUDIO_GETINFO, &ainfo);
+ if (ret == -1) {
+ /*
+ * Should never happen, but if we couldn't getinfo, then no point
+ * trying to setinfo
+ */
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ return;
+ }
+
+ /*
+ * Pause the audio - so audio stops playing immediately rather than
+ * waiting for the ringbuffer to empty.
+ */
+ ainfo.record.pause = !NULL;
+ ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+
+ /* Flush the audio */
+ ret = ioctl (sunaudiosrc->fd, I_FLUSH, FLUSHR);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+
+ /* unpause the audio */
+ ainfo.record.pause = NULL;
+ ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
+ if (ret == -1) {
+ GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
+ strerror (errno)));
+ }
+}
diff --git a/sys/sunaudio/gstsunaudiosrc.h b/sys/sunaudio/gstsunaudiosrc.h
new file mode 100644
index 0000000..e165f3b
--- /dev/null
+++ b/sys/sunaudio/gstsunaudiosrc.h
@@ -0,0 +1,67 @@
+/* GStreamer - SunAudio source
+ * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
+ * Brian Cameron <brian.cameron@sun.com>
+ *
+ * gstsunaudiosrc.h:
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_SUNAUDIO_SRC_H__
+#define __GST_SUNAUDIO_SRC_H__
+
+#include <sys/audioio.h>
+#include <gst/gst.h>
+#include <gst/audio/gstaudiosrc.h>
+
+#include "gstsunaudiomixerctrl.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_SUNAUDIO_SRC (gst_sunaudiosrc_get_type())
+#define GST_SUNAUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_SRC,GstSunAudioSrc))
+#define GST_SUNAUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_SRC,GstSunAudioSrcClass))
+#define GST_IS_SUNAUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_SRC))
+#define GST_IS_SUNAUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_SRC))
+
+typedef struct _GstSunAudioSrc GstSunAudioSrc;
+typedef struct _GstSunAudioSrcClass GstSunAudioSrcClass;
+
+struct _GstSunAudioSrc {
+ GstAudioSrc src;
+
+ gchar *device;
+ gint fd;
+ gint control_fd;
+
+ audio_device_t dev;
+ audio_info_t info;
+
+ gint bytes_per_sample;
+
+ GstSunAudioMixerCtrl *mixer;
+};
+
+struct _GstSunAudioSrcClass {
+ GstAudioSrcClass parent_class;
+};
+
+GType gst_sunaudiosrc_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_SUNAUDIO_SRC_H__ */
+