diff options
Diffstat (limited to 'sys/oss')
-rw-r--r-- | sys/oss/Makefile.am | 28 | ||||
-rw-r--r-- | sys/oss/Makefile.in | 884 | ||||
-rw-r--r-- | sys/oss/common.h | 43 | ||||
-rw-r--r-- | sys/oss/gstossaudio.c | 61 | ||||
-rw-r--r-- | sys/oss/gstossdmabuffer.h | 77 | ||||
-rw-r--r-- | sys/oss/gstosshelper.c | 407 | ||||
-rw-r--r-- | sys/oss/gstosshelper.h | 43 | ||||
-rw-r--r-- | sys/oss/gstossmixer.c | 378 | ||||
-rw-r--r-- | sys/oss/gstossmixer.h | 171 | ||||
-rw-r--r-- | sys/oss/gstossmixerelement.c | 218 | ||||
-rw-r--r-- | sys/oss/gstossmixerelement.h | 59 | ||||
-rw-r--r-- | sys/oss/gstossmixertrack.c | 172 | ||||
-rw-r--r-- | sys/oss/gstossmixertrack.h | 62 | ||||
-rw-r--r-- | sys/oss/gstosssink.c | 565 | ||||
-rw-r--r-- | sys/oss/gstosssink.h | 62 | ||||
-rw-r--r-- | sys/oss/gstosssrc.c | 537 | ||||
-rw-r--r-- | sys/oss/gstosssrc.h | 67 |
17 files changed, 3834 insertions, 0 deletions
diff --git a/sys/oss/Makefile.am b/sys/oss/Makefile.am new file mode 100644 index 0000000..c42dfea --- /dev/null +++ b/sys/oss/Makefile.am @@ -0,0 +1,28 @@ +plugin_LTLIBRARIES = libgstossaudio.la + +libgstossaudio_la_SOURCES = gstossaudio.c \ + gstosshelper.c \ + gstossmixer.c \ + gstossmixerelement.c \ + gstossmixertrack.c \ + gstosssink.c \ + gstosssrc.c + +libgstossaudio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) +libgstossaudio_la_LIBADD = \ + $(GST_PLUGINS_BASE_LIBS) \ + -lgstinterfaces-$(GST_MAJORMINOR) \ + -lgstaudio-$(GST_MAJORMINOR) \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) +libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstossaudio_la_LIBTOOLFLAGS = --tag=disable-static + +noinst_HEADERS = common.h \ + gstosssink.h \ + gstosssrc.h \ + gstosshelper.h \ + gstossdmabuffer.h \ + gstossmixer.h \ + gstossmixerelement.h \ + gstossmixertrack.h diff --git a/sys/oss/Makefile.in b/sys/oss/Makefile.in new file mode 100644 index 0000000..1b1a00e --- /dev/null +++ b/sys/oss/Makefile.in @@ -0,0 +1,884 @@ +# 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/oss +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 = +libgstossaudio_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libgstossaudio_la_OBJECTS = libgstossaudio_la-gstossaudio.lo \ + libgstossaudio_la-gstosshelper.lo \ + libgstossaudio_la-gstossmixer.lo \ + libgstossaudio_la-gstossmixerelement.lo \ + libgstossaudio_la-gstossmixertrack.lo \ + libgstossaudio_la-gstosssink.lo libgstossaudio_la-gstosssrc.lo +libgstossaudio_la_OBJECTS = $(am_libgstossaudio_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libgstossaudio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(libgstossaudio_la_CFLAGS) $(CFLAGS) \ + $(libgstossaudio_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 = $(libgstossaudio_la_SOURCES) +DIST_SOURCES = $(libgstossaudio_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 = libgstossaudio.la +libgstossaudio_la_SOURCES = gstossaudio.c \ + gstosshelper.c \ + gstossmixer.c \ + gstossmixerelement.c \ + gstossmixertrack.c \ + gstosssink.c \ + gstosssrc.c + +libgstossaudio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) +libgstossaudio_la_LIBADD = \ + $(GST_PLUGINS_BASE_LIBS) \ + -lgstinterfaces-$(GST_MAJORMINOR) \ + -lgstaudio-$(GST_MAJORMINOR) \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) + +libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstossaudio_la_LIBTOOLFLAGS = --tag=disable-static +noinst_HEADERS = common.h \ + gstosssink.h \ + gstosssrc.h \ + gstosshelper.h \ + gstossdmabuffer.h \ + gstossmixer.h \ + gstossmixerelement.h \ + gstossmixertrack.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/oss/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu sys/oss/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 +libgstossaudio.la: $(libgstossaudio_la_OBJECTS) $(libgstossaudio_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgstossaudio_la_LINK) -rpath $(plugindir) $(libgstossaudio_la_OBJECTS) $(libgstossaudio_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstossaudio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstosshelper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstossmixer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstossmixerelement.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstossmixertrack.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstosssink.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstossaudio_la-gstosssrc.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 $@ $< + +libgstossaudio_la-gstossaudio.lo: gstossaudio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstossaudio.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstossaudio.Tpo -c -o libgstossaudio_la-gstossaudio.lo `test -f 'gstossaudio.c' || echo '$(srcdir)/'`gstossaudio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstossaudio.Tpo $(DEPDIR)/libgstossaudio_la-gstossaudio.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstossaudio.c' object='libgstossaudio_la-gstossaudio.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstossaudio.lo `test -f 'gstossaudio.c' || echo '$(srcdir)/'`gstossaudio.c + +libgstossaudio_la-gstosshelper.lo: gstosshelper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstosshelper.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstosshelper.Tpo -c -o libgstossaudio_la-gstosshelper.lo `test -f 'gstosshelper.c' || echo '$(srcdir)/'`gstosshelper.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstosshelper.Tpo $(DEPDIR)/libgstossaudio_la-gstosshelper.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstosshelper.c' object='libgstossaudio_la-gstosshelper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstosshelper.lo `test -f 'gstosshelper.c' || echo '$(srcdir)/'`gstosshelper.c + +libgstossaudio_la-gstossmixer.lo: gstossmixer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstossmixer.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstossmixer.Tpo -c -o libgstossaudio_la-gstossmixer.lo `test -f 'gstossmixer.c' || echo '$(srcdir)/'`gstossmixer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstossmixer.Tpo $(DEPDIR)/libgstossaudio_la-gstossmixer.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstossmixer.c' object='libgstossaudio_la-gstossmixer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstossmixer.lo `test -f 'gstossmixer.c' || echo '$(srcdir)/'`gstossmixer.c + +libgstossaudio_la-gstossmixerelement.lo: gstossmixerelement.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstossmixerelement.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstossmixerelement.Tpo -c -o libgstossaudio_la-gstossmixerelement.lo `test -f 'gstossmixerelement.c' || echo '$(srcdir)/'`gstossmixerelement.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstossmixerelement.Tpo $(DEPDIR)/libgstossaudio_la-gstossmixerelement.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstossmixerelement.c' object='libgstossaudio_la-gstossmixerelement.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstossmixerelement.lo `test -f 'gstossmixerelement.c' || echo '$(srcdir)/'`gstossmixerelement.c + +libgstossaudio_la-gstossmixertrack.lo: gstossmixertrack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstossmixertrack.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstossmixertrack.Tpo -c -o libgstossaudio_la-gstossmixertrack.lo `test -f 'gstossmixertrack.c' || echo '$(srcdir)/'`gstossmixertrack.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstossmixertrack.Tpo $(DEPDIR)/libgstossaudio_la-gstossmixertrack.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstossmixertrack.c' object='libgstossaudio_la-gstossmixertrack.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstossmixertrack.lo `test -f 'gstossmixertrack.c' || echo '$(srcdir)/'`gstossmixertrack.c + +libgstossaudio_la-gstosssink.lo: gstosssink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstosssink.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstosssink.Tpo -c -o libgstossaudio_la-gstosssink.lo `test -f 'gstosssink.c' || echo '$(srcdir)/'`gstosssink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstosssink.Tpo $(DEPDIR)/libgstossaudio_la-gstosssink.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstosssink.c' object='libgstossaudio_la-gstosssink.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstosssink.lo `test -f 'gstosssink.c' || echo '$(srcdir)/'`gstosssink.c + +libgstossaudio_la-gstosssrc.lo: gstosssrc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -MT libgstossaudio_la-gstosssrc.lo -MD -MP -MF $(DEPDIR)/libgstossaudio_la-gstosssrc.Tpo -c -o libgstossaudio_la-gstosssrc.lo `test -f 'gstosssrc.c' || echo '$(srcdir)/'`gstosssrc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstossaudio_la-gstosssrc.Tpo $(DEPDIR)/libgstossaudio_la-gstosssrc.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstosssrc.c' object='libgstossaudio_la-gstosssrc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstossaudio_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstossaudio_la_CFLAGS) $(CFLAGS) -c -o libgstossaudio_la-gstosssrc.lo `test -f 'gstosssrc.c' || echo '$(srcdir)/'`gstosssrc.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/oss/common.h b/sys/oss/common.h new file mode 100644 index 0000000..2445c3d --- /dev/null +++ b/sys/oss/common.h @@ -0,0 +1,43 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000,2005 Wim Taymans <wim@fluendo.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. + */ + +#define SET_PARAM(_oss, _name, _val, _detail) \ +G_STMT_START { \ + int _tmp = _val; \ + if (ioctl(_oss->fd, _name, &_tmp) == -1) { \ + GST_ELEMENT_ERROR (_oss, RESOURCE, SETTINGS,\ + (NULL), \ + ("Unable to set param " _detail ": %s", \ + g_strerror (errno))); \ + return FALSE; \ + } \ + GST_DEBUG_OBJECT(_oss, _detail " %d", _tmp); \ +} G_STMT_END + +#define GET_PARAM(_oss, _name, _val, _detail) \ +G_STMT_START { \ + if (ioctl(oss->fd, _name, _val) == -1) { \ + GST_ELEMENT_ERROR (oss, RESOURCE, SETTINGS, \ + (NULL), \ + ("Unable to get param " _detail ": %s", \ + g_strerror (errno))); \ + return FALSE; \ + } \ +} G_STMT_END diff --git a/sys/oss/gstossaudio.c b/sys/oss/gstossaudio.c new file mode 100644 index 0000000..2a181e8 --- /dev/null +++ b/sys/oss/gstossaudio.c @@ -0,0 +1,61 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * + * 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 "gstossmixerelement.h" +#include "gstosssink.h" +#include "gstosssrc.h" + +GST_DEBUG_CATEGORY (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +static gboolean +plugin_init (GstPlugin * plugin) +{ + if (!gst_element_register (plugin, "ossmixer", GST_RANK_NONE, + GST_TYPE_OSS_MIXER_ELEMENT) || + !gst_element_register (plugin, "osssrc", GST_RANK_SECONDARY, + GST_TYPE_OSS_SRC) || + !gst_element_register (plugin, "osssink", GST_RANK_SECONDARY, + GST_TYPE_OSSSINK)) { + return FALSE; + } + + GST_DEBUG_CATEGORY_INIT (oss_debug, "oss", 0, "OSS elements"); + +#ifdef ENABLE_NLS + GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE, + LOCALEDIR); + 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, + "ossaudio", + "OSS (Open Sound System) support for GStreamer", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/sys/oss/gstossdmabuffer.h b/sys/oss/gstossdmabuffer.h new file mode 100644 index 0000000..c38ef6f --- /dev/null +++ b/sys/oss/gstossdmabuffer.h @@ -0,0 +1,77 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2005 Wim Taymans <wim@fluendo.com> + * + * gstossdmabuffer.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_OSSDMABUFFER_H__ +#define __GST_OSSDMABUFFER_H__ + +#include <gst/gst.h> + +#include "gstosshelper.h" +#include <gst/audio/gstringbuffer.h> + +G_BEGIN_DECLS + +#define GST_TYPE_OSSDMABUFFER (gst_ossdmabuffer_get_type()) +#define GST_OSSDMABUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSSDMABUFFER,GstOssDMABuffer)) +#define GST_OSSDMABUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSSDMABUFFER,GstOssDMABufferClass)) +#define GST_IS_OSSDMABUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSSDMABUFFER)) +#define GST_IS_OSSDMABUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSSDMABUFFER)) + +#define GST_OSSELEMENT_GET(obj) GST_OSSELEMENT (obj->element) + +typedef enum { + GST_OSSDMABUFFER_OPEN = (1 << 0), +} GstOssDMABufferFlags; + +typedef struct _GstOssDMABuffer GstOssDMABuffer; +typedef struct _GstOssDMABufferClass GstOssDMABufferClass; + +#define GST_OSSDMABUFFER_THREAD(buf) (GST_OSSDMABUFFER(buf)->thread) +#define GST_OSSDMABUFFER_LOCK GST_OBJECT_LOCK +#define GST_OSSDMABUFFER_UNLOCK GST_OBJECT_UNLOCK +#define GST_OSSDMABUFFER_COND(buf) (GST_OSSDMABUFFER(buf)->cond) +#define GST_OSSDMABUFFER_SIGNAL(buf) (g_cond_signal (GST_OSSDMABUFFER_COND (buf))) +#define GST_OSSDMABUFFER_WAIT(buf) (g_cond_wait (GST_OSSDMABUFFER_COND (buf), GST_OBJECT_GET_LOCK (buf))) + +struct _GstOssDMABuffer { + GstRingBuffer buffer; + + GstOssElement *element; + + int fd; + int caps; + int frag; + + GThread *thread; + GCond *cond; + gboolean running; +}; + +struct _GstOssDMABufferClass { + GstRingBufferClass parent_class; +}; + +GType gst_ossdmabuffer_get_type(void); + +G_END_DECLS + +#endif /* __GST_OSSDMABUFFER_H__ */ diff --git a/sys/oss/gstosshelper.c b/sys/oss/gstosshelper.c new file mode 100644 index 0000000..6d7e6bd --- /dev/null +++ b/sys/oss/gstosshelper.c @@ -0,0 +1,407 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wim.taymans@chello.be> + * + * gstosshelper.c: OSS helper routines + * + * 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 <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#ifdef HAVE_OSS_INCLUDE_IN_SYS +# include <sys/soundcard.h> +#else +# ifdef HAVE_OSS_INCLUDE_IN_ROOT +# include <soundcard.h> +# else +# ifdef HAVE_OSS_INCLUDE_IN_MACHINE +# include <machine/soundcard.h> +# else +# error "What to include?" +# endif /* HAVE_OSS_INCLUDE_IN_MACHINE */ +# endif /* HAVE_OSS_INCLUDE_IN_ROOT */ +#endif /* HAVE_OSS_INCLUDE_IN_SYS */ + +#include <gst/interfaces/propertyprobe.h> + +#include "gstosshelper.h" +#include "gstossmixer.h" + +GST_DEBUG_CATEGORY_EXTERN (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +typedef struct _GstOssProbe GstOssProbe; +struct _GstOssProbe +{ + int fd; + int format; + int n_channels; + GArray *rates; + int min; + int max; +}; + +typedef struct _GstOssRange GstOssRange; +struct _GstOssRange +{ + int min; + int max; +}; + +static GstStructure *gst_oss_helper_get_format_structure (unsigned int + format_bit); +static gboolean gst_oss_helper_rate_probe_check (GstOssProbe * probe); +static int gst_oss_helper_rate_check_rate (GstOssProbe * probe, int irate); +static void gst_oss_helper_rate_add_range (GQueue * queue, int min, int max); +static void gst_oss_helper_rate_add_rate (GArray * array, int rate); +static int gst_oss_helper_rate_int_compare (gconstpointer a, gconstpointer b); + +GstCaps * +gst_oss_helper_probe_caps (gint fd) +{ + GstOssProbe *probe; + int i; + gboolean ret; + GstStructure *structure; + unsigned int format_bit; + unsigned int format_mask; + GstCaps *caps; + + /* FIXME test make sure we're not currently playing */ + /* FIXME test both mono and stereo */ + + format_mask = AFMT_U8 | AFMT_S8; + + if (G_BYTE_ORDER == G_LITTLE_ENDIAN) + format_mask |= AFMT_S16_LE | AFMT_U16_LE; + else + format_mask |= AFMT_S16_BE | AFMT_U16_BE; + + caps = gst_caps_new_empty (); + + /* assume that the most significant bit of format_mask is 0 */ + for (format_bit = 1 << 31; format_bit > 0; format_bit >>= 1) { + if (format_bit & format_mask) { + GValue rate_value = { 0 }; + + probe = g_new0 (GstOssProbe, 1); + probe->fd = fd; + probe->format = format_bit; + /* FIXME: this is not working for all cards, see bug #518474 */ + probe->n_channels = 2; + + ret = gst_oss_helper_rate_probe_check (probe); + if (probe->min == -1 || probe->max == -1) { + g_array_free (probe->rates, TRUE); + g_free (probe); + continue; + } + + if (ret) { + GValue value = { 0 }; + + g_array_sort (probe->rates, gst_oss_helper_rate_int_compare); + + g_value_init (&rate_value, GST_TYPE_LIST); + g_value_init (&value, G_TYPE_INT); + + for (i = 0; i < probe->rates->len; i++) { + g_value_set_int (&value, g_array_index (probe->rates, int, i)); + + gst_value_list_append_value (&rate_value, &value); + } + + g_value_unset (&value); + } else { + /* one big range */ + g_value_init (&rate_value, GST_TYPE_INT_RANGE); + gst_value_set_int_range (&rate_value, probe->min, probe->max); + } + + g_array_free (probe->rates, TRUE); + g_free (probe); + + structure = gst_oss_helper_get_format_structure (format_bit); + gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); + gst_structure_set_value (structure, "rate", &rate_value); + g_value_unset (&rate_value); + + gst_caps_append_structure (caps, structure); + } + } + + if (gst_caps_is_empty (caps)) { + /* fixme: make user-visible */ + GST_WARNING ("Your OSS device could not be probed correctly"); + } + + GST_DEBUG ("probed caps: %" GST_PTR_FORMAT, caps); + + return caps; +} + +static GstStructure * +gst_oss_helper_get_format_structure (unsigned int format_bit) +{ + GstStructure *structure; + int endianness; + gboolean sign; + int width; + + switch (format_bit) { + case AFMT_U8: + endianness = 0; + sign = FALSE; + width = 8; + break; + case AFMT_S16_LE: + endianness = G_LITTLE_ENDIAN; + sign = TRUE; + width = 16; + break; + case AFMT_S16_BE: + endianness = G_BIG_ENDIAN; + sign = TRUE; + width = 16; + break; + case AFMT_S8: + endianness = 0; + sign = TRUE; + width = 8; + break; + case AFMT_U16_LE: + endianness = G_LITTLE_ENDIAN; + sign = FALSE; + width = 16; + break; + case AFMT_U16_BE: + endianness = G_BIG_ENDIAN; + sign = FALSE; + width = 16; + break; + default: + g_assert_not_reached (); + return NULL; + } + + structure = gst_structure_new ("audio/x-raw-int", + "width", G_TYPE_INT, width, + "depth", G_TYPE_INT, width, "signed", G_TYPE_BOOLEAN, sign, NULL); + + if (endianness) { + gst_structure_set (structure, "endianness", G_TYPE_INT, endianness, NULL); + } + + return structure; +} + +static gboolean +gst_oss_helper_rate_probe_check (GstOssProbe * probe) +{ + GstOssRange *range; + GQueue *ranges; + int exact_rates = 0; + gboolean checking_exact_rates = TRUE; + int n_checks = 0; + gboolean result = TRUE; + + ranges = g_queue_new (); + + probe->rates = g_array_new (FALSE, FALSE, sizeof (int)); + + probe->min = gst_oss_helper_rate_check_rate (probe, 1000); + n_checks++; + probe->max = gst_oss_helper_rate_check_rate (probe, 100000); + /* a little bug workaround */ + { + int max; + + max = gst_oss_helper_rate_check_rate (probe, 48000); + if (max > probe->max) { + GST_ERROR + ("Driver bug recognized (driver does not round rates correctly). Please file a bug report."); + probe->max = max; + } + } + n_checks++; + if (probe->min == -1 || probe->max == -1) { + /* This is a workaround for drivers that return -EINVAL (or another + * error) for rates outside of [8000,48000]. If this fails, the + * driver is seriously buggy, and probably doesn't work with other + * media libraries/apps. */ + probe->min = gst_oss_helper_rate_check_rate (probe, 8000); + probe->max = gst_oss_helper_rate_check_rate (probe, 48000); + } + if (probe->min == -1 || probe->max == -1) { + GST_DEBUG ("unexpected check_rate error"); + return FALSE; + } + gst_oss_helper_rate_add_range (ranges, probe->min + 1, probe->max - 1); + + while ((range = g_queue_pop_head (ranges))) { + int min1; + int max1; + int mid; + int mid_ret; + + GST_DEBUG ("checking [%d,%d]", range->min, range->max); + + mid = (range->min + range->max) / 2; + mid_ret = gst_oss_helper_rate_check_rate (probe, mid); + if (mid_ret == -1) { + /* FIXME ioctl returned an error. do something */ + GST_DEBUG ("unexpected check_rate error"); + } + n_checks++; + + if (mid == mid_ret && checking_exact_rates) { + int max_exact_matches = 20; + + exact_rates++; + if (exact_rates > max_exact_matches) { + GST_DEBUG ("got %d exact rates, assuming all are exact", + max_exact_matches); + result = FALSE; + g_free (range); + break; + } + } else { + checking_exact_rates = FALSE; + } + + /* Assume that the rate is arithmetically rounded to the nearest + * supported rate. */ + if (mid == mid_ret) { + min1 = mid - 1; + max1 = mid + 1; + } else { + if (mid < mid_ret) { + min1 = mid - (mid_ret - mid); + max1 = mid_ret + 1; + } else { + min1 = mid_ret - 1; + max1 = mid + (mid - mid_ret); + } + } + + gst_oss_helper_rate_add_range (ranges, range->min, min1); + gst_oss_helper_rate_add_range (ranges, max1, range->max); + + g_free (range); + } + + while ((range = g_queue_pop_head (ranges))) { + g_free (range); + } + g_queue_free (ranges); + + return result; +} + +static void +gst_oss_helper_rate_add_range (GQueue * queue, int min, int max) +{ + if (min <= max) { + GstOssRange *range = g_new0 (GstOssRange, 1); + + range->min = min; + range->max = max; + + g_queue_push_tail (queue, range); + /* push_head also works, but has different probing behavior */ + /*g_queue_push_head (queue, range); */ + } +} + +static int +gst_oss_helper_rate_check_rate (GstOssProbe * probe, int irate) +{ + int rate; + int format; + int n_channels; + int ret; + + rate = irate; + format = probe->format; + n_channels = probe->n_channels; + + GST_LOG ("checking format %d, channels %d, rate %d", + format, n_channels, rate); + ret = ioctl (probe->fd, SNDCTL_DSP_SETFMT, &format); + if (ret < 0 || format != probe->format) { + GST_DEBUG ("unsupported format: %d (%d)", probe->format, format); + return -1; + } + ret = ioctl (probe->fd, SNDCTL_DSP_CHANNELS, &n_channels); + if (ret < 0 || n_channels != probe->n_channels) { + GST_DEBUG ("unsupported channels: %d (%d)", probe->n_channels, n_channels); + return -1; + } + ret = ioctl (probe->fd, SNDCTL_DSP_SPEED, &rate); + if (ret < 0) { + GST_DEBUG ("unsupported rate: %d (%d)", irate, rate); + return -1; + } + + GST_DEBUG ("rate %d -> %d", irate, rate); + + if (rate == irate - 1 || rate == irate + 1) { + rate = irate; + } + gst_oss_helper_rate_add_rate (probe->rates, rate); + return rate; +} + +static void +gst_oss_helper_rate_add_rate (GArray * array, int rate) +{ + int i; + int val; + + for (i = 0; i < array->len; i++) { + val = g_array_index (array, int, i); + + if (val == rate) + return; + } + GST_DEBUG ("supported rate: %d", rate); + g_array_append_val (array, rate); +} + +static int +gst_oss_helper_rate_int_compare (gconstpointer a, gconstpointer b) +{ + const int *va = (const int *) a; + const int *vb = (const int *) b; + + if (*va < *vb) + return -1; + if (*va > *vb) + return 1; + return 0; +} diff --git a/sys/oss/gstosshelper.h b/sys/oss/gstosshelper.h new file mode 100644 index 0000000..1593fe3 --- /dev/null +++ b/sys/oss/gstosshelper.h @@ -0,0 +1,43 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wim.taymans@chello.be> + * + * gstosshelper.h: OSS helper routines. + * + * 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_OSS_HELPER_H__ +#define __GST_OSS_HELPER_H__ + + +#include <gst/gst.h> +#include <sys/types.h> + +#include "gstosshelper.h" + + +G_BEGIN_DECLS + + +GstCaps* gst_oss_helper_probe_caps (gint fd); + + +G_END_DECLS + + +#endif /* __GST_OSS_HELPER_H__ */ diff --git a/sys/oss/gstossmixer.c b/sys/oss/gstossmixer.c new file mode 100644 index 0000000..e563031 --- /dev/null +++ b/sys/oss/gstossmixer.c @@ -0,0 +1,378 @@ +/* GStreamer OSS Mixer implementation + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstossmixer.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> + +#ifdef HAVE_OSS_INCLUDE_IN_SYS +# include <sys/soundcard.h> +#else +# ifdef HAVE_OSS_INCLUDE_IN_ROOT +# include <soundcard.h> +# else +# ifdef HAVE_OSS_INCLUDE_IN_MACHINE +# include <machine/soundcard.h> +# else +# error "What to include?" +# endif /* HAVE_OSS_INCLUDE_IN_MACHINE */ +# endif /* HAVE_OSS_INCLUDE_IN_ROOT */ +#endif /* HAVE_OSS_INCLUDE_IN_SYS */ + +#include <gst/gst-i18n-plugin.h> + +#include "gstossmixer.h" +#include "gstossmixertrack.h" + +GST_DEBUG_CATEGORY_EXTERN (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +#define MASK_BIT_IS_SET(mask, bit) \ + (mask & (1 << bit)) + +static gboolean +gst_ossmixer_open (GstOssMixer * mixer) +{ +#ifdef SOUND_MIXER_INFO + struct mixer_info minfo; +#endif + + g_return_val_if_fail (mixer->mixer_fd == -1, FALSE); + + mixer->mixer_fd = open (mixer->device, O_RDWR); + if (mixer->mixer_fd == -1) + goto open_failed; + + /* get masks */ + if (ioctl (mixer->mixer_fd, SOUND_MIXER_READ_RECMASK, &mixer->recmask) < 0 + || ioctl (mixer->mixer_fd, SOUND_MIXER_READ_RECSRC, &mixer->recdevs) < 0 + || ioctl (mixer->mixer_fd, SOUND_MIXER_READ_STEREODEVS, + &mixer->stereomask) < 0 + || ioctl (mixer->mixer_fd, SOUND_MIXER_READ_DEVMASK, &mixer->devmask) < 0 + || ioctl (mixer->mixer_fd, SOUND_MIXER_READ_CAPS, &mixer->mixcaps) < 0) + goto masks_failed; + + /* get name, not fatal */ + g_free (mixer->cardname); +#ifdef SOUND_MIXER_INFO + if (ioctl (mixer->mixer_fd, SOUND_MIXER_INFO, &minfo) == 0) { + mixer->cardname = g_strdup (minfo.name); + GST_INFO ("Card name = %s", GST_STR_NULL (mixer->cardname)); + } else +#endif + { + mixer->cardname = g_strdup ("Unknown"); + GST_INFO ("Unknown card name"); + } + GST_INFO ("Opened mixer for device %s", mixer->device); + + return TRUE; + + /* ERRORS */ +open_failed: + { + /* this is valid. OSS devices don't need to expose a mixer */ + GST_DEBUG ("Failed to open mixer device %s, mixing disabled: %s", + mixer->device, strerror (errno)); + return FALSE; + } +masks_failed: + { + GST_DEBUG ("Failed to get device masks"); + close (mixer->mixer_fd); + mixer->mixer_fd = -1; + return FALSE; + } +} + +static void +gst_ossmixer_ensure_track_list (GstOssMixer * mixer) +{ + gint i, master = -1; + + g_return_if_fail (mixer->mixer_fd != -1); + + if (mixer->tracklist) + return; + + /* find master volume */ + if (mixer->devmask & SOUND_MASK_VOLUME) + master = SOUND_MIXER_VOLUME; + else if (mixer->devmask & SOUND_MASK_PCM) + master = SOUND_MIXER_PCM; + else if (mixer->devmask & SOUND_MASK_SPEAKER) + master = SOUND_MIXER_SPEAKER; /* doubtful... */ + /* else: no master, so we won't set any */ + + /* build track list */ + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { + if (mixer->devmask & (1 << i)) { + GstMixerTrack *track; + gboolean input = FALSE, stereo = FALSE, record = FALSE; + + /* track exists, make up capabilities */ + if (MASK_BIT_IS_SET (mixer->stereomask, i)) + stereo = TRUE; + if (MASK_BIT_IS_SET (mixer->recmask, i)) + input = TRUE; + if (MASK_BIT_IS_SET (mixer->recdevs, i)) + record = TRUE; + + /* do we want this in our list? */ + if (!((mixer->dir & GST_OSS_MIXER_CAPTURE && input == TRUE) || + (mixer->dir & GST_OSS_MIXER_PLAYBACK && i != SOUND_MIXER_PCM))) + /* the PLAYBACK case seems hacky, but that's how 0.8 had it */ + continue; + + /* add track to list */ + track = gst_ossmixer_track_new (mixer->mixer_fd, i, stereo ? 2 : 1, + (record ? GST_MIXER_TRACK_RECORD : 0) | + (input ? GST_MIXER_TRACK_INPUT : + GST_MIXER_TRACK_OUTPUT) | + ((master != i) ? 0 : GST_MIXER_TRACK_MASTER)); + mixer->tracklist = g_list_append (mixer->tracklist, track); + } + } +} + +GstOssMixer * +gst_ossmixer_new (const char *device, GstOssMixerDirection dir) +{ + GstOssMixer *ret = NULL; + + g_return_val_if_fail (device != NULL, NULL); + + ret = g_new0 (GstOssMixer, 1); + + ret->device = g_strdup (device); + ret->dir = dir; + ret->mixer_fd = -1; + + if (!gst_ossmixer_open (ret)) + goto error; + + return ret; + + /* ERRORS */ +error: + { + gst_ossmixer_free (ret); + return NULL; + } +} + +void +gst_ossmixer_free (GstOssMixer * mixer) +{ + g_return_if_fail (mixer != NULL); + + if (mixer->device) { + g_free (mixer->device); + mixer->device = NULL; + } + + if (mixer->cardname) { + g_free (mixer->cardname); + mixer->cardname = 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); +} + +/* unused with G_DISABLE_* */ +static G_GNUC_UNUSED gboolean +gst_ossmixer_contains_track (GstOssMixer * mixer, GstOssMixerTrack * osstrack) +{ + const GList *item; + + for (item = mixer->tracklist; item != NULL; item = item->next) + if (item->data == osstrack) + return TRUE; + + return FALSE; +} + +const GList * +gst_ossmixer_list_tracks (GstOssMixer * mixer) +{ + gst_ossmixer_ensure_track_list (mixer); + + return (const GList *) mixer->tracklist; +} + +void +gst_ossmixer_get_volume (GstOssMixer * mixer, + GstMixerTrack * track, gint * volumes) +{ + gint volume; + GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track); + + g_return_if_fail (mixer->mixer_fd != -1); + g_return_if_fail (gst_ossmixer_contains_track (mixer, osstrack)); + + if (track->flags & GST_MIXER_TRACK_MUTE) { + volumes[0] = osstrack->lvol; + if (track->num_channels == 2) { + volumes[1] = osstrack->rvol; + } + } else { + /* get */ + if (ioctl (mixer->mixer_fd, MIXER_READ (osstrack->track_num), &volume) < 0) { + g_warning ("Error getting recording device (%d) volume: %s", + osstrack->track_num, strerror (errno)); + volume = 0; + } + + osstrack->lvol = volumes[0] = (volume & 0xff); + if (track->num_channels == 2) { + osstrack->rvol = volumes[1] = ((volume >> 8) & 0xff); + } + } +} + +void +gst_ossmixer_set_volume (GstOssMixer * mixer, + GstMixerTrack * track, gint * volumes) +{ + gint volume; + GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track); + + g_return_if_fail (mixer->mixer_fd != -1); + g_return_if_fail (gst_ossmixer_contains_track (mixer, osstrack)); + + /* prepare the value for ioctl() */ + if (!(track->flags & GST_MIXER_TRACK_MUTE)) { + volume = (volumes[0] & 0xff); + if (track->num_channels == 2) { + volume |= ((volumes[1] & 0xff) << 8); + } + + /* set */ + if (ioctl (mixer->mixer_fd, MIXER_WRITE (osstrack->track_num), &volume) < 0) { + g_warning ("Error setting recording device (%d) volume (0x%x): %s", + osstrack->track_num, volume, strerror (errno)); + return; + } + } + + osstrack->lvol = volumes[0]; + if (track->num_channels == 2) { + osstrack->rvol = volumes[1]; + } +} + +void +gst_ossmixer_set_mute (GstOssMixer * mixer, GstMixerTrack * track, + gboolean mute) +{ + int volume; + GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track); + + g_return_if_fail (mixer->mixer_fd != -1); + g_return_if_fail (gst_ossmixer_contains_track (mixer, osstrack)); + + if (mute) { + volume = 0; + } else { + volume = (osstrack->lvol & 0xff); + if (MASK_BIT_IS_SET (mixer->stereomask, osstrack->track_num)) { + volume |= ((osstrack->rvol & 0xff) << 8); + } + } + + if (ioctl (mixer->mixer_fd, MIXER_WRITE (osstrack->track_num), &volume) < 0) { + g_warning ("Error setting mixer recording device volume (0x%x): %s", + volume, strerror (errno)); + return; + } + + if (mute) { + track->flags |= GST_MIXER_TRACK_MUTE; + } else { + track->flags &= ~GST_MIXER_TRACK_MUTE; + } +} + +void +gst_ossmixer_set_record (GstOssMixer * mixer, + GstMixerTrack * track, gboolean record) +{ + GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track); + + g_return_if_fail (mixer->mixer_fd != -1); + g_return_if_fail (gst_ossmixer_contains_track (mixer, osstrack)); + + /* if there's nothing to do... */ + if ((record && GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD)) || + (!record && !GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD))) + return; + + /* if we're exclusive, then we need to unset the current one(s) */ + if (mixer->mixcaps & SOUND_CAP_EXCL_INPUT) { + GList *track; + + for (track = mixer->tracklist; track != NULL; track = track->next) { + GstMixerTrack *turn = (GstMixerTrack *) track->data; + + turn->flags &= ~GST_MIXER_TRACK_RECORD; + } + mixer->recdevs = 0; + } + + /* set new record bit, if needed */ + if (record) { + mixer->recdevs |= (1 << osstrack->track_num); + } else { + mixer->recdevs &= ~(1 << osstrack->track_num); + } + + /* set it to the device */ + if (ioctl (mixer->mixer_fd, SOUND_MIXER_WRITE_RECSRC, &mixer->recdevs) < 0) { + g_warning ("Error setting mixer recording devices (0x%x): %s", + mixer->recdevs, strerror (errno)); + return; + } + + if (record) { + track->flags |= GST_MIXER_TRACK_RECORD; + } else { + track->flags &= ~GST_MIXER_TRACK_RECORD; + } +} diff --git a/sys/oss/gstossmixer.h b/sys/oss/gstossmixer.h new file mode 100644 index 0000000..d2e06fe --- /dev/null +++ b/sys/oss/gstossmixer.h @@ -0,0 +1,171 @@ +/* GStreamer OSS Mixer implementation + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstossmixer.h: 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. + */ + + +#ifndef __GST_OSS_MIXER_H__ +#define __GST_OSS_MIXER_H__ + + +#include <gst/gst.h> +#include <gst/interfaces/mixer.h> + +#include "gstosshelper.h" + + +G_BEGIN_DECLS + + +#define GST_OSS_MIXER(obj) ((GstOssMixer*)(obj)) + + +typedef enum { + GST_OSS_MIXER_CAPTURE = 1<<0, + GST_OSS_MIXER_PLAYBACK = 1<<1, + GST_OSS_MIXER_ALL = GST_OSS_MIXER_CAPTURE | GST_OSS_MIXER_PLAYBACK +} GstOssMixerDirection; + + +typedef struct _GstOssMixer GstOssMixer; + + +struct _GstOssMixer { + GList * tracklist; /* list of available tracks */ + + gint mixer_fd; + + gchar * device; + gchar * cardname; + + gint recmask; + gint recdevs; + gint stereomask; + gint devmask; + gint mixcaps; + + GstOssMixerDirection dir; +}; + + +GstOssMixer* gst_ossmixer_new (const gchar *device, + GstOssMixerDirection dir); +void gst_ossmixer_free (GstOssMixer *mixer); + +const GList* gst_ossmixer_list_tracks (GstOssMixer * mixer); +void gst_ossmixer_set_volume (GstOssMixer * mixer, + GstMixerTrack * track, + gint * volumes); +void gst_ossmixer_get_volume (GstOssMixer * mixer, + GstMixerTrack * track, + gint * volumes); +void gst_ossmixer_set_record (GstOssMixer * mixer, + GstMixerTrack * track, + gboolean record); +void gst_ossmixer_set_mute (GstOssMixer * mixer, + GstMixerTrack * track, + gboolean mute); + + +#define GST_IMPLEMENT_OSS_MIXER_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_ossmixer_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_ossmixer_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_ossmixer_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_ossmixer_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_ossmixer_set_mute (this->mixer, track, mute); \ +} \ + \ +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; \ +} + + +G_END_DECLS + + +#endif /* __GST_OSS_MIXER_H__ */ diff --git a/sys/oss/gstossmixerelement.c b/sys/oss/gstossmixerelement.c new file mode 100644 index 0000000..7ceb2b8 --- /dev/null +++ b/sys/oss/gstossmixerelement.c @@ -0,0 +1,218 @@ +/* OSS mixer interface element. + * Copyright (C) 2005 Andrew Vander Wingo <wingo@pobox.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-ossmixer + * + * This element lets you adjust sound input and output levels with the + * Open Sound System (OSS). It supports the #GstMixer interface, which can be + * used to obtain a list of available mixer tracks. Set the mixer element to + * READY state before using the #GstMixer interface on it. + * + * <refsect2> + * <title>Example pipelines</title> + * <para> + * ossmixer can't be used in a sensible way in gst-launch. + * </para> + * </refsect2> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstossmixerelement.h" + +GST_DEBUG_CATEGORY_EXTERN (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +#define DEFAULT_DEVICE "/dev/mixer" +#define DEFAULT_DEVICE_NAME NULL + +enum +{ + PROP_0, + PROP_DEVICE, + PROP_DEVICE_NAME +}; + +GST_BOILERPLATE_WITH_INTERFACE (GstOssMixerElement, gst_oss_mixer_element, + GstElement, GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, + gst_oss_mixer_element); + +GST_IMPLEMENT_OSS_MIXER_METHODS (GstOssMixerElement, gst_oss_mixer_element); + +static GstStateChangeReturn gst_oss_mixer_element_change_state (GstElement * + element, GstStateChange transition); + +static void gst_oss_mixer_element_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_oss_mixer_element_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_oss_mixer_element_finalize (GObject * object); + +static void +gst_oss_mixer_element_base_init (gpointer klass) +{ + gst_element_class_set_details_simple (GST_ELEMENT_CLASS (klass), "OSS Mixer", + "Generic/Audio", + "Control sound input and output levels with OSS", + "Andrew Vander Wingo <wingo@pobox.com>"); +} + +static void +gst_oss_mixer_element_class_init (GstOssMixerElementClass * klass) +{ + GstElementClass *element_class; + GObjectClass *gobject_class; + + element_class = (GstElementClass *) klass; + gobject_class = (GObjectClass *) klass; + + gobject_class->finalize = gst_oss_mixer_element_finalize; + gobject_class->set_property = gst_oss_mixer_element_set_property; + gobject_class->get_property = gst_oss_mixer_element_get_property; + + /** + * GstOssMixerElement:device + * + * OSS mixer device (usually /dev/mixer) + * + * Since: 0.10.5 + **/ + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", + "OSS mixer device (usually /dev/mixer)", DEFAULT_DEVICE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, + g_param_spec_string ("device-name", "Device name", + "Human-readable name of the sound device", DEFAULT_DEVICE_NAME, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_oss_mixer_element_change_state); +} + +static void +gst_oss_mixer_element_finalize (GObject * obj) +{ + GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (obj); + + g_free (this->device); + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +static void +gst_oss_mixer_element_init (GstOssMixerElement * this, + GstOssMixerElementClass * g_class) +{ + this->mixer = NULL; + this->device = g_strdup (DEFAULT_DEVICE); +} + +static void +gst_oss_mixer_element_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (object); + + switch (prop_id) { + case PROP_DEVICE: + g_free (this->device); + this->device = g_value_dup_string (value); + /* make sure we never set NULL */ + if (this->device == NULL) { + this->device = g_strdup (DEFAULT_DEVICE); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_oss_mixer_element_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (object); + + switch (prop_id) { + case PROP_DEVICE: + g_value_set_string (value, this->device); + break; + case PROP_DEVICE_NAME: + if (this->mixer) { + g_value_set_string (value, this->mixer->cardname); + } else { + g_value_set_string (value, NULL); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstStateChangeReturn +gst_oss_mixer_element_change_state (GstElement * element, + GstStateChange transition) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (!this->mixer) { + this->mixer = gst_ossmixer_new (this->device, GST_OSS_MIXER_ALL); + if (!this->mixer) + goto open_failed; + } + break; + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_NULL: + if (this->mixer) { + gst_ossmixer_free (this->mixer); + this->mixer = NULL; + } + break; + default: + break; + } + return ret; + + /* ERRORS */ +open_failed: + { + GST_ELEMENT_ERROR (element, RESOURCE, OPEN_READ_WRITE, (NULL), + ("Failed to open oss mixer device '%s'", this->device)); + return GST_STATE_CHANGE_FAILURE; + } +} diff --git a/sys/oss/gstossmixerelement.h b/sys/oss/gstossmixerelement.h new file mode 100644 index 0000000..2d47e0e --- /dev/null +++ b/sys/oss/gstossmixerelement.h @@ -0,0 +1,59 @@ +/* OSS mixer interface element. + * Copyright (C) 2005 Andrew Vander Wingo <wingo@pobox.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_OSS_MIXER_ELEMENT_H__ +#define __GST_OSS_MIXER_ELEMENT_H__ + + +#include "gstossmixer.h" + + +G_BEGIN_DECLS + + +#define GST_OSS_MIXER_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS_MIXER_ELEMENT,GstOssMixerElement)) +#define GST_OSS_MIXER_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS_MIXER_ELEMENT,GstOssMixerElementClass)) +#define GST_IS_OSS_MIXER_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS_MIXER_ELEMENT)) +#define GST_IS_OSS_MIXER_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS_MIXER_ELEMENT)) +#define GST_TYPE_OSS_MIXER_ELEMENT (gst_oss_mixer_element_get_type()) + + +typedef struct _GstOssMixerElement GstOssMixerElement; +typedef struct _GstOssMixerElementClass GstOssMixerElementClass; + + +struct _GstOssMixerElement { + GstElement parent; + + gchar *device; + GstOssMixer *mixer; +}; + +struct _GstOssMixerElementClass { + GstElementClass parent; +}; + + +GType gst_oss_mixer_element_get_type (void); + + +G_END_DECLS + + +#endif /* __GST_OSS_MIXER_ELEMENT_H__ */ diff --git a/sys/oss/gstossmixertrack.c b/sys/oss/gstossmixertrack.c new file mode 100644 index 0000000..3bc8cde --- /dev/null +++ b/sys/oss/gstossmixertrack.c @@ -0,0 +1,172 @@ +/* GStreamer OSS Mixer implementation + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstossmixer.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> + +#ifdef HAVE_OSS_INCLUDE_IN_SYS +# include <sys/soundcard.h> +#else +# ifdef HAVE_OSS_INCLUDE_IN_ROOT +# include <soundcard.h> +# else +# ifdef HAVE_OSS_INCLUDE_IN_MACHINE +# include <machine/soundcard.h> +# else +# error "What to include?" +# endif /* HAVE_OSS_INCLUDE_IN_MACHINE */ +# endif /* HAVE_OSS_INCLUDE_IN_ROOT */ +#endif /* HAVE_OSS_INCLUDE_IN_SYS */ + +#include <gst/gst-i18n-plugin.h> + +#include "gstossmixertrack.h" + +GST_DEBUG_CATEGORY_EXTERN (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +#define MASK_BIT_IS_SET(mask, bit) \ + (mask & (1 << bit)) + +G_DEFINE_TYPE (GstOssMixerTrack, gst_ossmixer_track, GST_TYPE_MIXER_TRACK); + +static void +gst_ossmixer_track_class_init (GstOssMixerTrackClass * klass) +{ + /* nop */ +} + +static void +gst_ossmixer_track_init (GstOssMixerTrack * track) +{ + track->lvol = track->rvol = 0; + track->track_num = 0; +} + +static const gchar **labels = NULL; + +/* three functions: firstly, OSS has the nasty habit of inserting + * spaces in the labels, we want to get rid of them. Secondly, + * i18n is impossible with OSS' way of providing us with mixer + * labels, so we make a 'given' list of i18n'ed labels. Thirdly, I + * personally don't like the "1337" names that OSS gives to their + * labels ("Vol", "Mic", "Rec"), I'd rather see full names. */ + +static void +fill_labels (void) +{ + gint i, pos; + const gchar *origs[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS; + const struct + { + const gchar *given; + const gchar *wanted; + } + cases[] = { + /* Note: this list is simply ripped from soundcard.h. For + * some people, some values might be missing (3D surround, + * etc.) - feel free to add them. That's the reason why + * I'm doing this in such a horribly complicated way. */ + { + "Vol ", _("Volume")}, { + "Bass ", _("Bass")}, { + "Trebl", _("Treble")}, { + "Synth", _("Synth")}, { + "Pcm ", _("PCM")}, { + "Spkr ", _("Speaker")}, { + "Line ", _("Line-in")}, { + "Mic ", _("Microphone")}, { + "CD ", _("CD")}, { + "Mix ", _("Mixer")}, { + "Pcm2 ", _("PCM-2")}, { + "Rec ", _("Record")}, { + "IGain", _("In-gain")}, { + "OGain", _("Out-gain")}, { + "Line1", _("Line-1")}, { + "Line2", _("Line-2")}, { + "Line3", _("Line-3")}, { + "Digital1", _("Digital-1")}, { + "Digital2", _("Digital-2")}, { + "Digital3", _("Digital-3")}, { + "PhoneIn", _("Phone-in")}, { + "PhoneOut", _("Phone-out")}, { + "Video", _("Video")}, { + "Radio", _("Radio")}, { + "Monitor", _("Monitor")}, { + NULL, NULL} + }; + + labels = g_malloc (sizeof (gchar *) * SOUND_MIXER_NRDEVICES); + + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { + for (pos = 0; cases[pos].given != NULL; pos++) { + if (!strcmp (cases[pos].given, origs[i])) { + labels[i] = g_strdup (cases[pos].wanted); + break; + } + } + if (cases[pos].given == NULL) + labels[i] = g_strdup (origs[i]); + } +} + +GstMixerTrack * +gst_ossmixer_track_new (gint mixer_fd, + gint track_num, gint max_chans, gint flags) +{ + GstOssMixerTrack *osstrack; + GstMixerTrack *track; + gint volume; + + if (!labels) + fill_labels (); + + osstrack = g_object_new (GST_TYPE_OSSMIXER_TRACK, NULL); + track = GST_MIXER_TRACK (osstrack); + track->label = g_strdup (labels[track_num]); + track->num_channels = max_chans; + track->flags = flags; + track->min_volume = 0; + track->max_volume = 100; + osstrack->track_num = track_num; + + /* volume */ + if (ioctl (mixer_fd, MIXER_READ (osstrack->track_num), &volume) < 0) { + g_warning ("Error getting device (%d) volume: %s", + osstrack->track_num, strerror (errno)); + volume = 0; + } + osstrack->lvol = (volume & 0xff); + if (track->num_channels == 2) { + osstrack->rvol = ((volume >> 8) & 0xff); + } + + return track; +} diff --git a/sys/oss/gstossmixertrack.h b/sys/oss/gstossmixertrack.h new file mode 100644 index 0000000..2e62ec8 --- /dev/null +++ b/sys/oss/gstossmixertrack.h @@ -0,0 +1,62 @@ +/* GStreamer OSS Mixer implementation + * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstossmixertrack.h: OSS 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_OSS_MIXER_TRACK_H__ +#define __GST_OSS_MIXER_TRACK_H__ + +#include <gst/gst.h> +#include <gst/interfaces/mixer.h> + +#include "gstosshelper.h" + +G_BEGIN_DECLS + +#define GST_TYPE_OSSMIXER_TRACK \ + (gst_ossmixer_track_get_type ()) +#define GST_OSSMIXER_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OSSMIXER_TRACK, \ + GstOssMixerTrack)) +#define GST_OSSMIXER_TRACK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_OSSMIXER_TRACK, \ + GstOssMixerTrackClass)) +#define GST_IS_OSSMIXER_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OSSMIXER_TRACK)) +#define GST_IS_OSSMIXER_TRACK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_OSSMIXER_TRACK)) + +typedef struct _GstOssMixerTrack { + GstMixerTrack parent; + + gint lvol, rvol; + gint track_num; +} GstOssMixerTrack; + +typedef struct _GstOssMixerTrackClass { + GstMixerTrackClass parent; +} GstOssMixerTrackClass; + +GType gst_ossmixer_track_get_type (void); +GstMixerTrack* gst_ossmixer_track_new (gint mixer_fd, + gint track_num, gint max_chans, gint flags); + +G_END_DECLS + +#endif /* __GST_OSS_MIXER_TRACK_H__ */ diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c new file mode 100644 index 0000000..9f9b137 --- /dev/null +++ b/sys/oss/gstosssink.c @@ -0,0 +1,565 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000,2005 Wim Taymans <wim@fluendo.com> + * + * gstosssink.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-osssink + * + * This element lets you output sound using the Open Sound System (OSS). + * + * Note that you should almost always use generic audio conversion elements + * like audioconvert and audioresample in front of an audiosink to make sure + * your pipeline works under all circumstances (those conversion elements will + * act in passthrough-mode if no conversion is necessary). + * + * <refsect2> + * <title>Example pipelines</title> + * |[ + * gst-launch -v audiotestsrc ! audioconvert ! volume volume=0.1 ! osssink + * ]| will output a sine wave (continuous beep sound) to your sound card (with + * a very low volume as precaution). + * |[ + * gst-launch -v filesrc location=music.ogg ! decodebin ! audioconvert ! audioresample ! osssink + * ]| will play an Ogg/Vorbis audio file and output it using the Open Sound System. + * </refsect2> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <sys/ioctl.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> + +#ifdef HAVE_OSS_INCLUDE_IN_SYS +# include <sys/soundcard.h> +#else +# ifdef HAVE_OSS_INCLUDE_IN_ROOT +# include <soundcard.h> +# else +# ifdef HAVE_OSS_INCLUDE_IN_MACHINE +# include <machine/soundcard.h> +# else +# error "What to include?" +# endif /* HAVE_OSS_INCLUDE_IN_MACHINE */ +# endif /* HAVE_OSS_INCLUDE_IN_ROOT */ +#endif /* HAVE_OSS_INCLUDE_IN_SYS */ + +#include "common.h" +#include "gstosssink.h" + +#include <gst/gst-i18n-plugin.h> + +GST_DEBUG_CATEGORY_EXTERN (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +static void gst_oss_sink_base_init (gpointer g_class); +static void gst_oss_sink_class_init (GstOssSinkClass * klass); +static void gst_oss_sink_init (GstOssSink * osssink); + +static void gst_oss_sink_dispose (GObject * object); +static void gst_oss_sink_finalise (GObject * object); + +static void gst_oss_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_oss_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); + +static GstCaps *gst_oss_sink_getcaps (GstBaseSink * bsink); + +static gboolean gst_oss_sink_open (GstAudioSink * asink); +static gboolean gst_oss_sink_close (GstAudioSink * asink); +static gboolean gst_oss_sink_prepare (GstAudioSink * asink, + GstRingBufferSpec * spec); +static gboolean gst_oss_sink_unprepare (GstAudioSink * asink); +static guint gst_oss_sink_write (GstAudioSink * asink, gpointer data, + guint length); +static guint gst_oss_sink_delay (GstAudioSink * asink); +static void gst_oss_sink_reset (GstAudioSink * asink); + +/* OssSink signals and args */ +enum +{ + LAST_SIGNAL +}; + +#define DEFAULT_DEVICE "/dev/dsp" +enum +{ + PROP_0, + PROP_DEVICE, +}; + +static GstStaticPadTemplate osssink_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-raw-int, " + "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, " + "signed = (boolean) { TRUE, FALSE }, " + "width = (int) 16, " + "depth = (int) 16, " + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; " + "audio/x-raw-int, " + "signed = (boolean) { TRUE, FALSE }, " + "width = (int) 8, " + "depth = (int) 8, " + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]") + ); + +static GstElementClass *parent_class = NULL; + +/* static guint gst_oss_sink_signals[LAST_SIGNAL] = { 0 }; */ + +GType +gst_oss_sink_get_type (void) +{ + static GType osssink_type = 0; + + if (!osssink_type) { + static const GTypeInfo osssink_info = { + sizeof (GstOssSinkClass), + gst_oss_sink_base_init, + NULL, + (GClassInitFunc) gst_oss_sink_class_init, + NULL, + NULL, + sizeof (GstOssSink), + 0, + (GInstanceInitFunc) gst_oss_sink_init, + }; + + osssink_type = + g_type_register_static (GST_TYPE_AUDIO_SINK, "GstOssSink", + &osssink_info, 0); + } + + return osssink_type; +} + +static void +gst_oss_sink_dispose (GObject * object) +{ + GstOssSink *osssink = GST_OSSSINK (object); + + if (osssink->probed_caps) { + gst_caps_unref (osssink->probed_caps); + osssink->probed_caps = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_oss_sink_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_set_details_simple (element_class, "Audio Sink (OSS)", + "Sink/Audio", + "Output to a sound card via OSS", + "Erik Walthinsen <omega@cse.ogi.edu>, " + "Wim Taymans <wim.taymans@chello.be>"); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&osssink_sink_factory)); +} + +static void +gst_oss_sink_class_init (GstOssSinkClass * klass) +{ + GObjectClass *gobject_class; + GstBaseSinkClass *gstbasesink_class; + GstAudioSinkClass *gstaudiosink_class; + + gobject_class = (GObjectClass *) klass; + gstbasesink_class = (GstBaseSinkClass *) klass; + gstaudiosink_class = (GstAudioSinkClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->dispose = gst_oss_sink_dispose; + gobject_class->finalize = gst_oss_sink_finalise; + gobject_class->get_property = gst_oss_sink_get_property; + gobject_class->set_property = gst_oss_sink_set_property; + + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", + "OSS device (usually /dev/dspN)", DEFAULT_DEVICE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_oss_sink_getcaps); + + gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_oss_sink_open); + gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_oss_sink_close); + gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_oss_sink_prepare); + gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_oss_sink_unprepare); + gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_oss_sink_write); + gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_oss_sink_delay); + gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_oss_sink_reset); +} + +static void +gst_oss_sink_init (GstOssSink * osssink) +{ + const gchar *device; + + GST_DEBUG_OBJECT (osssink, "initializing osssink"); + + device = g_getenv ("AUDIODEV"); + if (device == NULL) + device = DEFAULT_DEVICE; + osssink->device = g_strdup (device); + osssink->fd = -1; +} + +static void +gst_oss_sink_finalise (GObject * object) +{ + GstOssSink *osssink = GST_OSSSINK (object); + + g_free (osssink->device); + + G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (object)); +} + +static void +gst_oss_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOssSink *sink; + + sink = GST_OSSSINK (object); + + switch (prop_id) { + case PROP_DEVICE: + g_free (sink->device); + sink->device = g_value_dup_string (value); + if (sink->probed_caps) { + gst_caps_unref (sink->probed_caps); + sink->probed_caps = NULL; + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_oss_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOssSink *sink; + + sink = GST_OSSSINK (object); + + switch (prop_id) { + case PROP_DEVICE: + g_value_set_string (value, sink->device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstCaps * +gst_oss_sink_getcaps (GstBaseSink * bsink) +{ + GstOssSink *osssink; + GstCaps *caps; + + osssink = GST_OSSSINK (bsink); + + if (osssink->fd == -1) { + caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD + (bsink))); + } else if (osssink->probed_caps) { + caps = gst_caps_copy (osssink->probed_caps); + } else { + caps = gst_oss_helper_probe_caps (osssink->fd); + if (caps && !gst_caps_is_empty (caps)) { + osssink->probed_caps = gst_caps_copy (caps); + } + } + + return caps; +} + +static gint +ilog2 (gint x) +{ + /* well... hacker's delight explains... */ + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >> 16); + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x = x + (x >> 8); + x = x + (x >> 16); + return (x & 0x0000003f) - 1; +} + +static gint +gst_oss_sink_get_format (GstBufferFormat fmt) +{ + gint result; + + switch (fmt) { + case GST_MU_LAW: + result = AFMT_MU_LAW; + break; + case GST_A_LAW: + result = AFMT_A_LAW; + break; + case GST_IMA_ADPCM: + result = AFMT_IMA_ADPCM; + break; + case GST_U8: + result = AFMT_U8; + break; + case GST_S16_LE: + result = AFMT_S16_LE; + break; + case GST_S16_BE: + result = AFMT_S16_BE; + break; + case GST_S8: + result = AFMT_S8; + break; + case GST_U16_LE: + result = AFMT_U16_LE; + break; + case GST_U16_BE: + result = AFMT_U16_BE; + break; + case GST_MPEG: + result = AFMT_MPEG; + break; + default: + result = 0; + break; + } + return result; +} + +static gboolean +gst_oss_sink_open (GstAudioSink * asink) +{ + GstOssSink *oss; + int mode; + + oss = GST_OSSSINK (asink); + + mode = O_WRONLY; + mode |= O_NONBLOCK; + + oss->fd = open (oss->device, mode, 0); + if (oss->fd == -1) { + switch (errno) { + case EBUSY: + goto busy; + case EACCES: + goto no_permission; + default: + goto open_failed; + } + } + + return TRUE; + + /* ERRORS */ +busy: + { + GST_ELEMENT_ERROR (oss, RESOURCE, BUSY, + (_("Could not open audio device for playback. " + "Device is being used by another application.")), (NULL)); + return FALSE; + } +no_permission: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_WRITE, + (_("Could not open audio device for playback. " + "You don't have permission to open the device.")), + GST_ERROR_SYSTEM); + return FALSE; + } +open_failed: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_WRITE, + (_("Could not open audio device for playback.")), GST_ERROR_SYSTEM); + return FALSE; + } +} + +static gboolean +gst_oss_sink_close (GstAudioSink * asink) +{ + close (GST_OSSSINK (asink)->fd); + GST_OSSSINK (asink)->fd = -1; + return TRUE; +} + +static gboolean +gst_oss_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) +{ + GstOssSink *oss; + struct audio_buf_info info; + int mode; + int tmp; + + oss = GST_OSSSINK (asink); + + /* we opened non-blocking so that we can detect if the device is available + * without hanging forever. We now want to remove the non-blocking flag. */ + mode = fcntl (oss->fd, F_GETFL); + mode &= ~O_NONBLOCK; + if (fcntl (oss->fd, F_SETFL, mode) == -1) { + /* some drivers do no support unsetting the non-blocking flag, try to + * close/open the device then. This is racy but we error out properly. */ + gst_oss_sink_close (asink); + if ((oss->fd = open (oss->device, O_WRONLY, 0)) == -1) + goto non_block; + } + + tmp = gst_oss_sink_get_format (spec->format); + if (tmp == 0) + goto wrong_format; + + if (spec->width != 16 && spec->width != 8) + goto dodgy_width; + + SET_PARAM (oss, SNDCTL_DSP_SETFMT, tmp, "SETFMT"); + if (spec->channels == 2) + SET_PARAM (oss, SNDCTL_DSP_STEREO, 1, "STEREO"); + SET_PARAM (oss, SNDCTL_DSP_CHANNELS, spec->channels, "CHANNELS"); + SET_PARAM (oss, SNDCTL_DSP_SPEED, spec->rate, "SPEED"); + + tmp = ilog2 (spec->segsize); + tmp = ((spec->segtotal & 0x7fff) << 16) | tmp; + GST_DEBUG_OBJECT (oss, "set segsize: %d, segtotal: %d, value: %08x", + spec->segsize, spec->segtotal, tmp); + + SET_PARAM (oss, SNDCTL_DSP_SETFRAGMENT, tmp, "SETFRAGMENT"); + GET_PARAM (oss, SNDCTL_DSP_GETOSPACE, &info, "GETOSPACE"); + + spec->segsize = info.fragsize; + spec->segtotal = info.fragstotal; + + spec->bytes_per_sample = (spec->width / 8) * spec->channels; + oss->bytes_per_sample = (spec->width / 8) * spec->channels; + + GST_DEBUG_OBJECT (oss, "got segsize: %d, segtotal: %d, value: %08x", + spec->segsize, spec->segtotal, tmp); + + return TRUE; + + /* ERRORS */ +non_block: + { + GST_ELEMENT_ERROR (oss, RESOURCE, SETTINGS, (NULL), + ("Unable to set device %s in non blocking mode: %s", + oss->device, g_strerror (errno))); + return FALSE; + } +wrong_format: + { + GST_ELEMENT_ERROR (oss, RESOURCE, SETTINGS, (NULL), + ("Unable to get format %d", spec->format)); + return FALSE; + } +dodgy_width: + { + GST_ELEMENT_ERROR (oss, RESOURCE, SETTINGS, (NULL), + ("unexpected width %d", spec->width)); + return FALSE; + } +} + +static gboolean +gst_oss_sink_unprepare (GstAudioSink * asink) +{ + /* could do a SNDCTL_DSP_RESET, but the OSS manual recommends a close/open */ + + if (!gst_oss_sink_close (asink)) + goto couldnt_close; + + if (!gst_oss_sink_open (asink)) + goto couldnt_reopen; + + return TRUE; + + /* ERRORS */ +couldnt_close: + { + GST_DEBUG_OBJECT (asink, "Could not close the audio device"); + return FALSE; + } +couldnt_reopen: + { + GST_DEBUG_OBJECT (asink, "Could not reopen the audio device"); + return FALSE; + } +} + +static guint +gst_oss_sink_write (GstAudioSink * asink, gpointer data, guint length) +{ + return write (GST_OSSSINK (asink)->fd, data, length); +} + +static guint +gst_oss_sink_delay (GstAudioSink * asink) +{ + GstOssSink *oss; + gint delay = 0; + gint ret; + + oss = GST_OSSSINK (asink); + +#ifdef SNDCTL_DSP_GETODELAY + ret = ioctl (oss->fd, SNDCTL_DSP_GETODELAY, &delay); +#else + ret = -1; +#endif + if (ret < 0) { + audio_buf_info info; + + ret = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &info); + + delay = (ret < 0 ? 0 : (info.fragstotal * info.fragsize) - info.bytes); + } + return delay / oss->bytes_per_sample; +} + +static void +gst_oss_sink_reset (GstAudioSink * asink) +{ + /* There's nothing we can do here really: OSS can't handle access to the + * same device/fd from multiple threads and might deadlock or blow up in + * other ways if we try an ioctl SNDCTL_DSP_RESET or similar */ +} diff --git a/sys/oss/gstosssink.h b/sys/oss/gstosssink.h new file mode 100644 index 0000000..bb2ca93 --- /dev/null +++ b/sys/oss/gstosssink.h @@ -0,0 +1,62 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wtay@chello.be> + * + * gstosssink.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_OSSSINK_H__ +#define __GST_OSSSINK_H__ + + +#include <gst/gst.h> +#include <gst/audio/gstaudiosink.h> + +#include "gstosshelper.h" + +G_BEGIN_DECLS + +#define GST_TYPE_OSSSINK (gst_oss_sink_get_type()) +#define GST_OSSSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSSSINK,GstOssSink)) +#define GST_OSSSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSSSINK,GstOssSinkClass)) +#define GST_IS_OSSSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSSSINK)) +#define GST_IS_OSSSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSSSINK)) + +typedef struct _GstOssSink GstOssSink; +typedef struct _GstOssSinkClass GstOssSinkClass; + +struct _GstOssSink { + GstAudioSink sink; + + gchar *device; + gint fd; + gint bytes_per_sample; + + GstCaps *probed_caps; +}; + +struct _GstOssSinkClass { + GstAudioSinkClass parent_class; +}; + +GType gst_oss_sink_get_type(void); + +G_END_DECLS + +#endif /* __GST_OSSSINK_H__ */ diff --git a/sys/oss/gstosssrc.c b/sys/oss/gstosssrc.c new file mode 100644 index 0000000..33f585d --- /dev/null +++ b/sys/oss/gstosssrc.c @@ -0,0 +1,537 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000,2005 Wim Taymans <wim@fluendo.com> + * + * gstosssrc.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-osssrc + * + * This element lets you record sound using the Open Sound System (OSS). + * + * <refsect2> + * <title>Example pipelines</title> + * |[ + * gst-launch -v osssrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=mymusic.ogg + * ]| will record sound from your sound card using OSS and encode it to an + * Ogg/Vorbis file (this will only work if your mixer settings are right + * and the right inputs enabled etc.) + * </refsect2> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/ioctl.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> + +#ifdef HAVE_OSS_INCLUDE_IN_SYS +# include <sys/soundcard.h> +#else +# ifdef HAVE_OSS_INCLUDE_IN_ROOT +# include <soundcard.h> +# else +# ifdef HAVE_OSS_INCLUDE_IN_MACHINE +# include <machine/soundcard.h> +# else +# error "What to include?" +# endif /* HAVE_OSS_INCLUDE_IN_MACHINE */ +# endif /* HAVE_OSS_INCLUDE_IN_ROOT */ +#endif /* HAVE_OSS_INCLUDE_IN_SYS */ + +#include "gstosssrc.h" +#include "common.h" + +#include <gst/gst-i18n-plugin.h> + +GST_DEBUG_CATEGORY_EXTERN (oss_debug); +#define GST_CAT_DEFAULT oss_debug + +#define DEFAULT_DEVICE "/dev/dsp" +#define DEFAULT_DEVICE_NAME "" + +enum +{ + PROP_0, + PROP_DEVICE, + PROP_DEVICE_NAME, +}; + +GST_BOILERPLATE_WITH_INTERFACE (GstOssSrc, gst_oss_src, GstAudioSrc, + GST_TYPE_AUDIO_SRC, GstMixer, GST_TYPE_MIXER, gst_oss_src_mixer); + +GST_IMPLEMENT_OSS_MIXER_METHODS (GstOssSrc, gst_oss_src_mixer); + +static void gst_oss_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_oss_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); + +static void gst_oss_src_dispose (GObject * object); +static void gst_oss_src_finalize (GstOssSrc * osssrc); + +static GstCaps *gst_oss_src_getcaps (GstBaseSrc * bsrc); + +static gboolean gst_oss_src_open (GstAudioSrc * asrc); +static gboolean gst_oss_src_close (GstAudioSrc * asrc); +static gboolean gst_oss_src_prepare (GstAudioSrc * asrc, + GstRingBufferSpec * spec); +static gboolean gst_oss_src_unprepare (GstAudioSrc * asrc); +static guint gst_oss_src_read (GstAudioSrc * asrc, gpointer data, guint length); +static guint gst_oss_src_delay (GstAudioSrc * asrc); +static void gst_oss_src_reset (GstAudioSrc * asrc); + + + +static GstStaticPadTemplate osssrc_src_factory = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-raw-int, " + "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, " + "signed = (boolean) { TRUE, FALSE }, " + "width = (int) 16, " + "depth = (int) 16, " + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; " + "audio/x-raw-int, " + "signed = (boolean) { TRUE, FALSE }, " + "width = (int) 8, " + "depth = (int) 8, " + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]") + ); + + +static void +gst_oss_src_dispose (GObject * object) +{ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_oss_src_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_set_details_simple (element_class, "Audio Source (OSS)", + "Source/Audio", + "Capture from a sound card via OSS", + "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>"); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&osssrc_src_factory)); +} + +static void +gst_oss_src_class_init (GstOssSrcClass * klass) +{ + GObjectClass *gobject_class; + GstBaseSrcClass *gstbasesrc_class; + GstAudioSrcClass *gstaudiosrc_class; + + gobject_class = (GObjectClass *) klass; + gstbasesrc_class = (GstBaseSrcClass *) klass; + gstaudiosrc_class = (GstAudioSrcClass *) klass; + + gobject_class->dispose = gst_oss_src_dispose; + gobject_class->finalize = (GObjectFinalizeFunc) gst_oss_src_finalize; + gobject_class->get_property = gst_oss_src_get_property; + gobject_class->set_property = gst_oss_src_set_property; + + gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_oss_src_getcaps); + + gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_oss_src_open); + gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_oss_src_prepare); + gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_oss_src_unprepare); + gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_oss_src_close); + gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_oss_src_read); + gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_oss_src_delay); + gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_oss_src_reset); + + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", + "OSS device (usually /dev/dspN)", DEFAULT_DEVICE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, + g_param_spec_string ("device-name", "Device name", + "Human-readable name of the sound device", DEFAULT_DEVICE_NAME, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_oss_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOssSrc *src; + + src = GST_OSS_SRC (object); + + switch (prop_id) { + case PROP_DEVICE: + if (src->device) + g_free (src->device); + src->device = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_oss_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOssSrc *src; + + src = GST_OSS_SRC (object); + + switch (prop_id) { + case PROP_DEVICE: + g_value_set_string (value, src->device); + break; + case PROP_DEVICE_NAME: + g_value_set_string (value, src->device_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_oss_src_init (GstOssSrc * osssrc, GstOssSrcClass * g_class) +{ + const gchar *device; + + GST_DEBUG ("initializing osssrc"); + + device = g_getenv ("AUDIODEV"); + if (device == NULL) + device = DEFAULT_DEVICE; + + osssrc->fd = -1; + osssrc->device = g_strdup (device); + osssrc->device_name = g_strdup (DEFAULT_DEVICE_NAME); + osssrc->probed_caps = NULL; +} + +static void +gst_oss_src_finalize (GstOssSrc * osssrc) +{ + g_free (osssrc->device); + g_free (osssrc->device_name); + + G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (osssrc)); +} + +static GstCaps * +gst_oss_src_getcaps (GstBaseSrc * bsrc) +{ + GstOssSrc *osssrc; + GstCaps *caps; + + osssrc = GST_OSS_SRC (bsrc); + + if (osssrc->fd == -1) { + GST_DEBUG_OBJECT (osssrc, "device not open, using template caps"); + return NULL; /* base class will get template caps for us */ + } + + if (osssrc->probed_caps) { + GST_LOG_OBJECT (osssrc, "Returning cached caps"); + return gst_caps_ref (osssrc->probed_caps); + } + + caps = gst_oss_helper_probe_caps (osssrc->fd); + + if (caps) { + osssrc->probed_caps = gst_caps_ref (caps); + } + + GST_INFO_OBJECT (osssrc, "returning caps %" GST_PTR_FORMAT, caps); + + return caps; +} + +static gint +ilog2 (gint x) +{ + /* well... hacker's delight explains... */ + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >> 16); + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x = x + (x >> 8); + x = x + (x >> 16); + return (x & 0x0000003f) - 1; +} + +static gint +gst_oss_src_get_format (GstBufferFormat fmt) +{ + gint result; + + switch (fmt) { + case GST_MU_LAW: + result = AFMT_MU_LAW; + break; + case GST_A_LAW: + result = AFMT_A_LAW; + break; + case GST_IMA_ADPCM: + result = AFMT_IMA_ADPCM; + break; + case GST_U8: + result = AFMT_U8; + break; + case GST_S16_LE: + result = AFMT_S16_LE; + break; + case GST_S16_BE: + result = AFMT_S16_BE; + break; + case GST_S8: + result = AFMT_S8; + break; + case GST_U16_LE: + result = AFMT_U16_LE; + break; + case GST_U16_BE: + result = AFMT_U16_BE; + break; + case GST_MPEG: + result = AFMT_MPEG; + break; + default: + result = 0; + break; + } + return result; +} + +static gboolean +gst_oss_src_open (GstAudioSrc * asrc) +{ + GstOssSrc *oss; + int mode; + + oss = GST_OSS_SRC (asrc); + + mode = O_RDONLY; + mode |= O_NONBLOCK; + + oss->fd = open (oss->device, mode, 0); + if (oss->fd == -1) { + switch (errno) { + case EACCES: + goto no_permission; + default: + goto open_failed; + } + } + + if (!oss->mixer) { + oss->mixer = gst_ossmixer_new ("/dev/mixer", GST_OSS_MIXER_CAPTURE); + + if (oss->mixer) { + g_free (oss->device_name); + oss->device_name = g_strdup (oss->mixer->cardname); + } + } + return TRUE; + +no_permission: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + (_("Could not open audio device for recording. " + "You don't have permission to open the device.")), + GST_ERROR_SYSTEM); + return FALSE; + } +open_failed: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + (_("Could not open audio device for recording.")), + ("Unable to open device %s for recording: %s", + oss->device, g_strerror (errno))); + return FALSE; + } +} + +static gboolean +gst_oss_src_close (GstAudioSrc * asrc) +{ + GstOssSrc *oss; + + oss = GST_OSS_SRC (asrc); + + close (oss->fd); + + if (oss->mixer) { + gst_ossmixer_free (oss->mixer); + oss->mixer = NULL; + } + + gst_caps_replace (&oss->probed_caps, NULL); + + return TRUE; +} + +static gboolean +gst_oss_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) +{ + GstOssSrc *oss; + struct audio_buf_info info; + int mode; + int fmt, tmp; + + oss = GST_OSS_SRC (asrc); + + mode = fcntl (oss->fd, F_GETFL); + mode &= ~O_NONBLOCK; + if (fcntl (oss->fd, F_SETFL, mode) == -1) + goto non_block; + + fmt = gst_oss_src_get_format (spec->format); + if (fmt == 0) + goto wrong_format; + + tmp = ilog2 (spec->segsize); + tmp = ((spec->segtotal & 0x7fff) << 16) | tmp; + GST_DEBUG_OBJECT (oss, "set segsize: %d, segtotal: %d, value: %08x", + spec->segsize, spec->segtotal, tmp); + + SET_PARAM (oss, SNDCTL_DSP_SETFRAGMENT, tmp, "SETFRAGMENT"); + + SET_PARAM (oss, SNDCTL_DSP_RESET, 0, "RESET"); + + SET_PARAM (oss, SNDCTL_DSP_SETFMT, fmt, "SETFMT"); + if (spec->channels == 2) + SET_PARAM (oss, SNDCTL_DSP_STEREO, 1, "STEREO"); + SET_PARAM (oss, SNDCTL_DSP_CHANNELS, spec->channels, "CHANNELS"); + SET_PARAM (oss, SNDCTL_DSP_SPEED, spec->rate, "SPEED"); + + GET_PARAM (oss, SNDCTL_DSP_GETISPACE, &info, "GETISPACE"); + + spec->segsize = info.fragsize; + spec->segtotal = info.fragstotal; + + if (spec->width != 16 && spec->width != 8) + goto dodgy_width; + + spec->bytes_per_sample = (spec->width / 8) * spec->channels; + oss->bytes_per_sample = (spec->width / 8) * spec->channels; + memset (spec->silence_sample, 0, spec->bytes_per_sample); + + GST_DEBUG_OBJECT (oss, "got segsize: %d, segtotal: %d, value: %08x", + spec->segsize, spec->segtotal, tmp); + + return TRUE; + +non_block: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to set device %s in non blocking mode: %s", + oss->device, g_strerror (errno)), (NULL)); + return FALSE; + } +wrong_format: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unable to get format %d", spec->format), (NULL)); + return FALSE; + } +dodgy_width: + { + GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ, + ("Unexpected width %d", spec->width), (NULL)); + return FALSE; + } +} + +static gboolean +gst_oss_src_unprepare (GstAudioSrc * asrc) +{ + /* could do a SNDCTL_DSP_RESET, but the OSS manual recommends a close/open */ + + if (!gst_oss_src_close (asrc)) + goto couldnt_close; + + if (!gst_oss_src_open (asrc)) + goto couldnt_reopen; + + return TRUE; + +couldnt_close: + { + GST_DEBUG_OBJECT (asrc, "Could not close the audio device"); + return FALSE; + } +couldnt_reopen: + { + GST_DEBUG_OBJECT (asrc, "Could not reopen the audio device"); + return FALSE; + } +} + +static guint +gst_oss_src_read (GstAudioSrc * asrc, gpointer data, guint length) +{ + return read (GST_OSS_SRC (asrc)->fd, data, length); +} + +static guint +gst_oss_src_delay (GstAudioSrc * asrc) +{ + GstOssSrc *oss; + gint delay = 0; + gint ret; + + oss = GST_OSS_SRC (asrc); + +#ifdef SNDCTL_DSP_GETODELAY + ret = ioctl (oss->fd, SNDCTL_DSP_GETODELAY, &delay); +#else + ret = -1; +#endif + if (ret < 0) { + audio_buf_info info; + + ret = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &info); + + delay = (ret < 0 ? 0 : (info.fragstotal * info.fragsize) - info.bytes); + } + return delay / oss->bytes_per_sample; +} + +static void +gst_oss_src_reset (GstAudioSrc * asrc) +{ + /* There's nothing we can do here really: OSS can't handle access to the + * same device/fd from multiple threads and might deadlock or blow up in + * other ways if we try an ioctl SNDCTL_DSP_RESET or similar */ +} diff --git a/sys/oss/gstosssrc.h b/sys/oss/gstosssrc.h new file mode 100644 index 0000000..0d14613 --- /dev/null +++ b/sys/oss/gstosssrc.h @@ -0,0 +1,67 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wtay@chello.be> + * + * gstosssrc.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_OSS_SRC_H__ +#define __GST_OSS_SRC_H__ + + +#include <gst/gst.h> +#include <gst/audio/gstaudiosrc.h> + +#include "gstosshelper.h" +#include "gstossmixer.h" + +G_BEGIN_DECLS + +#define GST_TYPE_OSS_SRC (gst_oss_src_get_type()) +#define GST_OSS_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSS_SRC,GstOssSrc)) +#define GST_OSS_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSS_SRC,GstOssSrcClass)) +#define GST_IS_OSS_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSS_SRC)) +#define GST_IS_OSS_SRC_CLASS(klas) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSS_SRC)) + +typedef struct _GstOssSrc GstOssSrc; +typedef struct _GstOssSrcClass GstOssSrcClass; + +struct _GstOssSrc { + GstAudioSrc src; + + gint fd; + gint bytes_per_sample; + + gchar *device; + gchar *device_name; + + GstCaps *probed_caps; + + GstOssMixer *mixer; +}; + +struct _GstOssSrcClass { + GstAudioSrcClass parent_class; +}; + +GType gst_oss_src_get_type(void); + +G_END_DECLS + +#endif /* __GST_OSS_SRC_H__ */ |