From 2fd4aeff5ae576c583be1b54fd0ad44544287071 Mon Sep 17 00:00:00 2001 From: "rafael@riseup.net" Date: Fri, 17 Sep 2010 20:37:46 +0000 Subject: [PATCH] Pulse support added. --- darkice/trunk/AUTHORS | 2 + darkice/trunk/ChangeLog | 4 + darkice/trunk/INSTALL | 375 ++++++++++++++-- darkice/trunk/configure.in | 36 ++ darkice/trunk/install-sh | 5 +- darkice/trunk/man/darkice.1 | 1 + darkice/trunk/man/darkice.cfg.5 | 6 +- darkice/trunk/missing | 49 ++- darkice/trunk/mkinstalldirs | 5 +- darkice/trunk/src/AudioSource.cpp | 13 + darkice/trunk/src/AudioSource.h | 13 + darkice/trunk/src/DarkIce.cpp | 5 +- darkice/trunk/src/Makefile.am | 6 +- darkice/trunk/src/PulseAudioDspSource.cpp | 440 +++++++++++++++++++ darkice/trunk/src/PulseAudioDspSource.h | 494 ++++++++++++++++++++++ 15 files changed, 1395 insertions(+), 59 deletions(-) create mode 100644 darkice/trunk/src/PulseAudioDspSource.cpp create mode 100644 darkice/trunk/src/PulseAudioDspSource.h diff --git a/darkice/trunk/AUTHORS b/darkice/trunk/AUTHORS index afdbc6b..c999517 100644 --- a/darkice/trunk/AUTHORS +++ b/darkice/trunk/AUTHORS @@ -43,3 +43,5 @@ with contributions by: Clemens Ladisch Edwin van den Oetelaar Adrian Knoth + Filipe Roque + Johann Fot diff --git a/darkice/trunk/ChangeLog b/darkice/trunk/ChangeLog index e0bf946..ce1f788 100644 --- a/darkice/trunk/ChangeLog +++ b/darkice/trunk/ChangeLog @@ -1,4 +1,8 @@ Darkice next release + o Added pulseaudio support + closes ticket #25 + thanks to Filipe Roque and + and Johann Fot o Added rtprio parameter and revisited realtime priority closes ticket #21 thanks to Adrian Knoth diff --git a/darkice/trunk/INSTALL b/darkice/trunk/INSTALL index 9c330dc..7d1c323 100644 --- a/darkice/trunk/INSTALL +++ b/darkice/trunk/INSTALL @@ -1,52 +1,365 @@ -DarkIce installation notes +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type ========================== -DarkIce uses the following libraries (and associated header files): + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: -for capability to stream mp3 to IceCast 1.x and Shoutcast: -- libmp3lame + CPU-COMPANY-SYSTEM -for capability to stream Ogg Vorbis to IceCast 2: -- libogg -- libvoribs -- libvorbisenc +where SYSTEM can have one of these forms: -To install libmp3lame, please refer to INSTALL.lame. -To install libogg, libvoribs and libvorbisenc, please look at INSTALL.vorbis. + OS + KERNEL-OS + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. -Installing DarkIce ------------------- + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. -If you're reading this, you probably have downloaded and extracted the -DarkIce tarball. Go to the directory you extracted it, and try: + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. -./configure --help +Sharing Defaults +================ -This will give you all the compile configuration options. + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. -On Solaris systems, for some reason the configure script does not -find the include file lame/lame.h if it uses the SUN Workshop C compiler -as a preprocessor for testing. Therefore you might consider setting: +Defining Variables +================== -export CPP="gcc -E" + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: -This hack is not needed on other systems. + ./configure CC=/usr/local2/bin/gcc -If chosing the default compile options, issue the following commands: +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). -./configure -make -make install +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: -For the last step, you need to be root or have write permissions in the -target directories, usually directories under /usr/local. + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash -Now you should have DarkIce installed. For documentation, try +`configure' Invocation +====================== -man darkice + `configure' recognizes the following options to control how it +operates. -To try out the program, try +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. -darkice -h +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/darkice/trunk/configure.in b/darkice/trunk/configure.in index 395304a..7ab1c6e 100644 --- a/darkice/trunk/configure.in +++ b/darkice/trunk/configure.in @@ -265,6 +265,42 @@ else fi +dnl----------------------------------------------------------------------------- +dnl link PULSEAUDIO sound system if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(PULSEAUDIO_INCFLAGS) +AC_SUBST(PULSEAUDIO_LDFLAGS) + +AC_ARG_WITH(pulseaudio, +[ --with-pulseaudio use PULSEAUDIO sound system [yes] ], + USE_PULSEAUDIO=${withval}, USE_PULSEAUDIO="yes" ) +AC_ARG_WITH(pulseaudio-prefix, +[ --with-pulseaudio-prefix=DIR alternate location for PULSEAUDIO [/usr] + look for libraries in PULSEAUDIO-PREFIX/lib, + for headers in PULSEAUDIO-PREFIX/include], + CONFIG_PULSEAUDIO_PREFIX="${withval}", CONFIG_PULSEAUDIO_PREFIX="/usr") + +if test "x${USE_PULSEAUDIO}" = "xyes" ; then + AC_MSG_CHECKING( [for pulseaudio libraries at ${CONFIG_PULSEAUDIO_PREFIX}] ) + LA_SEARCH_LIB( PULSEAUDIO_LIB_LOC, PULSEAUDIO_INC_LOC, pulseaudio/asoundlib.h, + ${CONFIG_PULSEAUDIO_PREFIX}) + + if test "x${PULSEAUDIO_LIB_LOC}" != "x" ; then + + AC_DEFINE( HAVE_PULSEAUDIO_LIB, 1, [build with PULSEAUDIO sound system] ) + if test "x${PULSEAUDIO_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + PULSEAUDIO_INCFLAGS="-I${PULSEAUDIO_INC_LOC}" + fi + PULSEAUDIO_LDFLAGS="-L${PULSEAUDIO_LIB_LOC} -lpulse-simple -L${PULSEAUDIO_LIB_LOC} -lpulse" + AC_MSG_RESULT( [found at ${CONFIG_PULSEAUDIO_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without PULSEAUDIO support]) + fi +else + AC_MSG_RESULT( [building without PULSEAUDIO support] ) +fi + + dnl----------------------------------------------------------------------------- dnl link JACK sound server if requested dnl----------------------------------------------------------------------------- diff --git a/darkice/trunk/install-sh b/darkice/trunk/install-sh index a5897de..6781b98 100755 --- a/darkice/trunk/install-sh +++ b/darkice/trunk/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2006-12-25.00 +scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -515,5 +515,6 @@ done # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/darkice/trunk/man/darkice.1 b/darkice/trunk/man/darkice.1 index 2be095c..1f0873f 100644 --- a/darkice/trunk/man/darkice.1 +++ b/darkice/trunk/man/darkice.1 @@ -13,6 +13,7 @@ DarkIce can record from: * ALSA audio devices * Solaris audio interface * Jack sources + * PulseAudio sources DarkIce can encode in the following formats: diff --git a/darkice/trunk/man/darkice.cfg.5 b/darkice/trunk/man/darkice.cfg.5 index 18396c6..ac53157 100644 --- a/darkice/trunk/man/darkice.cfg.5 +++ b/darkice/trunk/man/darkice.cfg.5 @@ -78,9 +78,10 @@ Required values: .TP .I device Specify the device to record from, which can be an OSS DSP device, -an ALSA source or you can use Jack audio. +an ALSA source, PulseAudio source or you can use Jack audio. - OSS DSP audio device to record from (e.g. /dev/dsp) - ALSA DSP device name (e.g. hwplug:0,0) +- for PulseAudio use "pulseaudio" - the string 'jack', to have an unconnected Jack port, or 'jack_auto' to automatically make Jack connect to the first source. .TP @@ -98,6 +99,9 @@ Number of channels to record (e.g. 1 for mono, 2 for stereo) .I jackClientName The name of the jack input channel created by darkice if device=jack is specified. +.TP +.I paSourceName +The name of the PulseAudio source to use. It can be "default", an index or a device string obtained from running "pactl list" .PP .B [icecast-x] diff --git a/darkice/trunk/missing b/darkice/trunk/missing index 1c8ff70..28055d2 100755 --- a/darkice/trunk/missing +++ b/darkice/trunk/missing @@ -1,10 +1,10 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. -scriptversion=2006-05-10.23 +scriptversion=2009-04-28.21; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -18,9 +18,7 @@ scriptversion=2006-05-10.23 # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -89,6 +87,9 @@ Supported PROGRAM values: tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + Send bug reports to ." exit $? ;; @@ -106,15 +107,22 @@ Send bug reports to ." esac +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect -# the program). +# the program). This is about non-GNU programs, so use $1 not +# $program. case $1 in - lex|yacc) + lex*|yacc*) # Not GNU programs, they don't have --version. ;; - tar) + tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 @@ -138,7 +146,7 @@ esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. -case $1 in +case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if @@ -148,7 +156,7 @@ WARNING: \`$1' is $msg. You should only need it if touch aclocal.m4 ;; - autoconf) + autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the @@ -157,7 +165,7 @@ WARNING: \`$1' is $msg. You should only need it if touch configure ;; - autoheader) + autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want @@ -187,7 +195,7 @@ WARNING: \`$1' is $msg. You should only need it if while read f; do touch "$f"; done ;; - autom4te) + autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the @@ -210,7 +218,7 @@ WARNING: \`$1' is needed, but is $msg. fi ;; - bison|yacc) + bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package @@ -240,7 +248,7 @@ WARNING: \`$1' $msg. You should only need it if fi ;; - lex|flex) + lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package @@ -263,7 +271,7 @@ WARNING: \`$1' is $msg. You should only need it if fi ;; - help2man) + help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the @@ -277,11 +285,11 @@ WARNING: \`$1' is $msg. You should only need it if else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" - exit 1 + exit $? fi ;; - makeinfo) + makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file @@ -310,7 +318,7 @@ WARNING: \`$1' is $msg. You should only need it if touch $file ;; - tar) + tar*) shift # We have already tried tar in the generic part. @@ -363,5 +371,6 @@ exit 0 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/darkice/trunk/mkinstalldirs b/darkice/trunk/mkinstalldirs index ef7e16f..4191a45 100755 --- a/darkice/trunk/mkinstalldirs +++ b/darkice/trunk/mkinstalldirs @@ -1,7 +1,7 @@ #! /bin/sh # mkinstalldirs --- make directory hierarchy -scriptversion=2006-05-11.19 +scriptversion=2009-04-28.21; # UTC # Original author: Noah Friedman # Created: 1993-05-16 @@ -157,5 +157,6 @@ exit $errstatus # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/darkice/trunk/src/AudioSource.cpp b/darkice/trunk/src/AudioSource.cpp index 0229b73..2387396 100644 --- a/darkice/trunk/src/AudioSource.cpp +++ b/darkice/trunk/src/AudioSource.cpp @@ -61,6 +61,7 @@ static const char fileid[] = "$Id$"; AudioSource * AudioSource :: createDspSource( const char * deviceName, const char * jackClientName, + const char * paSourceName, int sampleRate, int bitsPerSample, int channel) @@ -110,6 +111,18 @@ AudioSource :: createDspSource( const char * deviceName, throw Exception( __FILE__, __LINE__, "trying to open JACK device without " "support compiled", deviceName); +#endif + } else if ( Util::strEq( deviceName, "pulseaudio", 10) ) { +#if defined( SUPPORT_PULSEAUDIO_DSP ) + Reporter::reportEvent( 1, "Using PulseAudio audio server as input device."); + return new PulseAudioDspSource( paSourceName, + sampleRate, + bitsPerSample, + channel); +#else + throw Exception( __FILE__, __LINE__, + "trying to open PulseAudio device without " + "support compiled", deviceName); #endif } else { #if defined( SUPPORT_ALSA_DSP ) diff --git a/darkice/trunk/src/AudioSource.h b/darkice/trunk/src/AudioSource.h index 7c027e6..b400115 100644 --- a/darkice/trunk/src/AudioSource.h +++ b/darkice/trunk/src/AudioSource.h @@ -56,6 +56,11 @@ #define SUPPORT_ALSA_DSP 1 #endif +#if defined( HAVE_PULSEAUDIO_LIB ) +// we have an PULSEAUDIO sound system available +#define SUPPORT_PULSEAUDIO_DSP 1 +#endif + #if defined( HAVE_SYS_SOUNDCARD_H ) // we have an OSS DSP sound source device available #define SUPPORT_OSS_DSP 1 @@ -76,6 +81,7 @@ #endif #if !defined( SUPPORT_ALSA_DSP ) \ + && !defined( SUPPORT_PULSEAUDIO_DSP ) \ && !defined( SUPPORT_OSS_DSP ) \ && !defined( SUPPORT_JACK_DSP ) \ && !defined( SUPPORT_SOLARIS_DSP ) \ @@ -264,6 +270,8 @@ class AudioSource : public Source, public virtual Reporter * the supplied DSP name parameter. * * @param deviceName the audio device (/dev/dspX, hwplug:0,0, etc) + * @param jackClientName the source name for jack server + * @param paSourceName the pulse audio source * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). * @param bitsPerSample bits per sample (e.g. 16 bits). * @param channel number of channels of the audio source @@ -273,6 +281,7 @@ class AudioSource : public Source, public virtual Reporter static AudioSource * createDspSource( const char * deviceName, const char * jackClientName, + const char * paSourceName, int sampleRate = 44100, int bitsPerSample = 16, int channel = 2) throw ( Exception ); @@ -289,6 +298,10 @@ class AudioSource : public Source, public virtual Reporter #include "AlsaDspSource.h" #endif +#if defined( SUPPORT_PULSEAUDIO_DSP ) +#include "PulseAudioDspSource.h" +#endif + #if defined( SUPPORT_OSS_DSP ) #include "OssDspSource.h" #endif diff --git a/darkice/trunk/src/DarkIce.cpp b/darkice/trunk/src/DarkIce.cpp index 3b425c0..dc2a09d 100644 --- a/darkice/trunk/src/DarkIce.cpp +++ b/darkice/trunk/src/DarkIce.cpp @@ -144,6 +144,7 @@ DarkIce :: init ( const Config & config ) throw ( Exception ) bool reconnect; const char * device; const char * jackClientName; + const char * paSourceName; // the [general] section if ( !(cs = config.get( "general")) ) { @@ -185,9 +186,11 @@ DarkIce :: init ( const Config & config ) throw ( Exception ) channel = Util::strToL( str); device = cs->getForSure( "device", " missing in section [input]"); jackClientName = cs->get ( "jackClientName"); + paSourceName = cs->get ( "paSourceName"); dsp = AudioSource::createDspSource( device, jackClientName, + paSourceName, sampleRate, bitsPerSample, channel ); @@ -1202,7 +1205,7 @@ DarkIce :: encode ( void ) throw ( Exception ) (dsp->getBitsPerSample() / 8UL) * dsp->getChannel() * duration; - + len = encConnector->transfer( bytes, 4096, 1, 0 ); reportEvent( 1, len, "bytes transfered to the encoders"); diff --git a/darkice/trunk/src/Makefile.am b/darkice/trunk/src/Makefile.am index 9ffdabf..d202fa9 100644 --- a/darkice/trunk/src/Makefile.am +++ b/darkice/trunk/src/Makefile.am @@ -2,9 +2,9 @@ bin_PROGRAMS = darkice AM_CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@ @JACK_CFLAGS@ INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @FAAC_INCFLAGS@ @AACPLUS_INCFLAGS@ @TWOLAME_INCFLAGS@ \ - @ALSA_INCFLAGS@ @JACK_INCFLAGS@ @SRC_INCFLAGS@ + @ALSA_INCFLAGS@ @PULSEAUDIO_INCFLAGS@ @JACK_INCFLAGS@ @SRC_INCFLAGS@ LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @FAAC_LDFLAGS@ @AACPLUS_LDFLAGS@ @TWOLAME_LDFLAGS@ \ - @ALSA_LDFLAGS@ @JACK_LDFLAGS@ @SRC_LDFLAGS@ + @ALSA_LDFLAGS@ @PULSEAUDIO_LDFLAGS@ @JACK_LDFLAGS@ @SRC_LDFLAGS@ if HAVE_SRC_LIB AFLIB_SOURCE = @@ -74,6 +74,8 @@ darkice_SOURCES = AudioEncoder.h\ Reporter.cpp\ AlsaDspSource.h\ AlsaDspSource.cpp\ + PulseAudioDspSource.h\ + PulseAudioDspSource.cpp\ JackDspSource.h\ JackDspSource.cpp\ main.cpp \ diff --git a/darkice/trunk/src/PulseAudioDspSource.cpp b/darkice/trunk/src/PulseAudioDspSource.cpp new file mode 100644 index 0000000..5a367cf --- /dev/null +++ b/darkice/trunk/src/PulseAudioDspSource.cpp @@ -0,0 +1,440 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved. + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : PulseAudioDspSource.cpp + Version : $Revision: 461 $ + Author : $Author: rafael@riseup.net $ + Location : $HeadURL$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "AudioSource.h" + +// compile only if configured for PULSEAUDIO +#ifdef SUPPORT_PULSEAUDIO_DSP + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Util.h" +#include "Exception.h" +#include "PulseAudioDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id: PulseAudioDspSource.cpp 461 2009-12-01 12:57:31Z rafael@riseup.net $"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +PulseAudioDspSource :: init ( const char * paSourceName ) throw ( Exception ) +{ + + if (paSourceName == NULL) + { + throw Exception( __FILE__, __LINE__, "no paSourceName specified"); + } + Reporter::reportEvent( 1, "Using PulseAudio source: ", paSourceName); + Util::strEq( paSourceName , "default" ); + if (Util::strEq( paSourceName , "default" )) + { + sourceName = NULL; + } + else + { + sourceName = Util::strDup( paSourceName); + } + ss.channels = getChannel(); + ss.rate = getSampleRate(); + + //Supported for some bits per sample, both Big and Little endian + if (isBigEndian()) + { + switch (getBitsPerSample()) + { + case 8: + ss.format = PA_SAMPLE_U8; + break; + case 16: + ss.format = PA_SAMPLE_S16BE; + break; + case 24: + ss.format = PA_SAMPLE_S24BE; + break; + case 32: + ss.format = PA_SAMPLE_S32BE; + break; + default: + ss.format = PA_SAMPLE_INVALID; + } + } + else + { + switch (getBitsPerSample()) + { + case 8: + ss.format = PA_SAMPLE_U8; + break; + case 16: + ss.format = PA_SAMPLE_S16LE; + break; + case 24: + ss.format = PA_SAMPLE_S24LE; + break; + case 32: + ss.format = PA_SAMPLE_S32LE; + break; + default: + ss.format = PA_SAMPLE_INVALID; + } + } +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +PulseAudioDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] sourceName; +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +PulseAudioDspSource :: open ( void ) throw ( Exception ) +{ + char client_name[255]; + + //to identify each darkice on pulseaudio server + snprintf(client_name, 255, "darkice-%d", getpid()); + + if (!(s = pa_simple_new(NULL, client_name, PA_STREAM_RECORD, sourceName, "darkice record", &ss, NULL, NULL, &error))) { + throw Exception( __FILE__, __LINE__, ": pa_simple_new() failed: %s\n", pa_strerror(error)); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +PulseAudioDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ +//this seems to be a problem. +//to explore in the future +/* if ( !isOpen() ) { + return false; + } +*/ + + /* + * FIXME How to check if it can read? + */ + return true; // bad!! +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +PulseAudioDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + int ret; + + ret = pa_simple_read(s, buf, len, &error); + if ( ret < 0) { + throw Exception(__FILE__, __LINE__, ": pa_simple_read() failed: %s\n", pa_strerror(error)); + } + return len; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +PulseAudioDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + pa_simple_free(s); +} + +#endif // HAVE_PULSEAUDIO_LIB +/*------------------------------------------------------------------------------ + + Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved. + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : PulseAudioDspSource.cpp + Version : $Revision: 461 $ + Author : $Author: rafael@riseup.net $ + Location : $HeadURL$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "AudioSource.h" + +// compile only if configured for PULSEAUDIO +#ifdef SUPPORT_PULSEAUDIO_DSP + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Util.h" +#include "Exception.h" +#include "PulseAudioDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id: PulseAudioDspSource.cpp 461 2009-12-01 12:57:31Z rafael@riseup.net $"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +PulseAudioDspSource :: init ( const char * paSourceName ) throw ( Exception ) +{ + + if (paSourceName == NULL) + { + throw Exception( __FILE__, __LINE__, "no paSourceName specified"); + } + Reporter::reportEvent( 1, "Using PulseAudio source: ", paSourceName); + Util::strEq( paSourceName , "default" ); + if (Util::strEq( paSourceName , "default" )) + { + sourceName = NULL; + } + else + { + sourceName = Util::strDup( paSourceName); + } + ss.channels = getChannel(); + ss.rate = getSampleRate(); + + //Supported for some bits per sample, both Big and Little endian + if (isBigEndian()) + { + switch (getBitsPerSample()) + { + case 8: + ss.format = PA_SAMPLE_U8; + break; + case 16: + ss.format = PA_SAMPLE_S16BE; + break; + case 24: + ss.format = PA_SAMPLE_S24BE; + break; + case 32: + ss.format = PA_SAMPLE_S32BE; + break; + default: + ss.format = PA_SAMPLE_INVALID; + } + } + else + { + switch (getBitsPerSample()) + { + case 8: + ss.format = PA_SAMPLE_U8; + break; + case 16: + ss.format = PA_SAMPLE_S16LE; + break; + case 24: + ss.format = PA_SAMPLE_S24LE; + break; + case 32: + ss.format = PA_SAMPLE_S32LE; + break; + default: + ss.format = PA_SAMPLE_INVALID; + } + } +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +PulseAudioDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] sourceName; +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +PulseAudioDspSource :: open ( void ) throw ( Exception ) +{ + char client_name[255]; + + //to identify each darkice on pulseaudio server + snprintf(client_name, 255, "darkice-%d", getpid()); + + if (!(s = pa_simple_new(NULL, client_name, PA_STREAM_RECORD, sourceName, "darkice record", &ss, NULL, NULL, &error))) { + throw Exception( __FILE__, __LINE__, ": pa_simple_new() failed: %s\n", pa_strerror(error)); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +PulseAudioDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ +//this seems to be a problem. +//to explore in the future +/* if ( !isOpen() ) { + return false; + } +*/ + + /* + * FIXME How to check if it can read? + */ + return true; // bad!! +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +PulseAudioDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + int ret; + + ret = pa_simple_read(s, buf, len, &error); + if ( ret < 0) { + throw Exception(__FILE__, __LINE__, ": pa_simple_read() failed: %s\n", pa_strerror(error)); + } + return len; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +PulseAudioDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + pa_simple_free(s); +} + +#endif // HAVE_PULSEAUDIO_LIB diff --git a/darkice/trunk/src/PulseAudioDspSource.h b/darkice/trunk/src/PulseAudioDspSource.h new file mode 100644 index 0000000..6f3f705 --- /dev/null +++ b/darkice/trunk/src/PulseAudioDspSource.h @@ -0,0 +1,494 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved. + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : PulseAudioDspSource.h + Version : $Revision: 394 $ + Author : $Author: darkeye $ + Location : $HeadURL$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef PULSEAUDIO_SOURCE_H +#define PULSEAUDIO_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Reporter.h" +#include "AudioSource.h" + +#ifdef HAVE_PULSEAUDIO_LIB + +#include +#include +#include +#else +#error configure for PULSEAUDIO +#endif + +/* ================================================================ constants */ + +/* =================================================================== macros */ + +/* =============================================================== data types */ + +/** + * An audio input based on the PULSEAUDIO sound system + * + * @author $Author: darkeye $ + * @version $Revision: 394 $ + */ +class PulseAudioDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * Name of the capture PCM stream. + */ + char *sourceName; + + /** + * Handle for PulseAudio + */ + pa_simple *s ; + + /** + * format definitions for pulseaudio + */ + pa_sample_spec ss; + + int error; + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + PulseAudioDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the PCM to open. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-iitialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param name the PCM (e.g. "hwplug:0,0"). + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + PulseAudioDspSource ( const char * paSourceName, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( paSourceName); + } + + /** + * Copy Constructor. + * + * @param ds the object to copy. + * @exception Exception + */ + inline + PulseAudioDspSource ( const PulseAudioDspSource & ds ) throw ( Exception ) + : AudioSource( ds ) + { + init( ds.sourceName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~PulseAudioDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual PulseAudioDspSource & + operator= ( const PulseAudioDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.sourceName); + } + return *this; + } + + /** + * Open the PulseAudioDspSource. + * + * @return true if opening was successful, false otherwise + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the PulseAudioDspSource is open. + * + * @return true if the PulseAudioDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return s==NULL; + } + + /** + * Check if the PulseAudioDspSource can be read from. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the PulseAudioDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the PulseAudioDspSource. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the PulseAudioDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); + +}; + +/* ================================================= external data structures */ + +/* ====================================================== function prototypes */ + +#endif /* PULSEAUDIO_SOURCE_H */ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved. + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : PulseAudioDspSource.h + Version : $Revision: 394 $ + Author : $Author: darkeye $ + Location : $HeadURL$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef PULSEAUDIO_SOURCE_H +#define PULSEAUDIO_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Reporter.h" +#include "AudioSource.h" + +#ifdef HAVE_PULSEAUDIO_LIB + +#include +#include +#include +#else +#error configure for PULSEAUDIO +#endif + +/* ================================================================ constants */ + +/* =================================================================== macros */ + +/* =============================================================== data types */ + +/** + * An audio input based on the PULSEAUDIO sound system + * + * @author $Author: darkeye $ + * @version $Revision: 394 $ + */ +class PulseAudioDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * Name of the capture PCM stream. + */ + char *sourceName; + + /** + * Handle for PulseAudio + */ + pa_simple *s ; + + /** + * format definitions for pulseaudio + */ + pa_sample_spec ss; + + int error; + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + PulseAudioDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the PCM to open. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-iitialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param name the PCM (e.g. "hwplug:0,0"). + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + PulseAudioDspSource ( const char * paSourceName, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( paSourceName); + } + + /** + * Copy Constructor. + * + * @param ds the object to copy. + * @exception Exception + */ + inline + PulseAudioDspSource ( const PulseAudioDspSource & ds ) throw ( Exception ) + : AudioSource( ds ) + { + init( ds.sourceName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~PulseAudioDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual PulseAudioDspSource & + operator= ( const PulseAudioDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.sourceName); + } + return *this; + } + + /** + * Open the PulseAudioDspSource. + * + * @return true if opening was successful, false otherwise + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the PulseAudioDspSource is open. + * + * @return true if the PulseAudioDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return s==NULL; + } + + /** + * Check if the PulseAudioDspSource can be read from. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the PulseAudioDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the PulseAudioDspSource. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the PulseAudioDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); + +}; + +/* ================================================= external data structures */ + +/* ====================================================== function prototypes */ + +#endif /* PULSEAUDIO_SOURCE_H */