diff options
author | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:46:56 +0900 |
---|---|---|
committer | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:46:56 +0900 |
commit | 4fcf0a9192ac1dee34309a66be632530b66f6822 (patch) | |
tree | e09f9233b63b22f97084798dcf6ffd3c85cc3adb /sys/sunaudio | |
parent | dfa84b358c7cdf0535eba1fead62fc4122cc56e6 (diff) | |
download | gst-plugins-good0.10-4fcf0a9192ac1dee34309a66be632530b66f6822.tar.gz gst-plugins-good0.10-4fcf0a9192ac1dee34309a66be632530b66f6822.tar.bz2 gst-plugins-good0.10-4fcf0a9192ac1dee34309a66be632530b66f6822.zip |
Git init
Diffstat (limited to 'sys/sunaudio')
-rw-r--r-- | sys/sunaudio/Makefile.am | 26 | ||||
-rw-r--r-- | sys/sunaudio/Makefile.in | 882 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudio.c | 63 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixer.c | 104 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixer.h | 51 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixerctrl.c | 585 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixerctrl.h | 189 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixeroptions.c | 157 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixeroptions.h | 65 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixertrack.c | 158 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiomixertrack.h | 78 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiosink.c | 651 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiosink.h | 78 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiosrc.c | 423 | ||||
-rw-r--r-- | sys/sunaudio/gstsunaudiosrc.h | 67 |
15 files changed, 3577 insertions, 0 deletions
diff --git a/sys/sunaudio/Makefile.am b/sys/sunaudio/Makefile.am new file mode 100644 index 0000000..e106ce3 --- /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_MAJORMINOR@ \ + -lgstaudio-@GST_MAJORMINOR@ \ + $(GST_PLUGINS_BASE_LIBS) \ + $(GST_LIBS) +libgstsunaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstsunaudio_la_LIBTOOLFLAGS = --tag=disable-static + +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 100644 index 0000000..07e94c4 --- /dev/null +++ b/sys/sunaudio/Makefile.in @@ -0,0 +1,882 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ +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@ +subdir = sys/sunaudio +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +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-objc.m4 \ + $(top_srcdir)/common/m4/as-python.m4 \ + $(top_srcdir)/common/m4/as-scrub-include.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/esd.m4 \ + $(top_srcdir)/m4/gconf-2.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gst-fionread.m4 \ + $(top_srcdir)/m4/gst-shout2.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__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_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +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 $@ +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_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +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_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgstsunaudio_la_SOURCES) +DIST_SOURCES = $(libgstsunaudio_la_SOURCES) +HEADERS = $(noinst_HEADERS) +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@ +ANNODEX_CFLAGS = @ANNODEX_CFLAGS@ +ANNODEX_LIBS = @ANNODEX_LIBS@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZ2_LIBS = @BZ2_LIBS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_GOBJECT_CFLAGS = @CAIRO_GOBJECT_CFLAGS@ +CAIRO_GOBJECT_LIBS = @CAIRO_GOBJECT_LIBS@ +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@ +ESD_CFLAGS = @ESD_CFLAGS@ +ESD_CONFIG = @ESD_CONFIG@ +ESD_LIBS = @ESD_LIBS@ +EXEEXT = @EXEEXT@ +FFLAGS = @FFLAGS@ +FGREP = @FGREP@ +FLAC_CFLAGS = @FLAC_CFLAGS@ +FLAC_LIBS = @FLAC_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +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@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +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_ALL_LDFLAGS = @GST_ALL_LDFLAGS@ +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_CXXFLAGS = @GST_CXXFLAGS@ +GST_GDP_CFLAGS = @GST_GDP_CFLAGS@ +GST_GDP_LIBS = @GST_GDP_LIBS@ +GST_LEVEL_DEFAULT = @GST_LEVEL_DEFAULT@ +GST_LIBS = @GST_LIBS@ +GST_LICENSE = @GST_LICENSE@ +GST_LT_LDFLAGS = @GST_LT_LDFLAGS@ +GST_MAJORMINOR = @GST_MAJORMINOR@ +GST_OPTION_CFLAGS = @GST_OPTION_CFLAGS@ +GST_OPTION_CXXFLAGS = @GST_OPTION_CXXFLAGS@ +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_SELECTED = @GST_PLUGINS_SELECTED@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GST_PREFIX = @GST_PREFIX@ +GST_TOOLS_DIR = @GST_TOOLS_DIR@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +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@ +HAL_CFLAGS = @HAL_CFLAGS@ +HAL_LIBS = @HAL_LIBS@ +HAVE_AVC1394 = @HAVE_AVC1394@ +HAVE_BZ2 = @HAVE_BZ2@ +HAVE_CXX = @HAVE_CXX@ +HAVE_DIRECTSOUND = @HAVE_DIRECTSOUND@ +HAVE_GCONFTOOL = @HAVE_GCONFTOOL@ +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_CONFIG = @LIBCACA_CONFIG@ +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@ +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@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJC_LDFLAGS = @OBJC_LDFLAGS@ +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_0_9_11_CFLAGS = @PULSE_0_9_11_CFLAGS@ +PULSE_0_9_11_LIBS = @PULSE_0_9_11_LIBS@ +PULSE_0_9_12_CFLAGS = @PULSE_0_9_12_CFLAGS@ +PULSE_0_9_12_LIBS = @PULSE_0_9_12_LIBS@ +PULSE_0_9_13_CFLAGS = @PULSE_0_9_13_CFLAGS@ +PULSE_0_9_13_LIBS = @PULSE_0_9_13_LIBS@ +PULSE_0_9_15_CFLAGS = @PULSE_0_9_15_CFLAGS@ +PULSE_0_9_15_LIBS = @PULSE_0_9_15_LIBS@ +PULSE_0_9_16_CFLAGS = @PULSE_0_9_16_CFLAGS@ +PULSE_0_9_16_LIBS = @PULSE_0_9_16_LIBS@ +PULSE_0_9_20_CFLAGS = @PULSE_0_9_20_CFLAGS@ +PULSE_0_9_20_LIBS = @PULSE_0_9_20_LIBS@ +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@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +WARNING_CXXFLAGS = @WARNING_CXXFLAGS@ +WAVPACK_CFLAGS = @WAVPACK_CFLAGS@ +WAVPACK_LIBS = @WAVPACK_LIBS@ +WIN32_LIBS = @WIN32_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@ +XVIDEO_LIBS = @XVIDEO_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_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@ +lt_ECHO = @lt_ECHO@ +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_alias = @target_alias@ +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_MAJORMINOR@ \ + -lgstaudio-@GST_MAJORMINOR@ \ + $(GST_PLUGINS_BASE_LIBS) \ + $(GST_LIBS) + +libgstsunaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstsunaudio_la_LIBTOOLFLAGS = --tag=disable-static +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) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @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 " $(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)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgstsunaudio.la: $(libgstsunaudio_la_OBJECTS) $(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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudio.c' object='libgstsunaudio_la-gstsunaudio.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudiosink.c' object='libgstsunaudio_la-gstsunaudiosink.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudiomixerctrl.c' object='libgstsunaudio_la-gstsunaudiomixerctrl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudiomixer.c' object='libgstsunaudio_la-gstsunaudiomixer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudiomixertrack.c' object='libgstsunaudio_la-gstsunaudiomixertrack.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudiomixeroptions.c' object='libgstsunaudio_la-gstsunaudiomixeroptions.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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 +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstsunaudiosrc.c' object='libgstsunaudio_la-gstsunaudiosrc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +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 all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES ctags 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 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..07aa575 --- /dev/null +++ b/sys/sunaudio/gstsunaudio.c @@ -0,0 +1,63 @@ +/* + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 + setlocale (LC_ALL, ""); + 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..7688450 --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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_details_simple (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..7ab6e74 --- /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., 675 Mass Ave, Cambridge, MA 02139, 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..0723134 --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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..d38f02f --- /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., 675 Mass Ave, Cambridge, MA 02139, 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 (GstMixerClass * klass) \ +{ \ + GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE; \ + \ + /* set up the interface hooks */ \ + klass->list_tracks = interface_as_function ## _list_tracks; \ + klass->set_volume = interface_as_function ## _set_volume; \ + klass->get_volume = interface_as_function ## _get_volume; \ + klass->set_mute = interface_as_function ## _set_mute; \ + klass->set_record = interface_as_function ## _set_record; \ + klass->get_option = interface_as_function ## _get_option; \ + klass->set_option = interface_as_function ## _set_option; \ + klass->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..1fa025b --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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..fb02b46 --- /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., 59 Temple Place - Suite 330, + */ + +#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..786ef0d --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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..83be9fc --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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..c125dae --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 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_details_simple (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 gconf 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..cad4e88 --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 gconf 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..f0529be --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 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_details_simple (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..95d9613 --- /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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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__ */ + |