ecasound-2.9.1/0000755000076400007640000000000012261520737010342 500000000000000ecasound-2.9.1/aclocal.m40000644000076400007640000115755012261511322012126 00000000000000# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 Free Software Foundation, Inc. # This file 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. # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl _LT_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_INIT ]) # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2008 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) fi ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX # ----------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method == "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC*) # IBM XL 8.0 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then _LT_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], [[If ld is used when linking, flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=echo else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ]) dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${F77-"f77"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${FC-"f95"} compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC="$lt_save_CC" ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC= CC=${RC-"windres"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC="$lt_save_CC" ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 6 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file 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. # Generated from ltversion.in. # serial 3017 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6b]) m4_define([LT_PACKAGE_REVISION], [1.3017]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6b' macro_revision='1.3017' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file 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. # serial 4 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file 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. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file 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. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file 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. # serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file 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. # serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file 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. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file 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. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file 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. # serial 12 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file 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. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file 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. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file 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. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file 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. # serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. # # This file 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. # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file 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. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file 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. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file 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. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file 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. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) ecasound-2.9.1/Makefile.in0000644000076400007640000005746412261511325012340 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/Makefile.am # Description: Ecasound multitrack audio processing tool # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING INSTALL NEWS TODO \ compile config.guess config.sub depcomp install-sh ltmain.sh \ missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ EXTRA_DIST = AUTHORS BUGS COPYING.GPL COPYING.LGPL NEWS RELNOTES TODO ecasoundrc.in effect_presets generic_oscillators SUBDIRS = kvutils libecasound ecasound libecasoundc pyecasound rubyecasound ecatools Documentation examples AUTOMAKE_OPTIONS = foreign RELEASE = 1 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done 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; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(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; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(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; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkdir_p) $(distdir)/libecasound $(distdir)/libecasoundc @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod u+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive 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) 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-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-data-local install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-local uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-libtool clean-local \ clean-recursive ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-hook dist-shar dist-tarZ dist-zip distcheck \ distclean distclean-generic distclean-hdr distclean-libtool \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive \ mostlyclean mostlyclean-generic mostlyclean-libtool \ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-info-am uninstall-local docs: cd Documentation ; $(MAKE) $(AM_MAKEFLAGS) docs install-data-local: ecasoundrc $(INSTALL) -d $(DESTDIR)$(pkgdatadir) $(INSTALL_DATA) $(top_builddir)/ecasoundrc $(DESTDIR)$(pkgdatadir)/ecasoundrc $(INSTALL_DATA) $(top_srcdir)/effect_presets $(DESTDIR)$(pkgdatadir)/effect_presets $(INSTALL_DATA) $(top_srcdir)/ecatools/ecasound.el $(DESTDIR)$(pkgdatadir)/ecasound.el $(INSTALL_DATA) $(top_srcdir)/generic_oscillators $(DESTDIR)$(pkgdatadir)/generic_oscillators uninstall-local: rm -f $(DESTDIR)$(pkgdatadir)/effect_presets \ $(DESTDIR)$(pkgdatadir)/ecasound.el \ $(DESTDIR)$(pkgdatadir)/generic_oscillators \ $(DESTDIR)$(pkgdatadir)/ecasoundrc rmdir $(DESTDIR)$(pkgdatadir) || echo "Skipping non-empty directory" ecasoundrc: ecasoundrc.in Makefile.am sed -e "s%[@]VERSION[@]%$(VERSION)%" \ -e "s%[@]prefix[@]%$(prefix)%" \ -e "s%[@]pkgdatadir[@]%$(pkgdatadir)%" \ < $(top_srcdir)/ecasoundrc.in > ecasoundrc clean-local: rm -fv ecasoundrc dist-hook: docs # 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: ecasound-2.9.1/effect_presets0000644000076400007640000001733710664032032013210 00000000000000# -------------------------------------------------------------------- # ecasound effect presets definitions # -------------------------------------------------------------------- # # - all lines beginning with a '#' are ignored # - preset format: # "preset_name_or_number = | ... | " # - you can use '\' sign to split lines # - preset parameters and available descriptors: # -efl:%1,100 = first param of -efl is a public preset parameter # -pd:name_of_preset = preset description # -ppn:par1,...,parN = parameter names (public params) # -ppd:val1,...,valN = default param values # -ppl:val1,...,valN = lower bounds for param values # -ppu:val1,...,valN = upper bounds for param values # -ppt:flags1,...,flagsN = special flags for parameter N # ('i'=integer, 'l'=logarithmic, 'o'=output, 't'=toggle) # # -------------------------------------------------------------------- # ====== # Compression/dynamics (dyn_) # dyn_compress_supersoft = -eca:69,0,0.25,0.25 -ea:%1 \ -pd:Supersoft_compressor -ppn:gain-% -ppd:100 -ppl:0 -ppu:1000 dyn_compress_soft = -eca:69,0,0.25,0.5 -ea:%1 \ -pd:Soft_compressor -ppn:gain-% -ppd:100 -ppl:0 -ppu:1000 dyn_compress_medium = -eca:69,0,0.25,1.0 -ea:%1 \ -pd:Medium_compressor -ppn:gain-% -ppd:100 -ppl:0 -ppu:1000 dyn_compress_hard = -eca:69,0,0.5,1.0 -ea:%1 \ -pd:Hard_compressor -ppn:gain-% -ppd:100 -ppl:0 -ppu:1000 dyn_compress_infinite = -eca:69,0,1.0,1.0 -ea:%1 \ -pd:Infinite_to_one_compressor -ppn:gain-% -ppd:100 -ppl:0 -ppu:1000 dyn_compress_brutal = -ec:999,10 -ea:%1 \ -pd:Ultra_brutal_compressor -ppn:gain-% -ppd:100 -ppl:0 -ppu:1000 # ====== # EQ (eq_) # eq_template = -efb:10,20 -ea:%1 | \ -efb:40,40 -ea:%2 | \ -efb:100,80 -ea:%3 | \ -efb:220,160 -ea:%4 | \ -efb:460,320 -ea:%5 | \ -efb:940,640 -ea:%6 | \ -efb:1900,1280 -ea:%7 | \ -efb:3800,2520 -ea:%8 | \ -efb:7620,5120 -ea:%9 | \ -efb:15300,10240 -ea:%10 \ -pd:Big_eq_template \ -ppn:10hz,40hz,100hz,220hz,460hz,940hz,1900hz,3800hz,7620hz,15300hz \ -ppd:100,100,100,100,100,100,100,100,100,100 \ -ppl:0,0,0,0,0,0,0,0,0,0 \ -ppu:500,500,500,500,500,500,500,500,500,500 eq_template2 = -efb:1000,2000 -ea:%1 | \ -efb:4000,2000 -ea:%2 \ -pd:Dual_band_eq_template \ -ppn:1000hz,4000hz -ppd:100,100 \ -ppl:0,0 -ppu:500,500 # ====== # Filters (f_) # f_lowp_sine = -ef3:800,1.5,0.9 -kos:1,400,4200,0.2,0 \ -pd:Reson_lowpass_filter_controlled_by_a_sine_oscillator f_lowp_sine2 = -efl:400 -kos:1,200,2000,0.5,0 \ -pd:Lowpass_filter_controlled_by_a_sine_oscillator f_high_and_low = -efl:400 | -efh:4000 -ea:800 \ -pd:Parallel_high_and_lowpass_filters f_res_bandpass = -ef1:%1,%2 \ -pd:Reson_bandpass_filter -ppn:freq,width -ppd:1500,700 -ppl:0,1 f_res_lowpass = -ef3:%1,1.5,0.7 \ -pd:Reson_lowpass_filter -ppd:800 -ppl:0 f_lowpass = -efl:%1 -ppn:freq_hz -ppd:300 -pd:Simple_lowpass_filter f_bandpass = -efb:%1,%2 \ -pd:Bandpass_filter -ppn:freq,width -ppd:1500,700 -ppl:0,1 f_rejectband = -efr:1500,1000 -pd:Band_reject_filter f_highpass = -efh:2000 \ -pd:Reson_lowpass -ppd:1500 -ppl:0 f_inverse_comb = -efi:8,0.999 \ -pd:Inverse_comb_filter f_resonator = -efs:1500,1000 -pd:Resonator_filter f_two_filters = -efl:800 -ea:%1 | -efh:800 -ea:%2 \ -pd:Parallel_highpass_and_lowpass_filters \ -ppl:0,0 -ppu:1000,- \ -ppd:100,100 -ppn:lowgain,highgain f_two_filters_pareq = -efl:%1 -ea:%2 | \ -efh:%3 -ea:%4 \ -ppn:lowfreq,lowgain,highfreq,highgain \ -ppd:200,100,2000,100 \ -pd:Two_paraller_filters_with_gain_controls f_filtertest = -efl:%1 -ea:100 | \ -efh:%2 -ea:100 | \ -ea:100 -ppd:100 -ppn:freq1,freq2 \ -pd:Two_paraller_filters # ====== # Gates (gate_) gate_noisegate_1 = -enm:18,20,50,50,50 -pd:Noise_gate gate_noisegate_delanalog = -enm:0.20,0.1,1000,50,0 -pd:Noise_gate_for_analog_hum_removal gate_crop = -gc:1,0.5 -pd:Crop_gate_example gate_threshold = -ge:15,20,1 -pd:Threshold_gate_example # ====== # Time/delay effects (time_) time_reverb1 = -etr:40,0,85 -pd:Bathroom_reverb time_reverb2 = -etr:60,0,70 -pd:Plain_reverb time_reverb3 = -etf:30 -pd:Fake_stereo time_reverb4 = -pn:reverb1 -pn:reverb2 -pd:Reverb_combo time_delay1 = -etd:200,0,3,60 -pd:200ms_triple_delay time_delay2 = -etm:200,3,60 -pd:200ms_triple_multidelay time_wicked_dub = -etm:500,1,90 -epp:100 -kos:1,0,100,0.3,0.5 | \ -etm:333,1,90 -epp:0 -kos:1,0,100,0.8,0 | -ea:90 \ -pd:Wicked_dub_mix time_flanger1 = -etl:2,20,50,0.5 -pd:Flanger time_chorus1 = -etc:2,20,50,0.5 -pd:Chorus time_phaser1 = -etp:2,50,50,0.05 -pd:Phaser # ====== # Various / mixes (var_) var_sweeping_pan = -epp:0 -kos:1,0,100,%1,5 \ -pd:Sweeping_pan_envelope -ppn:speed_hz -ppd:0.2 var_switching_pan = -epp:0 -kf:1,0,100,%1,0,0 \ -pd:Panner_that_alternates_between_left_and_right -ppn:speed_hz -ppd:0.2 var_chipmunk = -ei:400 -efl:400 -kos:1,400,10000,2,0 \ -pd:Chipmunk_generator var_parchip = -ei:%1 -efl:400 -kos:1,400,10000,%2,0 \ -ppn:pitch,modfreq -ppd:100,0.5 \ -pd:Chipmunk_sweep var_paralmadness = -efb:0,2000 -kos:1,1,3000,%1,0 -ea:150 | \ -efb:0,2000 -kos:1,3000,5000,%2,0 -ea:150 | \ -efh:0 -kos:1,3000,5000,%3,0 -ea:200 \ -ppn:freq1,freq2,freq3 -ppd:0.2,0.2,0.2 \ -pd:Parallel_madness # ====== # Contributed / Arto Hamara [artham] var_stretched_tape = -ei:100 -kos:1,93,100,.5,0 -kx -kos:4,.1,1,.1 \ -pd:Stretched_tape var_molten_tape = -ei:100 -kos:1,85,105,.5,0 -kx -kos:4,.1,2,.1 \ -pd:Molten_tape var_dali = -ei:100 -kos:1,85,105,.5,0 -kx -kos:4,.1,2,.1 \ -etd:100,1,0,70 -epp:0 -kos:1,20,80,.5,0 -kx -kos:4,.1,2,.1 \ -pd:Dali # ====== # Contributed / S.Massy [smassy] # Results of spending an hour messing around. # var_aw = -efl:0 -kos:1,500,5500,%1,0 -ppn:speed -ppd:0.5 \ -pd:Classic_auto_wah var_aw_custom = -efl:0 -kos:1,%1,%2,%3,0 -ppn:low,high,speed -ppd:100,8000,0.5 \ -pd:Class_auto_wah_with_controls # Now the autowah again but with the triangular osc which gives a sharper # movement. It really depends of what you're playing, can sound as good as it # can sound bad. That's the joy of autowahs. var_aw_tri = -efl:0 -kf:1,500,5500,%1,1,0 -ppn:speed -ppd:0.5 \ -pd:Auto_wah_triangular_osc # Now once again we define another version with more definable params. var_aw_tri_custom = -efl:0 -kf:1,%low,%high,%1,1,0 -ppn:speed -ppd:0.5 \ -pd:Auto_wah_triangular_osc_with_control # Experimental stuff: # I was trying to have a wah reacting to the volume, it doesn't work very # well but I still end up with a "to dig up" envelope shaper. var_aw_ksv = -eS:0 -efl:0 -ksv:1,1000,6000,0,1 \ -pd:Volume_sensitive_wah # ====== # Presets using LADSPA plugins (lad_) lad_hermes = \ -eli:1200,3,%1,0.27,%2,100,%3,40,%4,1.5,1,2,-4,-4,-50,-20,-20,-20,200,1000,3,1,3,5,1500,0.65,0,130,0,5,400,0.8,0,0,-177,1,150,0.9,0.97,30,30,0.025,0.9,0.5,0.05,0.7,0.5,0.1,0.5,0.5,0,20,20 \ -pd:LADSPA_hermesFilter -ppn:p1,p2,p3,p4 -ppd:1,1,1,1 lad_sc4 = \ -eli:1882,0,40,40,-18,6,6,6,%1,%2 \ -pd:LADSPA_SC4_compressor -ppn:output-amplitude-dB,output-gain-reduction-dB \ -ppd:0,0 -ppt:lo,lo lad_sc4_rg = \ -eli:1882,0,40,40,-18,%1,6,%2,%3,%4 \ -pd:LADSPA_SC4_compressor -ppn:ratio,gain-dB,output-amplitude-dB,output-gain-reduction-dB \ -ppd:6,3,0,0 -ppl:1,-40 -ppu:20,12 -ppt:-,-,lo,lo lad_metronome = -el:sine_fcac,880,1 -eemb:%1,10 -efl:2000 \ -pd:LADSPA_sineosc_metronome -ppn:bpm -ppd:120 -ppl:1 lad_oscillator_test = -eli:1205,%1,0 -ea:%2 \ -pd:LADSPA_Oscillator_test \ -ppn:freq,gain1 \ -ppd:200,100 \ -ppl:1,0 -ppu:1300,1000 \ -ppt:-,- lad_oscillator_stack = -el:analogueOsc,%1,%2 -ea:%4 | \ -el:analogueOsc,%1,%3 -ea:%5 \ -pd:LADSPA_stack_of_analogue_oscillators \ -ppn:freq,osctype1,osctype2,gain1,gain2 \ -ppd:200,0,0,100,100 \ -ppl:1,0,0,0,0 -ppu:1300,3,3,1000,1000 \ -ppt:-,i,i,- # ====== # Other / compatibility presets metronome = -el:sine_fcac,880,1 -eemb:%1,10 -efl:2000 \ -ppn:bpm -ppd:100 -pd:Sineosc_metronome ecasound-2.9.1/ltmain.sh0000755000076400007640000073337712260112130012110 00000000000000# Generated from ltmain.m4sh. # ltmain.sh (GNU libtool) 2.2.6b # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print informational messages (default) # --version print version information # -h, --help print short or long help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . PROGRAM=ltmain.sh PACKAGE=libtool VERSION="2.2.6b Debian-2.2.6b-2" TIMESTAMP="" package_revision=1.3017 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # NLS nuisances: We save the old values to restore during execute mode. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} : ${EGREP="/bin/grep -E"} : ${FGREP="/bin/grep -F"} : ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # Generated shell functions inserted here. # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: # In the unlikely event $progname began with a '-', it would play havoc with # func_echo (imagine progname=-n), so we prepend ./ in that case: func_dirname_and_basename "$progpath" progname=$func_basename_result case $progname in -*) progname=./$progname ;; esac # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname${mode+: }$mode: $*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` done my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "X$my_tmpdir" | $Xsed } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "X$1" | $Xsed \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_version # Echo version message to standard output and exit. func_version () { $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $SED -n '/^# Usage:/,/# -h/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" $ECHO $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help # Echo long help message to standard output and exit. func_help () { $SED -n '/^# Usage:/,/# Report bugs to/ { s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p }' < "$progpath" exit $? } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { func_error "missing argument for $1" exit_cmd=exit } exit_cmd=: # Check that we have a working $ECHO. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then # Yippee, $ECHO works! : else # Restart under the correct shell, and then maybe $ECHO will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # Parse options once, thoroughly. This comes as soon as possible in # the script to make things like `libtool --version' happen quickly. { # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Parse non-mode specific arguments: while test "$#" -gt 0; do opt="$1" shift case $opt in --config) func_config ;; --debug) preserve_args="$preserve_args $opt" func_echo "enabling shell trace mode" opt_debug='set -x' $opt_debug ;; -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break execute_dlfiles="$execute_dlfiles $1" shift ;; --dry-run | -n) opt_dry_run=: ;; --features) func_features ;; --finish) mode="finish" ;; --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break case $1 in # Valid mode arguments: clean) ;; compile) ;; execute) ;; finish) ;; install) ;; link) ;; relink) ;; uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac mode="$1" shift ;; --preserve-dup-deps) opt_duplicate_deps=: ;; --quiet|--silent) preserve_args="$preserve_args $opt" opt_silent=: ;; --verbose| -v) preserve_args="$preserve_args $opt" opt_silent=false ;; --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break preserve_args="$preserve_args $opt $1" func_enable_tag "$1" # tagname is set here shift ;; # Separate optargs to long options: -dlopen=*|--mode=*|--tag=*) func_opt_split "$opt" set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} shift ;; -\?|-h) func_usage ;; --help) opt_help=: ;; --version) func_version ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) nonopt="$opt" break ;; esac done case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_duplicate_deps ;; esac # Having warned about all mis-specified options, bail out if # anything was wrong. $exit_cmd $EXIT_FAILURE } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } ## ----------- ## ## Main. ## ## ----------- ## $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi test -z "$mode" && func_fatal_error "error: you must specify a MODE." # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$mode' for more information." } # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_ltwrapper_scriptname_result="" if func_ltwrapper_executable_p "$1"; then func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" fi } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case "$@ " in " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi removelist="$removelist $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist="$removelist $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir command="$command -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$mode'" ;; esac $ECHO $ECHO "Try \`$progname --help' for more information about other modes." exit $? } # Now that we've collected a possible --mode arg, show help if necessary $opt_help && func_mode_help # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $execute_dlfiles; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_quote_for_eval "$file" args="$args $func_quote_for_eval_result" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" $ECHO "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS $ECHO "X----------------------------------------------------------------------" | $Xsed $ECHO "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done $ECHO $ECHO "If you ever happen to want to link against installed libraries" $ECHO "in a given directory, LIBDIR, you must either use libtool, and" $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" $ECHO "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" $ECHO " during execution" fi if test -n "$runpath_var"; then $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" $ECHO " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $ECHO $ECHO "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" $ECHO "pages." ;; *) $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac $ECHO "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS } test "$mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $ECHO "X$nonopt" | $GREP shtool >/dev/null; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" install_prog="$install_prog$func_quote_for_eval_result" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog="$install_prog $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for progfile in $progfiles; do func_verbose "extracting global C symbols from \`$progfile'" $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" } done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" fi $ECHO >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; *) lt_dlsym_const=const ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ extern $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags="$symtab_cflags $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper_part1 [arg=no] # # Emit the first part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part1 () { func_emit_wrapper_part1_arg1=no if test -n "$1" ; then func_emit_wrapper_part1_arg1=$1 fi $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then ECHO=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then # Yippee, \$ECHO works! : else # Restart under the correct shell, and then maybe \$ECHO will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $ECHO "\ # Find the directory that this script lives in. thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done " } # end: func_emit_wrapper_part1 # func_emit_wrapper_part2 [arg=no] # # Emit the second part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part2 () { func_emit_wrapper_part2_arg1=no if test -n "$1" ; then func_emit_wrapper_part2_arg1=$1 fi $ECHO "\ # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # end: func_emit_wrapper_part2 # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=no if test -n "$1" ; then func_emit_wrapper_arg1=$1 fi # split this up so that func_emit_cwrapperexe_src # can call each part independently. func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" } # func_to_host_path arg # # Convert paths to host format when used with build tools. # Intended for use with "native" mingw (where libtool itself # is running under the msys shell), or in the following cross- # build environments: # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # where wine is equipped with the `winepath' executable. # In the native mingw case, the (msys) shell automatically # converts paths for any non-msys applications it launches, # but that facility isn't available from inside the cwrapper. # Similar accommodations are necessary for $host mingw and # $build cygwin. Calling this function does no harm for other # $host/$build combinations not listed above. # # ARG is the path (on $build) that should be converted to # the proper representation for $host. The result is stored # in $func_to_host_path_result. func_to_host_path () { func_to_host_path_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' case $build in *mingw* ) # actually, msys # awkward: cmd appends spaces to result lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_path_tmp1=`( cmd //c echo "$1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_path_tmp1=`cygpath -w "$1"` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # Unfortunately, winepath does not exit with a non-zero # error code, so we are forced to check the contents of # stdout. On the other hand, if the command is not # found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both # error code of zero AND non-empty stdout, which explains # the odd construction: func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` else # Allow warning below. func_to_host_path_result="" fi ;; esac if test -z "$func_to_host_path_result" ; then func_error "Could not determine host path corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_path_result="$1" fi ;; esac fi } # end: func_to_host_path # func_to_host_pathlist arg # # Convert pathlists to host format when used with build tools. # See func_to_host_path(), above. This function supports the # following $build/$host combinations (but does no harm for # combinations not listed here): # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # # Path separators are also converted from $build format to # $host format. If ARG begins or ends with a path separator # character, it is preserved (but converted to $host format) # on output. # # ARG is a pathlist (on $build) that should be converted to # the proper representation on $host. The result is stored # in $func_to_host_pathlist_result. func_to_host_pathlist () { func_to_host_pathlist_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_to_host_pathlist_tmp2="$1" # Once set for this call, this variable should not be # reassigned. It is used in tha fallback case. func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e 's|^:*||' -e 's|:*$||'` case $build in *mingw* ) # Actually, msys. # Awkward: cmd appends spaces to result. lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # unfortunately, winepath doesn't convert pathlists func_to_host_pathlist_result="" func_to_host_pathlist_oldIFS=$IFS IFS=: for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do IFS=$func_to_host_pathlist_oldIFS if test -n "$func_to_host_pathlist_f" ; then func_to_host_path "$func_to_host_pathlist_f" if test -n "$func_to_host_path_result" ; then if test -z "$func_to_host_pathlist_result" ; then func_to_host_pathlist_result="$func_to_host_path_result" else func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" fi fi fi IFS=: done IFS=$func_to_host_pathlist_oldIFS ;; esac if test -z "$func_to_host_pathlist_result" ; then func_error "Could not determine the host path(s) corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This may break if $1 contains DOS-style drive # specifications. The fix is not to complicate the expression # below, but for the user to provide a working wine installation # with winepath so that path translation in the cross-to-mingw # case works properly. lt_replace_pathsep_nix_to_dos="s|:|;|g" func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_replace_pathsep_nix_to_dos"` fi # Now, add the leading and trailing path separators back case "$1" in :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" ;; esac case "$1" in *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" ;; esac ;; esac fi } # end: func_to_host_pathlist # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include # define setmode _setmode #else # include # include # ifdef __CYGWIN__ # include # define HAVE_SETENV # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif # endif #endif #include #include #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif #ifdef _MSC_VER # define S_IXUSR _S_IEXEC # define stat _stat # ifndef _INTPTR_T_DEFINED # define intptr_t int # endif #endif #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifdef __CYGWIN__ # define FOPEN_WB "wb" #endif #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #undef LTWRAPPER_DEBUGPRINTF #if defined DEBUGWRAPPER # define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args static void ltwrapper_debugprintf (const char *fmt, ...) { va_list args; va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } #else # define LTWRAPPER_DEBUGPRINTF(args) #endif const char *program_name = NULL; void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_fatal (const char *message, ...); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_opt_process_env_set (const char *arg); void lt_opt_process_env_prepend (const char *arg); void lt_opt_process_env_append (const char *arg); int lt_split_name_value (const char *arg, char** name, char** value); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); static const char *script_text_part1 = EOF func_emit_wrapper_part1 yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ "/' -e 's/$/\\n"/' echo ";" cat <"))); for (i = 0; i < newargc; i++) { LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", tmp_pathspec)); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { char *errstr = strerror (errno); lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal ("Could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } void lt_setenv (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", (name ? name : ""), (value ? value : ""))); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } int lt_split_name_value (const char *arg, char** name, char** value) { const char *p; int len; if (!arg || !*arg) return 1; p = strchr (arg, (int)'='); if (!p) return 1; *value = xstrdup (++p); len = strlen (arg) - strlen (*value); *name = XMALLOC (char, len); strncpy (*name, arg, len-1); (*name)[len - 1] = '\0'; return 0; } void lt_opt_process_env_set (const char *arg) { char *name = NULL; char *value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); } lt_setenv (name, value); XFREE (name); XFREE (value); } void lt_opt_process_env_prepend (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); } new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_opt_process_env_append (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); } new_value = lt_extend_str (getenv (name), value, 1); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_update_exe_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF } # end: func_emit_cwrapperexe_src # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) deplibs="$deplibs $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs="$weak_libs $arg" prev= continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname '-L' '' "$arg" dir=$func_stripname_result if test -z "$dir"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" linker_flags="$linker_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -F/path gives path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_duplicate_deps ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= case $lib in *.la) func_source "$lib" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs="$deplibs $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" dir=$func_stripname_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $ECHO $ECHO "*** Warning: Trying to link with static lib archive $deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because the file extensions .$libext of this argument makes me believe" $ECHO "*** that it is just a static archive that I should not use here." else $ECHO $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) temp_rpath="$temp_rpath$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs="$notinst_deplibs $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then $ECHO if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $ECHO $ECHO "*** And there doesn't seem to be a static archive available" $ECHO "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $ECHO $ECHO "*** Warning: This system can not link to static lib archive $lib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $ECHO "*** But as you try to build a module library, libtool will still create " $ECHO "*** a static module, that should work as long as the dlopening application" $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_dirname "$deplib" "" "." dir="$func_dirname_result" # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else $ECHO $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs="$libobjs $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` done fi if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | $GREP . >/dev/null; then $ECHO if test "X$deplibs_check_method" = "Xnone"; then $ECHO "*** Warning: inter-library dependencies are not supported in this platform." else $ECHO "*** Warning: inter-library dependencies are not known to be supported." fi $ECHO "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $ECHO $ECHO "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" $ECHO "*** a static module, that should work as long as the dlopening" $ECHO "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $ECHO "*** The inter-library dependencies that have been dropped here will be" $ECHO "*** automatically added whenever a program is linked with this library" $ECHO "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $ECHO $ECHO "*** Since this library must not contain undefined symbols," $ECHO "*** because either the platform does not support them or" $ECHO "*** it was explicitly requested with -no-undefined," $ECHO "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" delfiles="$delfiles $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" func_len " $cmd" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$ECHO "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" $ECHO 'INPUT (' > $output for obj in $save_libobjs do $ECHO "$obj" >> $output done $ECHO ')' >> $output delfiles="$delfiles $output" elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do $ECHO "$obj" >> $output done delfiles="$delfiles $output" output=$firstobj\"$file_list_spec$output\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=$obj func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles="$delfiles $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *cegcc) # Disable wrappers for cegcc, we are cross compiling anyway. wrappers_required=no ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $ECHO for shipping. if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs="$oldobjs $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles oldobjs="$oldobjs $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else $ECHO "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlfiles="$newdlfiles $libdir/$name" ;; *) newdlfiles="$newdlfiles $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlprefiles="$newdlprefiles $libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$mode" = link || test "$mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) RM="$RM $arg"; rmforce=yes ;; -*) RM="$RM $arg" ;; *) files="$files $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then objdir="$origobjdir" else objdir="$dir/$origobjdir" fi func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result rmfiles="$rmfiles $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$mode" = uninstall || test "$mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 ecasound-2.9.1/COPYING.GPL0000644000076400007640000004311010664032032011724 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ecasound-2.9.1/pyecasound/0000755000076400007640000000000012261520737012514 500000000000000ecasound-2.9.1/pyecasound/test1_stresstest.py0000755000076400007640000000424210762576773016375 00000000000000#!/usr/bin/env python # ----------------------------------------------------------------------- # Runs a stress test using the pyeca interface # # Copyright (C) 2003 Kai Vehmanen (kai.vehmanen@wakkanet.fi) # Licensed under GPL. See the file 'COPYING' for more information. # ----------------------------------------------------------------------- import time import sys import os # --- # select pyeca implementation to use # test the default implementation from pyeca import * # test the native Python implementation #from ecacontrol import * # test the C implementation #from pyecasound import * # --- # configuration variables # run for how many seconds runlen = 5 # debug level (0, 1, 2, ...) debuglevel = 1 if os.path.isfile('../ecasound/ecasound_debug'): os.environ['ECASOUND'] = '../ecasound/ecasound_debug' if os.path.isfile('../ecasound/ecasound'): os.environ['ECASOUND'] = '../ecasound/ecasound' # if above tests fail, the default ecasound binary # will be used # main program e = ECA_CONTROL_INTERFACE(debuglevel) result = 0 e.command("cs-add play_chainsetup") e.command("c-add 1st_chain") e.command("ai-add rtnull") e.command("ao-add null") e.command("cop-add -ezx:1,0.0") e.command("ctrl-add -kos:2,-1,1,300,0") e.command("cop-add -efl:300") e.command("cop-add -evp") e.command("cop-select 3") e.command("copp-select 1") e.command("cs-connect") e.command("start") total_cmds = 0 while 1 and e.last_type() != 'e': e.command("get-position") curpos = e.last_float() if curpos > runlen or e.last_type() == 'e': break e.command("copp-get") if debuglevel == 2: #print curpos, e.last_float() #if curpos == None: # curpos = 0.0 sys.stderr.write('%6.2f %6.4f\r' % (curpos,e.last_float())) else: if debuglevel == 1: sys.stderr.write('.') total_cmds = total_cmds + 2 if e.last_type() == 'e': print 'Ended to error:', e.last_error() result = -1 else: e.command("stop") e.command("cs-disconnect") if debuglevel == 2: sys.stderr.write('\nprocessing speed: ' + str(total_cmds / runlen) + ' cmds/second.\n') if debuglevel > 0: sys.stderr.write('\n') sys.exit(result) ecasound-2.9.1/pyecasound/Makefile.in0000644000076400007640000005375612261511325014512 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/pyecasound/Makefile.am # Description: Python implmentation of the Ecasound Control Interface # License: LGPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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 = pyecasound DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ChangeLog TODO ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = LTLIBRARIES = $(noinst_LTLIBRARIES) libpyecasound_la_LIBADD = am_libpyecasound_la_OBJECTS = pyecasound.lo libpyecasound_la_OBJECTS = $(am_libpyecasound_la_OBJECTS) @ECA_AM_PYECASOUND_CEXT_TRUE@am_libpyecasound_la_rpath = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libpyecasound_la_SOURCES) DIST_SOURCES = $(libpyecasound_la_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign EXTRA_DIST = eci.py pyeca.py ecacontrol.py \ test1_stresstest.py \ test2_stresstest.py @ECA_AM_DEBUG_MODE_FALSE@ecasoundc_libs = ${top_builddir}/libecasoundc/libecasoundc.la # ---------------------------------------------------------------------- # defines # ---------------------------------------------------------------------- @ECA_AM_DEBUG_MODE_TRUE@ecasoundc_libs = ${top_builddir}/libecasoundc/libecasoundc_debug.la @ECA_AM_PYECASOUND_INSTALL_TRUE@pyecasound_install_list1 = $(srcdir)/eci.py \ @ECA_AM_PYECASOUND_INSTALL_TRUE@ $(srcdir)/pyeca.py \ @ECA_AM_PYECASOUND_INSTALL_TRUE@ $(srcdir)/ecacontrol.py @ECA_AM_PYECASOUND_INSTALL_TRUE@pyecasound_uninstall_list1 = $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/eci.py \ @ECA_AM_PYECASOUND_INSTALL_TRUE@ $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/pyeca.py \ @ECA_AM_PYECASOUND_INSTALL_TRUE@ $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/ecacontrol.py @ECA_AM_PYECASOUND_CEXT_TRUE@pyecasound_install_list2 = pyecasound.so @ECA_AM_PYECASOUND_CEXT_TRUE@pyecasound_uninstall_list2 = $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/pyecasound.so INCLUDES = -I$(srcdir) \ -I$(top_srcdir)/libecasoundc \ -I$(ECA_S_PYTHON_INCLUDES) @ECA_AM_PYECASOUND_INSTALL_TRUE@TESTS = test1_stresstest.py \ @ECA_AM_PYECASOUND_INSTALL_TRUE@ test2_stresstest.py # ---------------------------------------------------------------------- # header files # ---------------------------------------------------------------------- pyecasound_includes = pyecasound.h noinst_HEADERS = $(pyecasound_includes) # ---------------------------------------------------------------------- # source files # ---------------------------------------------------------------------- @ECA_AM_PYECASOUND_CEXT_TRUE@noinst_LTLIBRARIES = libpyecasound.la libpyecasound_la_SOURCES = pyecasound.c # libtool options to build for dlopen libpyecasound_la_LDFLAGS = -avoid-version -export-dynamic # ---------------------------------------------------------------------- # hooks # ---------------------------------------------------------------------- @ECA_AM_PYECASOUND_CEXT_TRUE@CLEANFILES = pyecasound.so all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign pyecasound/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign pyecasound/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_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 libpyecasound.la: $(libpyecasound_la_OBJECTS) $(libpyecasound_la_DEPENDENCIES) $(LINK) $(am_libpyecasound_la_rpath) $(libpyecasound_la_LDFLAGS) $(libpyecasound_la_OBJECTS) $(libpyecasound_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyecasound.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @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@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @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@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @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 $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: 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; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list='$(TESTS)'; \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ ;; \ *) \ echo "PASS: $$tst"; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ *) \ failed=`expr $$failed + 1`; \ echo "FAIL: $$tst"; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ echo "SKIP: $$tst"; \ fi; \ done; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="All $$all tests passed"; \ else \ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all tests failed"; \ else \ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ skipped="($$skip tests were not run)"; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ echo "$$dashes"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: 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: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-info: install-info-am install-man: 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-info-am uninstall-local .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES 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-exec install-exec-am install-exec-hook \ install-info install-info-am install-man 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-info-am uninstall-local @ECA_AM_PYECASOUND_CEXT_TRUE@all: pyecasound.so @ECA_AM_PYECASOUND_CEXT_TRUE@pyecasound.so: pyecasound.lo @ECA_AM_PYECASOUND_CEXT_TRUE@ $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) ${libpyecasound_la_LDFLAGS} -shared -nostartfiles -o pyecasound.so pyecasound.lo $(ecasoundc_libs) @ECA_AM_PYECASOUND_INSTALL_TRUE@install-exec-hook: $(pyecasound_install_list1) $(pyecasound_install_list2) @ECA_AM_PYECASOUND_INSTALL_TRUE@ $(INSTALL) -d $(DESTDIR)$(ECA_S_PYTHON_DLMODULES) @ECA_AM_PYECASOUND_INSTALL_TRUE@ $(INSTALL) $(pyecasound_install_list1) $(pyecasound_install_list2) $(DESTDIR)$(ECA_S_PYTHON_DLMODULES) @ECA_AM_PYECASOUND_INSTALL_FALSE@install-exec-hook: @ECA_AM_PYECASOUND_INSTALL_TRUE@uninstall-local: @ECA_AM_PYECASOUND_INSTALL_TRUE@ rm -f $(pyecasound_uninstall_list1) $(pyecasound_uninstall_list2) @ECA_AM_PYECASOUND_INSTALL_TRUE@ rmdir $(DESTDIR)$(ECA_S_PYTHON_DLMODULES) || echo "Skipping non-empty directory" @ECA_AM_PYECASOUND_INSTALL_FALSE@uninstall-local: # 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: ecasound-2.9.1/pyecasound/test2_stresstest.py0000755000076400007640000000413010664032032016342 00000000000000#!/usr/bin/env python # ----------------------------------------------------------------------- # A second stress test for the pyeca interface # # Copyright (C) 2003 Kai Vehmanen (kai.vehmanen@wakkanet.fi) # Licensed under GPL. See the file 'COPYING' for more information. # ----------------------------------------------------------------------- import time import sys import os # --- # select pyeca implementation to use # test the default implementation from pyeca import * # test the native Python implementation #from ecacontrol import * # test the C implementation #from pyecasound import * # --- # configuration variables # run for how many seconds runlen = 5 # debug level (0, 1, 2, ...) debuglevel = 1 if os.path.isfile('../ecasound/ecasound_debug'): os.environ['ECASOUND'] = '../ecasound/ecasound_debug' if os.path.isfile('../ecasound/ecasound'): os.environ['ECASOUND'] = '../ecasound/ecasound' # if above tests fail, the default ecasound binary # will be used # main program e = ECA_CONTROL_INTERFACE(debuglevel) result = 0 e.command("cs-add play_chainsetup") e.command("c-add 1st_chain") e.command("ai-add rtnull") e.command("ao-add null") e.command("cop-add -ezx:1,0.0") e.command("ctrl-add -kos:2,-1,1,300,0") e.command("cop-add -efl:300") e.command("cop-add -evp") e.command("cop-select 3") e.command("copp-select 1") e.command("cs-connect") e.command("start") total_cmds = 0 while 1 and e.last_type() != 'e': e.command("get-position") curpos = e.last_float() if curpos > runlen or e.last_type() == 'e': break if debuglevel > 0: sys.stderr.write('.') # some commands that return a lot # of return data e.command("cop-register") e.command("aio-register") e.command("int-cmd-list") total_cmds = total_cmds + 4 if e.last_type() == 'e': print 'Ended to error:', e.last_error() result = -1 else: e.command("stop") e.command("cs-disconnect") if debuglevel == 2: sys.stderr.write('\nprocessing speed: ' + str(total_cmds / runlen) + ' cmds/second.\n') if debuglevel > 0: sys.stderr.write('\n') sys.exit(result) ecasound-2.9.1/pyecasound/pyeca.py0000644000076400007640000000271711742614261014115 00000000000000"""Wrapper module which loads pyecasound (python module for Ecasound Control Interface). To use C version of pyecasound, you have to enable global share of symbols. Quote from python docs: --cut-- setdlopenflags(n) Set the flags used by the interpreter for dlopen() calls, such as when the interpreter loads extension modules. Among other things, this will enable a lazy resolving of symbols when importing a module, if called as sys.setdlopenflags(0). To share symbols across extension modules, call as sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL). Symbolic names for the flag modules can be either found in the dl module, or in the DLFCN module. If DLFCN is not available, it can be generated from /usr/include/dlfcn.h using the h2py script. Availability: Unix. New in version 2.2. --cut-- Otherwise falling back to native python version (possibly slower float-handling). """ import sys if hasattr(sys, 'version_info'): # attribute available from python 2.0 if sys.version_info[1] >=2: try: import dl sys.setdlopenflags(dl.RTLD_LAZY|dl.RTLD_GLOBAL) from pyecasound import * except: pass try: import DLFCN sys.setdlopenflags(DLFCN.RTLD_LAZY|DLFCN.RTLD_GLOBAL) from pyecasound import * except: from ecacontrol import * else: from ecacontrol import * else: from ecacontrol import * ecasound-2.9.1/pyecasound/ecacontrol.py0000755000076400007640000002303411742630427015145 00000000000000"""Native python ECI (ecasound control interface) implementation Can be used to replace the C implementation 'pyecasound.so'. """ authors="""Kai Vehmanen, Eric S. Tiedemann and Janne Halttunen.""" import sys if sys.hexversion < 0x02040000: print >>sys.stderr, "ERROR: Python 2.4 or newer is required by ecacontrol.py" sys.exit(-1) import re import subprocess from select import select import os import signal import string import time _ecasound=[] type_override={} eci_str_sync_lost= 'Connection to the processing engine was lost.\n' class ECA_CONTROL_INTERFACE: def __init__(I, verbose=1): """Instantiate new ECI session verbose: set this false to get rid of startup-messages """ I.verbose=verbose I._cmd='' I._type='' I._timeout=5 # in seconds I._resp={} I.initialize() def __call__(I, cmd, f=None): if f != None: val=I.command_float_arg(cmd, f) else: cmds=string.split(cmd, '\n') if len(cmds) > 1: v=[] for c in cmds: c=string.strip(c) if c: v.append(I.command(c)) if I.error(): raise Exception(v[-1]) val=string.join(map(str, v), '\n') else: val=I.command(cmd) if I.error(): raise Exception(val) return val def _readline(I): return string.strip(I.eca.stdout.readline()) def _read_eca(I): buffer='' while select([I.eca.stdout.fileno()],[],[I.eca.stdout.fileno()],0.01)[0]: buffer=buffer+I.eca.stdout.read(1) return buffer def _parse_response(I): tm=''; r=(); failcount=0 if I.verbose > 2: print 'c=' + I._cmd while 1: s=I._read_eca() #print 'read s=' + s if s: if I.verbose > 3: print 's=<', s, '>' else: failcount = failcount + 1 if failcount < I._timeout * 10: #if failcount < 0: time.sleep(0.01) continue else: print 'timeout: s=<' + s, '>, cmd=' + I._cmd + '.' r=('e', eci_str_sync_lost) break tm=tm+s m=expand_eiam_response(tm) r=parse_eiam_response(tm, m) if r: if I.verbose > 2: print 'r=', r break if not r: I._resp['e']='-' I._type='e' r=None else: I._type=r[0] if I._cmd in type_override.keys(): I._type=type_override[I._cmd] if I._type == 'S': I._resp[I._type]=string.split(r[1], ',') elif I._type == 'Sn': I._resp[I._type]=string.split(r[1], '\n') elif I._type == 'f': I._resp[I._type]=float(r[1]) elif I._type == 'i': I._resp[I._type]=int(r[1]) elif I._type == 'li': I._resp[I._type]=long(r[1]) else: I._resp[I._type]=r[1] return I._resp[I._type] def initialize(I): """Reserve resources""" ## if _ecasound is not None: ## I.cleanup() # exit previous ecasound session cleanly global _ecasound try: ecasound_binary = os.environ['ECASOUND'] except KeyError: ecasound_binary = '' if ecasound_binary == '': ecasound_binary = 'ecasound' p = subprocess.Popen(ecasound_binary + ' -c -d:256 2>/dev/null', shell=True, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True) _ecasound.append(p) I.eca=_ecasound[-1] lines='' lines=lines+I._readline()+'\n' version=I._readline() s=string.find(version, 'ecasound v') if float(version[s+10:s+13])>=2.2: lines=lines+version+'\n' else: raise RuntimeError('ecasound version 2.2 required!') lines=lines+I._readline()+'\n' if I.verbose: print lines print __doc__ print 'by', authors print '\n(to get rid of this message, pass zero to instance init)' I.command('int-output-mode-wellformed') #I._read_eca() #I.command('debug 256') def cleanup(I): """Free all reserved resources""" I.eca.stdin.write('quit\n') os.kill(I.eca.pid, signal.SIGTERM) signal.signal(signal.SIGALRM, handler) signal.alarm(2) try: return I.eca.wait() except: pass signal.alarm(0) os.kill(I.eca.pid, signal.SIGKILL) def command(I,cmd): """Issue an EIAM command""" cmd=string.strip(cmd) if cmd: I._cmd=cmd I.eca.stdin.write(cmd+'\n') return I._parse_response() def command_float_arg(I,cmd,f=None): """Issue an EIAM command This function can be used instead of command(string), if the command in question requires exactly one numerical parameter.""" cmd=string.strip(cmd) if cmd: I._cmd=cmd if f: I.eca.stdin.write('%s %f\n' % (cmd,f)) else: I.eca.stdin.write(cmd+'\n') return I._parse_response() def error(I): """Return true if error has occured during the execution of last EIAM command""" if I._type=='e': return 1 def last_error(I): """Return a string describing the last error""" if I.error(): return I._resp.get('e') else: return '' def last_float(I): """Return the last floating-point return value""" return I._resp.get('f') def last_integer(I): """Return the last integer return value This function is also used to return boolean values.""" return I._resp.get('i') def last_long_integer(I): """Return the last long integer return value Long integers are used to pass values like 'length_in_samples' and 'length_in_bytes'. It's implementation specific whether there's any real difference between integers and long integers.""" return I._resp.get('li') def last_string(I): """Return the last string return value""" return I._resp.get('s') def last_string_list(I): """Return the last collection of strings (one or more strings)""" return I._resp.get('S') def last_type(I): return I._type def current_event(I): """** not implemented **""" pass def events_available(I): """** not implemented **""" pass def next_event(I): """** not implemented **""" pass def handler(*args): print 'AARGH!' raise Exception, 'killing me not so softly' expand=re.compile('256 ([0-9]{1,5}) (.+)\r\n(.*)\r\n\r\n.*', re.MULTILINE | re.S) def expand_eiam_response(st): """Checks wheter 'str' is a valid EIAM response. @return Regex match object. """ m = expand.search(st) return m parse=re.compile('256 ([0-9]{1,5}) (.+)\r\n(.*)', re.MULTILINE | re.S) def parse_eiam_response(st, m=None): """Parses a valid EIAM response. @param m Valid regex match object. @param str The whole EIAM response. @return tuple of return value type and value """ if not m: m = parse.search(st) if not m: return () if m and len(m.groups()) == 0: #print "(pyeca) Matching groups failed: %s" % str(m.groups()) return ('e','Matching groups failed') if m and len(m.groups()) == 3: #print 'received=', len(m.group(3)), ', expected=', m.group(1) if int(m.group(1)) != len(m.group(3)): print '(pyeca) Response length error. Received ', len(m.group(3)), ', expected for ', m.group(1), '.' #print 'g=', m.group(3) return ('e', 'Response length error.') if m: return (m.group(2), m.group(3)) return ('e','') class base: def __init__(I, eci, cmd): I.eci=eci I.cmd=string.replace(cmd, '_', '-') def __call__(I): return I.eci(I.cmd) class string_argument(base): def __call__(I, s): return I.eci('%s %s' % (I.cmd,s)) class EIAM: def __init__(I, verbose=0): I._eci=ECA_CONTROL_INTERFACE(verbose) I._cmds=I._eci('int-cmd-list') for c in I._cmds: c=string.replace(c, '-', '_') if string.count(c, 'add') \ or string.count(c, 'select'): I.__dict__[c]=string_argument(I._eci,c) else: I.__dict__[c]=base(I._eci,c) def main(): e=ECA_CONTROL_INTERFACE() print e.command('c-add huppaa') print e.command('c-list') print e(""" c-list c-status """) print e.cleanup() if __name__ == '__main__': main() ecasound-2.9.1/pyecasound/pyecasound.h0000644000076400007640000000024510664032032014747 00000000000000#ifndef INCLUDED_PYECASOUND_H #define INCLUDED_PYECASOUND_H #ifdef __cplusplus extern "C" { #endif void initpyecasound(void); #ifdef __cplusplus } #endif #endif ecasound-2.9.1/pyecasound/ChangeLog0000644000076400007640000000136110664032032014176 000000000000002003-03-18 Kai Vehmanen * ecacontrol.py: support for ECASOUND environment variable 2003-03-11 Janne Halttunen * python module name change from ecanative to ecacontrol * support for multiple functional instances of ECI class * disabled curses output from ecasound engine * added check for ecasound version number 2003-02-22 Janne Halttunen * native python ECI implementation 2001-04-27 Kai Vehmanen * library version 0:0:0 frozen 2000-12-06 Kai Vehmanen * development started; libtool version number 0:0:0 ----------------------------------------------------------------------- ecasound-2.9.1/pyecasound/Makefile.am0000644000076400007640000000570511172655420014475 00000000000000# ---------------------------------------------------------------------- # File: ecasound/pyecasound/Makefile.am # Description: Python implmentation of the Ecasound Control Interface # License: LGPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- AUTOMAKE_OPTIONS = foreign EXTRA_DIST = eci.py pyeca.py ecacontrol.py \ test1_stresstest.py \ test2_stresstest.py # ---------------------------------------------------------------------- # defines # ---------------------------------------------------------------------- if ECA_AM_DEBUG_MODE ecasoundc_libs = ${top_builddir}/libecasoundc/libecasoundc_debug.la else ecasoundc_libs = ${top_builddir}/libecasoundc/libecasoundc.la endif if ECA_AM_PYECASOUND_INSTALL pyecasound_install_list1 = $(srcdir)/eci.py \ $(srcdir)/pyeca.py \ $(srcdir)/ecacontrol.py pyecasound_uninstall_list1 = $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/eci.py \ $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/pyeca.py \ $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/ecacontrol.py endif if ECA_AM_PYECASOUND_CEXT pyecasound_install_list2 = pyecasound.so pyecasound_uninstall_list2 = $(DESTDIR)$(ECA_S_PYTHON_DLMODULES)/pyecasound.so endif INCLUDES = -I$(srcdir) \ -I$(top_srcdir)/libecasoundc \ -I$(ECA_S_PYTHON_INCLUDES) if ECA_AM_PYECASOUND_INSTALL TESTS = test1_stresstest.py \ test2_stresstest.py endif # ---------------------------------------------------------------------- # header files # ---------------------------------------------------------------------- pyecasound_includes = pyecasound.h noinst_HEADERS = $(pyecasound_includes) # ---------------------------------------------------------------------- # source files # ---------------------------------------------------------------------- if ECA_AM_PYECASOUND_CEXT noinst_LTLIBRARIES = libpyecasound.la endif libpyecasound_la_SOURCES = pyecasound.c # libtool options to build for dlopen libpyecasound_la_LDFLAGS = -avoid-version -export-dynamic if ECA_AM_PYECASOUND_CEXT all: pyecasound.so pyecasound.so: pyecasound.lo $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) ${libpyecasound_la_LDFLAGS} -shared -nostartfiles -o pyecasound.so pyecasound.lo $(ecasoundc_libs) endif # ---------------------------------------------------------------------- # hooks # ---------------------------------------------------------------------- if ECA_AM_PYECASOUND_CEXT CLEANFILES=pyecasound.so endif if ECA_AM_PYECASOUND_INSTALL install-exec-hook: $(pyecasound_install_list1) $(pyecasound_install_list2) $(INSTALL) -d $(DESTDIR)$(ECA_S_PYTHON_DLMODULES) $(INSTALL) $(pyecasound_install_list1) $(pyecasound_install_list2) $(DESTDIR)$(ECA_S_PYTHON_DLMODULES) else install-exec-hook: endif if ECA_AM_PYECASOUND_INSTALL uninstall-local: rm -f $(pyecasound_uninstall_list1) $(pyecasound_uninstall_list2) rmdir $(DESTDIR)$(ECA_S_PYTHON_DLMODULES) || echo "Skipping non-empty directory" else uninstall-local: endif ecasound-2.9.1/pyecasound/TODO0000644000076400007640000000020410664032032013107 00000000000000------------------- * pyecasound TODO * ------------------- - finish eiam-class, in which eiam commands are seen as python-methods ecasound-2.9.1/pyecasound/eci.py0000644000076400007640000000550610664032032013543 00000000000000""" # eci.ECI -- A higher-level interface to pyeca. # Copyright 2001 Eric S. Tiedemann (est@hyperreal.org) # GPLed some updates by Janne Halttunen """ import pyeca as _pyeca import types as _types class ECIError(Exception): def __init__(self, what): Exception.__init__(self, what) self.what = what def __str__(self): return '' % self.what class ECI: """An ECI is and ECA Control Interface object. It can be called with ECI command strings (and an optional float value) as arguments. A list or tuple of command strings is also accepted and commands can be separated by newlines within a single string. The value of a command (or of the last command in a sequence) if returned as a value of the appropriate Python type (possibly None). On errors, an ECIException is raised that has a `what' member with the exception message. These exceptions also stringify prettily. """ def __init__(self, *args): self.e = apply(_pyeca.ECA_CONTROL_INTERFACE, args) def __call__(self, cmd, f=None): if f != None: self.e.command_float_arg(cmd, f) else: if type(cmd) == _types.ListType or type(cmd) == _types.TupleType: v = None for c in cmd: v = self(c) return v else: cmds = cmd.split('\n') if len(cmds) > 1: v = None for c in cmds: v = self(c) return v else: self.e.command(cmd) t = self.e.last_type() if not t or t == '-': return None elif t == 'S': return self.e.last_string_list() elif t == 's': return self.e.last_string() elif t == 'f': return self.e.last_float() elif t == 'i': return self.e.last_integer() elif t == 'li': return self.e.last_long_integer() elif t == 'e' or self.e.error(): raise ECIError, '%s: %s' % (self.e.last_error(), cmd) else: raise ECIError, "unknown return type '%s'!" % t if __name__ == '__main__': import time, sys file = sys.argv[1] e = ECI() # uncomment to raise an error :) #e('foo') e(""" cs-add play_chainsetup c-add 1st_chain ai-add %s ao-add /dev/dsp cop-add -efl:100 cop-select 1 copp-select 1 cs-connect start""" % file) cutoff_inc = 500.0 while 1: time.sleep(1) if e("engine-status") != "running" or e("get-position") > 15: break e("copp-set", cutoff_inc + e("copp-get")) e("""stop cs-disconnect""") print "Chain operator status: ", e("cop-status") ecasound-2.9.1/pyecasound/pyecasound.c0000644000076400007640000001413510762576640014766 00000000000000/** * @file pyecasound.c Python interface to the ecasound control interface */ // ------------------------------------------------------------------------ // pyecasound.cpp: Python interface to the ecasound control interface // Copyright (C) 2000-2002,2008 Kai Vehmanen // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 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 #include #include "pyecasound.h" typedef struct { PyObject_HEAD eci_handle_t eci; } pyeca_control_t; // staticforward PyTypeObject pyeca_control_type; static void pyeca_control_del(PyObject *self, PyObject *args); static PyObject* pyeca_getattr(PyObject *self, char *name); // ********************************************************************/ static PyObject * pyeca_command(PyObject* self, PyObject *args) { char *str; pyeca_control_t *selfp; if (!PyArg_ParseTuple(args, "s", &str)) return NULL; selfp = (pyeca_control_t*) self; eci_command_r(selfp->eci, str); return Py_BuildValue(""); } static PyObject * pyeca_command_float_arg(PyObject* self, PyObject *args) { char *str; double v; pyeca_control_t *selfp; if (!PyArg_ParseTuple(args, "sd", &str, &v)) return NULL; selfp = (pyeca_control_t*) self; eci_command_float_arg_r(selfp->eci, str, v); return Py_BuildValue(""); } static PyObject * pyeca_last_string_list(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; int count = eci_last_string_list_count_r(selfp->eci); int n; PyObject *list = Py_BuildValue("[]"); for(n = 0; n < count; n++) { PyList_Append(list, Py_BuildValue("s", eci_last_string_list_item_r(selfp->eci, n))); } return(list); } static PyObject * pyeca_last_string(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; return Py_BuildValue("s", eci_last_string_r(selfp->eci)); } static PyObject * pyeca_last_float(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; return Py_BuildValue("d", eci_last_float_r(selfp->eci)); } static PyObject * pyeca_last_integer(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; return Py_BuildValue("i", eci_last_integer_r(selfp->eci)); } static PyObject * pyeca_last_long_integer(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; return Py_BuildValue("l", eci_last_long_integer_r(selfp->eci)); } static PyObject * pyeca_last_error(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; return Py_BuildValue("s", eci_last_error_r(selfp->eci)); } static PyObject * pyeca_error(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; int i = eci_error_r(selfp->eci); return Py_BuildValue("i", i); } static PyObject * pyeca_last_type(PyObject* self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; return Py_BuildValue("s", eci_last_type_r(selfp->eci)); } static PyObject * pyeca_events_available(PyObject* self, PyObject *args) { return Py_BuildValue("i", 0); } static PyObject * pyeca_next_event(PyObject* self, PyObject *args) { return Py_BuildValue(""); } static PyObject * pyeca_current_event(PyObject* self, PyObject *args) { return Py_BuildValue(""); } static struct PyMethodDef pyeca_control_methods[] = { { "command", pyeca_command, METH_VARARGS}, { "command_float_arg", pyeca_command_float_arg, METH_VARARGS}, { "last_string_list", pyeca_last_string_list, METH_VARARGS}, { "last_string", pyeca_last_string, METH_VARARGS}, { "last_float", pyeca_last_float, METH_VARARGS}, { "last_integer", pyeca_last_integer, METH_VARARGS}, { "last_long_integer", pyeca_last_long_integer, METH_VARARGS}, { "last_error", pyeca_last_error, METH_VARARGS}, { "last_type", pyeca_last_type, METH_VARARGS}, { "error", pyeca_error, METH_VARARGS}, { "events_available", pyeca_events_available, METH_VARARGS}, { "next_event", pyeca_next_event, METH_VARARGS}, { "current_event", pyeca_current_event, METH_VARARGS}, { NULL, NULL } }; // ********************************************************************/ static PyTypeObject pyeca_control_type = { PyObject_HEAD_INIT(&PyType_Type) 0, "ECA_CONTROL_INTERFACE", sizeof (pyeca_control_t), 0, (destructor) pyeca_control_del, 0, (getattrfunc) pyeca_getattr, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // ********************************************************************/ static PyObject *pyeca_control_new(PyObject *self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) PyObject_New(pyeca_control_t, &pyeca_control_type); selfp->eci = eci_init_r(); self = (PyObject *) selfp; return(self); } static PyObject* pyeca_getattr(PyObject *self, char *name) { return Py_FindMethod(pyeca_control_methods, (PyObject*) self, name); } static void pyeca_control_del(PyObject *self, PyObject *args) { pyeca_control_t *selfp = (pyeca_control_t*) self; eci_cleanup_r(selfp->eci); PyObject_Del(self); } static PyMethodDef pyecamethods[] = { {"ECA_CONTROL_INTERFACE", pyeca_control_new, METH_VARARGS }, {NULL, NULL } }; void initpyecasound(void) { Py_InitModule("pyecasound", pyecamethods); } ecasound-2.9.1/acinclude.m40000644000076400007640000001256311547157307012467 00000000000000dnl --- dnl acinclude.m4 for ecasound dnl --- ## ------------------------------------------------------------------------ ## Check for JACK support ## ## defines: ECA_AM_COMPILE_JACK, ECA_S_JACK_LIBS, ECA_S_JACK_INCLUDES, ## ECA_COMPILE_JACK, ECA_JACK_TRANSPORT_API, ECA_JACK_FEATSET ## ------------------------------------------------------------------------ AC_DEFUN([AC_CHECK_JACK], [ AC_CHECK_HEADER(jack/jack.h,jack_support=yes,jack_support=no) AC_ARG_WITH(jack, [ --with-jack=DIR Compile against JACK installed in DIR], [ ECA_S_JACK_LIBS="-L${withval}/lib" ECA_S_JACK_INCLUDES="-I${withval}/include" jack_support=yes ]) AC_ARG_ENABLE(jack, [ --enable-jack Enable JACK support (default=yes, if found)], [ case "$enableval" in y | yes) AC_MSG_RESULT(yes) jack_support=yes ;; n | no) AC_MSG_RESULT(no) jack_support=no ;; *) AC_MSG_ERROR([Invalid parameter value for --enable-jack: $enableval]) ;; esac ]) AM_CONDITIONAL(ECA_AM_COMPILE_JACK, test x$jack_support = xyes) if test x$jack_support = xyes; then AC_DEFINE([ECA_COMPILE_JACK], 1, [enable JACK support]) ECA_S_JACK_LIBS="${ECA_S_JACK_LIBS} -ljack" case "$host" in *darwin*) AM_LDFLAGS="$AM_LDFLAGS -framework CoreAudio" ;; esac fi AC_LANG_C old_cppflags=$CPPFLAGS old_ldflags=$LDFLAGS old_INCLUDES=$INCLUDES CPPFLAGS="$CPPFLAGS $ECA_S_JACK_INCLUDES" LDFLAGS="$LDFLAGS $ECA_S_JACK_LIBS" AC_TRY_LINK( [ #include ], [ jack_position_t t; int *a = (void*)&jack_transport_query; int *b = (void*)&jack_transport_start; int *c = (void*)&jack_transport_stop; int *d = (void*)&jack_transport_locate; t.frame = 0; t.valid = 0; return 0; ], [ ECA_JACK_TRANSPORT_API="3" ], [ ECA_JACK_TRANSPORT_API="0" ] ) # note: check for the new latency API added to JACK 0.120.1 AC_TRY_LINK( [ #include ], [ jack_latency_range_t t; t.min = 0; t.max = 0; return 0; ], [ ECA_JACK_FEATSET="1" ], [ ECA_JACK_FEATSET="0" ] ) CPPFLAGS="$old_cppflags" LDFLAGS="$old_ldflags" INCLUDES="$old_INCLUDES" echo "Using JACK transport API version:" ${ECA_JACK_TRANSPORT_API} AC_DEFINE_UNQUOTED([ECA_JACK_TRANSPORT_API], ${ECA_JACK_TRANSPORT_API}, [version of JACK transport API to use]) echo "Using JACK feature set (ecasound specific):" ${ECA_JACK_FEATSET} AC_DEFINE_UNQUOTED([ECA_JACK_FEATSET], ${ECA_JACK_FEATSET}, [ecasound specific versioning of JACK interface features ]) AC_SUBST(ECA_S_JACK_LIBS) AC_SUBST(ECA_S_JACK_INCLUDES) ]) ## ------------------------------------------------------------------------ ## Check for LFS (now deprecated, v3 is only a stub that doesn't ## peform any checks) ## ## version: 3 ## ## refs: ## - http://www.gnu.org/software/libtool/manual/libc/Feature-Test-Macros.html ## - http://www.suse.de/~aj/linux_lfs.html ## - http://en.wikipedia.org/wiki/Large_file_support ## ## modifies: AM_CXXFLAGS, AM_CFLAGS ## defines: enable_largefile ## ------------------------------------------------------------------------ ## AC_DEFUN([AC_CHECK_LARGEFILE], [ echo "checking for largefile support (>2GB files)..." dnl note: this is only for backwards compatibility AC_ARG_WITH(largefile, [ --with-largefile deprecated option, now used by default], []) AC_SYS_LARGEFILE if test x$ac_cv_sys_file_offset_bits = x64 ; then dnl note: Just to be sure that the define is there even dnl if config.h is not included in right order w.r.t. dnl the system headers. AM_CXXFLAGS="$AM_CXXFLAGS -D_FILE_OFFSET_BITS=64" AM_CFLAGS="$AM_CFLAGS -D_FILE_OFFSET_BITS=64" enable_largefile=yes fi dnl old checks dnl ---------- dnl [ if test "x$withval" = "xyes" ; then dnl enable_largefile="yes" dnl fi dnl ] dnl if test "x$enable_largefile" = "xyes"; then dnl dnl AC_DEFINE(_FILE_OFFSET_BITS, 64) dnl dnl AC_DEFINE(_LARGEFILE_SOURCE) dnl AM_CXXFLAGS="$AM_CXXFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" dnl AM_CFLAGS="$AM_CFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" dnl AC_MSG_RESULT(yes.) dnl else dnl AC_MSG_RESULT(no.) dnl fi ]) ## ------------------------------------------------------------------------ ## Check whether namespaces are supported. ## ## version: 3 ## ## defines: ECA_USE_CXX_STD_NAMESPACE ## ------------------------------------------------------------------------ ## AC_DEFUN([AC_CHECK_CXX_NAMESPACE_SUPPORT], [ AC_MSG_CHECKING(if C++ compiler supports namespaces) AC_LANG_CPLUSPLUS old_cxx_flags=$CXXFLAGS CXXFLAGS="-fno-exceptions $CXXFLAGS" # hack around gcc3.x feature AC_TRY_RUN( [ #include #include using std::string; int main(void) { string s ("foo"); std::vector v; return(0); } ], [ AC_MSG_RESULT(yes.) AC_DEFINE([ECA_USE_CXX_STD_NAMESPACE], 1, [use C++ std namespace]) ], [ AC_MSG_RESULT(no.) AC_MSG_WARN([C++ compiler has problems with namespaces. Build process can fail because of this.]) ] , [ AC_MSG_RESULT(no.) ] ) CXXFLAGS=$old_cxx_flags ]) ## ------------------------------------------------------------------------ ## Find a file (or one of more files in a list of dirs) ## ## version: 1 ## ------------------------------------------------------------------------ ## AC_DEFUN([AC_FIND_FILE], [ $3=NO for i in $2; do for j in $1; do if test -r "$i/$j"; then $3=$i break 2 fi done done ]) ecasound-2.9.1/COPYING0000644000076400007640000000146210664032032011307 00000000000000======================================================================= *** Ecasound - Licensing/distribution policy *** ======================================================================= Copyright (C) 1997-2006 Kai Vehmanen and others (see ecasound/AUTHORS). Ecasound is freely distributable according to the terms of the GNU General Public License (see the file 'COPYING.GPL'). This program is distributed without any warranty. See the file 'COPYING.GPL' for details. As an exception to the above, the C, C++ and python implementations of the Ecasound Control Interface (ECI) are licensed under the LGPL (see the file 'COPYING.LGPL'). This allows writing ECI applications that are not licensed under GPL. ======================================================================= ecasound-2.9.1/install-sh0000755000076400007640000003253712260112136012265 00000000000000#!/bin/sh # install - install a program, script, or datafile 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 # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ecasound-2.9.1/examples/0000755000076400007640000000000012261520737012160 500000000000000ecasound-2.9.1/examples/ecidoc_example.c0000644000076400007640000000331710664032032015200 00000000000000/************************************************************************* * Implementation of the following: * * 1. Setup ECI to read audio from file, apply a 100Hz lowpass filter, and * send it to the soundcard (/dev/dsp). * 2. Every second, check the current position. If the stream has * been running for over 15 seconds, exit immediately. Also, * every second, increase the lowpass filter's cutoff frequency * by 500Hz. * 3. Stop the stream (if not already finished) and disconnect the * chainsetup. Print chain operator status info. ************************************************************************/ #include #include #include /* compile with: * * gcc -o ecidoc_example ecidoc_example.c `libecasoundc-config --cflags --libs` */ int main(int argc, char *argv[]) { double cutoff_inc = 500.0; eci_init(); eci_command("cs-add play_chainsetup"); eci_command("c-add 1st_chain"); eci_command("ai-add foo.wav"); eci_command("ao-add /dev/dsp"); eci_command("cop-add -efl:100"); eci_command("cop-select 1"); eci_command("copp-select 1"); eci_command("cs-connect"); eci_command("start"); while(1) { double curpos, next_cutoff; sleep(1); eci_command("engine-status"); if (strcmp(eci_last_string(), "running") != 0) break; eci_command("get-position"); curpos = eci_last_float(); if (curpos > 15.0) break; eci_command("copp-get"); next_cutoff = cutoff_inc + eci_last_float(); eci_command_float_arg("copp-set", next_cutoff); } eci_command("stop"); eci_command("cs-disconnect"); eci_command("cop-status"); printf("Chain operator status: %s", eci_last_string()); eci_cleanup(); return(0); } ecasound-2.9.1/examples/Makefile.in0000644000076400007640000003034312261511324014140 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/examples/Makefile.am # Description: Example applications that use Ecasound libraries # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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 = examples DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ EXTRA_DIST = README \ ecatrimsilence.sh \ ecidoc_example.c \ ecidoc_example.cpp \ ecidoc_example.py \ normalize.py AUTOMAKE_OPTIONS = foreign all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 installdirs: 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) 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 mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-exec install-exec-am \ install-info install-info-am install-man install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # 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: ecasound-2.9.1/examples/ecidoc_example.cpp0000644000076400007640000000324510664032032015540 00000000000000/************************************************************************* * Implementation of the following: * * 1. Setup ECI to read audio from file, apply a 100Hz lowpass filter, and * send it to the soundcard (/dev/dsp). * 2. Every second, check the current position. If the stream has * been running for over 15 seconds, exit immediately. Also, * every second, increase the lowpass filter's cutoff frequency * by 500Hz. * 3. Stop the stream (if not already finished) and disconnect the * chainsetup. Print chain operator status info. ************************************************************************/ #include #include #include /* compile with: * * c++ -o ecidoc_example ecidoc_example.cpp `libecasoundc-config --cflags --libs` */ int main(int argc, char *argv[]) { double cutoff_inc = 500.0; ECA_CONTROL_INTERFACE e; e.command("cs-add play_chainsetup"); e.command("c-add 1st_chain"); e.command("ai-add foo.wav"); e.command("ao-add /dev/dsp"); e.command("cop-add -efl:100"); e.command("cop-select 1"); e.command("copp-select 1"); e.command("cs-connect"); e.command("start"); while(1) { sleep(1); e.command("engine-status"); if (e.last_string() != "running") break; e.command("get-position"); double curpos = e.last_float(); if (curpos > 15.0) break; e.command("copp-get"); double next_cutoff = cutoff_inc + e.last_float(); e.command_float_arg("copp-set", next_cutoff); } e.command("stop"); e.command("cs-disconnect"); e.command("cop-status"); std::cerr << "Chain operator status: " << e.last_string() << std::endl; return(0); } ecasound-2.9.1/examples/ecidoc_example.py0000644000076400007640000000257510664032032015413 00000000000000#!/usr/bin/env python # ----------------------------------------------------------------------- # Implementation of the following: # # 1. Setup ECI to read audio from file, apply a 100Hz lowpass filter, and # send it to the soundcard (/dev/dsp). # 2. Every second, check the current position. If the stream has # been running for over 15 seconds, exit immediately. Also, # every second, increase the lowpass filter's cutoff frequency # by 500Hz. # 3. Stop the stream (if not already finished) and disconnect the # chainsetup. Print chain operator status info. # ----------------------------------------------------------------------- import time from pyeca import * e = ECA_CONTROL_INTERFACE() e.command("cs-add play_chainsetup") e.command("c-add 1st_chain") e.command("ai-add foo.wav") e.command("ao-add /dev/dsp") e.command("cop-add -efl:100") e.command("cop-select 1") e.command("copp-select 1") e.command("cs-connect") e.command("start") cutoff_inc = 500.0 while 1: time.sleep(1) e.command("engine-status") if e.last_string() != "running": break e.command("get-position") curpos = e.last_float() if curpos > 15: break e.command("copp-get") next_cutoff = cutoff_inc + e.last_float() e.command_float_arg("copp-set", next_cutoff) e.command("stop") e.command("cs-disconnect") e.command("cop-status") print "Chain operator status: ", e.last_string() ecasound-2.9.1/examples/ecatrimsilence.sh0000755000076400007640000000131510664032032015415 00000000000000#!/bin/sh # # description: removes silence from the beginning and the end # of a file # version: 20050807-3 # usage: ecatrimsilence.sh tmp=ecatrimsilence-tmp.wav ECASOUND=ecasound if test -e $tmp ; then echo "error: temp file $tmp exists, unable to continue..." exit 1 fi if test ! -e $1 ; then echo "error: input file $1 does not exist, unable to continue..." exit 2 fi format=`ecalength -sf $1` echo "Trimming file ${1}." echo "Removing silence at the end..." $ECASOUND -q -f:${format} -i reverse,${1} -o ${tmp} -ge:1,0,1 -b:64 rm -f ${1} echo "Removing silence at the beginning..." $ECASOUND -q -f:${format} -i reverse,${tmp} -o ${1} -ge:1,0,1 -b:64 rm -f ${tmp} echo "Done." ecasound-2.9.1/examples/normalize.py0000644000076400007640000000371310664032032014445 00000000000000#!/usr/local/bin/python # ----------------------------------------------------------------------- # Example of an audio file volume normalizer (peak amplitude). # # 1. Takes the filename to be processed from the command line. # 2. Runs the audio file through ecasound's volume analyzer. # 3. If the signal isn't normalized (gain factor > 1), it is amplified # (gain factor from the analyzer) and the original file is replaced. # 4. Removes the temp file and exits. # # Known "bugs": # - if ecasound's internal sample rate doesn't match audio file's # sample rate, signal will get resampled twice # - might change the audio format of the processed files # ----------------------------------------------------------------------- import os import sys from tempfile import mktemp from pyeca import * # check arguments if len(sys.argv) < 2: sys.exit(-1) filename = sys.argv[1] if not os.path.isfile(filename): sys.exit(-1) tmpfile = mktemp(".wav") # create and configure the 'analyze' chainsetup e = ECA_CONTROL_INTERFACE() e.command("cs-add analyze") e.command("c-add 1") print "Normalizing file " + filename print "Using tempfile " + tmpfile e.command("ai-add " + filename) e.command("ao-add " + tmpfile) e.command("cop-add -ev") print "Analyzing sample data." e.command("cs-connect") e.command("run") e.command("cop-select 1") e.command("copp-select 2") e.command("copp-get") gain_factor = e.last_float() e.command("cs-disconnect") if gain_factor <= 1: print "File already normalized!" sys.exit(0) # create and config the 'apply' chainsetup a = ECA_CONTROL_INTERFACE() a.command("cs-add apply") a.command("c-add 1") a.command("ai-add " + tmpfile) a.command("ao-add " + filename) print "Applying gain factor: ", gain_factor a.command("cop-add -ea:100") a.command("cop-select 1") a.command("copp-select 1") a.command_float_arg("copp-set", gain_factor * 100) a.command("cs-connect") a.command("run") # remove the tempfile and exit os.remove(tmpfile) print "Done!" sys.exit(0) ecasound-2.9.1/examples/Makefile.am0000644000076400007640000000070210664032032014122 00000000000000# ---------------------------------------------------------------------- # File: ecasound/examples/Makefile.am # Description: Example applications that use Ecasound libraries # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- EXTRA_DIST = README \ ecatrimsilence.sh \ ecidoc_example.c \ ecidoc_example.cpp \ ecidoc_example.py \ normalize.py AUTOMAKE_OPTIONS = foreign ecasound-2.9.1/examples/README0000644000076400007640000000155410664032032012754 00000000000000======================================================================= *** Ecasound - Miscellanous example source code *** ======================================================================= This directory contains various clips of example code demonstrating the use of libecasound and the ecasound control interface (ECI). To see examples of ecasound use (not programming related), see the file 'Documentation/examples.html'. ----------------------------------------------------------------------- Included files ----------------------------------------------------------------------- - example programs from the "Ecasound Control Interface Documentation" - ecadoc_example.c [C] - ecadoc_example.cpp [C++] - ecadoc_example.py [Python] - Python scripts - normalize.py =======================================================================ecasound-2.9.1/libecasound/0000755000076400007640000000000012261520737012632 500000000000000ecasound-2.9.1/libecasound/ladspa.h0000644000076400007640000006571111224162022014164 00000000000000/* ladspa.h Linux Audio Developer's Simple Plugin API Version 1.1[LGPL]. Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, Stefan Westerfeld. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 LADSPA_INCLUDED #define LADSPA_INCLUDED #define LADSPA_VERSION "1.1" #define LADSPA_VERSION_MAJOR 1 #define LADSPA_VERSION_MINOR 1 #ifdef __cplusplus extern "C" { #endif /*****************************************************************************/ /* Overview: There is a large number of synthesis packages in use or development on the Linux platform at this time. This API (`The Linux Audio Developer's Simple Plugin API') attempts to give programmers the ability to write simple `plugin' audio processors in C/C++ and link them dynamically (`plug') into a range of these packages (`hosts'). It should be possible for any host and any plugin to communicate completely through this interface. This API is deliberately short and simple. To achieve compatibility with a range of promising Linux sound synthesis packages it attempts to find the `greatest common divisor' in their logical behaviour. Having said this, certain limiting decisions are implicit, notably the use of a fixed type (LADSPA_Data) for all data transfer and absence of a parameterised `initialisation' phase. See below for the LADSPA_Data typedef. Plugins are expected to distinguish between control and audio data. Plugins have `ports' that are inputs or outputs for audio or control data and each plugin is `run' for a `block' corresponding to a short time interval measured in samples. Audio data is communicated using arrays of LADSPA_Data, allowing a block of audio to be processed by the plugin in a single pass. Control data is communicated using single LADSPA_Data values. Control data has a single value at the start of a call to the `run()' or `run_adding()' function, and may be considered to remain this value for its duration. The plugin may assume that all its input and output ports have been connected to the relevant data location (see the `connect_port()' function below) before it is asked to run. Plugins will reside in shared object files suitable for dynamic linking by dlopen() and family. The file will provide a number of `plugin types' that can be used to instantiate actual plugins (sometimes known as `plugin instances') that can be connected together to perform tasks. This API contains very limited error-handling. */ /*****************************************************************************/ /* Fundamental data type passed in and out of plugin. This data type is used to communicate audio samples and control values. It is assumed that the plugin will work sensibly given any numeric input value although it may have a preferred range (see hints below). For audio it is generally assumed that 1.0f is the `0dB' reference amplitude and is a `normal' signal level. */ typedef float LADSPA_Data; /*****************************************************************************/ /* Special Plugin Properties: Optional features of the plugin type are encapsulated in the LADSPA_Properties type. This is assembled by ORing individual properties together. */ typedef int LADSPA_Properties; /* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a real-time dependency (e.g. listens to a MIDI device) and so its output must not be cached or subject to significant latency. */ #define LADSPA_PROPERTY_REALTIME 0x1 /* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin may cease to work correctly if the host elects to use the same data location for both input and output (see connect_port()). This should be avoided as enabling this flag makes it impossible for hosts to use the plugin to process audio `in-place.' */ #define LADSPA_PROPERTY_INPLACE_BROKEN 0x2 /* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin is capable of running not only in a conventional host but also in a `hard real-time' environment. To qualify for this the plugin must satisfy all of the following: (1) The plugin must not use malloc(), free() or other heap memory management within its run() or run_adding() functions. All new memory used in run() must be managed via the stack. These restrictions only apply to the run() function. (2) The plugin will not attempt to make use of any library functions with the exceptions of functions in the ANSI standard C and C maths libraries, which the host is expected to provide. (3) The plugin will not access files, devices, pipes, sockets, IPC or any other mechanism that might result in process or thread blocking. (4) The plugin will take an amount of time to execute a run() or run_adding() call approximately of form (A+B*SampleCount) where A and B depend on the machine and host in use. This amount of time may not depend on input signals or plugin state. The host is left the responsibility to perform timings to estimate upper bounds for A and B. */ #define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4 #define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME) #define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN) #define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE) /*****************************************************************************/ /* Plugin Ports: Plugins have `ports' that are inputs or outputs for audio or data. Ports can communicate arrays of LADSPA_Data (for audio inputs/outputs) or single LADSPA_Data values (for control input/outputs). This information is encapsulated in the LADSPA_PortDescriptor type which is assembled by ORing individual properties together. Note that a port must be an input or an output port but not both and that a port must be a control or audio port but not both. */ typedef int LADSPA_PortDescriptor; /* Property LADSPA_PORT_INPUT indicates that the port is an input. */ #define LADSPA_PORT_INPUT 0x1 /* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */ #define LADSPA_PORT_OUTPUT 0x2 /* Property LADSPA_PORT_CONTROL indicates that the port is a control port. */ #define LADSPA_PORT_CONTROL 0x4 /* Property LADSPA_PORT_AUDIO indicates that the port is a audio port. */ #define LADSPA_PORT_AUDIO 0x8 #define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT) #define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT) #define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL) #define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO) /*****************************************************************************/ /* Plugin Port Range Hints: The host may wish to provide a representation of data entering or leaving a plugin (e.g. to generate a GUI automatically). To make this more meaningful, the plugin should provide `hints' to the host describing the usual values taken by the data. Note that these are only hints. The host may ignore them and the plugin must not assume that data supplied to it is meaningful. If the plugin receives invalid input data it is expected to continue to run without failure and, where possible, produce a sensible output (e.g. a high-pass filter given a negative cutoff frequency might switch to an all-pass mode). Hints are meaningful for all input and output ports but hints for input control ports are expected to be particularly useful. More hint information is encapsulated in the LADSPA_PortRangeHintDescriptor type which is assembled by ORing individual hint types together. Hints may require further LowerBound and UpperBound information. All the hint information for a particular port is aggregated in the LADSPA_PortRangeHint structure. */ typedef int LADSPA_PortRangeHintDescriptor; /* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field of the LADSPA_PortRangeHint should be considered meaningful. The value in this field should be considered the (inclusive) lower bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also specified then the value of LowerBound should be multiplied by the sample rate. */ #define LADSPA_HINT_BOUNDED_BELOW 0x1 /* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field of the LADSPA_PortRangeHint should be considered meaningful. The value in this field should be considered the (inclusive) upper bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also specified then the value of UpperBound should be multiplied by the sample rate. */ #define LADSPA_HINT_BOUNDED_ABOVE 0x2 /* Hint LADSPA_HINT_TOGGLED indicates that the data item should be considered a Boolean toggle. Data less than or equal to zero should be considered `off' or `false,' and data above zero should be considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or LADSPA_HINT_DEFAULT_1. */ #define LADSPA_HINT_TOGGLED 0x4 /* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified should be interpreted as multiples of the sample rate. For instance, a frequency range from 0Hz to the Nyquist frequency (half the sample rate) could be requested by this hint in conjunction with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds at all must support this hint to retain meaning. */ #define LADSPA_HINT_SAMPLE_RATE 0x8 /* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the user will find it more intuitive to view values using a logarithmic scale. This is particularly useful for frequencies and gains. */ #define LADSPA_HINT_LOGARITHMIC 0x10 /* Hint LADSPA_HINT_INTEGER indicates that a user interface would probably wish to provide a stepped control taking only integer values. Any bounds set should be slightly wider than the actual integer range required to avoid floating point rounding errors. For instance, the integer set {0,1,2,3} might be described as [-0.1, 3.1]. */ #define LADSPA_HINT_INTEGER 0x20 /* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal' value for the port that is sensible as a default. For instance, this value is suitable for use as an initial value in a user interface or as a value the host might assign to a control port when the user has not provided one. Defaults are encoded using a mask so only one default may be specified for a port. Some of the hints make use of lower and upper bounds, in which case the relevant bound or bounds must be available and LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting default must be rounded if LADSPA_HINT_INTEGER is present. Default values were introduced in LADSPA v1.1. */ #define LADSPA_HINT_DEFAULT_MASK 0x3C0 /* This default values indicates that no default is provided. */ #define LADSPA_HINT_DEFAULT_NONE 0x0 /* This default hint indicates that the suggested lower bound for the port should be used. */ #define LADSPA_HINT_DEFAULT_MINIMUM 0x40 /* This default hint indicates that a low value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 + log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper * 0.25). */ #define LADSPA_HINT_DEFAULT_LOW 0x80 /* This default hint indicates that a middle value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 + log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper * 0.5). */ #define LADSPA_HINT_DEFAULT_MIDDLE 0xC0 /* This default hint indicates that a high value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 + log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper * 0.75). */ #define LADSPA_HINT_DEFAULT_HIGH 0x100 /* This default hint indicates that the suggested upper bound for the port should be used. */ #define LADSPA_HINT_DEFAULT_MAXIMUM 0x140 /* This default hint indicates that the number 0 should be used. Note that this default may be used in conjunction with LADSPA_HINT_TOGGLED. */ #define LADSPA_HINT_DEFAULT_0 0x200 /* This default hint indicates that the number 1 should be used. Note that this default may be used in conjunction with LADSPA_HINT_TOGGLED. */ #define LADSPA_HINT_DEFAULT_1 0x240 /* This default hint indicates that the number 100 should be used. */ #define LADSPA_HINT_DEFAULT_100 0x280 /* This default hint indicates that the Hz frequency of `concert A' should be used. This will be 440 unless the host uses an unusual tuning convention, in which case it may be within a few Hz. */ #define LADSPA_HINT_DEFAULT_440 0x2C0 #define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW) #define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE) #define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED) #define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE) #define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC) #define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER) #define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK) #define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MINIMUM) #define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_LOW) #define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MIDDLE) #define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_HIGH) #define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MAXIMUM) #define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_0) #define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_1) #define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_100) #define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_440) typedef struct _LADSPA_PortRangeHint { /* Hints about the port. */ LADSPA_PortRangeHintDescriptor HintDescriptor; /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When LADSPA_HINT_SAMPLE_RATE is also active then this value should be multiplied by the relevant sample rate. */ LADSPA_Data LowerBound; /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When LADSPA_HINT_SAMPLE_RATE is also active then this value should be multiplied by the relevant sample rate. */ LADSPA_Data UpperBound; } LADSPA_PortRangeHint; /*****************************************************************************/ /* Plugin Handles: This plugin handle indicates a particular instance of the plugin concerned. It is valid to compare this to NULL (0 for C++) but otherwise the host should not attempt to interpret it. The plugin may use it to reference internal instance data. */ typedef void * LADSPA_Handle; /*****************************************************************************/ /* Descriptor for a Type of Plugin: This structure is used to describe a plugin type. It provides a number of functions to examine the type, instantiate it, link it to buffers and workspaces and to run it. */ typedef struct _LADSPA_Descriptor { /* This numeric identifier indicates the plugin type uniquely. Plugin programmers may reserve ranges of IDs from a central body to avoid clashes. Hosts may assume that IDs are below 0x1000000. */ unsigned long UniqueID; /* This identifier can be used as a unique, case-sensitive identifier for the plugin type within the plugin file. Plugin types should be identified by file and label rather than by index or plugin name, which may be changed in new plugin versions. Labels must not contain white-space characters. */ const char * Label; /* This indicates a number of properties of the plugin. */ LADSPA_Properties Properties; /* This member points to the null-terminated name of the plugin (e.g. "Sine Oscillator"). */ const char * Name; /* This member points to the null-terminated string indicating the maker of the plugin. This can be an empty string but not NULL. */ const char * Maker; /* This member points to the null-terminated string indicating any copyright applying to the plugin. If no Copyright applies the string "None" should be used. */ const char * Copyright; /* This indicates the number of ports (input AND output) present on the plugin. */ unsigned long PortCount; /* This member indicates an array of port descriptors. Valid indices vary from 0 to PortCount-1. */ const LADSPA_PortDescriptor * PortDescriptors; /* This member indicates an array of null-terminated strings describing ports (e.g. "Frequency (Hz)"). Valid indices vary from 0 to PortCount-1. */ const char * const * PortNames; /* This member indicates an array of range hints for each port (see above). Valid indices vary from 0 to PortCount-1. */ const LADSPA_PortRangeHint * PortRangeHints; /* This may be used by the plugin developer to pass any custom implementation data into an instantiate call. It must not be used or interpreted by the host. It is expected that most plugin writers will not use this facility as LADSPA_Handle should be used to hold instance data. */ void * ImplementationData; /* This member is a function pointer that instantiates a plugin. A handle is returned indicating the new plugin instance. The instantiation function accepts a sample rate as a parameter. The plugin descriptor from which this instantiate function was found must also be passed. This function must return NULL if instantiation fails. Note that instance initialisation should generally occur in activate() rather than here. */ LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long SampleRate); /* This member is a function pointer that connects a port on an instantiated plugin to a memory location at which a block of data for the port will be read/written. The data location is expected to be an array of LADSPA_Data for audio ports or a single LADSPA_Data value for control ports. Memory issues will be managed by the host. The plugin must read/write the data at these locations every time run() or run_adding() is called and the data present at the time of this connection call should not be considered meaningful. connect_port() may be called more than once for a plugin instance to allow the host to change the buffers that the plugin is reading or writing. These calls may be made before or after activate() or deactivate() calls. connect_port() must be called at least once for each port before run() or run_adding() is called. When working with blocks of LADSPA_Data the plugin should pay careful attention to the block size passed to the run function as the block allocated may only just be large enough to contain the block of samples. Plugin writers should be aware that the host may elect to use the same buffer for more than one port and even use the same buffer for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN). However, overlapped buffers or use of a single buffer for both audio and control data may result in unexpected behaviour. */ void (*connect_port)(LADSPA_Handle Instance, unsigned long Port, LADSPA_Data * DataLocation); /* This member is a function pointer that initialises a plugin instance and activates it for use. This is separated from instantiate() to aid real-time support and so that hosts can reinitialise a plugin instance by calling deactivate() and then activate(). In this case the plugin instance must reset all state information dependent on the history of the plugin instance except for any data locations provided by connect_port() and any gain set by set_run_adding_gain(). If there is nothing for activate() to do then the plugin writer may provide a NULL rather than an empty function. When present, hosts must call this function once before run() (or run_adding()) is called for the first time. This call should be made as close to the run() call as possible and indicates to real-time plugins that they are now live. Plugins should not rely on a prompt call to run() after activate(). activate() may not be called again unless deactivate() is called first. Note that connect_port() may be called before or after a call to activate(). */ void (*activate)(LADSPA_Handle Instance); /* This method is a function pointer that runs an instance of a plugin for a block. Two parameters are required: the first is a handle to the particular instance to be run and the second indicates the block size (in samples) for which the plugin instance may run. Note that if an activate() function exists then it must be called before run() or run_adding(). If deactivate() is called for a plugin instance then the plugin instance may not be reused until activate() has been called again. If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE then there are various things that the plugin should not do within the run() or run_adding() functions (see above). */ void (*run)(LADSPA_Handle Instance, unsigned long SampleCount); /* This method is a function pointer that runs an instance of a plugin for a block. This has identical behaviour to run() except in the way data is output from the plugin. When run() is used, values are written directly to the memory areas associated with the output ports. However when run_adding() is called, values must be added to the values already present in the memory areas. Furthermore, output values written must be scaled by the current gain set by set_run_adding_gain() (see below) before addition. run_adding() is optional. When it is not provided by a plugin, this function pointer must be set to NULL. When it is provided, the function set_run_adding_gain() must be provided also. */ void (*run_adding)(LADSPA_Handle Instance, unsigned long SampleCount); /* This method is a function pointer that sets the output gain for use when run_adding() is called (see above). If this function is never called the gain is assumed to default to 1. Gain information should be retained when activate() or deactivate() are called. This function should be provided by the plugin if and only if the run_adding() function is provided. When it is absent this function pointer must be set to NULL. */ void (*set_run_adding_gain)(LADSPA_Handle Instance, LADSPA_Data Gain); /* This is the counterpart to activate() (see above). If there is nothing for deactivate() to do then the plugin writer may provide a NULL rather than an empty function. Hosts must deactivate all activated units after they have been run() (or run_adding()) for the last time. This call should be made as close to the last run() call as possible and indicates to real-time plugins that they are no longer live. Plugins should not rely on prompt deactivation. Note that connect_port() may be called before or after a call to deactivate(). Deactivation is not similar to pausing as the plugin instance will be reinitialised when activate() is called to reuse it. */ void (*deactivate)(LADSPA_Handle Instance); /* Once an instance of a plugin has been finished with it can be deleted using the following function. The instance handle passed ceases to be valid after this call. If activate() was called for a plugin instance then a corresponding call to deactivate() must be made before cleanup() is called. */ void (*cleanup)(LADSPA_Handle Instance); } LADSPA_Descriptor; /**********************************************************************/ /* Accessing a Plugin: */ /* The exact mechanism by which plugins are loaded is host-dependent, however all most hosts will need to know is the name of shared object file containing the plugin types. To allow multiple hosts to share plugin types, hosts may wish to check for environment variable LADSPA_PATH. If present, this should contain a colon-separated path indicating directories that should be searched (in order) when loading plugin types. A plugin programmer must include a function called "ladspa_descriptor" with the following function prototype within the shared object file. This function will have C-style linkage (if you are using C++ this is taken care of by the `extern "C"' clause at the top of the file). A host will find the plugin shared object file by one means or another, find the ladspa_descriptor() function, call it, and proceed from there. Plugin types are accessed by index (not ID) using values from 0 upwards. Out of range indexes must result in this function returning NULL, so the plugin count can be determined by checking for the least index that results in NULL being returned. */ const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); /* Datatype corresponding to the ladspa_descriptor() function. */ typedef const LADSPA_Descriptor * (*LADSPA_Descriptor_Function)(unsigned long Index); /**********************************************************************/ #ifdef __cplusplus } #endif #endif /* LADSPA_INCLUDED */ /* EOF */ ecasound-2.9.1/libecasound/eca-fileio-stream.h0000644000076400007640000000252210664032032016201 00000000000000#ifndef INCLUDED_FILEIO_STREAM_H #define INCLUDED_FILEIO_STREAM_H #include #include #include "eca-fileio.h" /** * File-I/O and buffering routines using normal file streams. */ class ECA_FILE_IO_STREAM : public ECA_FILE_IO { public: ECA_FILE_IO_STREAM (void) { } virtual ~ECA_FILE_IO_STREAM(void); // -- // Open/close routines // --- virtual void open_file(const std::string& fname, const std::string& fmode); virtual void open_stdin(void); virtual void open_stdout(void); virtual void open_stderr(void); virtual void close_file(void); // -- // Normal file operations // --- virtual void read_to_buffer(void* obuf, off_t bytes); virtual void write_from_buffer(void* obuf, off_t bytes); virtual void set_file_position(off_t newpos); virtual void set_file_position_advance(off_t fw); virtual void set_file_position_end(void); virtual off_t get_file_position(void) const; virtual off_t get_file_length(void) const; // -- // Status // --- virtual bool is_file_ready(void) const; virtual bool is_file_error(void) const; virtual off_t file_bytes_processed(void) const; virtual const std::string& file_mode(void) const { return(mode_rep); } private: FILE *f1; off_t curpos_rep; off_t last_rep; std::string mode_rep; std::string fname_rep; bool standard_mode; }; #endif ecasound-2.9.1/libecasound/audiofx.cpp0000644000076400007640000000474311053067202014714 00000000000000// ------------------------------------------------------------------------ // audiofx.cpp: General effect processing routines. // Copyright (C) 1999-2002,2004,2006,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include "sample-specs.h" #include "samplebuffer.h" #include "audiofx.h" #include "eca-logger.h" EFFECT_BASE::EFFECT_BASE(void) : channels_rep(0) { } EFFECT_BASE::~EFFECT_BASE(void) { } void EFFECT_BASE::init(SAMPLE_BUFFER* sbuf) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Init w/ samplerate " + kvu_numtostr(samples_per_second()) + " for object " + name() + "."); set_channels(sbuf->number_of_channels()); DBC_CHECK(channels() > 0); DBC_CHECK(samples_per_second() > 0); } int EFFECT_BASE::channels(void) const { return channels_rep; } void EFFECT_BASE::set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_rate) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Setting samplerate to " + kvu_numtostr(new_rate) + " for object " + name() + ". Old value " + kvu_numtostr(samples_per_second()) + "."); /* note: changing the sample rate might change values of * of parameters, so we want to preserve the values */ if (samples_per_second() != new_rate) { std::vector old_values (number_of_params()); for(int n = 0; n < number_of_params(); n++) { old_values[n] = get_parameter(n + 1); } ECA_SAMPLERATE_AWARE::set_samples_per_second(new_rate); for(int n = 0; n < number_of_params(); n++) { set_parameter(n + 1, old_values[n]); } } } void EFFECT_BASE::set_channels(int v) { channels_rep = v; } ecasound-2.9.1/libecasound/samplebuffer_functions.cpp0000644000076400007640000000753211262077634020033 00000000000000// ------------------------------------------------------------------------ // samplebuffer_functions.cpp: Extra functions for SAMPLE_BUFFER class // Copyright (C) 2000,2001,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include "kvu_dbc.h" #include "kvu_inttypes.h" #include "samplebuffer.h" #include "samplebuffer_functions.h" #undef NEVER_USED_CODE void SAMPLE_BUFFER_FUNCTIONS::fill_with_random_samples(SAMPLE_BUFFER *sbuf) { std::srand(std::time(0)); int ch_count = sbuf->number_of_channels(); int i_count = sbuf->length_in_samples(); for (int ch = 0; ch < ch_count; ch++) { SAMPLE_BUFFER::sample_t *buf = sbuf->buffer[ch]; for (int i = 0; i < i_count; i++) { int foo = std::rand(); assert(sizeof(SAMPLE_BUFFER::sample_t) <= sizeof(foo)); std::memcpy(buf, &foo, sizeof(SAMPLE_BUFFER::sample_t)); } } } /** * Returns true if 'a' and 'b' have the same exact signal content, * or if the two signals are sufficiently close to each * other considering the limits imposed by implementation (e.g. * precision of the floating point type used to represent * a sample). * * @param bitprec adjust precision (defaults to 24) * @param verbose_stderr whether to output comparison traces to * stderr */ bool SAMPLE_BUFFER_FUNCTIONS::is_almost_equal(const SAMPLE_BUFFER& a, const SAMPLE_BUFFER& b, int bitprec, bool verbose_stderr) { if (a.number_of_channels() != b.number_of_channels()) return false; if (a.length_in_samples() != b.length_in_samples()) return false; int ch_count = a.number_of_channels(); int i_count = a.length_in_samples(); for (int ch = 0; ch < ch_count; ch++) { for (int i = 0; i < i_count; i++) { if (a.buffer[ch][i] != b.buffer[ch][i]) { /* note: the following is intended only for comparing * audio signals with a nominal range of [-1,1] * and precision of 'bitprec' bits */ const SAMPLE_SPECS::sample_t diff_threshold = 1.0 / ((1 << bitprec) - 1); SAMPLE_SPECS::sample_t diff = std::fabs(a.buffer[ch][i] - b.buffer[ch][i]); if (verbose_stderr == true) { std::fprintf(stderr, "%s: diff for sample ch%d[%d], diff %.30f [%s], (a=%.30f to b=%.30f, thrshd %.30f)\n", __FILE__, ch, i, diff, diff > diff_threshold ? "MISMATCH" : "INRANGE", a.buffer[ch][i], b.buffer[ch][i], diff_threshold); } if (diff > diff_threshold) { return false; } { #if NEVER_USED_CODE /* integer-based comparison */ assert(sizeof(SAMPLE_BUFFER::sample_t) == sizeof(uint32_t)); /* allow diff of one in binary representation */ const int diff_threshold_ints = 1; uint32_t aint = *reinterpret_cast(&a.buffer[ch][i]); uint32_t bint = *reinterpret_cast(&b.buffer[ch][i]); uint32_t diff = std::labs(aint - bint); if (diff_total > diff_threshold_ints) { return false; } #endif } } } } return true; } ecasound-2.9.1/libecasound/osc-gen.h0000644000076400007640000000251211747065175014266 00000000000000#ifndef INCLUDED_GENERIC_OSCILLATOR_H #define INCLUDED_GENERIC_OSCILLATOR_H #include #include #include "oscillator.h" #include "eca-error.h" /** * Generic oscillator * * Oscillator value varies according to discrete * envelope points. */ class GENERIC_OSCILLATOR : public OSCILLATOR { public: virtual void init(void); virtual parameter_t value(double pos_secs); virtual std::string parameter_names(void) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; std::string name(void) const { return "Generic oscillator"; } GENERIC_OSCILLATOR* clone(void) const { return new GENERIC_OSCILLATOR(*this); } GENERIC_OSCILLATOR* new_expr(void) const { return new GENERIC_OSCILLATOR(*this); } GENERIC_OSCILLATOR(double freq = 0.0f, int mode = 0); virtual ~GENERIC_OSCILLATOR (void); protected: void prepare_envelope(void); private: class POINT { public: double pos; double val; }; size_t current_stage(double pos); void set_param_count(int n); std::vector envtable_rep; std::vector params_rep; size_t last_stage_rep; double last_pos_scaled_rep; int mode_rep; double first_value_rep, last_value_rep; double loop_length_rep; // loop length in seconds std::string param_names_rep; }; #endif ecasound-2.9.1/libecasound/dynamic-object.h0000644000076400007640000000154010765306255015617 00000000000000#ifndef INCLUDED_DYNAMIC_OBJECT_H #define INCLUDED_DYNAMIC_OBJECT_H #include "dynamic-parameters.h" #include "eca-object.h" /** * Virtual class for objects supporting dynamic parameter * control. * * Related design patterns: * - Factory Method / Virtual Constructor (GoF107) * * @author Kai Vehmanen */ template class DYNAMIC_OBJECT : public DYNAMIC_PARAMETERS, public ECA_OBJECT { public: virtual ~DYNAMIC_OBJECT (void) {} /** * Virtual method that clones the current object and returns * a pointer to it. This must be implemented by all subclasses! */ virtual DYNAMIC_OBJECT* clone(void) const = 0; /** * Virtual method that creates a new object of current type. * This must be implemented by all subclasses! */ virtual DYNAMIC_OBJECT* new_expr(void) const = 0; }; #endif ecasound-2.9.1/libecasound/osc-gen-file.cpp0000644000076400007640000000724711747055227015545 00000000000000// ------------------------------------------------------------------------ // osc-gen-file.cpp: Generic oscillator using envelope presets // Copyright (C) 1999-2002,2004,2007,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // This program is fre 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 #include #include #include #include #include "resource-file.h" #include "eca-resources.h" #include "osc-gen-file.h" #include "eca-logger.h" GENERIC_OSCILLATOR_FILE::GENERIC_OSCILLATOR_FILE(double freq, int mode) : GENERIC_OSCILLATOR(freq, mode) { set_parameter(1, get_parameter(1)); set_parameter(2, mode); } GENERIC_OSCILLATOR_FILE::~GENERIC_OSCILLATOR_FILE (void) { } void GENERIC_OSCILLATOR_FILE::get_oscillator_preset(int preset) { ECA_RESOURCES ecarc; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Opening genosc envelope file."); std::string user_filename = ecarc.resource("user-resource-directory") + "/" + ecarc.resource("resource-file-genosc-envelopes"); std::string pname = kvu_numtostr(preset); RESOURCE_FILE rc; rc.resource_file(user_filename); rc.load(); if (rc.has(pname) != true) { std::string global_filename = ecarc.resource("resource-directory") + "/" + ecarc.resource("resource-file-genosc-envelopes"); rc.resource_file(global_filename); rc.load(); } if (rc.has(pname) == true) { parse_envelope(rc.resource(pname)); } else { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Oscillator preset " + pname + " not found!"); } } void GENERIC_OSCILLATOR_FILE::parse_envelope(const std::string& str) { std::vector tokens = kvu_string_to_words(str); size_t dynparams_offset = 2; // number of points if (tokens.size() > 2) { GENERIC_OSCILLATOR::set_parameter(3, (tokens.size() - dynparams_offset) / 2); } else { GENERIC_OSCILLATOR::set_parameter(3, 0); } if (tokens.size() > 0) { // start value GENERIC_OSCILLATOR::set_parameter(4, atof(tokens[0].c_str())); if (tokens.size() > 1) { // start value GENERIC_OSCILLATOR::set_parameter(5, atof(tokens[1].c_str())); // set individual points for(unsigned int n = dynparams_offset; n < tokens.size(); n++) { GENERIC_OSCILLATOR::set_parameter(6 + n - dynparams_offset, atof(tokens[n].c_str())); } } } prepare_envelope(); } void GENERIC_OSCILLATOR_FILE::set_parameter(int param, CONTROLLER_SOURCE::parameter_t value) { switch (param) { case 1: case 2: GENERIC_OSCILLATOR::set_parameter(param, value); break; case 3: preset_rep = static_cast(value); get_oscillator_preset(preset_rep); break; } } CONTROLLER_SOURCE::parameter_t GENERIC_OSCILLATOR_FILE::get_parameter(int param) const { switch (param) { case 1: case 2: return GENERIC_OSCILLATOR::get_parameter(param); case 3: return static_cast(preset_rep); } return 0.0; } ecasound-2.9.1/libecasound/preset.cpp0000644000076400007640000004152711740524567014577 00000000000000// ------------------------------------------------------------------------ // preset.cpp: Class for representing effect presets // Copyright (C) 2000-2002,2004-2007,2009 Kai Vehmanen // Copyright (C) 2001 Arto Hamara // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include #include #include "eca-chain.h" #include "eca-chainop.h" #include "generic-controller.h" #include "eca-object-factory.h" #include "samplebuffer.h" #include "eca-logger.h" #include "eca-error.h" #include "preset.h" #include "preset_impl.h" using std::string; using std::vector; using std::cerr; using std::endl; PRESET::PRESET(void) { impl_repp = new PRESET_impl(); impl_repp->parsed_rep = false; } PRESET::PRESET(const string& formatted_string) { impl_repp = new PRESET_impl(); parse(formatted_string); } PRESET::~PRESET(void) { vector::iterator q = chains.begin(); while(q != chains.end()) { delete *q; ++q; } vector::iterator p = buffers.begin(); while(p != buffers.end()) { if (p != buffers.begin()) delete *p; // first buffer points to an // outside buffer -> not // deleted here ++p; } for(size_t n = 0; n < impl_repp->pardesclist_rep.size(); n++) { delete impl_repp->pardesclist_rep[n]; impl_repp->pardesclist_rep[n] = 0; } // NOTE: chainops and controllers are deleted in CHAIN::~CHAIN() delete impl_repp; impl_repp = 0; } PRESET* PRESET::clone(void) const { vector param_values; for(int n = 0; n < number_of_params(); n++) { param_values.push_back(get_parameter(n + 1)); } PRESET* preset = new PRESET(impl_repp->parse_string_rep); for(int n = 0; n < preset->number_of_params(); n++) { preset->set_parameter(n + 1, param_values[n]); } return preset; } PRESET* PRESET::new_expr(void) const { return new PRESET(impl_repp->parse_string_rep); } void PRESET::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { for(size_t q = 0; q < chains.size(); q++) { chains[q]->set_samples_per_second(v); } ECA_SAMPLERATE_AWARE::set_samples_per_second(v); } string PRESET::name(void) const { return impl_repp->name_rep; } string PRESET::description(void) const { return impl_repp->description_rep; } void PRESET::set_name(const string& v) { impl_repp->name_rep = v; } /** * Whether preset data has been parsed */ bool PRESET::is_parsed(void) const { return impl_repp->parsed_rep; } void PRESET::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { if (param > 0 && param <= static_cast(impl_repp->pardesclist_rep.size())) *pd = *impl_repp->pardesclist_rep[param - 1]; } /** * Parse preset data from the formatted string given * as argument. * * require: * formatted_string.empty() == false * ensure: * is_parsed() == true */ void PRESET::parse(const string& formatted_string) { // -------- DBC_REQUIRE(formatted_string.empty() == false); // -------- impl_repp->parse_string_rep = formatted_string; chains.clear(); chains.push_back(new CHAIN()); chains.back()->set_samples_per_second(samples_per_second()); // FIXME: add support for quotes (ie. "one token with space" style) vector tokens = kvu_string_to_words(formatted_string); vector::const_iterator p = tokens.begin(); while(p != tokens.end()) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Parsing: " + *p + "."); /* case 1: new chain */ if (*p == "|") { add_chain(); } /* case 2: preset specific option */ else if (is_preset_option(*p) == true) { parse_preset_option(*p); } /* case 3: ecasound cop option */ else { parse_operator_option(*p); } ++p; } impl_repp->parsed_rep = true; // -------- DBC_ENSURE(is_parsed() == true); // -------- } bool PRESET::is_preset_option(const string& arg) const { if (arg.size() < 2 || arg[0] != '-') return false; switch(arg[1]) { case 'p': { if (arg.size() < 3) return false; switch(arg[2]) { case 'd': case 'p': return true; default: { } } } default: { } } return false; } void PRESET::parse_preset_option(const string& arg) { if (arg.size() < 2) return; if (arg[0] != '-') return; switch(arg[1]) { case 'p': { if (arg.size() < 3) return; switch(arg[2]) { case 'd': { /* -pd:preset_description */ impl_repp->description_rep = kvu_get_argument_number(1, arg); break; } case 'p': { if (arg.size() < 4) return; switch(arg[3]) { case 'd': { /* -ppd:x,y,z (param default values) */ set_preset_defaults(kvu_get_arguments(arg)); break; } case 'n': { /* -ppn:x,y,z (param names) */ set_preset_param_names(kvu_get_arguments(arg)); break; } case 'l': { /* -ppl:x,y,z (param lower bounds) */ set_preset_lower_bounds(kvu_get_arguments(arg)); break; } case 'u': { /* -ppu:x,y,z (param upper bounds) */ set_preset_upper_bounds(kvu_get_arguments(arg)); break; } case 't': { /* -ppt:x,y,z (param toggle) */ set_preset_toggles(kvu_get_arguments(arg)); break; } default: { ECA_LOG_MSG(ECA_LOGGER::info, "Unknown preset option (1) " + arg + "."); break; } } break; /* -pp */ } default: { ECA_LOG_MSG(ECA_LOGGER::info, "Unknown preset option (2) " + arg + "."); break; } } break; /* -p */ } default: { ECA_LOG_MSG(ECA_LOGGER::info, "Unknown preset option (3) " + arg + "."); break; } } } void PRESET::extend_pardesc_vector(int number) { while (static_cast(impl_repp->pardesclist_rep.size()) < number) { DBC_DECLARE(size_t oldsize = impl_repp->pardesclist_rep.size()); impl_repp->pardesclist_rep.push_back(new OPERATOR::PARAM_DESCRIPTION()); // cerr << "(preset) adding pardesclist_rep item." << endl; DBC_CHECK(impl_repp->pardesclist_rep.size() == oldsize + 1); } } void PRESET::set_preset_defaults(const vector& args) { extend_pardesc_vector(args.size()); for(size_t n = 0; n < args.size(); n++) { if (args[n].size() > 0 && args[n][0] == '-') continue; impl_repp->pardesclist_rep[n]->default_value = atof(args[n].c_str()); set_parameter(n + 1, impl_repp->pardesclist_rep[n]->default_value); // cerr << "(preset) setting default for " << n << " to " << impl_repp->pardesclist_rep[n]->default_value << "." << endl; } } void PRESET::set_preset_param_names(const vector& args) { impl_repp->preset_param_names_rep.resize(args.size()); for(size_t n = 0; n < args.size(); n++) { impl_repp->preset_param_names_rep[n] = args[n]; // cerr << "(preset) setting param name for " << n << " to " << impl_repp->preset_param_names_rep[n] << "." << endl; } } void PRESET::set_preset_lower_bounds(const vector& args) { extend_pardesc_vector(args.size()); for(size_t n = 0; n < args.size(); n++) { if (args[n].size() > 0 && args[n][0] == '-') { impl_repp->pardesclist_rep[n]->bounded_below = false; } else { impl_repp->pardesclist_rep[n]->bounded_below = true; impl_repp->pardesclist_rep[n]->lower_bound = atof(args[n].c_str()); // cerr << "(preset) setting lowbound for " << n << " to " << impl_repp->pardesclist_rep[n]->lower_bound << "." << endl; } } } void PRESET::set_preset_upper_bounds(const vector& args) { extend_pardesc_vector(args.size()); for(size_t n = 0; n < args.size(); n++) { if (args[n].size() > 0 && args[n][0] == '-') { impl_repp->pardesclist_rep[n]->bounded_above = false; } else { impl_repp->pardesclist_rep[n]->bounded_above = true; impl_repp->pardesclist_rep[n]->upper_bound = atof(args[n].c_str()); // cerr << "(preset) setting upperbound for " << n << " to " << impl_repp->pardesclist_rep[n]->upper_bound << "." << endl; } } } void PRESET::set_preset_toggles(const vector& args) { extend_pardesc_vector(args.size()); for(size_t n = 0; n < args.size(); n++) { impl_repp->pardesclist_rep[n]->integer = false; impl_repp->pardesclist_rep[n]->logarithmic = false; impl_repp->pardesclist_rep[n]->output = false; impl_repp->pardesclist_rep[n]->toggled = false; if (args[n].find("i") != string::npos) impl_repp->pardesclist_rep[n]->integer = true; if (args[n].find("l") != string::npos) impl_repp->pardesclist_rep[n]->logarithmic = true; if (args[n].find("o") != string::npos) impl_repp->pardesclist_rep[n]->output = true; if (args[n].find("t") != string::npos) impl_repp->pardesclist_rep[n]->toggled = true; ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Setting preset toggles: integer=") + kvu_numtostr(impl_repp->pardesclist_rep[n]->integer) + ", log=" + kvu_numtostr(impl_repp->pardesclist_rep[n]->logarithmic) + ", output=" + kvu_numtostr(impl_repp->pardesclist_rep[n]->output) + ", toggle=" + kvu_numtostr(impl_repp->pardesclist_rep[n]->toggled) + "."); } } void PRESET::parse_operator_option(const string& arg) { CHAIN_OPERATOR *cop; GENERIC_CONTROLLER* gctrl; /* phase 1: parse for cop definitions -eabc:1.0,%param1,2.0 */ vector arg_indices; vector arg_slave_indices; vector ps_parts(kvu_get_number_of_arguments(arg)); for(int i = 0; i < kvu_get_number_of_arguments(arg); i++) { string onearg = kvu_get_argument_number(i + 1, arg); if(onearg.size() > 0 && onearg[0] == '%') { // FIXME: what if %xxx options are given in the "wrong" order? size_t preset_index = atoi(kvu_get_argument_number(i + 1, arg).substr(1).c_str()); if (preset_index <= arg_indices.size()) { preset_index = arg_indices.size() + 1; } arg_indices.push_back(preset_index); arg_slave_indices.push_back(i + 1); ps_parts[i] = "0.0"; // make sure param is mentioned in param_names list if (impl_repp->preset_param_names_rep.size() < preset_index) { impl_repp->preset_param_names_rep.resize(preset_index); impl_repp->preset_param_names_rep[preset_index - 1] = string("arg-") + kvu_numtostr(preset_index); } } else { ps_parts[i] = onearg; } } DBC_CHECK(arg_indices.size() == arg_slave_indices.size()); /* phase 2: 'ps' is set to -eabc:1.0,2.0,2.0 (no %-params) */ string ps = "-" + kvu_get_argument_prefix(arg) + ":" + kvu_vector_to_string(ps_parts, ","); // cerr << "Creating object from '" << ps << "'." << endl; /* phase 3: create an object using 'ps' */ DYNAMIC_OBJECT* object = 0; cop = 0; cop = ECA_OBJECT_FACTORY::create_chain_operator(ps); if (cop == 0) cop = ECA_OBJECT_FACTORY::create_ladspa_plugin(ps); if(cop == 0) cop=ECA_OBJECT_FACTORY::create_lv2_plugin(ps); if (cop != 0) { chains.back()->add_chain_operator(cop); chains.back()->selected_chain_operator_as_target(); object = cop; } else { if (kvu_get_argument_prefix(ps) == "kx") chains.back()->selected_controller_as_target(); else { gctrl = ECA_OBJECT_FACTORY::create_controller(ps); if (gctrl != 0) { impl_repp->gctrls_rep.push_back(gctrl); chains.back()->add_controller(gctrl); } object = gctrl; } } /* phase 4: create an object using 'ps' */ if (object != 0) { for(int i = 0; i < static_cast(arg_indices.size()); i++) { // NOTE: there's a one-to-many connection between // presets' parameters and 'object-param' pairs // (ie. one preset-parameter can control // multiple object params (param_objects and // param_indices) size_t preset_index = arg_indices[i]; // NOTE: for instance for LADSPA plugins -el:label,par1,par2 // number_of_args is 3, but number_of_params is 2! int slave_index = arg_slave_indices[i]; slave_index -= kvu_get_number_of_arguments(arg) - object->number_of_params(); if (preset_index > impl_repp->slave_param_objects_rep.size()) { impl_repp->slave_param_objects_rep.resize(preset_index); impl_repp->slave_param_indices_rep.resize(preset_index); } impl_repp->slave_param_objects_rep[preset_index - 1].push_back(object); impl_repp->slave_param_indices_rep[preset_index - 1].push_back(slave_index); // cerr << "Linking preset parameter " << preset_index << " to object '" << impl_repp->slave_param_objects_rep[preset_index - 1].back()->name() << "', and its parameter '" << impl_repp->slave_param_objects_rep[preset_index - 1].back()->get_parameter_name(impl_repp->slave_param_indices_rep[preset_index - 1].back()) << "'." << endl; DBC_CHECK(impl_repp->slave_param_objects_rep.size() == impl_repp->slave_param_indices_rep.size()); } } } void PRESET::add_chain(void) { chains.push_back(new CHAIN()); buffers.push_back(new SAMPLE_BUFFER()); } string PRESET::parameter_names(void) const { return kvu_vector_to_string(impl_repp->preset_param_names_rep, ","); } void PRESET::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { if (param > 0 && param <= static_cast(impl_repp->slave_param_objects_rep.size())) { for(size_t n = 0; n < impl_repp->slave_param_objects_rep[param - 1].size(); n++) { DBC_CHECK(static_cast(impl_repp->slave_param_indices_rep.size()) > param - 1); DBC_CHECK(impl_repp->slave_param_indices_rep[param - 1].size() > n); int index = impl_repp->slave_param_indices_rep[param - 1][n]; // cerr << "Setting preset " << name() << " param " << param << " (" << impl_repp->slave_param_objects_rep[param-1][n]->get_parameter_name(param) << "), of object " << impl_repp->slave_param_objects_rep[param-1][n]->name() << ", with index number " << index << ", to value " << value << "." << endl; impl_repp->slave_param_objects_rep[param-1][n]->set_parameter(index, value); } } } CHAIN_OPERATOR::parameter_t PRESET::get_parameter(int param) const { if (param > 0 && param <= static_cast(impl_repp->slave_param_objects_rep.size())) { DBC_CHECK(static_cast(impl_repp->slave_param_indices_rep.size()) > param - 1); if (impl_repp->slave_param_indices_rep[param - 1].size() > 0) { int index = impl_repp->slave_param_indices_rep[param - 1][0]; DBC_CHECK(index > 0); // cerr << "Getting preset " << name() << " param " << param << ", index number " << index cerr << " with value " << impl_repp->slave_param_objects_rep[param-1][0]->get_parameter(index) << "." << endl; return impl_repp->slave_param_objects_rep[param-1][0]->get_parameter(index); } } return 0.0f; } void PRESET::init(SAMPLE_BUFFER *insample) { DBC_CHECK(samples_per_second() > 0); first_buffer = insample; chains[0]->set_samples_per_second(samples_per_second()); chains[0]->init(first_buffer, first_buffer->number_of_channels(), first_buffer->number_of_channels()); for(size_t q = 1; q < chains.size(); q++) { DBC_CHECK(q - 1 < buffers.size()); buffers[q - 1]->length_in_samples(first_buffer->length_in_samples()); buffers[q - 1]->number_of_channels(first_buffer->number_of_channels()); chains[q]->set_samples_per_second(samples_per_second()); chains[q]->init(buffers[q - 1], first_buffer->number_of_channels(), first_buffer->number_of_channels()); } for(size_t n = 0; n < impl_repp->gctrls_rep.size(); n++) { impl_repp->gctrls_rep[n]->init(); } } void PRESET::release(void) { /* reimplemented from CHAIN_OPERATOR base class; * see init() */ vector::iterator q = chains.begin(); while(q != chains.end()) { (*q)->release(); ++q; } first_buffer = 0; } void PRESET::process(void) { vector::iterator p = buffers.begin(); while(p != buffers.end()) { (*p)->copy_all_content(*first_buffer); ++p; } vector::iterator q = chains.begin(); while(q != chains.end()) { (*q)->process(); ++q; } if (chains.size() > 1) { first_buffer->divide_by(chains.size()); p = buffers.begin(); while(p != buffers.end()) { first_buffer->add_with_weight(**p, static_cast(chains.size())); ++p; } } } ecasound-2.9.1/libecasound/eca-engine.cpp0000644000076400007640000014674512260763330015267 00000000000000// ------------------------------------------------------------------------ // eca-engine.cpp: Main processing engine // Copyright (C) 1999-2009,2012 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include #include #include #include #include #include /* gettimeofday() */ #include #include #include #include #include #include "samplebuffer.h" #include "audioio.h" #include "audioio-buffered.h" #include "audioio-device.h" #include "audioio-db-client.h" #include "audioio-loop.h" #include "audioio-barrier.h" #include "audioio-mp3.h" #include "midi-server.h" #include "eca-chain.h" #include "eca-chainop.h" #include "eca-error.h" #include "eca-logger.h" #include "eca-chainsetup-edit.h" #include "eca-engine.h" #include "eca-engine_impl.h" using std::cerr; using std::endl; using std::vector; /** * Enable and disable features */ /* Profile callback execution */ // #define PROFILE_ENGINE /** * Local macro definitions */ #ifdef PROFILE_ENGINE_EXECUTION #define PROFILE_ENGINE_STATEMENT(x) (x) #else #define PROFILE_ENGINE_STATEMENT(x) ((void)0) #endif /** * Prototypes of static functions */ static void mix_to_outputs_divide_helper(const SAMPLE_BUFFER *from, SAMPLE_BUFFER *to, int divide_by, bool first_time); static void mix_to_outputs_sum_helper(const SAMPLE_BUFFER *from, SAMPLE_BUFFER *to, bool first_time); /** * Implementations of non-static functions */ /********************************************************************** * Driver implementation **********************************************************************/ int ECA_ENGINE_DEFAULT_DRIVER::exec(ECA_ENGINE* engine, ECA_CHAINSETUP* csetup) { bool drain_at_end = false; engine_repp = engine; exit_request_rep = false; engine->init_engine_state(); while(true) { engine_repp->check_command_queue(); /* case 1: external exit request */ if (exit_request_rep == true) break; /* case 2: engine running, execute one loop iteration */ if (engine_repp->status() == ECA_ENGINE::engine_status_running) { engine_repp->engine_iteration(); } else { /* case 3a-i: engine finished and in batch mode -> exit */ if (engine_repp->status() == ECA_ENGINE::engine_status_finished && engine_repp->batch_mode() == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "batch finished in exec, exit"); drain_at_end = true; break; } /* case 3a-ii: engine error occured -> exit */ else if (engine_repp->status() == ECA_ENGINE::engine_status_error) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "engine error, exit"); break; } /* case 3b: engine not running, wait for commands */ engine_repp->wait_for_commands(); } engine_repp->update_engine_state(); } if (engine_repp->is_prepared() == true) engine_repp->stop_operation(drain_at_end); return 0; } void ECA_ENGINE_DEFAULT_DRIVER::start(void) { if (engine_repp->is_prepared() != true) engine_repp->prepare_operation(); engine_repp->start_operation(); } void ECA_ENGINE_DEFAULT_DRIVER::stop(bool drain) { if (engine_repp->is_prepared() == true) engine_repp->stop_operation(drain); } void ECA_ENGINE_DEFAULT_DRIVER::exit(void) { if (engine_repp->is_prepared() == true) engine_repp->stop_operation(); exit_request_rep = true; /* no need to block here as the next * function will be exec() */ } /********************************************************************** * Engine implementation - Public functions **********************************************************************/ /** * Context help: * J = originates from driver callback * E = ----- " ------- engine thread (exec()) * C = ----- " ------- control thread (external) * * X-level-Y -> Y = steps from originating functions */ /** * Class constructor. A pointer to an enabled * ECA_CHAINSETUP object must be given as argument. * * @pre csetup != 0 * @pre csetup->is_enabled() == true * @post status() == ECA_ENGINE::engine_status_stopped */ ECA_ENGINE::ECA_ENGINE(ECA_CHAINSETUP* csetup) : prepared_rep(false), running_rep(false), finished_rep(false), outputs_finished_rep(0), driver_errors_rep(0), csetup_repp(csetup), mixslot_repp(0) { // -- DBC_REQUIRE(csetup != 0); DBC_REQUIRE(csetup->is_enabled() == true); // -- ECA_LOG_MSG(ECA_LOGGER::system_objects, "ECA_ENGINE constructor"); csetup_repp->toggle_locked_state(true); impl_repp = new ECA_ENGINE_impl; mixslot_repp = new SAMPLE_BUFFER(buffersize(), 0); init_variables(); init_connection_to_chainsetup(); PROFILE_ENGINE_STATEMENT(init_profiling()); csetup_repp->toggle_locked_state(false); // -- DBC_ENSURE(status() == ECA_ENGINE::engine_status_stopped); // -- } /** * Class destructor. */ ECA_ENGINE::~ECA_ENGINE(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "ECA_ENGINE destructor"); if (csetup_repp != 0) { command(ECA_ENGINE::ep_exit, 0.0f); wait_for_exit(5); if (csetup_repp != 0) { cleanup(); } } PROFILE_ENGINE_STATEMENT(dump_profile_info()); if (driver_local == true) { delete driver_repp; driver_repp = 0; } for(size_t n = 0; n < cslots_rep.size(); n++) { delete cslots_rep[n]; } delete mixslot_repp; delete impl_repp; ECA_LOG_MSG(ECA_LOGGER::subsystems, "Engine exiting"); } /** * Launches the engine. This function will block * until processing is finished. * * Note that a exec() is a one-shot function. * It's not possible to call it multiple times. * * @param batch_mode if true, once engine is started * it will continue processing until * 'status() == engine_status_finished' * condition is reached and then exit; * if false, engine will react to * commands until explicit 'exit' is * given * * @see command() * @see status() * * @pre is_valid() == true * @post status() == ECA_ENGINE::engine_status_notready * @post is_valid() != true */ int ECA_ENGINE::exec(bool batch_mode) { // -- DBC_REQUIRE(csetup_repp != 0); DBC_REQUIRE(csetup_repp->is_enabled() == true); // -- int result = 0; csetup_repp->toggle_locked_state(true); batchmode_enabled_rep = batch_mode; ECA_LOG_MSG(ECA_LOGGER::subsystems, "Engine - Driver start"); int res = driver_repp->exec(this, csetup_repp); if (res < 0) { ++driver_errors_rep; ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Engine has raised an error! " "Possible causes: connection lost to system services, unable to adapt " "to changes in operating environment, etc."); } csetup_repp->toggle_locked_state(false); signal_exit(); if (outputs_finished_rep > 0) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: An output object has raised an error! " "Possible causes: Out of disk space, permission denied, unable to launch external " "applications needed in processing, etc."); } DBC_CHECK(status() == ECA_ENGINE::engine_status_stopped || status() == ECA_ENGINE::engine_status_finished || status() == ECA_ENGINE::engine_status_error); if (status() == ECA_ENGINE::engine_status_error) { result = -1; } cleanup(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Engine state when finishing: " + kvu_numtostr(static_cast(status()))); // -- DBC_ENSURE(status() == ECA_ENGINE::engine_status_notready); // -- return result; } /** * Sends 'cmd' to engines command queue. Commands are * processed in the server's main loop. * * context: C-level-0 * must no be called from exec() context */ void ECA_ENGINE::command(Engine_command_t cmd, double arg) { ECA_ENGINE::complex_command_t item; item.type = cmd; item.m.legacy.value = arg; impl_repp->command_queue_rep.push_back(item); } /** * Sends 'ccmd' to engines command queue. Commands are * processed in the server's main loop. Passing a complex * command allows to address objects regardless of * the state of ECA_CHAINSETUP iterators (i.e. currently * selected objects). * * context: C-level-0 * must no be called from exec() context */ void ECA_ENGINE::command(complex_command_t ccmd) { impl_repp->command_queue_rep.push_back(ccmd); } /** * Wait for a stop signal. Functions blocks until * the signal is received or 'timeout' seconds * has elapsed. * * context: C-level-0 * must not be run from the engine * driver context * * @see signal_stop() */ void ECA_ENGINE::wait_for_stop(int timeout) { struct timespec timeoutspec; // FIXME: start to use MONOTONIC, needs pthread_condattr_setclock int ret = kvu_pthread_cond_timeout(timeout, &timeoutspec, false); DBC_CHECK(ret == 0); pthread_mutex_lock(&impl_repp->ecasound_stop_mutex_repp); while(running_rep == true) { ret = pthread_cond_timedwait(&impl_repp->ecasound_stop_cond_repp, &impl_repp->ecasound_stop_mutex_repp, &timeoutspec); ECA_LOG_MSG(ECA_LOGGER::system_objects, kvu_pthread_timed_wait_result(ret, "wait_for_stop")); } pthread_mutex_unlock(&impl_repp->ecasound_stop_mutex_repp); } /** * Wait for an exit signal. Function blocks until * the signal is received or 'timeout' seconds * has elapsed. * * context: C-level-0 * * @see signal_exit() */ void ECA_ENGINE::wait_for_exit(int timeout) { int ret = kvu_pthread_timed_wait(&impl_repp->ecasound_exit_mutex_repp, &impl_repp->ecasound_exit_cond_repp, timeout); ECA_LOG_MSG(ECA_LOGGER::info, kvu_pthread_timed_wait_result(ret, "(eca_main) wait_for_exit")); } /********************************************************************** * Engine implementation - Public functions for observing engine * status information **********************************************************************/ /** * Returns true engine's internal * state is valid for processing. * * context: C-level-0 * no limitations */ bool ECA_ENGINE::is_valid(void) const { if (csetup_repp == 0 || csetup_repp->is_enabled() != true || csetup_repp->is_valid() != true || chains_repp == 0 || chains_repp->size() == 0 || inputs_repp == 0 || inputs_repp->size() == 0 || outputs_repp == 0 || outputs_repp->size() == 0) { return false; } return true; } /** * Whether current setup has finite length. * * context: C-level-0 */ bool ECA_ENGINE::is_finite_length(void) const { DBC_CHECK(csetup_repp != 0); if (csetup_repp->max_length_set() == true || csetup_repp->number_of_realtime_inputs() == 0) { return true; } return false; } /** * Returns engine's current status. * * context: C-level-0 * no limitations */ ECA_ENGINE::Engine_status_t ECA_ENGINE::status(void) const { if (csetup_repp == 0) return ECA_ENGINE::engine_status_notready; /* calculated in update_engine_status() */ if (finished_rep == true) return ECA_ENGINE::engine_status_finished; if (outputs_finished_rep > 0 || driver_errors_rep > 0) return ECA_ENGINE::engine_status_error; if (is_running() == true) return ECA_ENGINE::engine_status_running; if (is_prepared() == true) return ECA_ENGINE::engine_status_stopped; return ECA_ENGINE::engine_status_stopped; } /********************************************************************** * Engine implementation - API for engine driver objects **********************************************************************/ /** * Processes available new commands. If no * messages are available, function will return * immediately without blocking. * * context: E-level-1 * can be run at the same time as engine_iteration(); * note! this is called with the engine lock held * so no long operations allowed! */ void ECA_ENGINE::check_command_queue(void) { while(impl_repp->command_queue_rep.is_empty() != true) { ECA_ENGINE::complex_command_t item; int popres = impl_repp->command_queue_rep.pop_front(&item); if (popres <= 0) { /* queue is empty or temporarily unavailable, unable to continue * processing messages without blocking */ break; } switch(item.type) { // --- // Basic commands. // --- case ep_exit: { // FIXME: is clear the right thing or should remaining cmds // be still processed? OTOH, client app should know... impl_repp->command_queue_rep.clear(); ECA_LOG_MSG(ECA_LOGGER::system_objects,"ecasound_queue: exit!"); driver_repp->exit(); return; } // --- // Chain operators (stateless addressing) // --- case ep_exec_edit: { csetup_repp->execute_edit(item.cs); if (item.cs.need_chain_reinit) { reinit_chains(true); } break; } case ep_prepare: { if (is_prepared() != true) prepare_operation(); break; } case ep_start: { if (status() != engine_status_running) request_start(); break; } case ep_stop: { if (status() == engine_status_running || status() == engine_status_finished) request_stop(false); break; } case ep_stop_with_drain: { if (status() == engine_status_running || status() == engine_status_finished) request_stop(true); break; } // --- // Global position // --- case ep_rewind: { change_position(- item.m.legacy.value); break; } case ep_forward: { change_position(item.m.legacy.value); break; } case ep_setpos: { set_position(item.m.legacy.value); break; } case ep_setpos_samples: { set_position_samples(static_cast(item.m.legacy.value)); break; } case ep_setpos_live_samples: { set_position_samples_live(static_cast(item.m.legacy.value)); break; } case ep_debug: break; } /* switch */ } } /** * Waits for new commands to arrive. Function * will block until at least one new message * is available or until a timeout occurs. * * context: E-level-1 * can be run at the same time as * engine_iteration() */ void ECA_ENGINE::wait_for_commands(void) { impl_repp->command_queue_rep.poll(5, 0); } /** * Intializes internal state variables. * * context: E-level-1 * must not be run at the same * time as engine_iteration() * * @see update_engine_state() */ void ECA_ENGINE::init_engine_state(void) { finished_rep = false; inputs_not_finished_rep = 1; // for the 1st iteration outputs_finished_rep = 0; mixslot_repp->event_tag_set(SAMPLE_BUFFER::tag_end_of_stream, false); for(size_t n = 0; n < cslots_rep.size(); n++) { cslots_rep[n]->event_tag_set(SAMPLE_BUFFER::tag_end_of_stream, false); } } /** * Updates engine state to match current * situation. * * context: J-level-0 * must not be run at the same * time as engine_iteration() * * @see init_engine_state() */ void ECA_ENGINE::update_engine_state(void) { // -- // Check whether all inputs have finished // (note: as update_engine_state() is // guaranteed to not to be called at the same // time as engine_iteration(), this is the // only safe place to calculate finished state if (inputs_not_finished_rep == 0 && outputs_finished_rep == 0 && finished_rep != true) { if (is_running() == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects,"all inputs finished - stop"); // FIXME: this is still wrong, command() is not fully rt-safe // we are not allowed to call request_stop here command(ECA_ENGINE::ep_stop_with_drain, 0.0f); } state_change_to_finished(); } // -- // Check whether some output has raised an error if (status() == ECA_ENGINE::engine_status_error) { if (is_running() == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects,"output error - stop"); // FIXME: this is still wrong, command() is not fully rt-safe // we are not allowed to call request_stop here command(ECA_ENGINE::ep_stop, 0.0f); } } } /** * Executes one engine loop iteration. It is critical * that this function is only called when engine is * running. * * @pre is_running() == true * * context: J-level-0 */ void ECA_ENGINE::engine_iteration(void) { DBC_CHECK(is_running() == true); PROFILE_ENGINE_STATEMENT(impl_repp->looptimer_rep.start(); impl_repp->looptimer_range_rep.start()); inputs_not_finished_rep = 0; prehandle_control_position(); inputs_to_chains(); process_chains(); // FIXME: add support for sub-buffersize offsets if (preroll_samples_rep >= recording_offset_rep) { /* record material to non-real-time outputs */ mix_to_outputs(false); } else { /* skip slave targets */ mix_to_outputs(true); preroll_samples_rep += buffersize(); } posthandle_control_position(); PROFILE_ENGINE_STATEMENT(impl_repp->looptimer_rep.stop(); impl_repp->looptimer_range_rep.stop()); } /** * Reinitialize chains * * Flush any existing state from the chain operators (e.g. * old audio data in buffers, changes in configuration, and * so forth). * * @arg force force reinitialization even if chain itself * reports it is properly initialized */ void ECA_ENGINE::reinit_chains(bool force) { for(size_t i = 0; i != chains_repp->size(); i++) { if (force == true || (*chains_repp)[i]->is_initialized() != true) { (*chains_repp)[i]->init(0, 0, 0); } } } /** * Prepares engine for operation. Prepares all * realtime devices and starts servers. * * This function should be called by the * driver before it starts iterating the * engine's main loop. * * context: E-level-1/3 * must not be run at the same time * as engine_iteration() * * @pre is_running() != true * @pre is_prepared() != true * @post is_prepared() == true * @post status() == ECA_ENGINE::engine_status_running */ void ECA_ENGINE::prepare_operation(void) { // --- DBC_REQUIRE(is_running() != true); DBC_REQUIRE(is_prepared() != true); // --- /* 1. acquire rt-lock for chainsetup and samplebuffers */ csetup_repp->toggle_locked_state(true); for(size_t n = 0; n < cslots_rep.size(); n++) { cslots_rep[n]->set_rt_lock(true); } mixslot_repp->set_rt_lock(true); /* 2. reinitialize chains if necessary */ reinit_chains(true); /* 3. start subsystem servers and forked audio objects */ start_forked_objects(); start_servers(); /* 4. prepare rt objects */ prepare_realtime_objects(); /* ... initial offset is needed because preroll is * incremented only after checking whether we are * still in preroll mode */ preroll_samples_rep = buffersize(); /* 6. enable rt-scheduling */ if (csetup_repp->raised_priority() == true) { if (kvu_set_thread_scheduling(SCHED_FIFO, csetup_repp->get_sched_priority()) != 0) ECA_LOG_MSG(ECA_LOGGER::system_objects, "Unable to change scheduling policy!"); else ECA_LOG_MSG(ECA_LOGGER::user_objects, std::string("Using realtime-scheduling (SCHED_FIFO:") + kvu_numtostr(csetup_repp->get_sched_priority()) + ")."); } /* 7. change engine to active and running */ prepared_rep = true; init_engine_state(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "engine prepared"); // --- DBC_ENSURE(is_prepared() == true); DBC_ENSURE(status() == ECA_ENGINE::engine_status_stopped); // --- } /** * Starts engine operation. * * This function should be called by the * driver just before it starts iterating the * engine's main loop. * * context: E-level-1/3 * must not be run at the same time * as engine_iteration() * * @pre is_prepared() == true * @pre is_running() != true * @post is_running() == true * @post status() == ECA_ENGINE::engine_status_running */ void ECA_ENGINE::start_operation(void) { // --- DBC_REQUIRE(is_prepared() == true); DBC_REQUIRE(is_running() != true); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "starting engine operation!"); start_realtime_objects(); running_rep = true; // --- DBC_ENSURE(is_running() == true); DBC_ENSURE(status() == ECA_ENGINE::engine_status_running); // --- } /** * Stops all realtime devices and servers. * * This function should be called by the * driver when it stops iterating the * engine's main loop. * * context: E-level-1/3 * must not be run at the same time * as engine_iteration() * * @param drain whether to block until all queued data is processed * by realtime devices before stopping * * @pre is_running() == true * @post is_running() != true * @post is_prepared() != true */ void ECA_ENGINE::stop_operation(bool drain) { // --- DBC_REQUIRE(is_prepared() == true); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "stopping engine operation!"); /* stop realtime devices */ for (unsigned int adev_sizet = 0; adev_sizet != realtime_objects_rep.size(); adev_sizet++) { if (realtime_objects_rep[adev_sizet]->is_running() == true) realtime_objects_rep[adev_sizet]->stop(drain); } prepared_rep = false; /* release samplebuffer rt-locks */ for(size_t n = 0; n < cslots_rep.size(); n++) { cslots_rep[n]->set_rt_lock(false); } mixslot_repp->set_rt_lock(false); stop_servers(); stop_forked_objects(); /* lower priority back to normal */ if (csetup_repp->raised_priority() == true) { if (kvu_set_thread_scheduling(SCHED_OTHER, 0) != 0) ECA_LOG_MSG(ECA_LOGGER::info, "Unable to change scheduling back to SCHED_OTHER!"); else ECA_LOG_MSG(ECA_LOGGER::system_objects, "Changed back to non-realtime scheduling SCHED_OTHER."); } /* release chainsetup lock */ csetup_repp->toggle_locked_state(false); /* signals wait_for_stop() that engine operation has stopped */ signal_stop(); // --- DBC_ENSURE(is_running() != true); DBC_ENSURE(is_prepared() != true); // --- } /** * Whether engine has been actived * with prepare_operation(). * * context: no limitations */ bool ECA_ENGINE::is_prepared(void) const { return prepared_rep; } /** * Whether engine has been started * with start_operation(). * * context: no limitations */ bool ECA_ENGINE::is_running(void) const { return running_rep; } /********************************************************************** * Engine implementation - Attribute functions **********************************************************************/ long int ECA_ENGINE::buffersize(void) const { DBC_CHECK(csetup_repp != 0); return csetup_repp->buffersize(); } int ECA_ENGINE::max_channels(void) const { int result = 0; for(unsigned int n = 0; n < csetup_repp->inputs.size(); n++) { if (csetup_repp->inputs[n]->channels() > result) result = csetup_repp->inputs[n]->channels(); } for(unsigned int n = 0; n < csetup_repp->outputs.size(); n++) { if (csetup_repp->outputs[n]->channels() > result) result = csetup_repp->outputs[n]->channels(); } return result; } /********************************************************************** * Engine implementation - Private functions for transport control **********************************************************************/ /** * Requests the engine driver to start operation. * * This function should only be called from * check_command_queue(). * * @pre status() != engine_status_running * * context: E-level-2 */ void ECA_ENGINE::request_start(void) { // --- DBC_REQUIRE(status() != engine_status_running); // --- ECA_LOG_MSG(ECA_LOGGER::user_objects, "Request start"); // -- // start the driver driver_repp->start(); } /** * Requests the engine driver to stop operation. * * This function should only be called from * check_command_queue(). * * @pre status() == ECA_ENGINE::engine_status_running || * status() == ECA_ENGINE::engine_status_finished * * context: E-level-2 */ void ECA_ENGINE::request_stop(bool drain) { // --- DBC_REQUIRE(status() == engine_status_running || status() == engine_status_finished); // --- ECA_LOG_MSG(ECA_LOGGER::user_objects, std::string("Request stop (") + (drain ? std::string("drain") : std::string("no-drain")) + ")"); driver_repp->stop(drain); } /** * Sends a stop signal indicating that engine * state has changed to stopped. * * context: E-level-1/4 * * @see wait_for_stop() */ void ECA_ENGINE::signal_stop(void) { pthread_mutex_lock(&impl_repp->ecasound_stop_mutex_repp); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Signaling stop"); running_rep = false; pthread_cond_broadcast(&impl_repp->ecasound_stop_cond_repp); pthread_mutex_unlock(&impl_repp->ecasound_stop_mutex_repp); } /** * Sends an exit signal indicating that engine * driver has exited. * * context: E-level-1/4 * * @see wait_for_exit() */ void ECA_ENGINE::signal_exit(void) { pthread_mutex_lock(&impl_repp->ecasound_exit_mutex_repp); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Signaling exit"); pthread_cond_broadcast(&impl_repp->ecasound_exit_cond_repp); pthread_mutex_unlock(&impl_repp->ecasound_exit_mutex_repp); } /** * Processing is start If and only if processing * previously stopped with conditional_stop(). * * context: E-level-3 */ void ECA_ENGINE::conditional_start(void) { if (was_running_rep == true) { // don't call request_start(), as it would signal that we are // starting from completely halted state if (is_prepared() != true) prepare_operation(); start_operation(); } } /** * Processing is stopped. * * context: E-level-3 * * @see conditional_stop() * @see request_stop() */ void ECA_ENGINE::conditional_stop(void) { if (status() == ECA_ENGINE::engine_status_running) { ECA_LOG_MSG(ECA_LOGGER::system_objects,"conditional stop"); was_running_rep = true; // don't call request_stop(), as it would signal that we are // stopping completely (JACK transport stop will be sent to all) if (is_prepared() == true) stop_operation(false); } else was_running_rep = false; } void ECA_ENGINE::start_servers(void) { if (csetup_repp->double_buffering() == true) { csetup_repp->pserver_repp->start(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "prefilling i/o buffers."); csetup_repp->pserver_repp->wait_for_full(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "i/o buffers prefilled."); } if (use_midi_rep == true) { csetup_repp->midi_server_repp->start(); } } void ECA_ENGINE::stop_servers(void) { if (csetup_repp->double_buffering() == true) { csetup_repp->pserver_repp->stop(); csetup_repp->pserver_repp->wait_for_stop(); } if (use_midi_rep == true) { csetup_repp->midi_server_repp->stop(); } } /** * Goes through all input/outputs in 'vec', checks whether they * implement the AUDIO_IO_BARRIER interface, and if yes, * issues either 'start_io()' or 'stop_io()' on them. */ static void priv_toggle_forked_objects(bool start, std::vector* vec) { unsigned int n; for(n = 0; n < vec->size(); n++) { AUDIO_IO_BARRIER *barrier = dynamic_cast((*vec)[n]); if (barrier) { if (start) barrier->start_io(); else barrier->stop_io(); } } } void ECA_ENGINE::start_forked_objects(void) { priv_toggle_forked_objects(true, inputs_repp); priv_toggle_forked_objects(true, outputs_repp); } void ECA_ENGINE::stop_forked_objects(void) { priv_toggle_forked_objects(false, inputs_repp); priv_toggle_forked_objects(false, outputs_repp); } void ECA_ENGINE::state_change_to_finished(void) { if (finished_rep != true) { ECA_LOG_MSG_NOPREFIX(ECA_LOGGER::info, ""); ECA_LOG_MSG(ECA_LOGGER::subsystems, "Engine - Processing finished"); } finished_rep = true; } void ECA_ENGINE::prepare_realtime_objects(void) { /* 1. prepare objects */ for (unsigned int n = 0; n < realtime_objects_rep.size(); n++) { realtime_objects_rep[n]->prepare(); } /* 2. prefill rt output objects with silence */ mixslot_repp->make_silent(); for (unsigned int n = 0; n < realtime_outputs_rep.size(); n++) { if (realtime_outputs_rep[n]->prefill_space() > 0) { if (realtime_outputs_rep[n]->prefill_space() < prefill_threshold_rep * buffersize()) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "audio output '" + realtime_outputs_rep[n]->name() + "' only offers " + kvu_numtostr(realtime_outputs_rep[n]->prefill_space()) + " frames of prefill space. Decreasing amount of prefill."); prefill_threshold_rep = realtime_outputs_rep[n]->prefill_space() / buffersize(); } ECA_LOG_MSG(ECA_LOGGER::user_objects, "prefilling rt-outputs with " + kvu_numtostr(prefill_threshold_rep) + " blocks."); for (int m = 0; m < prefill_threshold_rep; m++) { realtime_outputs_rep[n]->write_buffer(mixslot_repp); } } } } void ECA_ENGINE::start_realtime_objects(void) { /* 1. start all realtime devices */ for (unsigned int n = 0; n < realtime_objects_rep.size(); n++) realtime_objects_rep[n]->start(); } /** * Performs a close-open cycle for all realtime * devices. */ void ECA_ENGINE::reset_realtime_devices(void) { for (size_t n = 0; n < realtime_objects_rep.size(); n++) { if (realtime_objects_rep[n]->is_open() == true) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Reseting rt-object " + realtime_objects_rep[n]->label()); realtime_objects_rep[n]->close(); } } for (size_t n = 0; n < realtime_objects_rep.size(); n++) { realtime_objects_rep[n]->open(); } } /********************************************************************** * Engine implementation - Private functions for observing and * modifying position **********************************************************************/ SAMPLE_SPECS::sample_pos_t ECA_ENGINE::current_position_in_samples(void) const { return csetup_repp->position_in_samples(); } double ECA_ENGINE::current_position_in_seconds_exact(void) const { return csetup_repp->position_in_seconds_exact(); } // FIXME: remove #if 0 double ECA_ENGINE::current_position_chain(void) const { AUDIO_IO* ptr = (*inputs_repp)[(*chains_repp)[csetup_repp->active_chain_index_rep]->connected_input()]; return ptr->position_in_seconds_exact(); return 0.0f; } #endif /** * Seeks to position 'seconds'. Affects all input and * outputs objects, and the chainsetup object position. * * context: E-level-2 */ void ECA_ENGINE::set_position(double seconds) { conditional_stop(); csetup_repp->seek_position_in_seconds(seconds); // reinit chains to flush out any stale audio data related // to the old position reinit_chains(true); // FIXME: calling init_engine_state() may lead to races init_engine_state(); conditional_start(); } /** * Seeks to position 'samples'. Affects all input and * outputs objects, and the chainsetup object position. * * context: E-level-2 */ void ECA_ENGINE::set_position_samples(SAMPLE_SPECS::sample_pos_t samples) { conditional_stop(); csetup_repp->seek_position_in_samples(samples); // reinit chains to flush out any stale audio data related // to the old position reinit_chains(true); // FIXME: calling init_engine_state() may lead to races init_engine_state(); conditional_start(); } /** * Seeks to position 'samples' without stopping the engine. * Affects all input and outputs objects, and the chainsetup * object position. * * context: E-level-2 */ void ECA_ENGINE::set_position_samples_live(SAMPLE_SPECS::sample_pos_t samples) { csetup_repp->seek_position_in_samples(samples); // FIXME: calling init_engine_state() may lead to races init_engine_state(); } /** * Seeks to position 'current+seconds'. Affects all input and * outputs objects, and the chainsetup object position. * * context: E-level-2 */ void ECA_ENGINE::change_position(double seconds) { double curpos = csetup_repp->position_in_seconds_exact(); conditional_stop(); csetup_repp->seek_position_in_seconds(curpos + seconds); conditional_start(); } /** * Calculates how much data we need to process and sets the * buffersize accordingly for all non-real-time inputs. * * context: J-level-1 */ void ECA_ENGINE::prehandle_control_position(void) { csetup_repp->change_position_in_samples(buffersize()); if (csetup_repp->max_length_set() == true && csetup_repp->is_over_max_length() == true) { int extra_tail = csetup_repp->position_in_samples() - csetup_repp->max_length_in_samples(); int buffer_remain = buffersize() - extra_tail; if (buffer_remain < 0) buffer_remain = 0; else if (buffer_remain > buffersize()) buffer_remain = buffersize(); for(unsigned int adev_sizet = 0; adev_sizet < non_realtime_inputs_rep.size(); adev_sizet++) { non_realtime_inputs_rep[adev_sizet]->set_buffersize(buffer_remain); } } } /** * If we've processed all the data that was requested, stop or rewind. * Also resets buffersize to its default value. If finished * state is reached, engine status is set to * 'ECA_ENGINE::engine_status_finished'. */ void ECA_ENGINE::posthandle_control_position(void) { if (csetup_repp->max_length_set() == true && csetup_repp->is_over_max_length() == true) { if (csetup_repp->looping_enabled() == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects,"loop point reached"); inputs_not_finished_rep = 1; csetup_repp->seek_position_in_samples(0); for(unsigned int adev_sizet = 0; adev_sizet < non_realtime_inputs_rep.size(); adev_sizet++) { non_realtime_inputs_rep[adev_sizet]->set_buffersize(buffersize()); } } else { ECA_LOG_MSG(ECA_LOGGER::system_objects,"posthandle_c_p over_max - stop"); if (status() == ECA_ENGINE::engine_status_running || status() == ECA_ENGINE::engine_status_finished) { command(ECA_ENGINE::ep_stop_with_drain, 0.0f); } state_change_to_finished(); } } } /********************************************************************** * Engine implementation - Private functions for setup and cleanup **********************************************************************/ /** * Called only from class constructor. */ void ECA_ENGINE::init_variables(void) { use_midi_rep = false; batchmode_enabled_rep = false; driver_local = false; pthread_cond_init(&impl_repp->ecasound_stop_cond_repp, NULL); pthread_mutex_init(&impl_repp->ecasound_stop_mutex_repp, NULL); pthread_cond_init(&impl_repp->ecasound_exit_cond_repp, NULL); pthread_mutex_init(&impl_repp->ecasound_exit_mutex_repp, NULL); } /** * Called only from class constructor. */ void ECA_ENGINE::init_connection_to_chainsetup(void) { inputs_repp = &(csetup_repp->inputs); outputs_repp = &(csetup_repp->outputs); chains_repp = &(csetup_repp->chains); init_engine_state(); init_driver(); init_prefill(); init_servers(); init_chains(); create_cache_object_lists(); update_cache_chain_connections(); update_cache_latency_values(); } /** * Initializes the engine driver object. */ void ECA_ENGINE::init_driver(void) { if (csetup_repp->engine_driver_repp != 0) { driver_repp = csetup_repp->engine_driver_repp; driver_local = false; } else { driver_repp = new ECA_ENGINE_DEFAULT_DRIVER(); driver_local = true; } } /** * Initializes prefill variables. */ void ECA_ENGINE::init_prefill(void) { int channels = (max_channels() > 0 ? max_channels() : 1); prefill_threshold_rep = 0; if (csetup_repp->max_buffers() == true) prefill_threshold_rep = ECA_ENGINE::prefill_threshold_constant / buffersize() / channels; if (prefill_threshold_rep < ECA_ENGINE::prefill_blocks_constant) prefill_threshold_rep = ECA_ENGINE::prefill_blocks_constant; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Prefill loops: " + kvu_numtostr(prefill_threshold_rep) + " (blocksize " + kvu_numtostr(buffersize()) + ")."); } /** * * Called only from init_connection_to_chainsetup(). */ void ECA_ENGINE::init_servers(void) { if (csetup_repp->midi_devices.size() > 0) { use_midi_rep = true; ECA_LOG_MSG(ECA_LOGGER::info, "Initializing MIDI-server."); csetup_repp->midi_server_repp->init(); } } /** * Called only from init_connection_to_chainsetup(). */ void ECA_ENGINE::init_chains(void) { mixslot_repp->number_of_channels(max_channels()); mixslot_repp->event_tag_set(SAMPLE_BUFFER::tag_mixed_content); cslots_rep.resize(chains_repp->size()); for(size_t n = 0; n < cslots_rep.size(); n++) { cslots_rep[n] = new SAMPLE_BUFFER(buffersize(), max_channels()); } for (unsigned int c = 0; c != chains_repp->size(); c++) { int inch = (*inputs_repp)[(*chains_repp)[c]->connected_input()]->channels(); int outch = (*outputs_repp)[(*chains_repp)[c]->connected_output()]->channels(); (*chains_repp)[c]->init(cslots_rep[c], inch, outch); } } /** * Frees all reserved resources. * * @post status() == ECA_ENGINE::engine_status_notready * @post is_valid() != true */ void ECA_ENGINE::cleanup(void) { if (csetup_repp != 0) { csetup_repp->toggle_locked_state(true); vector::iterator q = csetup_repp->chains.begin(); while(q != csetup_repp->chains.end()) { if (*q != 0) { (*q)->disconnect_buffer(); } ++q; } csetup_repp->toggle_locked_state(false); } csetup_repp = 0; // -- DBC_ENSURE(status() == ECA_ENGINE::engine_status_notready); DBC_ENSURE(is_valid() != true); // -- } /** * Updates 'input_chain_count_rep' and * 'output_chain_count_rep'. */ void ECA_ENGINE::update_cache_chain_connections(void) { input_chain_count_rep.resize(inputs_repp->size()); for(unsigned int n = 0; n < inputs_repp->size(); n++) { input_chain_count_rep[n] = csetup_repp->number_of_attached_chains_to_input(csetup_repp->inputs[n]); } output_chain_count_rep.resize(outputs_repp->size()); for(unsigned int n = 0; n < outputs_repp->size(); n++) { output_chain_count_rep[n] = csetup_repp->number_of_attached_chains_to_output(csetup_repp->outputs[n]); } } /** * Update system latency values for multitrack * recording. */ void ECA_ENGINE::update_cache_latency_values(void) { if (csetup_repp->multitrack_mode() == true && csetup_repp->multitrack_mode_offset() == -1) { long int in_latency = -1; for(unsigned int n = 0; n < realtime_inputs_rep.size(); n++) { if (in_latency == -1) { in_latency = realtime_inputs_rep[n]->latency(); } else { if (in_latency != realtime_inputs_rep[n]->latency()) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Latency mismatch between input objects!"); } } ECA_LOG_MSG(ECA_LOGGER::user_objects, "Input latency for '" + realtime_inputs_rep[n]->name() + "' is " + kvu_numtostr(in_latency) + "."); } long int out_latency = -1; for(unsigned int n = 0; n < realtime_outputs_rep.size(); n++) { if (out_latency == -1) { if (realtime_outputs_rep[n]->prefill_space() > 0) { long int max_prefill = prefill_threshold_rep * buffersize(); if (max_prefill > realtime_outputs_rep[n]->prefill_space()) { max_prefill = realtime_outputs_rep[n]->prefill_space(); } out_latency = max_prefill + realtime_outputs_rep[n]->latency(); } else out_latency = realtime_outputs_rep[n]->latency(); } else { if ((realtime_outputs_rep[n]->prefill_space() > 0 && out_latency != (prefill_threshold_rep * buffersize()) + realtime_outputs_rep[n]->latency()) || (realtime_outputs_rep[n]->prefill_space() == 0 && out_latency != realtime_outputs_rep[n]->latency())) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Latency mismatch between output objects!"); } } ECA_LOG_MSG(ECA_LOGGER::user_objects, "Output latency for '" + realtime_outputs_rep[n]->name() + "' is " + kvu_numtostr(out_latency) + "."); } recording_offset_rep = (out_latency > in_latency ? out_latency : in_latency); if (recording_offset_rep % buffersize()) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Recording offset not divisible with chainsetup buffersize."); } ECA_LOG_MSG(ECA_LOGGER::user_objects, "recording offset is " + kvu_numtostr(recording_offset_rep) + " samples."); } else if (csetup_repp->multitrack_mode() == true) { /* multitrack_mode_offset() explicitly given (not -1) */ recording_offset_rep = csetup_repp->multitrack_mode_offset(); } else { recording_offset_rep = 0; } } /** * Assigns input and output objects in lists of realtime * and nonrealtime objects. */ void ECA_ENGINE::create_cache_object_lists(void) { for(unsigned int n = 0; n < inputs_repp->size(); n++) { if (AUDIO_IO_DEVICE::is_realtime_object((*inputs_repp)[n]) == true) { realtime_inputs_rep.push_back(static_cast((*inputs_repp)[n])); realtime_objects_rep.push_back(static_cast((*inputs_repp)[n])); } else { non_realtime_inputs_rep.push_back((*inputs_repp)[n]); non_realtime_objects_rep.push_back((*inputs_repp)[n]); } } DBC_CHECK(static_cast(realtime_inputs_rep.size()) == csetup_repp->number_of_realtime_inputs()); for(unsigned int n = 0; n < outputs_repp->size(); n++) { if (AUDIO_IO_DEVICE::is_realtime_object((*outputs_repp)[n]) == true) { realtime_outputs_rep.push_back(static_cast((*outputs_repp)[n])); realtime_objects_rep.push_back(static_cast((*outputs_repp)[n])); } else { non_realtime_outputs_rep.push_back((*outputs_repp)[n]); non_realtime_objects_rep.push_back((*outputs_repp)[n]); } } DBC_CHECK(static_cast(realtime_outputs_rep.size()) == csetup_repp->number_of_realtime_outputs()); } /** * Called only from class constructor. */ void ECA_ENGINE::init_profiling(void) { impl_repp->looptimer_low_rep = static_cast(buffersize()) / csetup_repp->samples_per_second(); impl_repp->looptimer_mid_rep = static_cast(buffersize() * 2) / csetup_repp->samples_per_second(); impl_repp->looptimer_high_rep = static_cast(buffersize()) * prefill_threshold_rep / csetup_repp->samples_per_second(); impl_repp->looptimer_rep.set_lower_bound_seconds(impl_repp->looptimer_low_rep); impl_repp->looptimer_rep.set_upper_bound_seconds(impl_repp->looptimer_high_rep); impl_repp->looptimer_range_rep.set_lower_bound_seconds(impl_repp->looptimer_mid_rep); impl_repp->looptimer_range_rep.set_upper_bound_seconds(impl_repp->looptimer_mid_rep); } /** * Prints profiling information to stderr. */ void ECA_ENGINE::dump_profile_info(void) { long int slower_than_rt = impl_repp->looptimer_rep.event_count() - impl_repp->looptimer_rep.events_under_lower_bound() - impl_repp->looptimer_rep.events_over_upper_bound(); cerr << "*** profile begin ***" << endl; cerr << "Loops faster than realtime: " << kvu_numtostr(impl_repp->looptimer_rep.events_under_lower_bound()); cerr << " (<" << kvu_numtostr(impl_repp->looptimer_low_rep * 1000, 1) << " msec)" << endl; cerr << "Loops slower than realtime: " << kvu_numtostr(slower_than_rt); cerr << " (>=" << kvu_numtostr(impl_repp->looptimer_low_rep * 1000, 1) << " msec)" << endl; cerr << "Loops slower than realtime: " << kvu_numtostr(impl_repp->looptimer_range_rep.events_over_upper_bound()); cerr << " (>" << kvu_numtostr(impl_repp->looptimer_mid_rep * 1000, 1) << " msec)" << endl; cerr << "Loops exceeding all buffering: " << kvu_numtostr(impl_repp->looptimer_rep.events_over_upper_bound()); cerr << " (>" << kvu_numtostr(impl_repp->looptimer_high_rep * 1000, 1) << " msec)" << endl; cerr << "Total loops: " << kvu_numtostr(impl_repp->looptimer_rep.event_count()) << endl; cerr << "Fastest/slowest/average loop time: "; cerr << kvu_numtostr(impl_repp->looptimer_rep.min_duration_seconds() * 1000, 1); cerr << "/"; cerr << kvu_numtostr(impl_repp->looptimer_rep.max_duration_seconds() * 1000, 1); cerr << "/"; cerr << kvu_numtostr(impl_repp->looptimer_rep.average_duration_seconds() * 1000, 1); cerr << " msec." << endl; cerr << "*** profile end ***" << endl; } /********************************************************************** * Engine implementation - Private functions for signal routing **********************************************************************/ /** * Reads audio data from input objects. * * context: J-level-1 (see */ void ECA_ENGINE::inputs_to_chains(void) { /** * - go through all inputs * - depending on connectivity, read either to a mixdown slot, or * directly to a per-chain slot */ for(size_t inputnum = 0; inputnum < inputs_repp->size(); inputnum++) { if (input_chain_count_rep[inputnum] > 1) { /* case-1a: read buffer from input 'inputnum' to 'mixslot'; * later (1b) the data is copied to each per-chain slow * to which input is connected to */ mixslot_repp->length_in_samples(buffersize()); if ((*inputs_repp)[inputnum]->finished() != true) { (*inputs_repp)[inputnum]->read_buffer(mixslot_repp); if ((*inputs_repp)[inputnum]->finished() != true) { inputs_not_finished_rep++; } } else { /* note: no more input data for this change (N:1 input-chain case) */ mixslot_repp->make_empty(); } } for (size_t c = 0; c != chains_repp->size(); c++) { if ((*chains_repp)[c]->connected_input() == static_cast(inputnum)) { if (input_chain_count_rep[inputnum] == 1) { /* case-2: read buffer from input 'inputnum' to chain 'c' */ cslots_rep[c]->length_in_samples(buffersize()); if ((*inputs_repp)[inputnum]->finished() != true) { (*inputs_repp)[inputnum]->read_buffer(cslots_rep[c]); if ((*inputs_repp)[inputnum]->finished() != true) { inputs_not_finished_rep++; } } else { /* note: no more input data for this change (1:1 input-chain case) */ cslots_rep[c]->make_empty(); } /* note: input connected to only one chain, so no need to iterate through the other chains */ break; } else { /* case-1b: input connected to chain 'n', copy 'mixslot' to * the matching per-chain slot */ cslots_rep[c]->copy_all_content(*mixslot_repp); } } } } } /** * context: J-level-1 */ void ECA_ENGINE::process_chains(void) { vector::const_iterator p = chains_repp->begin(); while(p != chains_repp->end()) { (*p)->process(); ++p; } } void mix_to_outputs_divide_helper(const SAMPLE_BUFFER *from, SAMPLE_BUFFER *to, int divide_by, bool first_time) { if (first_time == true) { // this is the first output connected to this chain if (from->number_of_channels() < to->number_of_channels()) { to->make_silent(); } to->copy_matching_channels(*from); to->divide_by(divide_by); } else { to->add_with_weight(*from, divide_by); } } void mix_to_outputs_sum_helper(const SAMPLE_BUFFER *from, SAMPLE_BUFFER *to, bool first_time) { if (first_time == true) { // this is the first output connected to this chain if (from->number_of_channels() < to->number_of_channels()) { to->make_silent(); } to->copy_matching_channels(*from); } else { to->add_matching_channels(*from); } } /** * context: J-level-1 */ void ECA_ENGINE::mix_to_outputs(bool skip_realtime_target_outputs) { for(size_t outputnum = 0; outputnum < outputs_repp->size(); outputnum++) { if (skip_realtime_target_outputs == true) { if (csetup_repp->is_realtime_target_output(outputnum) == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Skipping rt-target output " + (*outputs_repp)[outputnum]->label() + "."); continue; } } int count = 0; /* FIXME: number_of_channels() may end up allocating memory! */ mixslot_repp->number_of_channels((*outputs_repp)[outputnum]->channels()); for(size_t n = 0; n != chains_repp->size(); n++) { // -- // if chain is already released, skip // -- if ((*chains_repp)[n]->connected_output() == -1) { // -- // skip, if chain is not connected // -- continue; } if ((*chains_repp)[n]->connected_output() == static_cast(outputnum)) { // -- // output is connected to this chain // -- if (output_chain_count_rep[outputnum] == 1) { // -- // there's only one output connected to this chain, // so we don't need to mix anything // -- (*outputs_repp)[outputnum]->write_buffer(cslots_rep[n]); if ((*outputs_repp)[outputnum]->finished() == true) /* note: loop devices always connected both as inputs as * outputs, so their finished status must not be * counted as an error (like for other output types) */ if (dynamic_cast((*outputs_repp)[outputnum]) == 0) outputs_finished_rep++; break; } else { ++count; if (csetup_repp->mix_mode() == ECA_CHAINSETUP::cs_mmode_avg) mix_to_outputs_divide_helper(cslots_rep[n], mixslot_repp, output_chain_count_rep[outputnum], (count == 1)); else mix_to_outputs_sum_helper(cslots_rep[n], mixslot_repp, (count == 1)); mixslot_repp->event_tags_add(*cslots_rep[n]); if (count == output_chain_count_rep[outputnum]) { (*outputs_repp)[outputnum]->write_buffer(mixslot_repp); if ((*outputs_repp)[outputnum]->finished() == true) /* note: loop devices always connected both as inputs as * outputs, so their finished status must not be * counted as an error (like for other output types) */ if (dynamic_cast((*outputs_repp)[outputnum]) == 0) outputs_finished_rep++; } } } } } } /********************************************************************** * Engine implementation - Obsolete functions **********************************************************************/ ecasound-2.9.1/libecasound/audioio-mikmod.h0000644000076400007640000000433511141362360015627 00000000000000#ifndef INCLUDED_AUDIOIO_MIKMOD_H #define INCLUDED_AUDIOIO_MIKMOD_H #include #include #include "audioio-buffered.h" #include "audioio-forked-stream.h" /** * Interface to module players such as MikMod that support * UNIX pipe i/o. * * @author Kai Vehmanen */ class MIKMOD_INTERFACE : public AUDIO_IO_BUFFERED, public AUDIO_IO_FORKED_STREAM { private: static std::string default_mikmod_cmd; public: static void set_mikmod_cmd(const std::string& value); public: MIKMOD_INTERFACE (const std::string& name = ""); virtual ~MIKMOD_INTERFACE(void); virtual MIKMOD_INTERFACE* clone(void) const { return new MIKMOD_INTERFACE(*this); } virtual MIKMOD_INTERFACE* new_expr(void) const { return new MIKMOD_INTERFACE(); } virtual std::string name(void) const { return("MikMod tracker module"); } virtual std::string description(void) const { return("Interface to module players that support UNIX pipe i/o."); } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; virtual int supported_io_modes(void) const { return(io_read); } virtual string parameter_names(void) const { return("filename,opt_filename"); } virtual bool supports_seeking(void) const { return(false); } virtual void open(void) throw (AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples) { } virtual bool finished(void) const { return(finished_rep); } virtual void start_io(void); virtual void stop_io(void); protected: /* functions called by AUDIO_IO_FORKED_STREAM that require * the use of AUDIO_IO methods */ virtual bool do_supports_seeking(void) const { return supports_seeking(); } virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { set_position_in_samples(pos); } private: std::string opt_filename_rep; bool triggered_rep; bool finished_rep; long int bytes_read_rep; int filedes_rep; FILE* f1_rep; void seek_position_in_samples(long pos); MIKMOD_INTERFACE& operator=(const MIKMOD_INTERFACE& x) { return *this; } void fork_mikmod(void); void kill_mikmod(void); }; #endif ecasound-2.9.1/libecasound/Makefile.in0000644000076400007640000014570712261511325014626 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/libecasound/Makefile.am # Description: Ecasound main library # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ check_PROGRAMS = libecasound_tester$(EXEEXT) subdir = libecasound DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/libecasound-config.in \ ChangeLog ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = libecasound-config 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = @ECA_AM_DEBUG_MODE_FALSE@am__DEPENDENCIES_2 = $(top_builddir)/libecasound/plugins/libecasound_plugins.la \ @ECA_AM_DEBUG_MODE_FALSE@ $(am__DEPENDENCIES_1) @ECA_AM_DEBUG_MODE_TRUE@am__DEPENDENCIES_2 = $(top_builddir)/libecasound/plugins/libecasound_plugins_debug.la \ @ECA_AM_DEBUG_MODE_TRUE@ $(am__DEPENDENCIES_1) libecasound_la_DEPENDENCIES = $(am__DEPENDENCIES_2) am__libecasound_la_SOURCES_DIST = audioio-cdr.cpp audioio-ewf.cpp \ audioio-mp3.cpp audioio-ogg.cpp audioio-wave.cpp audioio.cpp \ audioio-buffered.cpp audioio-device.cpp audioio-null.cpp \ audioio-raw.cpp audioio-mikmod.cpp audioio-rtnull.cpp \ audioio-loop.cpp audioio-forked-stream.cpp \ audioio-timidity.cpp audioio-db-server.cpp \ audioio-db-buffer.cpp audioio-db-client.cpp \ audioio-typeselect.cpp audioio-resample.cpp \ audioio-reverse.cpp audioio-proxy.cpp audioio-flac.cpp \ audioio-aac.cpp audioio-tone.cpp audioio-seqbase.cpp \ audioio-acseq.cpp audioio-oss.cpp jack-connections.cpp \ midi-server.cpp midi-client.cpp midi-parser.cpp midiio.cpp \ midiio-raw.cpp midiio-aseq.cpp eca-chain.cpp eca-engine.cpp \ samplebuffer.cpp samplebuffer_functions.cpp eca-session.cpp \ eca-resources.cpp resource-file.cpp eca-logger.cpp \ eca-logger-default.cpp eca-logger-interface.cpp \ eca-logger-wellformed.cpp layer.cpp samplebuffer_iterators.cpp \ eca-version.cpp eca-operator.cpp generic-controller.cpp \ eca-object-factory.cpp eca-chainsetup.cpp \ eca-chainsetup-bufparams.cpp eca-chainsetup-parser.cpp \ eca-chainsetup-position.cpp eca-control.cpp \ eca-control-base.cpp eca-control-dump.cpp eca-control-main.cpp \ eca-control-mt.cpp eca-control-objects.cpp \ eca-iamode-parser.cpp eca-samplerate-aware.cpp \ eca-audio-position.cpp eca-audio-format.cpp eca-audio-time.cpp \ eca-fileio-stream.cpp eca-fileio-mmap.cpp eca-osc.cpp \ eca-static-object-maps.cpp eca-object-map.cpp \ eca-preset-map.cpp audiofx.cpp audiofx_misc.cpp \ audiofx_amplitude.cpp audiofx_compressor.cpp \ audiofx_analysis.cpp audiofx_envelope_modulation.cpp \ audiofx_filter.cpp audiofx_rcfilter.cpp audiofx_reverb.cpp \ audiofx_timebased.cpp audiogate.cpp audiofx_mixing.cpp \ audiofx_ladspa.cpp audiofx_lv2.cpp audiofx_lv2_world.cpp \ audio-stamp.cpp global-preset.cpp preset.cpp file-preset.cpp \ midi-cc.cpp osc-gen.cpp osc-gen-file.cpp osc-sine.cpp \ linear-envelope.cpp two-stage-linear-envelope.cpp \ stamp-ctrl.cpp generic-linear-envelope.cpp am__objects_1 = audioio-cdr.lo audioio-ewf.lo audioio-mp3.lo \ audioio-ogg.lo audioio-wave.lo audioio.lo audioio-buffered.lo \ audioio-device.lo audioio-null.lo audioio-raw.lo \ audioio-mikmod.lo audioio-rtnull.lo audioio-loop.lo \ audioio-forked-stream.lo audioio-timidity.lo \ audioio-db-server.lo audioio-db-buffer.lo audioio-db-client.lo \ audioio-typeselect.lo audioio-resample.lo audioio-reverse.lo \ audioio-proxy.lo audioio-flac.lo audioio-aac.lo \ audioio-tone.lo audioio-seqbase.lo audioio-acseq.lo @ECA_AM_COMPILE_OSS_TRUE@am__objects_2 = audioio-oss.lo @ECA_AM_COMPILE_JACK_TRUE@am__objects_3 = jack-connections.lo am__objects_4 = midi-server.lo midi-client.lo midi-parser.lo midiio.lo \ midiio-raw.lo midiio-aseq.lo am__objects_5 = eca-chain.lo eca-engine.lo samplebuffer.lo \ samplebuffer_functions.lo eca-session.lo eca-resources.lo \ resource-file.lo eca-logger.lo eca-logger-default.lo \ eca-logger-interface.lo eca-logger-wellformed.lo layer.lo \ samplebuffer_iterators.lo eca-version.lo eca-operator.lo \ generic-controller.lo eca-object-factory.lo eca-chainsetup.lo \ eca-chainsetup-bufparams.lo eca-chainsetup-parser.lo \ eca-chainsetup-position.lo eca-control.lo eca-control-base.lo \ eca-control-dump.lo eca-control-main.lo eca-control-mt.lo \ eca-control-objects.lo eca-iamode-parser.lo \ eca-samplerate-aware.lo eca-audio-position.lo \ eca-audio-format.lo eca-audio-time.lo eca-fileio-stream.lo \ eca-fileio-mmap.lo eca-osc.lo eca-static-object-maps.lo \ eca-object-map.lo eca-preset-map.lo am__objects_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) am__objects_7 = audiofx.lo audiofx_misc.lo audiofx_amplitude.lo \ audiofx_compressor.lo audiofx_analysis.lo \ audiofx_envelope_modulation.lo audiofx_filter.lo \ audiofx_rcfilter.lo audiofx_reverb.lo audiofx_timebased.lo \ audiogate.lo audiofx_mixing.lo audiofx_ladspa.lo \ audiofx_lv2.lo audiofx_lv2_world.lo audio-stamp.lo am__objects_8 = global-preset.lo preset.lo file-preset.lo am__objects_9 = midi-cc.lo osc-gen.lo osc-gen-file.lo osc-sine.lo \ linear-envelope.lo two-stage-linear-envelope.lo stamp-ctrl.lo \ generic-linear-envelope.lo @ECA_AM_DISABLE_EFFECTS_FALSE@am__objects_10 = $(am__objects_7) \ @ECA_AM_DISABLE_EFFECTS_FALSE@ $(am__objects_8) \ @ECA_AM_DISABLE_EFFECTS_FALSE@ $(am__objects_9) am_libecasound_la_OBJECTS = $(am__objects_6) $(am__objects_10) libecasound_la_OBJECTS = $(am_libecasound_la_OBJECTS) @ECA_AM_DEBUG_MODE_FALSE@am_libecasound_la_rpath = -rpath $(libdir) am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) libecasound_debug_la_DEPENDENCIES = $(am__DEPENDENCIES_3) am__libecasound_debug_la_SOURCES_DIST = audioio-cdr.cpp \ audioio-ewf.cpp audioio-mp3.cpp audioio-ogg.cpp \ audioio-wave.cpp audioio.cpp audioio-buffered.cpp \ audioio-device.cpp audioio-null.cpp audioio-raw.cpp \ audioio-mikmod.cpp audioio-rtnull.cpp audioio-loop.cpp \ audioio-forked-stream.cpp audioio-timidity.cpp \ audioio-db-server.cpp audioio-db-buffer.cpp \ audioio-db-client.cpp audioio-typeselect.cpp \ audioio-resample.cpp audioio-reverse.cpp audioio-proxy.cpp \ audioio-flac.cpp audioio-aac.cpp audioio-tone.cpp \ audioio-seqbase.cpp audioio-acseq.cpp audioio-oss.cpp \ jack-connections.cpp midi-server.cpp midi-client.cpp \ midi-parser.cpp midiio.cpp midiio-raw.cpp midiio-aseq.cpp \ eca-chain.cpp eca-engine.cpp samplebuffer.cpp \ samplebuffer_functions.cpp eca-session.cpp eca-resources.cpp \ resource-file.cpp eca-logger.cpp eca-logger-default.cpp \ eca-logger-interface.cpp eca-logger-wellformed.cpp layer.cpp \ samplebuffer_iterators.cpp eca-version.cpp eca-operator.cpp \ generic-controller.cpp eca-object-factory.cpp \ eca-chainsetup.cpp eca-chainsetup-bufparams.cpp \ eca-chainsetup-parser.cpp eca-chainsetup-position.cpp \ eca-control.cpp eca-control-base.cpp eca-control-dump.cpp \ eca-control-main.cpp eca-control-mt.cpp \ eca-control-objects.cpp eca-iamode-parser.cpp \ eca-samplerate-aware.cpp eca-audio-position.cpp \ eca-audio-format.cpp eca-audio-time.cpp eca-fileio-stream.cpp \ eca-fileio-mmap.cpp eca-osc.cpp eca-static-object-maps.cpp \ eca-object-map.cpp eca-preset-map.cpp audiofx.cpp \ audiofx_misc.cpp audiofx_amplitude.cpp audiofx_compressor.cpp \ audiofx_analysis.cpp audiofx_envelope_modulation.cpp \ audiofx_filter.cpp audiofx_rcfilter.cpp audiofx_reverb.cpp \ audiofx_timebased.cpp audiogate.cpp audiofx_mixing.cpp \ audiofx_ladspa.cpp audiofx_lv2.cpp audiofx_lv2_world.cpp \ audio-stamp.cpp global-preset.cpp preset.cpp file-preset.cpp \ midi-cc.cpp osc-gen.cpp osc-gen-file.cpp osc-sine.cpp \ linear-envelope.cpp two-stage-linear-envelope.cpp \ stamp-ctrl.cpp generic-linear-envelope.cpp am_libecasound_debug_la_OBJECTS = $(am__objects_6) $(am__objects_10) libecasound_debug_la_OBJECTS = $(am_libecasound_debug_la_OBJECTS) @ECA_AM_DEBUG_MODE_TRUE@am_libecasound_debug_la_rpath = -rpath \ @ECA_AM_DEBUG_MODE_TRUE@ $(libdir) am__objects_11 = libecasound_tester.$(OBJEXT) \ eca-test-repository.$(OBJEXT) eca-test-case.$(OBJEXT) am_libecasound_tester_OBJECTS = $(am__objects_11) libecasound_tester_OBJECTS = $(am_libecasound_tester_OBJECTS) @ECA_AM_DEBUG_MODE_FALSE@am__DEPENDENCIES_4 = $(top_builddir)/libecasound/libecasound.la \ @ECA_AM_DEBUG_MODE_FALSE@ $(top_builddir)/kvutils/libkvutils.la @ECA_AM_DEBUG_MODE_TRUE@am__DEPENDENCIES_4 = $(top_builddir)/libecasound/libecasound_debug.la \ @ECA_AM_DEBUG_MODE_TRUE@ $(top_builddir)/kvutils/libkvutils_debug.la libecasound_tester_DEPENDENCIES = $(am__DEPENDENCIES_4) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libecasound_la_SOURCES) $(libecasound_debug_la_SOURCES) \ $(libecasound_tester_SOURCES) DIST_SOURCES = $(am__libecasound_la_SOURCES_DIST) \ $(am__libecasound_debug_la_SOURCES_DIST) \ $(libecasound_tester_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ # Pass pkgdatadir to CPPFLAGS AM_CPPFLAGS = @AM_CPPFLAGS@ "-DECA_PKGDATADIR=\"${pkgdatadir}\"" AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ EXTRA_DIST = ChangeLog AUTOMAKE_OPTIONS = foreign SUBDIRS = plugins @ECA_AM_DEBUG_MODE_FALSE@lib_LTLIBRARIES = libecasound.la # ---------------------------------------------------------------------- # build targets and compiler options target defines # ---------------------------------------------------------------------- @ECA_AM_DEBUG_MODE_TRUE@lib_LTLIBRARIES = libecasound_debug.la TESTS = libecasound_tester @ECA_AM_DEBUG_MODE_FALSE@eca_libadd = $(top_builddir)/libecasound/plugins/libecasound_plugins.la $(ECA_S_EXTRA_LIBS) # ---------------------------------------------------------------------- # compiler and linker options # ---------------------------------------------------------------------- # if ECA_AM_ALL_STATIC # FIXME: always link ecasound-plugins statically @ECA_AM_DEBUG_MODE_TRUE@eca_libadd = $(top_builddir)/libecasound/plugins/libecasound_plugins_debug.la $(ECA_S_EXTRA_LIBS) eca_ldflags = -version-info @LIBECASOUND_VERSION@:0:@LIBECASOUND_VERSION_AGE@ @ECA_AM_DEBUG_MODE_FALSE@libecasound_tester_libs = $(top_builddir)/libecasound/libecasound.la \ @ECA_AM_DEBUG_MODE_FALSE@ $(top_builddir)/kvutils/libkvutils.la @ECA_AM_DEBUG_MODE_TRUE@libecasound_tester_libs = $(top_builddir)/libecasound/libecasound_debug.la \ @ECA_AM_DEBUG_MODE_TRUE@ $(top_builddir)/kvutils/libkvutils_debug.la # note! Automake >= 1.5 will install stripped libraries # with "make install-strip". Older versions won't # strip libraries even if INSTALL_STRIP_FLAG is set. # also libtool 1.3.2 and older have problems # with stripping libraries. INCLUDES = -I$(srcdir) \ -I$(top_srcdir) \ -I$(top_srcdir)/kvutils \ $(ECA_S_EXTRA_CPPFLAGS) # ---------------------------------------------------------------------- # header files # ---------------------------------------------------------------------- ecasound_audiofx_include = \ audiofx.h \ audiofx_misc.h \ audiofx_amplitude.h \ audiofx_compressor.h \ audiofx_analysis.h \ audiofx_envelope_modulation.h \ audiofx_filter.h \ audiofx_rcfilter.h \ audiofx_reverb.h \ audiofx_timebased.h \ audiogate.h \ audiofx_mixing.h \ audiofx_ladspa.h \ audiofx_lv2.h \ audiofx_lv2_world.h \ audio-stamp.h ecasound_preset_include = \ preset.h \ preset_impl.h \ file-preset.h \ global-preset.h ecasound_audioio_include = \ audioio.h \ audioio-buffered.h \ audioio-device.h \ audioio-plugin.h \ audioio-manager.h \ audioio-cdr.h \ audioio-cdr_impl.h \ audioio-ewf.h \ audioio-mp3.h \ audioio-mp3_impl.h \ audioio-ogg.h \ audioio-wave.h \ audioio-raw.h \ audioio-oss.h \ audioio-oss_impl.h \ audioio-null.h \ audioio-rtnull.h \ audioio-mikmod.h \ audioio-loop.h \ audioio-forked-stream.h \ audioio-timidity.h \ audioio-db-server.h \ audioio-db-server_impl.h \ audioio-db-buffer.h \ audioio-db-client.h \ audioio-proxy.h \ audioio-typeselect.h \ audioio-resample.h \ audioio-reverse.h \ audioio-flac.h \ audioio-aac.h \ audioio-tone.h \ audioio-seqbase.h \ audioio-acseq.h \ audioio-barrier.h ecasound_midi_include = \ midi-server.h \ midi-client.h \ midi-parser.h \ midiio.h \ midiio-raw.h \ midiio-aseq.h ecasound_controller_include = \ ctrl-source.h \ midi-cc.h \ oscillator.h \ osc-gen.h \ osc-gen-file.h \ osc-sine.h \ linear-envelope.h \ two-stage-linear-envelope.h \ stamp-ctrl.h \ generic-linear-envelope.h ecasound_general_include = \ eca-chain.h \ eca-chainop.h \ eca-chainsetup-edit.h \ eca-error.h \ eca-logger.h \ eca-logger-default.h \ eca-logger-interface.h \ eca-logger-wellformed.h \ eca-engine.h \ eca-engine-driver.h \ eca-engine_impl.h \ eca-session.h \ eca-resources.h \ resource-file.h \ layer.h \ eca-static-object-maps.h \ eca-object-map.h \ eca-preset-map.h \ samplebuffer.h \ samplebuffer_impl.h \ samplebuffer_functions.h \ samplebuffer_iterators.h \ sample-specs.h \ sample-ops_impl.h \ eca-sample-conversion.h \ eca-version.h \ eca-object-factory.h \ eca-chainsetup.h \ eca-chainsetup_impl.h \ eca-chainsetup-bufparams.h \ eca-chainsetup-parser.h \ eca-chainsetup-position.h \ eca-control.h \ eca-control-dump.h \ eca-control-main.h \ eca-control-mt.h \ eca-iamode-parser.h \ eca-iamode-parser_impl.h \ eca-audio-position.h \ eca-fileio.h \ eca-fileio-stream.h \ eca-fileio-mmap.h \ eca-osc.h \ dynamic-parameters.h \ dynamic-object.h \ eca-object.h \ eca-operator.h \ generic-controller.h \ eca-samplerate-aware.h \ eca-audio-format.h \ eca-audio-time.h \ jack-connections.h ecasound_extra_include = \ ladspa.h ecasound_test_framework_include = \ eca-test-repository.h \ eca-test-case.h \ audiofx_amplitude_test.h \ audioio_test.h \ audioio-device_test.h \ eca-audio-time_test.h \ eca-chainsetup_test.h \ eca-chainsetup-parser_test.h \ eca-control_test.h \ eca-session_test.h \ eca-object-factory_test.h \ eca-sample-conversion_test.h \ generic-linear-envelope_test.h \ samplebuffer_test.h # note! also remembers to update install-data-local and # uninstall-data targets noinst_HEADERS = $(ecasound_audiofx_include) \ $(ecasound_preset_include) \ $(ecasound_audioio_include) \ $(ecasound_midi_include) \ $(ecasound_controller_include) \ $(ecasound_general_include) \ $(ecasound_extra_include) \ $(ecasound_test_framework_include) # ---------------------------------------------------------------------- # source files # ---------------------------------------------------------------------- ecasound_audiofx_src = audiofx.cpp \ audiofx_misc.cpp \ audiofx_amplitude.cpp \ audiofx_compressor.cpp \ audiofx_analysis.cpp \ audiofx_envelope_modulation.cpp \ audiofx_filter.cpp \ audiofx_rcfilter.cpp \ audiofx_reverb.cpp \ audiofx_timebased.cpp \ audiogate.cpp \ audiofx_mixing.cpp \ audiofx_ladspa.cpp \ audiofx_lv2.cpp \ audiofx_lv2_world.cpp \ audio-stamp.cpp ecasound_preset_src = global-preset.cpp \ preset.cpp \ file-preset.cpp ecasound_audioio1_src = audioio-cdr.cpp \ audioio-ewf.cpp \ audioio-mp3.cpp \ audioio-ogg.cpp \ audioio-wave.cpp \ audioio.cpp \ audioio-buffered.cpp \ audioio-device.cpp \ audioio-null.cpp \ audioio-raw.cpp \ audioio-mikmod.cpp \ audioio-rtnull.cpp \ audioio-loop.cpp \ audioio-forked-stream.cpp \ audioio-timidity.cpp \ audioio-db-server.cpp \ audioio-db-buffer.cpp \ audioio-db-client.cpp \ audioio-typeselect.cpp \ audioio-resample.cpp \ audioio-reverse.cpp \ audioio-proxy.cpp \ audioio-flac.cpp \ audioio-aac.cpp \ audioio-tone.cpp \ audioio-seqbase.cpp \ audioio-acseq.cpp @ECA_AM_COMPILE_OSS_FALSE@ecasound_audioio2_src = @ECA_AM_COMPILE_OSS_TRUE@ecasound_audioio2_src = audioio-oss.cpp @ECA_AM_COMPILE_JACK_FALSE@jack_connections_src = @ECA_AM_COMPILE_JACK_TRUE@jack_connections_src = jack-connections.cpp ecasound_midi_src = \ midi-server.cpp \ midi-client.cpp \ midi-parser.cpp \ midiio.cpp \ midiio-raw.cpp \ midiio-aseq.cpp ecasound_controller_src = \ midi-cc.cpp \ osc-gen.cpp \ osc-gen-file.cpp \ osc-sine.cpp \ linear-envelope.cpp \ two-stage-linear-envelope.cpp \ stamp-ctrl.cpp \ generic-linear-envelope.cpp ecasound_general_src = eca-chain.cpp \ eca-engine.cpp \ samplebuffer.cpp \ samplebuffer_functions.cpp \ eca-session.cpp \ eca-resources.cpp \ resource-file.cpp \ eca-logger.cpp \ eca-logger-default.cpp \ eca-logger-interface.cpp \ eca-logger-wellformed.cpp \ layer.cpp \ samplebuffer_iterators.cpp \ eca-version.cpp \ eca-operator.cpp \ generic-controller.cpp \ eca-object-factory.cpp \ eca-chainsetup.cpp \ eca-chainsetup-bufparams.cpp \ eca-chainsetup-parser.cpp \ eca-chainsetup-position.cpp \ eca-control.cpp \ eca-control-base.cpp \ eca-control-dump.cpp \ eca-control-main.cpp \ eca-control-mt.cpp \ eca-control-objects.cpp \ eca-iamode-parser.cpp \ eca-samplerate-aware.cpp \ eca-audio-position.cpp \ eca-audio-format.cpp \ eca-audio-time.cpp \ eca-fileio-stream.cpp \ eca-fileio-mmap.cpp \ eca-osc.cpp \ eca-static-object-maps.cpp \ eca-object-map.cpp \ eca-preset-map.cpp ecasound_common1_src = $(ecasound_audioio1_src) \ $(ecasound_audioio2_src) \ $(jack_connections_src) \ $(ecasound_midi_src) \ $(ecasound_general_src) @ECA_AM_DISABLE_EFFECTS_FALSE@ecasound_common2_src = $(ecasound_audiofx_src) \ @ECA_AM_DISABLE_EFFECTS_FALSE@ $(ecasound_preset_src) \ @ECA_AM_DISABLE_EFFECTS_FALSE@ $(ecasound_controller_src) @ECA_AM_DISABLE_EFFECTS_TRUE@ecasound_common2_src = libecasound_tester_src = \ libecasound_tester.cpp \ eca-test-repository.cpp \ eca-test-case.cpp libecasound_la_SOURCES = $(ecasound_common1_src) $(ecasound_common2_src) libecasound_debug_la_SOURCES = $(ecasound_common1_src) $(ecasound_common2_src) libecasound_la_LDFLAGS = -export-dynamic $(eca_ldflags) -static libecasound_la_LIBADD = $(eca_libadd) libecasound_debug_la_LDFLAGS = $(libecasound_la_LDFLAGS) libecasound_debug_la_LIBADD = $(libecasound_la_LIBADD) libecasound_tester_SOURCES = $(libecasound_tester_src) #libecasound_tester_CFLAGS = $(AM_CFLAGS) libecasound_tester_LDADD = $(libecasound_tester_libs) all: all-recursive .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libecasound/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign libecasound/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh libecasound-config: $(top_builddir)/config.status $(srcdir)/libecasound-config.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_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 libecasound.la: $(libecasound_la_OBJECTS) $(libecasound_la_DEPENDENCIES) $(CXXLINK) $(am_libecasound_la_rpath) $(libecasound_la_LDFLAGS) $(libecasound_la_OBJECTS) $(libecasound_la_LIBADD) $(LIBS) libecasound_debug.la: $(libecasound_debug_la_OBJECTS) $(libecasound_debug_la_DEPENDENCIES) $(CXXLINK) $(am_libecasound_debug_la_rpath) $(libecasound_debug_la_LDFLAGS) $(libecasound_debug_la_OBJECTS) $(libecasound_debug_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done libecasound_tester$(EXEEXT): $(libecasound_tester_OBJECTS) $(libecasound_tester_DEPENDENCIES) @rm -f libecasound_tester$(EXEEXT) $(CXXLINK) $(libecasound_tester_LDFLAGS) $(libecasound_tester_OBJECTS) $(libecasound_tester_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio-stamp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_amplitude.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_analysis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_compressor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_envelope_modulation.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_filter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_ladspa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_lv2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_lv2_world.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_misc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_mixing.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_rcfilter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_reverb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiofx_timebased.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiogate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-aac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-acseq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-buffered.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-cdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-db-buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-db-client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-db-server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-ewf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-flac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-forked-stream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-loop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-mikmod.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-mp3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-null.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-ogg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-oss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-proxy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-raw.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-resample.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-reverse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-rtnull.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-seqbase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-timidity.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-tone.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-typeselect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio-wave.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-audio-format.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-audio-position.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-audio-time.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-chain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-chainsetup-bufparams.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-chainsetup-parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-chainsetup-position.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-chainsetup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-control-base.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-control-dump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-control-main.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-control-mt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-control-objects.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-control.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-engine.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-fileio-mmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-fileio-stream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-iamode-parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-logger-default.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-logger-interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-logger-wellformed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-logger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-object-factory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-object-map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-operator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-osc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-preset-map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-resources.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-samplerate-aware.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-session.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-static-object-maps.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-test-case.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-test-repository.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eca-version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-preset.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic-controller.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic-linear-envelope.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global-preset.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jack-connections.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecasound_tester.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-envelope.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi-cc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi-client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi-parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi-server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midiio-aseq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midiio-raw.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midiio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osc-gen-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osc-gen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osc-sine.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preset.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/samplebuffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/samplebuffer_functions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/samplebuffer_iterators.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stamp-ctrl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/two-stage-linear-envelope.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done 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; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ 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; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list='$(TESTS)'; \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ ;; \ *) \ echo "PASS: $$tst"; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ *) \ failed=`expr $$failed + 1`; \ echo "FAIL: $$tst"; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ echo "SKIP: $$tst"; \ fi; \ done; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="All $$all tests passed"; \ else \ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all tests failed"; \ else \ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ skipped="($$skip tests were not run)"; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ echo "$$dashes"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive 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) 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-recursive clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-data-local install-exec-am: install-libLTLIBRARIES install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \ uninstall-local uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool clean-recursive ctags \ ctags-recursive distclean distclean-compile distclean-generic \ distclean-libtool distclean-recursive distclean-tags distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-exec \ install-exec-am install-info install-info-am \ install-libLTLIBRARIES install-man install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am uninstall-info-am \ uninstall-libLTLIBRARIES uninstall-local # --------------------------------------------------------------------- # Install targets - note! we don't install $ecasound_extra_include # nor $ecasound_test_framework_include install-data-local: $(INSTALL) -d $(DESTDIR)$(includedir)/libecasound cd $(srcdir) ; \ $(INSTALL_DATA) \ $(ecasound_audiofx_include) \ $(ecasound_preset_include) \ $(ecasound_audioio_include) \ $(ecasound_controller_include) \ $(ecasound_midi_include) \ $(ecasound_general_include) \ $(DESTDIR)$(includedir)/libecasound $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL_SCRIPT) libecasound-config $(DESTDIR)$(bindir)/libecasound-config # --------------------------------------------------------------------- # Uninstall targets uninstall-local: cd $(DESTDIR)$(includedir)/libecasound && \ rm -f $(ecasound_audiofx_include) \ $(ecasound_preset_include) \ $(ecasound_audioio_include) \ $(ecasound_controller_include) \ $(ecasound_midi_include) \ $(ecasound_general_include) rmdir $(DESTDIR)$(includedir)/libecasound || echo "Skipping" rm -f $(DESTDIR)$(bindir)/libecasound-config rmdir $(DESTDIR)$(bindir) || echo "Skipping" # 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: ecasound-2.9.1/libecasound/audioio-ewf.cpp0000644000076400007640000001127611035215603015464 00000000000000// ------------------------------------------------------------------------ // audioio-ewf.cpp: Ecasound wave format input/output // Copyright (C) 1999-2002,2005,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include #include #include #include #include "eca-object-factory.h" #include "samplebuffer.h" #include "audioio-ewf.h" #include "eca-error.h" #include "eca-logger.h" using std::cout; using std::endl; using SAMPLE_SPECS::sample_pos_t; /** * FIXME notes (last update 2008-03-09) * * - Add (more) sanity checks for ewf fields. */ EWFFILE::EWFFILE (void) { } EWFFILE::~EWFFILE(void) { } EWFFILE* EWFFILE::clone(void) const { EWFFILE* target = new EWFFILE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void EWFFILE::open(void) throw(AUDIO_IO::SETUP_ERROR &) { if (io_mode() != AUDIO_IO::io_read) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Writing to EWF files is a deprecated feature since 2.4.7 (2008), and it will be disabled in a future release."); ewf_rc.resource_file(label()); ewf_rc.load(); read_ewf_data(); AUDIO_SEQUENCER_BASE::open(); } void EWFFILE::close(void) { if (io_mode() != AUDIO_IO::io_read) write_ewf_data(); AUDIO_SEQUENCER_BASE::close(); } void EWFFILE::init_default_child(void) throw(ECA_ERROR&) { string::const_iterator e = std::find(label().begin(), label().end(), '.'); if (e == label().end()) { throw(ECA_ERROR("AUDIOIO-EWF", "Invalid file name; unable to open file.",ECA_ERROR::retry)); } string child_name (label().begin(), e); child_name += ".wav"; set_child_object_string(child_name); DBC_CHECK(child_name == child_object_string()); ewf_rc.resource("source", child_object_string()); } void EWFFILE::read_ewf_data(void) throw(ECA_ERROR&) { if (ewf_rc.has("source")) set_child_object_string(ewf_rc.resource("source")); else init_default_child(); if (ewf_rc.has("offset")) { set_child_offset(ECA_AUDIO_TIME(ewf_rc.resource("offset"))); } else set_child_offset(ECA_AUDIO_TIME()); /* FIXME: doesn't work, if child has different srate and start-pos * specified in samples, the result is incorrect! */ if (ewf_rc.has("start-position")) { set_child_start_position(ECA_AUDIO_TIME(ewf_rc.resource("start-position"))); } else set_child_start_position(ECA_AUDIO_TIME()); if (ewf_rc.has("length")) { set_child_length(ECA_AUDIO_TIME(ewf_rc.resource("length"))); } toggle_looping(ewf_rc.boolean_resource("looping")); const std::vector keys = ewf_rc.keywords(); std::vector::const_iterator p = keys.begin(); while(p != keys.end()) { if (*p != "source" && *p != "offset" && *p != "start-position" && *p != "length" && *p != "looping") ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Unknown keyword '" + *p + "' in EWF file '" + label() + "'."); ++p; } } void EWFFILE::write_ewf_data(void) { ewf_rc.resource("source", child_object_string()); if (child_offset().samples() > 0) ewf_rc.resource("offset", kvu_numtostr(child_offset().seconds(),6)); if (child_start_position().samples() != 0) ewf_rc.resource("start-position", kvu_numtostr(child_start_position().seconds(), 6)); if (child_looping() == true) ewf_rc.resource("looping","true"); if (child_length().valid() == true) ewf_rc.resource("length", kvu_numtostr(child_length().seconds(), 6)); ewf_rc.save(); } std::string EWFFILE::parameter_names(void) const { return AUDIO_IO::parameter_names(); } void EWFFILE::set_parameter(int param, std::string value) { AUDIO_IO::set_parameter(param, value); } std::string EWFFILE::get_parameter(int param) const { return AUDIO_IO::get_parameter(param); } ecasound-2.9.1/libecasound/audioio-db-buffer.cpp0000644000076400007640000000643711562466671016564 00000000000000// ------------------------------------------------------------------------ // audioio-db-buffer.cpp: Buffer used between db server and client // Copyright (C) 2000-2002 Kai Vehmanen // // 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 "samplebuffer.h" #include "audioio-db-buffer.h" /** * Constructor. */ AUDIO_IO_DB_BUFFER::AUDIO_IO_DB_BUFFER(int number_of_buffers, long int buffersize, int channels) : readptr_rep(0), writeptr_rep(0), finished_rep(0), sbufs_rep(number_of_buffers) { for(size_t n = 0; n < sbufs_rep.size(); n++) { sbufs_rep[n] = new SAMPLE_BUFFER(buffersize, channels); } // std::cerr << "Created a new client buffer with " << sbufs_rep.size() << " buffers." << std::endl; } AUDIO_IO_DB_BUFFER::~AUDIO_IO_DB_BUFFER(void) { for(size_t n = 0; n < sbufs_rep.size(); n++) { delete sbufs_rep[n]; } } /** * Resets all pointers to their initial state. */ void AUDIO_IO_DB_BUFFER::reset(void) { readptr_rep.set(0); writeptr_rep.set(0); finished_rep.set(0); } /** * Number of sample buffer available for reading. * * Note! As concurrent access is allowed by * the implement, the actual number of * samples available for reading can * be greater than that reported by * read_space(). */ int AUDIO_IO_DB_BUFFER::read_space(void) { int write = writeptr_rep.get(); int read = readptr_rep.get(); if (write >= read) return(write - read); else return((write - read + sbufs_rep.size()) % sbufs_rep.size()); } /** * Number of sample buffers available for writing. * * Note! As concurrent access is allowed by * the implement, the actual number of * samples available for writing can * be greater than that reported by * write_space(). */ int AUDIO_IO_DB_BUFFER::write_space(void) { int write = writeptr_rep.get(); int read = readptr_rep.get(); if (write > read) return(((read - write + sbufs_rep.size()) % sbufs_rep.size()) - 1); else if (write < read) return(read - write - 1); else return(sbufs_rep.size() - 1); } /** * Increment the read pointer by one. * * Note! Cannot be called from multiple concurrent * execution contexts. **/ void AUDIO_IO_DB_BUFFER::advance_read_pointer(void) { readptr_rep.set((readptr_rep.get() + 1) % sbufs_rep.size()); } /** * Increment the write pointer by one. * * Note! Cannot be called from multiple concurrent * execution contexts. **/ void AUDIO_IO_DB_BUFFER::advance_write_pointer(void) { writeptr_rep.set((writeptr_rep.get() + 1) % sbufs_rep.size()); } ecasound-2.9.1/libecasound/audiofx_amplitude.cpp0000644000076400007640000004377011755703520016774 00000000000000// ------------------------------------------------------------------------ // audiofx_amplitude.cpp: Amplitude effects and dynamic processors. // Copyright (C) 1999-2000,2003,2008,2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include "samplebuffer_iterators.h" #include "audiofx_amplitude.h" #include "eca-logger.h" #include "eca-error.h" template static void priv_resize_buffer(std::vector *buffer, int count) { buffer->resize(count); for(int i = 0; i < count; i++) (*buffer)[i] = 0.0; } EFFECT_AMPLITUDE::~EFFECT_AMPLITUDE(void) { } EFFECT_AMPLITUDE::parameter_t EFFECT_AMPLITUDE::db_to_linear(parameter_t value) { return std::pow(10.0f, static_cast(value * 0.05f)); } void EFFECT_AMPLITUDE::init(SAMPLE_BUFFER* sbuf) { cur_sbuf_repp = sbuf; EFFECT_BASE::init(sbuf); } void EFFECT_AMPLITUDE::release(void) { cur_sbuf_repp = 0; EFFECT_BASE::release(); } EFFECT_AMPLIFY::EFFECT_AMPLIFY (EFFECT_AMPLITUDE::parameter_t multiplier_percent) { set_parameter(1, multiplier_percent); } EFFECT_AMPLIFY::~EFFECT_AMPLIFY(void) { } void EFFECT_AMPLIFY::set_parameter(int param, parameter_t value) { switch (param) { case 1: gain_rep = value / 100.0; break; } } CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY::get_parameter(int param) const { switch (param) { case 1: return gain_rep * 100.0; } return 0.0; } void EFFECT_AMPLIFY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); } void EFFECT_AMPLIFY::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); sbuf_repp = sbuf; } void EFFECT_AMPLIFY::release(void) { sbuf_repp = 0; } void EFFECT_AMPLIFY::process(void) { sbuf_repp->multiply_by(gain_rep); } /** * Unoptimized version of process(). */ void EFFECT_AMPLIFY::process_ref(void) { i.begin(); while(!i.end()) { *i.current() = *i.current() * gain_rep; i.next(); } } EFFECT_AMPLIFY_DB::EFFECT_AMPLIFY_DB(parameter_t gain, int channel) : channel_rep(-1), sbuf_repp(0) { set_parameter(1, gain); set_parameter(2, channel); } EFFECT_AMPLIFY_DB::~EFFECT_AMPLIFY_DB(void) { } void EFFECT_AMPLIFY_DB::set_parameter(int param, parameter_t value) { switch (param) { case 1: gain_rep = EFFECT_AMPLITUDE::db_to_linear(value); gain_db_rep = value; break; case 2: { int ch = static_cast(value); /* note: ch==0 -> apply to all channels */ if (ch >= 0) { bool reinit = false; if (channel_rep != ch && sbuf_repp != 0) { reinit = true; } channel_rep = ch; /* note: must be done after 'channel_rep' is set */ if (reinit == true) init(sbuf_repp); } } break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY_DB::get_parameter(int param) const { switch (param) { case 1: return gain_db_rep; case 2: return channel_rep; } DBC_NEVER_REACHED(); return 0.0; } void EFFECT_AMPLIFY_DB::init(SAMPLE_BUFFER* sbuf) { sbuf_repp = sbuf; if (channel_rep > 0) { i_ch.init(sbuf, channel_rep - 1); } else { i_all.init(sbuf); } EFFECT_BASE::init(sbuf); } void EFFECT_AMPLIFY_DB::release(void) { sbuf_repp = 0; } void EFFECT_AMPLIFY_DB::process(void) { if (channel_rep > 0 && channel_rep <= channels()) { sbuf_repp->multiply_by(gain_rep, channel_rep - 1); } else { sbuf_repp->multiply_by(gain_rep); } } /** * Unoptimized version of process(). */ void EFFECT_AMPLIFY_DB::process_ref(void) { if (channel_rep > 0 && channel_rep < channels()) { i_ch.begin(); while(!i_ch.end()) { *i_ch.current() *= gain_rep; i_ch.next(); } } else { i_all.begin(); while(!i_all.end()) { *i_all.current() *= gain_rep; i_all.next(); } } } int EFFECT_AMPLIFY_DB::output_channels(int i_channels) const { if (channel_rep > i_channels) return channel_rep; return i_channels; } EFFECT_AMPLIFY_CLIPCOUNT::EFFECT_AMPLIFY_CLIPCOUNT (parameter_t multiplier_percent, int max_clipped) { set_parameter(1, multiplier_percent); set_parameter(2, max_clipped); num_of_clipped = 0; } void EFFECT_AMPLIFY_CLIPCOUNT::set_parameter(int param, parameter_t value) { switch (param) { case 1: gain = value / 100.0; break; case 2: maxnum_of_clipped = (int)value; break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY_CLIPCOUNT::get_parameter(int param) const { switch (param) { case 1: return gain * 100.0; case 2: return maxnum_of_clipped; } DBC_NEVER_REACHED(); return 0.0f; } void EFFECT_AMPLIFY_CLIPCOUNT::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); } void EFFECT_AMPLIFY_CLIPCOUNT::process(void) { i.begin(); while(!i.end()) { *i.current() = *i.current() * gain; if (*i.current() > SAMPLE_SPECS::impl_max_value || *i.current() < SAMPLE_SPECS::impl_min_value) { num_of_clipped++; } else { num_of_clipped = 0; } i.next(); } if (num_of_clipped > maxnum_of_clipped && maxnum_of_clipped != 0) { MESSAGE_ITEM otemp; otemp.setprecision(0); otemp << "(audiofx_amplitude) WARNING! Signal is clipping! "; otemp << num_of_clipped; otemp << " consecutive clipped samples."; ECA_LOG_MSG(ECA_LOGGER::info, otemp.to_string()); } } void EFFECT_AMPLIFY_CLIPCOUNT::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); } EFFECT_AMPLIFY_CHANNEL::EFFECT_AMPLIFY_CHANNEL (parameter_t multiplier_percent, int channel) { set_parameter(1, multiplier_percent); set_parameter(2, channel); } int EFFECT_AMPLIFY_CHANNEL::output_channels(int i_channels) const { if (channel_rep + 1 > i_channels) return channel_rep + 1; return i_channels; } void EFFECT_AMPLIFY_CHANNEL::set_parameter(int param, parameter_t value) { switch (param) { case 1: gain = value / 100.0; break; case 2: channel_rep = static_cast(value); channel_rep--; break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY_CHANNEL::get_parameter(int param) const { switch (param) { case 1: return gain * 100.0; case 2: return static_cast(channel_rep + 1); } DBC_NEVER_REACHED(); return 0.0; } void EFFECT_AMPLIFY_CHANNEL::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); switch (param) { case 2: { pd->default_value = 1.0f; pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->integer = true; } } } void EFFECT_AMPLIFY_CHANNEL::init(SAMPLE_BUFFER *insample) { i.init(insample); EFFECT_AMPLITUDE::init(insample); } void EFFECT_AMPLIFY_CHANNEL::process(void) { if (channel_rep >= 0 && channel_rep < channels()) { cur_sbuf_repp->multiply_by(gain, channel_rep); } } /** * Unoptimized version of process(). */ void EFFECT_AMPLIFY_CHANNEL::process_ref(void) { if (channel_rep >= 0 && channel_rep < channels()) { i.begin(channel_rep); while(!i.end()) { *i.current() = *i.current() * gain; i.next(); } } } EFFECT_LIMITER::EFFECT_LIMITER (parameter_t limiting_percent) { set_parameter(1, limiting_percent); } EFFECT_LIMITER::~EFFECT_LIMITER(void) { } void EFFECT_LIMITER::set_parameter(int param, parameter_t value) { switch (param) { case 1: limit_rep = value / 100.0; break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_LIMITER::get_parameter(int param) const { switch (param) { case 1: return limit_rep * 100.0; } DBC_NEVER_REACHED(); return 0.0; } void EFFECT_LIMITER::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); } void EFFECT_LIMITER::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); } void EFFECT_LIMITER::process(void) { i.begin(); while(!i.end()) { if (*i.current() < 0) { if ((-(*i.current())) > limit_rep) *i.current() = -limit_rep; } else { if (*i.current() > limit_rep) *i.current() = limit_rep; } i.next(); } } EFFECT_COMPRESS::EFFECT_COMPRESS (parameter_t compress_rate, parameter_t thold) { set_parameter(1, compress_rate); set_parameter(2, thold); first_time = true; } EFFECT_COMPRESS::EFFECT_COMPRESS (const EFFECT_COMPRESS& x) { crate = x.crate; threshold = x.threshold; delta = x.delta; ratio = x.ratio; first_time = x.first_time; lastin = x.lastin; lastout = x.lastout; } void EFFECT_COMPRESS::set_parameter(int param, parameter_t value) { switch (param) { case 1: crate = std::pow(2.0, value / 6.0); break; case 2: threshold = value / 100.0; break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_COMPRESS::get_parameter(int param) const { switch (param) { case 1: return (log (crate)) / (log (2.0f)) * 6.0; case 2: return threshold * 100.0; } DBC_NEVER_REACHED(); return 0.0; } void EFFECT_COMPRESS::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 1.0f; pd->description = "compression-rate-dB"; pd->bounded_above = true; pd->upper_bound = 99.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = true; pd->output = false; break; case 2: pd->default_value = 30.0f; pd->description = "threshold-%"; pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: DBC_NEVER_REACHED(); } } void EFFECT_COMPRESS::init(SAMPLE_BUFFER *insample) { i.init(insample); set_channels(insample->number_of_channels()); set_samples_per_second(samples_per_second()); priv_resize_buffer(&lastin, insample->number_of_channels()); priv_resize_buffer(&lastout, insample->number_of_channels()); } void EFFECT_COMPRESS::process(void) { i.begin(); while(!i.end()) { if (first_time) { first_time = false; lastin[i.channel()] = lastout[i.channel()] = *i.current(); } else { if (fabs(*i.current()) > threshold) { delta = *i.current() - lastin[i.channel()]; delta /= crate; new_value = lastin[i.channel()] + delta; ratio = new_value / lastin[i.channel()]; new_value = lastout[i.channel()] * ratio; if (new_value > SAMPLE_SPECS::impl_max_value) new_value = SAMPLE_SPECS::impl_max_value; else if (new_value < SAMPLE_SPECS::impl_min_value) new_value = SAMPLE_SPECS::impl_min_value; lastin[i.channel()] = *i.current(); *i.current() = lastout[i.channel()] = new_value; } else { lastin[i.channel()] = lastout[i.channel()] = *i.current(); } } i.next(); } } EFFECT_NOISEGATE::EFFECT_NOISEGATE (parameter_t thlevel_percent, parameter_t thtime, parameter_t a, parameter_t h, parameter_t r) { // map_parameters(); set_parameter(1, thlevel_percent); set_parameter(2, thtime); set_parameter(3, a); set_parameter(4, h); set_parameter(5, r); } void EFFECT_NOISEGATE::set_parameter(int param, parameter_t value) { switch (param) { case 1: th_level = SAMPLE_SPECS::max_amplitude * (value / 100.0); break; case 2: th_time = (value * (parameter_t)samples_per_second() / 1000.0); break; case 3: atime = (value * (parameter_t)samples_per_second() / 1000.0); break; case 4: htime = (value * (parameter_t)samples_per_second() / 1000.0); break; case 5: rtime = (value * (parameter_t)samples_per_second() / 1000.0); break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_NOISEGATE::get_parameter(int param) const { switch (param) { case 1: return th_level * 100.0 / (parameter_t)SAMPLE_SPECS::max_amplitude; case 2: return th_time * 1000.0 / (parameter_t)samples_per_second(); case 3: return atime * 1000.0 / (parameter_t)samples_per_second(); case 4: return htime * 1000.0 / (parameter_t)samples_per_second(); case 5: return rtime * 1000.0 / (parameter_t)samples_per_second(); } DBC_NEVER_REACHED(); return 0.0; } void EFFECT_NOISEGATE::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); } void EFFECT_NOISEGATE::init(SAMPLE_BUFFER *insample) { i.init(insample); set_channels(insample->number_of_channels()); set_samples_per_second(samples_per_second()); priv_resize_buffer(&th_time_lask, insample->number_of_channels()); priv_resize_buffer(&attack_lask, insample->number_of_channels()); priv_resize_buffer(&hold_lask, insample->number_of_channels()); priv_resize_buffer(&release_lask, insample->number_of_channels()); priv_resize_buffer(&gain, insample->number_of_channels()); ng_status.resize(insample->number_of_channels(), int(ng_waiting)); for(size_t n = 0; n < ng_status.size(); n++) ng_status[n] = ng_waiting; } void EFFECT_NOISEGATE::process(void) { i.begin(); while(!i.end()) { bool below = fabs(*i.current()) <= th_level; switch(ng_status[i.channel()]) { case ng_waiting: // --- // phase 1 - waiting // --- { if (below) { th_time_lask[i.channel()]++; if (th_time_lask[i.channel()] >= th_time) { th_time_lask[i.channel()] = 0.0; ng_status[i.channel()] = ng_attacking; ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from waiting to attacking"); } } else { th_time_lask[i.channel()] = 0; } break; } case ng_attacking: // --- // phase 2 - attack // --- { if (below) { attack_lask[i.channel()]++; gain[i.channel()] = (1.0 - (attack_lask[i.channel()] / atime)); if (attack_lask[i.channel()] >= atime) { attack_lask[i.channel()] = 0.0; ng_status[i.channel()] = ng_active; gain[i.channel()] = 0.0; ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from attack to active"); } *i.current() = *i.current() * gain[i.channel()]; } else { attack_lask[i.channel()] = 0; ng_status[i.channel()] = ng_waiting; ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from attack to waiting"); } break; } case ng_active: // --- // phase 3 - active // --- { if (below == false) { ng_status[i.channel()] = ng_holding; ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from active to holding"); } *i.current() = *i.current() * 0.0; break; } case ng_holding: // --- // phase 4 - holding // --- { if (!below) { hold_lask[i.channel()]++; if (hold_lask[i.channel()] >= htime) { hold_lask[i.channel()] = 0.0; ng_status[i.channel()] = ng_releasing; ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from holding to release"); } } *i.current() = *i.current() * 0.0; break; } case ng_releasing: // --- // phase 5 - releasing // --- { release_lask[i.channel()]++; gain[i.channel()] = release_lask[i.channel()] / rtime; if (release_lask[i.channel()] >= rtime) { release_lask[i.channel()] = 0.0; ng_status[i.channel()] = ng_waiting; ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from releasing to waiting"); } *i.current() = *i.current() * gain[i.channel()]; break; } } i.next(); } } EFFECT_NORMAL_PAN::EFFECT_NORMAL_PAN (parameter_t right_percent) { set_parameter(1, right_percent); } void EFFECT_NORMAL_PAN::set_parameter(int param, parameter_t value) { switch (param) { case 1: right_percent_rep = value; if (value == 50.0) { l_gain = r_gain = 1.0; } else if (value < 50.0) { l_gain = 1.0; r_gain = value / 50.0; } else if (value > 50.0) { r_gain = 1.0; l_gain = (100.0 - value) / 50.0; } break; default: DBC_NEVER_REACHED(); } } CHAIN_OPERATOR::parameter_t EFFECT_NORMAL_PAN::get_parameter(int param) const { switch (param) { case 1: return right_percent_rep; } return 0.0; } void EFFECT_NORMAL_PAN::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); switch (param) { case 1: { pd->default_value = 50.0f; pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; } default: DBC_NEVER_REACHED(); } } void EFFECT_NORMAL_PAN::init(SAMPLE_BUFFER *insample) { i.init(insample); EFFECT_AMPLITUDE::init(insample); } void EFFECT_NORMAL_PAN::process(void) { /* to match with out_channels() */ cur_sbuf_repp->number_of_channels(2); cur_sbuf_repp->multiply_by(l_gain, SAMPLE_SPECS::ch_left); cur_sbuf_repp->multiply_by(r_gain, SAMPLE_SPECS::ch_right); } /** * Unoptimized version of process(). */ void EFFECT_NORMAL_PAN::process_ref(void) { i.begin(0); while(!i.end()) { *i.current() = *i.current() * l_gain; i.next(); } i.begin(1); while(!i.end()) { *i.current() = *i.current() * r_gain; i.next(); } } ecasound-2.9.1/libecasound/file-preset.cpp0000644000076400007640000000327010664032032015466 00000000000000// ------------------------------------------------------------------------ // file_preset.cpp: File based effect preset // Copyright (C) 2000,2001 Kai Vehmanen // // 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 #include "resource-file.h" #include "eca-logger.h" #include "eca-error.h" #include "file-preset.h" FILE_PRESET::FILE_PRESET(const std::string& file_name) { RESOURCE_FILE pfile (file_name); std::string pname = "empty"; if (pfile.keywords().size() > 0) pname = pfile.keywords()[0]; set_name(pname); set_filename(file_name); parse(pfile.resource(pname)); } FILE_PRESET* FILE_PRESET::clone(void) const { std::vector param_values; for(int n = 0; n < number_of_params(); n++) { param_values.push_back(get_parameter(n + 1)); } FILE_PRESET* preset = new FILE_PRESET(filename()); for(int n = 0; n < preset->number_of_params(); n++) { preset->set_parameter(n + 1, param_values[n]); } return(preset); } ecasound-2.9.1/libecasound/audioio-aac.cpp0000644000076400007640000001614411141367001015424 00000000000000// ------------------------------------------------------------------------ // audioio-aac.cpp: Interface class for FAAC/FAAD AAC encoder/decoder. // Copyright (C) 2004-2006,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include /* atol() */ #include /* stat() */ #include /* stat() */ #include #include #include "audioio-aac.h" #include "eca-logger.h" /** * References: * http://www.audiocoding.com/ */ string AAC_FORKED_INTERFACE::default_input_cmd = "faad -w -b 1 -f 2 -d %f"; string AAC_FORKED_INTERFACE::default_output_cmd = "faac -P -o %f -R %s -B %b -C %c -"; void AAC_FORKED_INTERFACE::set_input_cmd(const std::string& value) { AAC_FORKED_INTERFACE::default_input_cmd = value; } void AAC_FORKED_INTERFACE::set_output_cmd(const std::string& value) { AAC_FORKED_INTERFACE::default_output_cmd = value; } AAC_FORKED_INTERFACE::AAC_FORKED_INTERFACE(const std::string& name) : triggered_rep(false), finished_rep(false) { set_label(name); } AAC_FORKED_INTERFACE::~AAC_FORKED_INTERFACE(void) { clean_child(true); if (is_open() == true) { close(); } } void AAC_FORKED_INTERFACE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { std::string urlprefix; finished_rep = false; triggered_rep = false; /** * FIXME: we have no idea about the audio format of the * stream we get from ogg123... maybe we should force decoder * to generate RIFF wave to a named pipe and parse the header...? */ if (io_mode() == io_read) { struct stat buf; int ret = ::stat(label().c_str(), &buf); if (ret != 0) { size_t offset = label().find_first_of("://"); if (offset == std::string::npos) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-AAC: Can't open file " + label() + ".")); } else { urlprefix = std::string(label(), 0, offset); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found url; protocol '" + urlprefix + "'."); } } /* decoder supports: fixed channel count and sample format, sample rate unknown and must be set manually */ set_channels(2); /* 5.1 downmixed to stereo if needed by faad2 */ /* FIXME: fix properly */ set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le); } else { /* encoder supports: coding, channel-count and srate configurable; fixed endianess */ set_sample_endianess(ECA_AUDIO_FORMAT::se_big); } AUDIO_IO::open(); } void AAC_FORKED_INTERFACE::close(void) { if (pid_of_child() > 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + ")."); clean_child(); triggered_rep = false; } AUDIO_IO::close(); } long int AAC_FORKED_INTERFACE::read_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_input_process(); } if (f1_rep != 0) { bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, f1_rep); } else { bytes_rep = 0; } if (bytes_rep < samples * frame_size() || bytes_rep == 0) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::info, "Can't start process \"" + AAC_FORKED_INTERFACE::default_input_cmd + "\". Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; } else finished_rep = false; return bytes_rep / frame_size(); } void AAC_FORKED_INTERFACE::write_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_output_process(); } if (wait_for_child() != true) { finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Attempt to write after child process has terminated."); } else { if (filedes_rep > 0) { bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples); } else { bytes_rep = 0; } if (bytes_rep < frame_size() * samples) { ECA_LOG_MSG(ECA_LOGGER::info, "Can't start process \"" + AAC_FORKED_INTERFACE::default_output_cmd + "\". FAAC v1.24 or newer is required. Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Error in writing to child process (to write " + kvu_numtostr(frame_size() * samples) + ", result " + kvu_numtostr(bytes_rep) + ")."); } else finished_rep = false; } } void AAC_FORKED_INTERFACE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; } } string AAC_FORKED_INTERFACE::get_parameter(int param) const { switch (param) { case 1: return label(); } return ""; } void AAC_FORKED_INTERFACE::fork_input_process(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, AAC_FORKED_INTERFACE::default_input_cmd); set_fork_command(AAC_FORKED_INTERFACE::default_input_cmd); set_fork_file_name(label()); fork_child_for_read(); if (child_fork_succeeded() == true) { /* NOTE: the file description will be closed by * AUDIO_IO_FORKED_STREAM::clean_child() */ filedes_rep = file_descriptor(); f1_rep = fdopen(filedes_rep, "r"); /* not part of */ if (f1_rep == 0) { finished_rep = true; triggered_rep = false; } } else f1_rep = 0; } void AAC_FORKED_INTERFACE::fork_output_process(void) { string command = AAC_FORKED_INTERFACE::default_output_cmd; set_fork_command(command); set_fork_file_name(label()); set_fork_bits(bits()); set_fork_channels(channels()); set_fork_sample_rate(samples_per_second()); fork_child_for_write(); if (child_fork_succeeded() == true) { filedes_rep = file_descriptor(); } else { filedes_rep = 0; } } void AAC_FORKED_INTERFACE::start_io(void) { if (triggered_rep != true) { if (io_mode() == io_read) fork_input_process(); else fork_output_process(); triggered_rep = true; } } void AAC_FORKED_INTERFACE::stop_io(void) { if (triggered_rep == true) { if (io_mode() == io_read) clean_child(true); else clean_child(false); triggered_rep = false; } } ecasound-2.9.1/libecasound/audiofx_analysis.h0000644000076400007640000001005111167727646016276 00000000000000#ifndef INCLUDED_AUDIOFX_ANALYSIS_H #define INCLUDED_AUDIOFX_ANALYSIS_H #include #include #include #include "samplebuffer_iterators.h" #include "audiofx.h" class MESSAGE_ITEM; /** * Virtual base for signal analyzers. * @author Kai Vehmanen */ class EFFECT_ANALYSIS : public EFFECT_BASE { public: virtual void set_parameter(int param, parameter_t value) { } virtual parameter_t get_parameter(int param) const { return(0.0); } virtual std::string parameter_names(void) const { return(""); } virtual ~EFFECT_ANALYSIS(void); }; /** * Analyzes the audio signal volume by using a set of * amplitude range buckets. * * @author Kai Vehmanen */ class EFFECT_VOLUME_BUCKETS : public EFFECT_ANALYSIS { private: std::vector num_of_samples; // number of samples processed std::vector > pos_samples_db; std::vector > neg_samples_db; SAMPLE_SPECS::sample_t max_pos, max_neg; mutable pthread_mutex_t lock_rep; SAMPLE_ITERATOR_CHANNELS i; void reset_all_stats(void); void reset_period_stats(void); void status_entry(const std::vector& buckets, std::string& otemp) const; public: parameter_t max_multiplier(void) const; virtual std::string name(void) const { return("Volume analysis"); } virtual std::string parameter_names(void) const { return("cumulative-mode,result-max-multiplier"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual std::string status(void) const; virtual EFFECT_VOLUME_BUCKETS* clone(void) const { return new EFFECT_VOLUME_BUCKETS(*this); } virtual EFFECT_VOLUME_BUCKETS* new_expr(void) const { return new EFFECT_VOLUME_BUCKETS(); } EFFECT_VOLUME_BUCKETS (void); virtual ~EFFECT_VOLUME_BUCKETS (void); }; /** * Keeps track of peak amplitude. * * @author Kai Vehmanen */ class EFFECT_VOLUME_PEAK : public EFFECT_ANALYSIS { public: virtual std::string name(void) const { return("Peak amplitude watcher"); } virtual std::string parameter_names(void) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); // virtual std::string status(void) const; virtual EFFECT_VOLUME_PEAK* clone(void) const { return new EFFECT_VOLUME_PEAK(*this); } virtual EFFECT_VOLUME_PEAK* new_expr(void) const { return new EFFECT_VOLUME_PEAK(); } EFFECT_VOLUME_PEAK (void); virtual ~EFFECT_VOLUME_PEAK (void); private: mutable volatile parameter_t * volatile max_amplitude_repp; mutable long int clipped_samples_rep; mutable std::string status_rep; SAMPLE_ITERATOR_CHANNELS i; }; /** * Calculates DC-offset. * * @author Kai Vehmanen */ class EFFECT_DCFIND : public EFFECT_ANALYSIS { private: std::vector pos_sum; std::vector neg_sum; std::vector num_of_samples; SAMPLE_SPECS::sample_t tempval; SAMPLE_ITERATOR_CHANNELS i; public: parameter_t get_deltafix(int channel) const; virtual std::string name(void) const { return("DC-Find"); } virtual std::string description(void) const { return("Calculates the DC-offset."); } virtual std::string parameter_names(void) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual std::string status(void) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual EFFECT_DCFIND* clone(void) const { return new EFFECT_DCFIND(*this); } virtual EFFECT_DCFIND* new_expr(void) const { return new EFFECT_DCFIND(); } EFFECT_DCFIND (void); }; #endif ecasound-2.9.1/libecasound/layer.cpp0000644000076400007640000001276010664032032014367 00000000000000/* layer.cpp Created by SMF aka Antoine Laydier . Minor modifications by Kai Vehmanen . 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*============================================================================= HEADERs =============================================================================*/ #include #include #include #include #include "layer.h" /*============================================================================= Class : Layers =============================================================================*/ const int Layer::MPG_MD_STEREO = 0; const int Layer::MPG_MD_JOINT_STEREO = 1; const int Layer::MPG_MD_DUAL_CHANNEL = 2; const int Layer::MPG_MD_MONO = 3; const int Layer::MPG_MD_LR_LR = 0; const int Layer::MPG_MD_LR_I = 1; const int Layer::MPG_MD_MS_LR = 2; const int Layer::MPG_MD_MS_I = 3; const char *Layer::mode_names[5] = {"stereo", "j-stereo", "dual-ch", "single-ch", "multi-ch"}; const char *Layer::layer_names[3] = {"I", "II", "III"}; const char *Layer::version_names[3] = {"MPEG-1", "MPEG-2 LSF", "MPEG-2.5"}; const char *Layer::version_nums[3] = {"1", "2", "2.5"}; const unsigned int Layer::bitrates[3][3][15] = { { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320} }, { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} }, { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} } }; const unsigned int Layer::s_freq[3][4] = { {44100, 48000, 32000, 0}, {22050, 24000, 16000, 0}, {11025, 8000, 8000, 0} }; const char * Layer::mode_name(void) { return (Layer::mode_names[mode_rep]); } const char * Layer::layer_name(void) { return (Layer::layer_names[lay_rep - 1]); } const char * Layer::version_name(void) { return (Layer::version_names[version_rep]); } const char * Layer::version_num(void) { return (Layer::version_nums[version_rep]); } int Layer::mode(void) { return(mode_rep); } unsigned int Layer::bitrate(void) { return (Layer::bitrates[version_rep][lay_rep - 1][bitrate_index_rep]); } unsigned int Layer::sfreq(void) { return (Layer::s_freq[version_rep][sampling_frequency_rep]); } unsigned long Layer::length(void) { return bitrate() ? (fileSize_rep / (unsigned long)bitrate() /125) : 0; } unsigned int Layer::pcmPerFrame(void) { return pcm_rep; } bool Layer::get(const char* filename) { unsigned char *buff = new unsigned char[1024]; unsigned char *buffer; size_t temp; size_t readsize; struct stat buf; FILE *file; // -- // 22.3.2000 - added the second parameter for getting // around FILE* compatibility issues, k@eca.cx stat(filename, &buf); fileSize_rep = (unsigned long)buf.st_size; /* Theoretically reading 1024 instead of just 4 means a performance hit * if we transfer over net filesystems... However, no filesystem I know * of uses block sizes under 1024 bytes. */ file = fopen(filename,"r"); if (!file) return(false); fseek(file, 0, SEEK_SET); readsize = fread(buff, 1, 1024, file); fclose(file); readsize -= 4; if (readsize <= 0) { delete[] buff; return (false); } buffer = buff-1; /* Scan through the block looking for a header */ do { buffer++; temp = ((buffer[0] << 4) & 0xFF0) | ((buffer[1] >> 4) & 0xE); } while ((temp != 0xFFE) && ((size_t)(buffer-buff)> 3 & 0x3)) { case 3: version_rep = 0; break; case 2: version_rep = 1; break; case 0: version_rep = 2; break; default: delete[] buff; return (false); } lay_rep = 4 - ((buffer[1] >> 1) & 0x3); error_protection_rep = !(buffer[1] & 0x1); bitrate_index_rep = (buffer[2] >> 4) & 0x0F; sampling_frequency_rep = (buffer[2] >> 2) & 0x3; padding_rep = (buffer[2] >> 1) & 0x01; extension_rep = buffer[2] & 0x01; mode_rep = (buffer[3] >> 6) & 0x3; mode_ext_rep = (buffer[3] >> 4) & 0x03; copyright_rep = (buffer[3] >> 3) & 0x01; original_rep = (buffer[3] >> 2) & 0x1; emphasis_rep = (buffer[3]) & 0x3; stereo_rep = (mode_rep == Layer::MPG_MD_MONO) ? 1 : 2; // Added by Cp pcm_rep = 32; if (lay_rep == 3) { pcm_rep *= 18; if (version_rep == 0) pcm_rep *= 2; } else{ pcm_rep *= 12; if (lay_rep == 2) pcm_rep *= 3; } delete[] buff; return (true); } } ecasound-2.9.1/libecasound/eca-engine_impl.h0000644000076400007640000000165711743344155015752 00000000000000#ifndef INCLUDED_ECA_ENGINE_IMPL_H #define INCLUDED_ECA_ENGINE_IMPL_H #include #include #include #include #include #include #include "eca-chainsetup.h" /** * Private class used in ECA_ENGINE * implementation. */ class ECA_ENGINE_impl { friend class ECA_ENGINE; private: PROCEDURE_TIMER looptimer_rep; PROCEDURE_TIMER looptimer_range_rep; double looptimer_low_rep; double looptimer_mid_rep; double looptimer_high_rep; MESSAGE_QUEUE_RT_C command_queue_rep; pthread_cond_t editlock_cond_repp; pthread_mutex_t editlock_mutex_repp; pthread_cond_t ecasound_stop_cond_repp; pthread_mutex_t ecasound_stop_mutex_repp; pthread_cond_t ecasound_exit_cond_repp; pthread_mutex_t ecasound_exit_mutex_repp; struct timeval multitrack_input_stamp_rep; }; #endif /* INCLUDED_ECA_ENGINE_IMPL_H */ ecasound-2.9.1/libecasound/audiofx_timebased.h0000644000076400007640000001604011744604400016373 00000000000000#ifndef INCLUDED_AUDIOFX_TIMEBASED_H #define INCLUDED_AUDIOFX_TIMEBASED_H #include #include #include #include "audiofx.h" #include "audiofx_filter.h" #include "osc-sine.h" typedef std::deque SINGLE_BUFFER; /** * Base class for time-based effects (delays, reverbs, etc). */ class EFFECT_TIME_BASED : public EFFECT_BASE { public: virtual EFFECT_TIME_BASED* clone(void) const = 0; }; /** * Delay effect */ class EFFECT_DELAY : public EFFECT_TIME_BASED { private: SAMPLE_ITERATOR_CHANNEL l,r; parameter_t surround; parameter_t dnum; long int dtime; parameter_t dtime_msec; parameter_t mix; parameter_t feedback; parameter_t laskuri; std::vector > buffer; public: virtual std::string name(void) const { return("Delay"); } virtual std::string parameter_names(void) const { return("delay-time-msec,surround-mode,number-of-delays,mix-%,feedback-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* insample); virtual void process(void); virtual int output_channels(int i_channels) const { return(2); } parameter_t get_delta_in_samples(void) { return(dnum * dtime); } EFFECT_DELAY* clone(void) const { return new EFFECT_DELAY(*this); } EFFECT_DELAY* new_expr(void) const { return new EFFECT_DELAY(); } EFFECT_DELAY (parameter_t delay_time = 100.0, int surround_mode = 0, int num_of_delays = 1, parameter_t mix_percent = 50.0, parameter_t feedback_percent = 100.0); }; /** * Multi-tap delay */ class EFFECT_MULTITAP_DELAY : public EFFECT_TIME_BASED { private: SAMPLE_ITERATOR_INTERLEAVED i; parameter_t surround; parameter_t mix; parameter_t dtime_msec; long int dtime, dnum; std::vector delay_index; std::vector > filled; std::vector > buffer; public: virtual std::string name(void) const { return("Multitap delay"); } virtual std::string parameter_names(void) const { return("delay-time-msec,number-of-delays,mix-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* insample); virtual void process(void); EFFECT_MULTITAP_DELAY* clone(void) const { return new EFFECT_MULTITAP_DELAY(*this); } EFFECT_MULTITAP_DELAY* new_expr(void) const { return new EFFECT_MULTITAP_DELAY(); } EFFECT_MULTITAP_DELAY (parameter_t delay_time = 100.0, int num_of_delays = 1, parameter_t mix_percent = 50.0); }; /** * Transforms a mono signal to stereo using a panned delay signal. * Suitable delays values range from 1 to 40 milliseconds. */ class EFFECT_FAKE_STEREO : public EFFECT_TIME_BASED { std::vector > buffer; SAMPLE_ITERATOR_CHANNEL l,r; long int dtime; parameter_t dtime_msec; public: std::string name(void) const { return("Fake stereo"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual std::string parameter_names(void) const { return("delay-time-msec"); } virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* insample); virtual void process(void); virtual int output_channels(int i_channels) const { return(2); } EFFECT_FAKE_STEREO* clone(void) const { return new EFFECT_FAKE_STEREO(*this); } EFFECT_FAKE_STEREO* new_expr(void) const { return new EFFECT_FAKE_STEREO(); } EFFECT_FAKE_STEREO (parameter_t delay_time = 20.0); }; /** * Simple reverb (based on a iir comb filter) */ class EFFECT_REVERB : public EFFECT_TIME_BASED { private: std::vector > buffer; SAMPLE_ITERATOR_CHANNEL l,r; parameter_t surround; parameter_t feedback; long int dtime; parameter_t dtime_msec; public: virtual std::string name(void) const { return("Reverb"); } virtual std::string parameter_names(void) const { return("delay-time,surround-mode,feedback-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* insample); virtual void process(void); virtual int output_channels(int i_channels) const { return(2); } parameter_t get_delta_in_samples(void) { return(dtime); } EFFECT_REVERB* clone(void) const { return new EFFECT_REVERB(*this); } EFFECT_REVERB* new_expr(void) const { return new EFFECT_REVERB(); } EFFECT_REVERB (parameter_t delay_time = 20.0, int surround_mode = 0, parameter_t feedback_percent = 50.0); }; /** * Base class for modulating delay effects */ class EFFECT_MODULATING_DELAY : public EFFECT_TIME_BASED { protected: std::vector > buffer; SAMPLE_ITERATOR_CHANNELS i; double advance_len_secs_rep, lfo_pos_secs_rep; long int dtime; parameter_t dtime_msec; parameter_t feedback, vartime; SINE_OSCILLATOR lfo; std::vector delay_index; std::vector filled; public: virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* insample); virtual void process(void); EFFECT_MODULATING_DELAY(parameter_t delay_time = 2.0, long int vartime_in_samples = 20, parameter_t feedback_percent = 50.0, parameter_t lfo_freq = 0.4); }; /** * Flanger */ class EFFECT_FLANGER : public EFFECT_MODULATING_DELAY { public: virtual std::string name(void) const { return("Flanger"); } virtual std::string parameter_names(void) const { return("delay-time-msec,variance-time-samples,feedback-%,lfo-freq"); } void process(void); EFFECT_FLANGER* clone(void) const { return new EFFECT_FLANGER(*this); } EFFECT_FLANGER* new_expr(void) const { return new EFFECT_FLANGER(); } }; /** * Chorus */ class EFFECT_CHORUS : public EFFECT_MODULATING_DELAY { public: virtual std::string name(void) const { return("Chorus"); } virtual std::string parameter_names(void) const { return("delay-time-msec,variance-time-samples,feedback-%,lfo-freq"); } void process(void); EFFECT_CHORUS* clone(void) const { return new EFFECT_CHORUS(*this); } EFFECT_CHORUS* new_expr(void) const { return new EFFECT_CHORUS(); } }; /** * Phaser */ class EFFECT_PHASER : public EFFECT_MODULATING_DELAY { public: virtual std::string name(void) const { return("Phaser"); } virtual std::string parameter_names(void) const { return("delay-time-msec,variance-time-samples,feedback-%,lfo-freq"); } void process(void); EFFECT_PHASER* clone(void) const { return new EFFECT_PHASER(*this); } EFFECT_PHASER* new_expr(void) const { return new EFFECT_PHASER(); } }; #endif ecasound-2.9.1/libecasound/global-preset.cpp0000644000076400007640000000467310664032032016017 00000000000000// ------------------------------------------------------------------------ // global_preset.cpp: Global effect preset // Copyright (C) 2000 Kai Vehmanen // // 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 #include "resource-file.h" #include "eca-resources.h" #include "eca-logger.h" #include "eca-error.h" #include "global-preset.h" GLOBAL_PRESET::GLOBAL_PRESET(const std::string& preset_name) : preset_name_rep(preset_name) { ECA_RESOURCES ecarc; ECA_LOG_MSG(ECA_LOGGER::system_objects,"(global-preset) Opening sc-preset file."); /* FIXME: is this correct; user resources should be nowadays handled in eca-resources.cpp */ std::string user_filename = ecarc.resource("user-resource-directory") + "/" + ecarc.resource("resource-file-effect-presets"); RESOURCE_FILE rc; rc.resource_file(user_filename); rc.load(); std::string raw = rc.resource(preset_name); if (raw == "") { std::string global_filename = ecarc.resource("resource-directory") + "/" + ecarc.resource("resource-file-effect-presets"); rc.resource_file(global_filename); rc.load(); raw = rc.resource(preset_name); } if (raw != "") { parse(raw); set_name(preset_name); } else { set_name("empty"); throw(ECA_ERROR("GLOBAL_PRESET", "requested preset \"" + preset_name + "\" was not found.")); } } GLOBAL_PRESET* GLOBAL_PRESET::clone(void) const { std::vector param_values; for(int n = 0; n < number_of_params(); n++) { param_values.push_back(get_parameter(n + 1)); } GLOBAL_PRESET* preset = new GLOBAL_PRESET(preset_name_rep); for(int n = 0; n < preset->number_of_params(); n++) { preset->set_parameter(n + 1, param_values[n]); } return(preset); } ecasound-2.9.1/libecasound/linear-envelope.h0000644000076400007640000000150011034531716016000 00000000000000#ifndef INCLUDED_LINEAR_ENVELOPE_H #define INCLUDED_LINEAR_ENVELOPE_H #include #include "ctrl-source.h" /** * Linear envelope */ class LINEAR_ENVELOPE : public CONTROLLER_SOURCE { public: LINEAR_ENVELOPE(void); virtual ~LINEAR_ENVELOPE(void); LINEAR_ENVELOPE* clone(void) const { return new LINEAR_ENVELOPE(*this); } LINEAR_ENVELOPE* new_expr(void) const { return new LINEAR_ENVELOPE(*this); } std::string name(void) const { return("Linear envelope"); } virtual void init(void); virtual parameter_t value(double pos_secs); virtual void set_initial_value(parameter_t arg) {} std::string parameter_names(void) const { return("length-sec"); } void set_parameter(int param, parameter_t value); parameter_t get_parameter(int param) const; private: parameter_t stages_len_rep; }; #endif ecasound-2.9.1/libecasound/eca-control-objects.cpp0000644000076400007640000020651312260762753017127 00000000000000// ------------------------------------------------------------------------ // eca-control-objects.cpp: Class for configuring libecasound objects // Copyright (C) 2000-2004,2006,2008,2009,2012,2013 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include #include #include /* DBC_* */ #include #include #include #include /* kvu_get_argument_number() */ #include "audioio.h" #include "eca-chain.h" #include "eca-chainop.h" #include "eca-chainsetup.h" #include "eca-control.h" #include "eca-engine.h" #include "eca-object-factory.h" #include "eca-session.h" #include "generic-controller.h" #include "eca-error.h" #include "eca-logger.h" /** * Import namespaces */ using std::string; /** * Definitions for member functions */ /** * Adds a new chainsetup * * @param name chainsetup name * * require: * name != "" * * ensure: * selected_chainsetup() == name || (last_error().size() > 0 && no_errors != true) */ void ECA_CONTROL::add_chainsetup(const string& name) { // -------- DBC_REQUIRE(name != ""); // -------- bool no_errors = true; int count = static_cast(session_repp->chainsetups_rep.size()); session_repp->add_chainsetup(name); if (static_cast(session_repp->chainsetups_rep.size()) > count) { select_chainsetup(name); ECA_LOG_MSG(ECA_LOGGER::info, "Added a new chainsetup with name \"" + name + "\"."); } else { set_last_error("Unable to add chainsetup with name \"" + name + "\"."); no_errors = false; } // -------- DBC_ENSURE(selected_chainsetup() == name || (last_error().size() > 0 && no_errors != true)); // -------- } /** * Removes chainsetup * * @param name chainsetup name * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * * ensure: * selected_chainsetup.empty() == true */ void ECA_CONTROL::remove_chainsetup(void) { // -------- DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(is_selected() == true); // -------- ECA_LOG_MSG(ECA_LOGGER::info, "Removing chainsetup: \"" + selected_chainsetup() + "\"."); session_repp->remove_chainsetup(); selected_chainsetup_repp = 0; // -------- DBC_ENSURE(selected_chainsetup().empty() == true); // -------- } /** * Loads chainsetup from file 'filename'. * * @param name chainsetup filename * * require: * filename != "" * * ensure: * filename exists implies loaded chainsetup == selected_chainsetup() */ void ECA_CONTROL::load_chainsetup(const string& filename) { try { session_repp->load_chainsetup(filename); selected_chainsetup_repp = session_repp->selected_chainsetup_repp; DBC_CHECK((selected_chainsetup_repp != 0 && selected_chainsetup_repp->filename() == filename) || selected_chainsetup_repp == 0); ECA_LOG_MSG(ECA_LOGGER::info, "Loaded chainsetup from file \"" + filename + "\"."); } catch(ECA_ERROR& e) { set_last_error(e.error_section() + ": \"" + e.error_message() + "\""); } } /** * Save selected chainsetup. * * @param filename chainsetup filename (if omitted, previously used filename will be used, if any) * * require: * selected_chainsetup().empty() != true */ void ECA_CONTROL::save_chainsetup(const string& filename) { // -------- DBC_REQUIRE(selected_chainsetup().empty() != true); // -------- try { if (filename.empty() == true) session_repp->save_chainsetup(); else session_repp->save_chainsetup(filename); ECA_LOG_MSG(ECA_LOGGER::info, "Saved selected chainsetup \"" + selected_chainsetup() + "\"."); } catch(ECA_ERROR& e) { set_last_error(e.error_section() + ": \"" + e.error_message() + "\""); } } /** * Selects chainsetup * * @param name chainsetup name * * require: * name != "" * * ensure: * name == selected_chainsetup() || * selected_chainsetup_rep == 0 */ void ECA_CONTROL::select_chainsetup(const string& name) { // -------- DBC_REQUIRE(name != ""); // -------- session_repp->select_chainsetup(name); selected_chainsetup_repp = session_repp->selected_chainsetup_repp; if (selected_chainsetup_repp == 0) { ECA_LOG_MSG(ECA_LOGGER::info, "Chainsetup \"" + name + "\" doesn't exist!"); set_last_error("Chainsetup \"" + name + "\" doesn't exist!"); } // else { ECA_LOG_MSG(ECA_LOGGER::info, "Selected chainsetup: \"" + selected_chainsetup() + "\"."); } // -------- DBC_ENSURE(name == selected_chainsetup() || is_selected() == false); // -------- } /** * Selects a chainsetup by index. * * @param index_number an integer identifier * * require: * index_number > 0 */ void ECA_CONTROL::select_chainsetup_by_index(int index_number) { // -------- DBC_REQUIRE(index_number > 0); // -------- for(std::vector::size_type p = 0; p != session_repp->chainsetups_rep.size(); p++) { if (index_number == static_cast(p + 1)) { select_chainsetup(session_repp->chainsetups_rep[p]->name()); break; } } } /** * Name of currently active chainsetup */ string ECA_CONTROL::selected_chainsetup(void) const { if (selected_chainsetup_repp != 0) return selected_chainsetup_repp->name(); return ""; } /** * Spawns an external editor for editing selected chainsetup * * require: * is_selected() * connected_chainsetup() != selected_chainsetup() */ void ECA_CONTROL::edit_chainsetup(void) { // -------- DBC_REQUIRE(selected_chainsetup().empty() != true); // -------- /* 1. check which editor to use (and exit if none * defined) */ string editori = ""; string use_getenv = resource_value("ext-cmd-text-editor-use-getenv"); if (use_getenv.size() == 0 || use_getenv == "true") { /* note: as specified in ecasoundrc(5), we should * default to 'true' */ if (std::getenv("EDITOR") != 0) { editori = std::getenv("EDITOR"); } } if (editori == "") editori = resource_value("ext-cmd-text-editor"); if (editori == "") { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Cannot edit, no text editor specified/available. See ecasoundrc(5) man page and the 'ext-cmd-text-editor' configuration variable."); return; } /* 2. detect hot-swap */ bool hot_swap = false; bool restart = false; if (connected_chainsetup() == selected_chainsetup()) { hot_swap = true; if (is_running()) restart = true; } /* 3. store runtime state of the old chainsetup */ string origname = selected_chainsetup_repp->name(); string origfilename = selected_chainsetup_repp->filename(); SAMPLE_SPECS::sample_pos_t origpos = selected_chainsetup_repp->position_in_samples(); /* 4. create a safely accessible temporary filename */ TEMPORARY_FILE_DIRECTORY tempfile_dir_rep; string tmpdir ("ecasound-"); char* tmp_p = std::getenv("USER"); if (tmp_p != NULL) { tmpdir += string(tmp_p); tempfile_dir_rep.reserve_directory(tmpdir); } if (tempfile_dir_rep.is_valid() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Unable to create temporary directory \"" + tmpdir + "\"."); return; } string filename = tempfile_dir_rep.create_filename("cs-edit-tmp", ".ecs"); /* 5. save selected chainsetup to the temp file */ if (hot_swap == true) session_repp->connected_chainsetup_repp->set_name("cs-edit-temp"); save_chainsetup(filename); if (hot_swap == true) session_repp->connected_chainsetup_repp->set_name(origname); else remove_chainsetup(); /* 6. fork an external text editor */ // FIXME: we should drop priviledge-level here (at least if root)! editori += " " + filename; int res = ::system(editori.c_str()); if (res == 127 || res == -1) { ECA_LOG_MSG(ECA_LOGGER::info, "Can't edit; unable to open file in text editor \"" + string(editori.c_str()) + "\"."); } else { /* 7. reload the edited chainsetup and reset runtime state */ load_chainsetup(filename); if (is_selected() != true) { ECA_LOG_MSG(ECA_LOGGER::info, std::string("Unable to parse chainsetup, keeping the temporary file ") + filename); } else { remove(filename.c_str()); if (origfilename.empty() != true) { set_chainsetup_filename(origfilename); } if (selected_chainsetup_repp) selected_chainsetup_repp->seek_position_in_samples(origpos); if (hot_swap == true) { /* 7.1 disconnect the chainsetup to be replaced */ disconnect_chainsetup(); /* 7.2 try to connect the edited chainsetup */ select_chainsetup("cs-edit-temp"); if (is_valid() == true) { connect_chainsetup(0); /* should succeed as is_valid() is true */ DBC_CHECK(is_connected() == true); if (is_connected() == true) { if (restart == true) { DBC_CHECK(is_running() != true); start(); } } } /* 7.3 if connecting the modified chainsetup fails */ if (is_connected() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "Can't connect; edited chainsetup is not valid."); } /* 7.4 remove the old chainsetup */ select_chainsetup(origname); remove_chainsetup(); select_chainsetup("cs-edit-temp"); selected_chainsetup_repp->set_name(origname); } } } } /** * Sets processing length in seconds. * * require: * is_selected() == true * value >= 0 */ void ECA_CONTROL::set_chainsetup_processing_length_in_seconds(double value) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- /* note! here we set the _maximum_ length of the chainsetup */ selected_chainsetup_repp->set_max_length_in_seconds(value); ECA_LOG_MSG(ECA_LOGGER::info, "Set chainsetup processing length to \"" + kvu_numtostr(value) + "\" seconds."); } /** * Sets processing length in samples. If 'value' is 0, * length in unspecified. * * require: * is_selected() == true * value >= 0 */ void ECA_CONTROL::set_chainsetup_processing_length_in_samples(SAMPLE_SPECS::sample_pos_t value) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- /* note! here we set the _maximum_ length of the chainsetup */ selected_chainsetup_repp->set_max_length_in_samples(value); ECA_LOG_MSG(ECA_LOGGER::info, "Set chainsetup processing length to \"" + kvu_numtostr(selected_chainsetup_repp->max_length_in_seconds_exact()) + "\" seconds."); } /** * Sets default open mode for audio outputs. * * require: * output_mode == AUDIO_IO::io_write || output_mode == AUDIO_IO::io_readwrite */ void ECA_CONTROL::set_chainsetup_output_mode(int output_mode) { // -------- DBC_REQUIRE(output_mode == AUDIO_IO::io_write || output_mode == AUDIO_IO::io_readwrite); // -------- selected_chainsetup_repp->set_output_openmode(output_mode); } /** * Sets chainsetup buffersize (in samples). * * @pre is_selected() == true */ void ECA_CONTROL::set_chainsetup_buffersize(int bsize) { // -------- DBC_REQUIRE(is_selected() == true); // -------- selected_chainsetup_repp->set_buffersize(bsize); } /** * Toggles chainsetup looping * * require: * is_selected() == true */ void ECA_CONTROL::toggle_chainsetup_looping(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- if (selected_chainsetup_repp->looping_enabled()) { selected_chainsetup_repp->toggle_looping(false); ECA_LOG_MSG(ECA_LOGGER::info, "Disabled looping."); } else { selected_chainsetup_repp->toggle_looping(true); ECA_LOG_MSG(ECA_LOGGER::info, "Enabled looping."); } } /** * Connects selected chainsetup * * require: * is_selected() == true * is_valid() == true * * ensure: * is_connected() == true || (last_error().size() > 0 && no_errors != true) */ void ECA_CONTROL::connect_chainsetup(struct eci_return_value *retval) { // -------- DBC_REQUIRE(is_selected()); DBC_REQUIRE(selected_chainsetup_repp != 0 && selected_chainsetup_repp->is_valid() == true); // -------- bool no_errors = true; string errmsg; if (is_connected() == true) { disconnect_chainsetup(); } try { session_repp->connect_chainsetup(); ECA_LOG_MSG(ECA_LOGGER::subsystems, "Connected chainsetup: \"" + connected_chainsetup() + "\""); } catch(ECA_ERROR& e) { errmsg = e.error_message(); no_errors = false; } if (is_connected() != true) { set_last_error(" Connecting chainsetup failed: \"" + errmsg + "\""); no_errors = false; } fill_command_retval(retval); // -------- DBC_ENSURE(is_connected() || no_errors != true); // -------- } /** * Name of connected chainsetup. */ string ECA_CONTROL::connected_chainsetup(void) const { if (session_repp->connected_chainsetup_repp != 0) { return session_repp->connected_chainsetup_repp->name(); } return ""; } /** * Disconnects activate chainsetup * * require: * is_connected() == true * * ensure: * connected_chainsetup() == "" */ void ECA_CONTROL::disconnect_chainsetup(void) { // -------- DBC_REQUIRE(is_connected()); // -------- if (is_engine_ready_for_commands() == true) { stop_on_condition(); } if (is_engine_created()) { close_engine(); } ECA_LOG_MSG(ECA_LOGGER::info, "Disconnecting chainsetup: \"" + connected_chainsetup() + "\"."); session_repp->disconnect_chainsetup(); // -------- DBC_ENSURE(connected_chainsetup() == ""); // -------- } /** * Changes the chainsetup position relatively to the current position. * Behaves differently depending on whether the selected * chainsetup is connected or not. * * require: * is_selected() == true */ void ECA_CONTROL::change_chainsetup_position(double seconds) { // -------- DBC_REQUIRE(is_selected()); // -------- // FIXME: check whether all audio devices support seeking, // raise an error if not (note: see other similar FIXMEs) if (connected_chainsetup() == selected_chainsetup() && is_engine_ready_for_commands() == true) { if (seconds < 0) engine_repp->command(ECA_ENGINE::ep_rewind, -seconds); else engine_repp->command(ECA_ENGINE::ep_forward, seconds); } else { selected_chainsetup_repp->seek_position_in_seconds(selected_chainsetup_repp->position_in_seconds() + seconds ); } } /** * Changes the chainsetup position in samples relatively to the * current position. Behaves differently depending on whether * the selected chainsetup is connected or not. * * require: * is_selected() == true */ void ECA_CONTROL::change_chainsetup_position_samples(SAMPLE_SPECS::sample_pos_t samples) { // -------- DBC_REQUIRE(is_selected()); // -------- // FIXME: check whether all audio devices support seeking, // raise an error if not (note: see other similar FIXMEs) if (connected_chainsetup() == selected_chainsetup() && is_engine_ready_for_commands() == true) { change_chainsetup_position(static_cast(samples) / selected_chainsetup_repp->samples_per_second()); } else { selected_chainsetup_repp->seek_position_in_samples(selected_chainsetup_repp->position_in_samples() + samples ); } } /** * Sets the chainsetup position. Behaves differently depending on * whether the selected chainsetup is connected or not. * * require: * is_selected() == true */ void ECA_CONTROL::set_chainsetup_position(double seconds) { // -------- DBC_REQUIRE(is_selected()); // -------- // FIXME: check whether all audio devices support seeking, // raise an error if not (note: see other similar FIXMEs) if (connected_chainsetup() == selected_chainsetup() && is_engine_ready_for_commands() == true) { engine_repp->command(ECA_ENGINE::ep_setpos, seconds); } else { selected_chainsetup_repp->seek_position_in_seconds(seconds); } } /** * Sets the chainsetup position in samples.. Behaves * differently depending on whether the selected chainsetup * is connected or not. * * require: * is_selected() == true */ void ECA_CONTROL::set_chainsetup_position_samples(SAMPLE_SPECS::sample_pos_t samples) { // -------- DBC_REQUIRE(is_selected()); // -------- // FIXME: check whether all audio devices support seeking, // raise an error if not (note: see other similar FIXMEs) if (connected_chainsetup() == selected_chainsetup() && is_engine_ready_for_commands() == true) { set_chainsetup_position(static_cast(samples) / selected_chainsetup_repp->samples_per_second()); } else { selected_chainsetup_repp->seek_position_in_samples(samples); } } /** * Gets a vector of al chainsetup names. */ std::vector ECA_CONTROL::chainsetup_names(void) const { return session_repp->chainsetup_names(); } /** * Gets a pointer to selected chainsetup, or 0 if no * chainsetup is selected. */ const ECA_CHAINSETUP* ECA_CONTROL::get_chainsetup(void) const { return selected_chainsetup_repp; } /** * Gets a pointer to connected chainsetup, or 0 if no * chainsetup is selected. */ const ECA_CHAINSETUP* ECA_CONTROL::get_connected_chainsetup(void) const { return session_repp->connected_chainsetup_repp; } /** * Gets a pointer to chainsetup with filename 'filename'. */ const ECA_CHAINSETUP* ECA_CONTROL::get_chainsetup_filename(const string& filename) const { std::vector::const_iterator p = session_repp->chainsetups_rep.begin(); while(p != session_repp->chainsetups_rep.end()) { if ((*p)->filename() == filename) { return (*p); } ++p; } return 0; } /** * Returns current buffersize of selected chainsetup. * * ®pre is_selected() == true */ int ECA_CONTROL::chainsetup_buffersize(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->buffersize(); } /** * Gets chainsetup filename (used by save_chainsetup()) * * ®pre is_selected() == true */ const string& ECA_CONTROL::chainsetup_filename(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->filename(); } /** * Sets chainsetup filename (used by save_chainsetup()) * * require: * is_selected() == true && * name.empty() != true */ void ECA_CONTROL::set_chainsetup_filename(const string& name) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(name.empty() != true); // -------- selected_chainsetup_repp->set_filename(name); } /** * Sets general chainsetup chainsetup parameter * * require: * is_selected() == true && * name.empty() != true */ void ECA_CONTROL::set_chainsetup_parameter(const string& name) { // -------- DBC_REQUIRE(is_selected() == true && name.empty() != true); // -------- selected_chainsetup_repp->interpret_global_option(name); if (selected_chainsetup_repp->interpret_result() != true) { /* for instance -f:xxx options are handle by * object-specific parsing */ selected_chainsetup_repp->interpret_object_option(name); } } /** * Sets general chainsetup chainsetup parameter * * require: * is_selected() == true && * name.empty() != true */ void ECA_CONTROL::set_chainsetup_sample_format(const string& name) { // -------- DBC_REQUIRE(is_selected() == true && name.empty() != true); // -------- selected_chainsetup_repp->interpret_object_option("-f:" + name); if (selected_chainsetup_repp->interpret_result() != true) { set_last_error(selected_chainsetup_repp->interpret_result_verbose()); } } /** * Adds a new chain (selected chainsetup). Added chain is automatically * selected. * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * * ensure: * selected_chains().size() > 0 */ void ECA_CONTROL::add_chain(const string& name) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chainsetup() != connected_chainsetup()); // -------- add_chains(std::vector (1, name)); // -------- DBC_ENSURE(selected_chains().size() > 0); // -------- } /** * Adds new chains (selected chainsetup). Added chains are automatically * selected. * * @param names comma separated list of chain names * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * * ensure: * selected_chains().size() > 0 */ void ECA_CONTROL::add_chains(const string& names) { // -------- DBC_REQUIRE(is_selected() == true && (session_repp->connected_chainsetup_repp != session_repp->selected_chainsetup_repp)); // -------- add_chains(kvu_string_to_vector(names, ',')); // -------- DBC_ENSURE(selected_chains().size() > 0); // -------- } /** * Adds new chains (selected chainsetup). Added chains are automatically * selected. * * @param namess vector of chain names * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * * ensure: * selected_chains().size() == names.size() */ void ECA_CONTROL::add_chains(const std::vector& new_chains) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- selected_chainsetup_repp->add_new_chains(new_chains); selected_chainsetup_repp->select_chains(new_chains); ECA_LOG_MSG(ECA_LOGGER::info, "Added chains: " + kvu_vector_to_string(new_chains, ", ") + "."); // -------- DBC_ENSURE(selected_chains().size() == new_chains.size()); // -------- } /** * Removes currently selected chain (selected chainsetup) * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() > 0 && * * ensure: * selected_chains().size() == 0 */ void ECA_CONTROL::remove_chains(void) { // -------- DBC_REQUIRE(is_selected() == true && selected_chains().size() > 0 && (session_repp->connected_chainsetup_repp != session_repp->selected_chainsetup_repp)); // -------- selected_chainsetup_repp->remove_chains(); ECA_LOG_MSG(ECA_LOGGER::info, "(eca-controlled) Removed selected chains."); // -------- DBC_ENSURE(selected_chains().size() == 0); // -------- } /** * Selects a set of chains using index numbers. Previously * selected chains are first all deselected. * * * @param index_numbers set of integer identifiers * * require: * is_selected() == true */ void ECA_CONTROL::select_chains_by_index(const std::vector& index_numbers) { // -------- DBC_REQUIRE(is_selected() == true); // -------- std::vector selchains; for(std::vector::size_type p = 0; p != selected_chainsetup_repp->chains.size(); p++) { for(std::vector::size_type q = 0; q != index_numbers.size(); q++) { if (index_numbers[q] == static_cast(p + 1)) { selchains.push_back(selected_chainsetup_repp->chains[p]->name()); break; } } } select_chains(selchains); } /** * Selects a chains (currently selected chainsetup). Previously * selected chains are first all deselected. * * require: * is_selected() == true * * ensure: * selected_chains().size() == 1 */ void ECA_CONTROL::select_chain(const string& chain) { // -------- DBC_REQUIRE(is_selected() == true); // -------- std::vector c (1); c[0] = chain; selected_chainsetup_repp->select_chains(c); // ECA_LOG_MSG(ECA_LOGGER::user_objects, "Selected chain: " + chain + "."); // -------- DBC_ENSURE(selected_chains().size() == 1); // -------- } /** * Selects chains (currently selected chainsetup). Previously * selected chains are first all deselected. * * @param chains vector of chain names * * require: * is_selected() == true * * ensure: * selected_chains().size() > 0 */ void ECA_CONTROL::select_chains(const std::vector& chains) { // -------- DBC_REQUIRE(is_selected() == true); // -------- selected_chainsetup_repp->select_chains(chains); // ECA_LOG_MSG(ECA_LOGGER::user_objects, "Selected chains: " + // vector_to_string(chains, ", ") + "."); } /** * Deselects chains (currently selected chainsetup) * * @param chains vector of chain names * * require: * is_selected() == true */ void ECA_CONTROL::deselect_chains(const std::vector& chains) { // -------- DBC_REQUIRE(is_selected() == true); // -------- std::vector schains = selected_chainsetup_repp->selected_chains(); std::vector::const_iterator p = chains.begin(); while(p != chains.end()) { std::vector::iterator o = schains.begin(); while(o != schains.end()) { if (*p == *o) { // ECA_LOG_MSG(ECA_LOGGER::info, "(eca-controller-objects) Deselected chain " + *o + "."); schains.erase(o); } else ++o; } ++p; } selected_chainsetup_repp->select_chains(schains); } /** * Selects all chains (currently selected chainsetup) * * require: * is_selected() == true */ void ECA_CONTROL::select_all_chains(void) { // -------- DBC_REQUIRE(is_selected() == true); // -------- selected_chainsetup_repp->select_all_chains(); // ECA_LOG_MSG(ECA_LOGGER::info, "Selected chains: " + vector_to_string(selected_chains(), ", ") + "."); } /** * Returns a list of selected chains (currently selected chainsetup) * * require: * is_selected() == true */ const std::vector& ECA_CONTROL::selected_chains(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->selected_chains(); } /** * Gets a vector of all chain names. * * require: * is_selected() == true */ std::vector ECA_CONTROL::chain_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->chain_names(); } /** * Gets a pointer to selected chain, or 0 if no chain is selected. * * require: * is_selected() == true * selected_chains().size() == 1 */ const CHAIN* ECA_CONTROL::get_chain(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- return get_chain_priv(); } /** * Gets a pointer to selected chain, or 0 if no chain is selected. */ CHAIN* ECA_CONTROL::get_chain_priv(void) const { const std::vector& schains = selected_chainsetup_repp->selected_chains(); std::vector::const_iterator o = schains.begin(); while(o != schains.end()) { for(std::vector::size_type p = 0; p != selected_chainsetup_repp->chains.size(); p++) { if (selected_chainsetup_repp->chains[p]->name() == *o) return selected_chainsetup_repp->chains[p]; } ++o; } return 0; } /** * Clears all selected chains (all chain operators and controllers * are removed) * * @param name chain name * * require: * is_selected() == true * is_running() != true */ void ECA_CONTROL::clear_chains(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(is_running() != true); // -------- selected_chainsetup_repp->clear_chains(); } /** * Clears all selected chains (all chain operators and controllers * are removed) * * @param name chain name * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() == 1 */ void ECA_CONTROL::rename_chain(const string& name) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(selected_chains().size() == 1); // -------- selected_chainsetup_repp->rename_chain(name); } void ECA_CONTROL::audio_input_as_selected(void) { /* note, here we check that the pointer is still a valid one */ if (selected_chainsetup_repp->ok_audio_object(selected_audio_input_repp) != true) selected_audio_input_repp = 0; selected_audio_object_repp = selected_audio_input_repp; } void ECA_CONTROL::audio_output_as_selected(void) { /* note, here we check that the pointer is still a valid one */ if (selected_chainsetup_repp->ok_audio_object(selected_audio_output_repp) != true) selected_audio_output_repp = 0; selected_audio_object_repp = selected_audio_output_repp; } /** * Sets default audio format. This format will be used, when * adding audio inputs and outputs. * * require: * is_selected() == true */ void ECA_CONTROL::set_default_audio_format(const string& sfrm, int channels, long int srate, bool interleaving) { // -------- DBC_REQUIRE(is_selected() == true); // -------- string format; format = "-f:"; format += sfrm; format += ","; format += kvu_numtostr(channels); format += ","; format += kvu_numtostr(srate); format += ","; if (interleaving == true) format += "i"; else format += "n"; selected_chainsetup_repp->interpret_object_option(format); if (selected_chainsetup_repp->interpret_result() != true) { set_last_error(selected_chainsetup_repp->interpret_result_verbose()); } } /** * Returns the default audio format. * * @pre is_selected() == true */ const ECA_AUDIO_FORMAT& ECA_CONTROL::default_audio_format(void) const { // -- DBC_REQUIRE(is_selected() == true); // -- return selected_chainsetup_repp->default_audio_format(); } /** * Sets default audio format. This format will be used, when * adding audio inputs and outputs. * * require: * is_selected() == true */ void ECA_CONTROL::set_default_audio_format(const ECA_AUDIO_FORMAT& format) { // -------- DBC_REQUIRE(is_selected() == true); // -------- set_default_audio_format(format.format_string(), static_cast(format.channels()), static_cast(format.samples_per_second()), format.interleaved_channels()); } static AUDIO_IO* priv_select_audio_object(const std::vector& objects, const std::string& name) { AUDIO_IO* result = 0; /* NOTE: ugly, but needed to maintain compability with older 2.4.x * releases that allowed double-quoted filenames to ai/ao-select */ std::string stripped_name; if (name.size() > 0 && name[0] == '"') { stripped_name = name; kvu_string_strip_outer_quotes(&stripped_name, '"'); } std::vector::size_type p = 0; for(p = 0; p != objects.size(); p++) { if (objects[p]->label() == name || objects[p]->label() == stripped_name) { result = objects[p]; /* note: in case 'name' is not unique, the first matching * instance is selected */ break; } } return result; } /** * Selects an audio input * * require: * is_selected() == true */ void ECA_CONTROL::select_audio_input(const string& name) { // -------- DBC_REQUIRE(is_selected() == true); // -------- selected_audio_input_repp = priv_select_audio_object(selected_chainsetup_repp->inputs, name); } /** * Selects an audio output * * require: * is_selected() == true */ void ECA_CONTROL::select_audio_output(const string& name) { // -------- DBC_REQUIRE(is_selected() == true); // -------- selected_audio_output_repp = priv_select_audio_object(selected_chainsetup_repp->outputs, name); } /** * Selects an audio input by index. * * @pre is_selected() == true * @pre index_number > 0 */ void ECA_CONTROL::select_audio_input_by_index(int index_number) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(index_number > 0); // -------- selected_audio_input_repp = 0; if (index_number <= static_cast(selected_chainsetup_repp->inputs.size())) selected_audio_input_repp = selected_chainsetup_repp->inputs[index_number-1]; } /** * Selects an audio output by index. * * @pre is_selected() == true * @pre index_number > 0 */ void ECA_CONTROL::select_audio_output_by_index(int index_number) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(index_number > 0); // -------- selected_audio_output_repp = 0; if (index_number <= static_cast(selected_chainsetup_repp->outputs.size())) selected_audio_output_repp = selected_chainsetup_repp->outputs[index_number-1]; } /** * Gets audio format information of the object given as argument. * Note! To get audio format information, audio objects need * to be opened. Because of this, object argument cannot be given * as a const pointer. */ ECA_AUDIO_FORMAT ECA_CONTROL::get_audio_format(AUDIO_IO* aobj) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(aobj != 0); // -------- bool was_open = true; if (aobj->is_open() == false) { was_open = false; try { aobj->open(); } catch(AUDIO_IO::SETUP_ERROR&) { // FIXME: what to do here? } } ECA_AUDIO_FORMAT t (aobj->channels(), aobj->samples_per_second(), aobj->sample_format(), aobj->interleaved_channels()); if (was_open == false) aobj->close(); return t; } /** * Sets the default audio format to the match the currently * select audio input's audio format. * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre selected_audio_object_repp != 0 */ void ECA_CONTROL::set_default_audio_format_to_selected_input(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0); // -------- set_default_audio_format(get_audio_format(selected_audio_input_repp)); } /** * Sets the default audio format to the match the currently * select audio output's audio format. * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre selected_audio_object_repp != 0 */ void ECA_CONTROL::set_default_audio_format_to_selected_output(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_output() != 0); // -------- set_default_audio_format(get_audio_format(selected_audio_output_repp)); } /** * Adds a new audio input (file, soundcard device, etc). Input * is attached to currently selected chains (if any). If 'filename' * doesn't exist or is otherwise invalid, no input is added. * * require: * filename.empty() == false * is_selected() == true * connected_chainsetup() != selected_chainsetup() */ void ECA_CONTROL::add_audio_input(const string& filename) { // -------- DBC_REQUIRE(filename.empty() == false); DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- selected_audio_input_repp = 0; selected_chainsetup_repp->interpret_object_option("-i:" + filename); if (selected_chainsetup_repp->interpret_result() == true) { select_audio_input(kvu_get_argument_number(1, filename)); ECA_LOG_MSG(ECA_LOGGER::info, "Added audio input \"" + filename + "\"."); } else { set_last_error(selected_chainsetup_repp->interpret_result_verbose()); } } /** * Adds a new audio output (file, soundcard device, etc). Output * is attached to currently selected chains (if any). If 'filename' * doesn't exist or is otherwise invalid, no input is added. * * require: * filename.empty() == false * is_selected() == true * connected_chainsetup() != selected_chainsetup() */ void ECA_CONTROL::add_audio_output(const string& filename) { // -------- DBC_REQUIRE(filename.empty() == false); DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- selected_audio_output_repp = 0; selected_chainsetup_repp->interpret_object_option("-o:" + filename); if (selected_chainsetup_repp->interpret_result() == true) { select_audio_output(kvu_get_argument_number(1, filename)); ECA_LOG_MSG(ECA_LOGGER::info, "Added audio output \"" + filename + "\"."); } else { set_last_error(selected_chainsetup_repp->interpret_result_verbose()); } } /** * Adds a default output (as defined in ~/.ecasoundrc) and attach * it to currently selected chains. * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() */ void ECA_CONTROL::add_default_output(void) { // -------- DBC_REQUIRE(selected_chains().size() > 0); DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); // -------- add_audio_output(ECA_OBJECT_FACTORY::probe_default_output_device()); ECA_LOG_MSG(ECA_LOGGER::info, "Added default output to selected chains."); } /** * Gets a vector of all audio input names. * * require: * is_selected() == true */ std::vector ECA_CONTROL::audio_input_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->audio_input_names(); } /** * Gets a vector of all audio output names. * * require: * is_selected() == true */ std::vector ECA_CONTROL::audio_output_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->audio_output_names(); } /** * Gets a pointer to the currently selected audio input. * Returns 0 if no audio object is selected. * * require: * is_selected() == true */ const AUDIO_IO* ECA_CONTROL::get_audio_input(void) { // -------- DBC_REQUIRE(is_selected() == true); // -------- /* note, here we check that the pointer is still a valid one */ if (selected_chainsetup_repp->ok_audio_object(selected_audio_input_repp) != true) selected_audio_input_repp = 0; return selected_audio_input_repp; } /** * Gets a pointer to the currently selected audio output. * Returns 0 if no audio object is selected. * * require: * is_selected() == true */ const AUDIO_IO* ECA_CONTROL::get_audio_output(void) { // -------- DBC_REQUIRE(is_selected() == true); // -------- /* note, here we check that the pointer is still a valid one */ if (selected_chainsetup_repp->ok_audio_object(selected_audio_output_repp) != true) selected_audio_output_repp = 0; return selected_audio_output_repp; } /** * Removes the selected audio input. * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre get_audio_input() != 0 * * @post selected_audio_input_repp = 0 */ void ECA_CONTROL::remove_audio_input(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0); // -------- ECA_LOG_MSG(ECA_LOGGER::info, "Removing selected audio input \"" + selected_audio_input_repp->label() + "\" from selected chains."); selected_chainsetup_repp->remove_audio_input(selected_audio_input_repp); selected_audio_input_repp = 0; // -------- DBC_ENSURE(selected_audio_input_repp == 0); // -------- } /** * Removes the selected audio output. * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre get_audio_output() != 0 * * @post selected_audio_output_repp = 0 */ void ECA_CONTROL::remove_audio_output(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_output() != 0); // -------- ECA_LOG_MSG(ECA_LOGGER::info, "Removing selected audio output \"" + selected_audio_output_repp->label() + "\" from selected chains."); selected_chainsetup_repp->remove_audio_output(selected_audio_output_repp); selected_audio_output_repp = 0; // -------- DBC_ENSURE(selected_audio_output_repp == 0); // -------- } /** * Attaches selected audio input to selected chains * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre get_audio_input() != 0 */ void ECA_CONTROL::attach_audio_input(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0); // -------- selected_chainsetup_repp->attach_input_to_selected_chains(selected_audio_input_repp); ECA_LOG_MSG(ECA_LOGGER::info, "Attached audio input \"" + selected_audio_input_repp->label() + "\" to selected chains."); } /** * Attaches selected audio output to selected chains * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre get_audio_output() != 0 */ void ECA_CONTROL::attach_audio_output(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_output() != 0); // -------- selected_chainsetup_repp->attach_output_to_selected_chains(selected_audio_output_repp); ECA_LOG_MSG(ECA_LOGGER::info, "Attached audio output \"" + selected_audio_output_repp->label() + "\" to selected chains."); } /** * Get a string containing a comma separated list of all chains * attached to input with index 'aiod'. * * @pre is_selected() == true */ string ECA_CONTROL::attached_chains_input(AUDIO_IO* aiod) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- vector t = selected_chainsetup_repp->get_attached_chains_to_input(aiod); string out = ""; vector::const_iterator p = t.begin(); while(p != t.end()) { out += *p; ++p; if (p != t.end()) out += ","; } return out; } /** * Get a string containing a comma separated list of all chains * attached to output with index 'aiod'. * * @pre is_selected() == true */ string ECA_CONTROL::attached_chains_output(AUDIO_IO* aiod) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- vector t = selected_chainsetup_repp->get_attached_chains_to_output(aiod); string out = ""; vector::const_iterator p = t.begin(); while(p != t.end()) { out += *p; ++p; if (p != t.end()) out += ","; } return out; } /** * Get a string containing a comma separated list of all chains * attached to audio object with name 'filename'. * * @pre is_selected() == true */ vector ECA_CONTROL::attached_chains(const string& filename) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- return selected_chainsetup_repp->get_attached_chains_to_iodev(filename); } /** * Rewinds selected audio object by 'pos_in_seconds' seconds * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre selected_audio_object_repp != 0 */ void ECA_CONTROL::rewind_audio_object(double seconds) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0 || get_audio_output() != 0); // -------- selected_audio_object_repp->seek_position_in_seconds(selected_audio_object_repp->position_in_seconds_exact() - seconds); } /** * Forwards selected audio object by 'pos_in_seconds' seconds * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre selected_audio_object_repp != 0 */ void ECA_CONTROL::forward_audio_object(double seconds) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0 || get_audio_output() != 0); // -------- selected_audio_object_repp->seek_position_in_seconds(selected_audio_object_repp->position_in_seconds_exact() + seconds); } /** * Sets position of selected audio object * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_audio_object_repp != 0 */ void ECA_CONTROL::set_audio_object_position(double seconds) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0 || get_audio_output() != 0); // -------- selected_audio_object_repp->seek_position_in_seconds(seconds); } /** * Sets position of selected audio object * * @pre is_selected() == true * @pre connected_chainsetup() != selected_chainsetup() * @pre selected_audio_object_repp != 0 */ void ECA_CONTROL::set_audio_object_position_samples(SAMPLE_SPECS::sample_pos_t samples) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0 || get_audio_output() != 0); // -------- selected_audio_object_repp->seek_position_in_samples(samples); } /** * Spawns an external wave editor for editing selected audio object. * * require: * is_selected() * connected_chainsetup() != selected_chainsetup() * selected_audio_object_repp != 0 */ void ECA_CONTROL::wave_edit_audio_object(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(connected_chainsetup() != selected_chainsetup()); DBC_REQUIRE(get_audio_input() != 0 || get_audio_output() != 0); // -------- string name = selected_audio_object_repp->label(); int res = ::system(string(resource_value("ext-cmd-wave-editor") + " " + name).c_str()); if (res == 127 || res == -1) { ECA_LOG_MSG(ECA_LOGGER::info, "Can't edit; unable to open wave editor \"" + resource_value("x-wave-editor") + "\"."); } } /** * Adds a new chain operator * * @param gcontrol_params is an Ecasound option string describing * a controlled: syntax is either "-:par1,...,parN", * or just ":par1,...,parN" * * require: * is_selected() == true * selected_chains().size() == 1 */ void ECA_CONTROL::add_chain_operator(const string& chainop_params) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_cop_add; edit.cs_ptr = selected_chainsetup_repp; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { /* note: unlike all other functions, first_selected_chain() * returns 0..N */ edit.m.c_generic_param.chain = p + 1; edit.param = chainop_params; edit.need_chain_reinit = true; execute_edit_on_selected(edit); } } /** * Adds a new chain operator. Pointer given as argument * will remain to be usable, but notice that it is * _NOT_ thread-safe to use assigned/registered objects * from client programs. You must be sure that ecasound * isn't using the same object as you are. The * easiest way to assure this is to disconnect * the chainsetup to which object is attached. * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() == 1 * cotmp != 0 */ void ECA_CONTROL::add_chain_operator(CHAIN_OPERATOR* cotmp) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(cotmp != 0); // -------- selected_chainsetup_repp->add_chain_operator(cotmp); } /** * Returns a pointer to the the selected chain operator. If no chain * operator is selected, 0 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 */ const CHAIN_OPERATOR* ECA_CONTROL::get_chain_operator(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- if (is_selected() == true) { unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) return selected_chainsetup_repp->chains[p]->get_selected_chain_operator(); } return 0; } /** * Returns a list of chain operator names. * * require: * is_selected() == true * selected_chains().size() == 1 */ std::vector ECA_CONTROL::chain_operator_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- std::vector result; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { CHAIN* selected_chain = selected_chainsetup_repp->chains[p]; int save_selected_cop = selected_chain->selected_chain_operator(); for(int n = 0; n < selected_chain->number_of_chain_operators(); n++) { selected_chain->select_chain_operator(n + 1); result.push_back(selected_chain->chain_operator_name()); } selected_chain->select_chain_operator(save_selected_cop); } return result; } /** * Returns the index of the selected chain operator. If no chain * operator is selected, -1 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 */ int ECA_CONTROL::selected_chain_operator(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) return selected_chainsetup_repp->chains[p]->selected_chain_operator(); return -1; } /** * Removes the selected chain operator * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() == 1 */ void ECA_CONTROL::remove_chain_operator(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chainsetup() != connected_chainsetup()); DBC_REQUIRE(selected_chains().size() == 1); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) selected_chainsetup_repp->chains[p]->remove_chain_operator(-1); } /** * Selects chain operator 'chainop_id'. * * require: * is_selected() == true * selected_chains().size() == 1 * chainop_id > 0 */ void ECA_CONTROL::select_chain_operator(int chainop_id) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(chainop_id > 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { CHAIN *ch = selected_chainsetup_repp->chains[p]; if (chainop_id < ch->number_of_chain_operators() + 1) { ch->select_chain_operator(chainop_id); } } } /** * Returns a list of chain operator parameter names. * * require: * is_selected == true * selected_chains().size() == 1 */ std::vector ECA_CONTROL::chain_operator_parameter_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- std::vector result; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { CHAIN* selected_chain = selected_chainsetup_repp->chains[p]; if (selected_chain->selected_chain_operator() > 0) { int save_selected_copp = selected_chain->selected_chain_operator_parameter(); for(int n = 0; n < selected_chain->number_of_chain_operator_parameters(); n++) { selected_chain->select_chain_operator_parameter(n + 1); result.push_back(selected_chain->chain_operator_parameter_name()); } selected_chain->select_chain_operator_parameter(save_selected_copp); } } return result; } /** * Selects chain operator parameter 'param'. * * require: * is_selected() == true * selected_chains().size() == 1 * get_chain_operator() != 0 * param > 0 */ void ECA_CONTROL::select_chain_operator_parameter(int param) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(param > 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { selected_chainsetup_repp->chains[p]->select_chain_operator_parameter(param); } } /** * Sets chain operator parameter value * * require: * is_selected() == true * selected_chains().size() == 1 * get_chain_operator() != 0 */ void ECA_CONTROL::set_chain_operator_parameter(CHAIN_OPERATOR::parameter_t value) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_chain_operator() != 0); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_cop_set_param; edit.cs_ptr = selected_chainsetup_repp; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { /* note: unlike all other functions, first_selected_chain() * returns 0..N */ CHAIN *chain = selected_chainsetup_repp->chains[p]; edit.m.cop_set_param.chain = p + 1; edit.m.cop_set_param.op = chain->selected_chain_operator(); edit.m.cop_set_param.param = chain->selected_chain_operator_parameter(); edit.m.cop_set_param.value = value; execute_edit_on_selected(edit); } } /** * Parsers input parameter to bypass/mute/etc toggles. * * if (str == "on") return 1 * if (str == "off") return 0 * if (str == "toggle") return -1 * return -1 */ static int priv_onofftoggle_to_int(const string& str) { if (str == "on") return 1; if (str == "off") return 0; return -1; } /** * Toggles whether chain is muted or not * * require: * is_selected() == true * selected_chains().size() > 0 */ void ECA_CONTROL::set_chain_muting(const string &arg) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() > 0); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_c_muting; edit.cs_ptr = selected_chainsetup_repp; int state_arg = priv_onofftoggle_to_int(arg); unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { edit.m.c_muting.chain = p + 1; edit.m.c_muting.val = state_arg; execute_edit_on_selected(edit); } } /** * Toggles whether chain operators are enabled or disabled * * require: * is_selected() == true * selected_chains().size() > 0 */ void ECA_CONTROL::set_chain_bypass(const string& arg) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() > 0); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_c_bypass; edit.cs_ptr = selected_chainsetup_repp; int state_arg = priv_onofftoggle_to_int(arg); unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { edit.m.c_bypass.chain = p + 1; edit.m.c_bypass.val = state_arg; execute_edit_on_selected(edit); } } /** * Modify chain operator bypass state * * require: * is_selected() == true * selected_chains().size() == 1 * get_chain_operator() != 0 */ void ECA_CONTROL::bypass_chain_operator(const string& arg) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_chain_operator() != 0); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_cop_bypass; edit.cs_ptr = selected_chainsetup_repp; int bypass_arg = priv_onofftoggle_to_int(arg); unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { /* note: unlike all other functions, first_selected_chain() * returns 0..N */ CHAIN *chain = selected_chainsetup_repp->chains[p]; edit.m.cop_bypass.chain = p + 1; edit.m.cop_bypass.op = chain->selected_chain_operator(); edit.m.cop_bypass.bypass = bypass_arg; execute_edit_on_selected(edit); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Set bypass of chain " + kvu_numtostr(p) + " op " + kvu_numtostr(edit.m.cop_bypass.op) + " to " + kvu_numtostr(bypass_arg)); } } /** * Returns true if selected chain op is bypasssed * * require: * is_selected() == true * selected_chains().size() == 1 * get_chain_operator() != 0 */ bool ECA_CONTROL::chain_operator_is_bypassed(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_chain_operator() != 0); // -------- int op_index = selected_chain_operator(); CHAIN* c = get_chain_priv(); if (c != 0) { return c->is_operator_bypassed(op_index); } return false; } /** * Returns true if selected chain is bypassed */ bool ECA_CONTROL::chain_is_bypassed(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- CHAIN* c = get_chain_priv(); if (c != 0) { return c->is_bypassed(); } return false; } /** * Returns true if selected chain is bypassed */ bool ECA_CONTROL::chain_is_muted(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- CHAIN* c = get_chain_priv(); if (c != 0) { return c->is_muted(); } return false; } /** * Returns the selected chain operator parameter value * * require: * is_selected() == true * selected_chains().size() == 1 */ CHAIN_OPERATOR::parameter_t ECA_CONTROL::get_chain_operator_parameter(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { if (selected_chainsetup_repp->chains[p]->selected_chain_operator() > 0 && selected_chainsetup_repp->chains[p]->selected_chain_operator_parameter() > 0) return selected_chainsetup_repp->chains[p]->get_parameter(); } return 0.0f; } /** * Returns the index number of selected chain operator parameter. * If no parameter is selected, 0 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 * get_chain_operator() != 0 */ int ECA_CONTROL::selected_chain_operator_parameter(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_chain_operator() != 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { return selected_chainsetup_repp->chains[p]->selected_chain_operator_parameter(); } return 0; } /** * Adds a new controller * * @param gcontrol_params is an Ecasound option string describing * a controlled: syntax is either "-:par1,...,parN", * or just ":par1,...,parN" * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() > 0 */ void ECA_CONTROL::add_controller(const string& gcontrol_params) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() > 0); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_ctrl_add; edit.cs_ptr = selected_chainsetup_repp; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { /* note: unlike all other functions, first_selected_chain() * returns 0..N */ edit.m.c_generic_param.chain = p + 1; edit.param = gcontrol_params; edit.need_chain_reinit = true; execute_edit_on_selected(edit); } } /** * Selects the Nth controller. * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() == 1 * controller_id > 0 */ void ECA_CONTROL::select_controller(int controller_id) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(controller_id > 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { CHAIN *ch = selected_chainsetup_repp->chains[p]; if (controller_id < ch->number_of_controllers() + 1) { selected_chainsetup_repp->chains[p]->select_controller(controller_id); } } } /** * Removes the selected controller. * * require: * is_selected() == true * connected_chainsetup() != selected_chainsetup() * selected_chains().size() == 1 * get_controller() != 0 */ void ECA_CONTROL::remove_controller(void) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chainsetup() != connected_chainsetup()); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_controller() != 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { selected_chainsetup_repp->chains[p]->remove_controller(); } } /** * Returns a list of controller names. * * require: * is_selected() == true * selected_chains().size() == 1 */ std::vector ECA_CONTROL::controller_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- std::vector result; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { CHAIN* selected_chain = selected_chainsetup_repp->chains[p]; int save_selected_ctrl = selected_chain->selected_controller(); for(int n = 0; n < selected_chain->number_of_controllers(); n++) { selected_chain->select_controller(n + 1); result.push_back(selected_chain->controller_name()); } selected_chain->select_controller(save_selected_ctrl); } return result; } /** * Returns a pointer to the selected controller. If no controller is * selected, 0 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 */ const GENERIC_CONTROLLER* ECA_CONTROL::get_controller(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) return selected_chainsetup_repp->chains[p]->get_selected_controller(); return 0; } /** * Returns the index number of the selected controller. If no controller is * selected, 0 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 */ int ECA_CONTROL::selected_controller(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) return selected_chainsetup_repp->chains[p]->selected_controller(); return 0; } /** * Returns a list of the selected controller's parameter names * * require: * is_selected() == true * selected_chains().size() == 1 * get_controller() != 0 */ std::vector ECA_CONTROL::controller_parameter_names(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_controller() != 0); // -------- std::vector result; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { CHAIN* selected_chain = selected_chainsetup_repp->chains[p]; int save_selected_ctrlp = selected_chain->selected_controller_parameter(); for(int n = 0; n < selected_chain->number_of_controller_parameters(); n++) { selected_chain->select_controller_parameter(n + 1); result.push_back(selected_chain->controller_parameter_name()); } selected_chain->select_controller_parameter(save_selected_ctrlp); } return result; } /** * Select a particular controller parameter * * require: * is_selected() == true * selected_chains().size() == 1 * param > 0 */ void ECA_CONTROL::select_controller_parameter(int param) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(param > 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { selected_chainsetup_repp->chains[p]->select_controller_parameter(param); } } /** * Returns the index number of selected controller parameter. * If no parameter is selected, 0 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 * get_controller() != 0 */ int ECA_CONTROL::selected_controller_parameter(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_controller() != 0); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { return selected_chainsetup_repp->chains[p]->selected_controller_parameter(); } return 0; } /** * Set the currently selected controller parameter * * require: * is_selected() == true * selected_chains().size() == 1 * get_controller() != 0 */ void ECA_CONTROL::set_controller_parameter(CHAIN_OPERATOR::parameter_t value) { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_controller() != 0); // -------- ECA::chainsetup_edit_t edit; edit.type = ECA::edit_ctrl_set_param; edit.cs_ptr = selected_chainsetup_repp; unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { /* note: unlike all other functions, first_selected_chain() * returns 0..N */ CHAIN *chain = selected_chainsetup_repp->chains[p]; edit.m.ctrl_set_param.chain = p + 1; edit.m.ctrl_set_param.op = chain->selected_controller(); edit.m.ctrl_set_param.param = chain->selected_controller_parameter(); edit.m.ctrl_set_param.value = value; execute_edit_on_selected(edit); } } /** * Returns the value of the currently selected controller parameter * If no controller or controller parameter is selected, 0.0 is returned. * * require: * is_selected() == true * selected_chains().size() == 1 */ CONTROLLER_SOURCE::parameter_t ECA_CONTROL::get_controller_parameter(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); // -------- unsigned int p = selected_chainsetup_repp->first_selected_chain(); if (p < selected_chainsetup_repp->chains.size()) { if (selected_chainsetup_repp->chains[p]->selected_controller() > 0 && selected_chainsetup_repp->chains[p]->selected_controller_parameter() > 0) return selected_chainsetup_repp->chains[p]->get_controller_parameter(); } return 0.0f; } /** * Returns the index number of chain operator that is the target for the currently selected * controller. * * require: * is_selected() == true * selected_chains().size() == 1 * get_controller() != 0 */ int ECA_CONTROL::selected_controller_target(void) const { // -------- DBC_REQUIRE(is_selected() == true); DBC_REQUIRE(selected_chains().size() == 1); DBC_REQUIRE(get_controller() != 0); // -------- /* We find the index of the chain_op that corresponds to the the selected controller's target by looping through the chain ops and comparing the value of the chain operator (a CHAIN_OPERATOR*) with the value of the controllers "target_pointer()". */ unsigned int p = selected_chainsetup_repp->first_selected_chain(); int result = 0; if (p < selected_chainsetup_repp->chains.size()) { CHAIN* selected_chain = selected_chainsetup_repp->chains[p]; OPERATOR* target = selected_chain->get_selected_controller()->target_pointer(); for(int n = 0; n < selected_chain->number_of_chain_operators(); n++) { if (selected_chain->get_chain_operator(n) == target) { result = n+1; break; } } } return result; } ecasound-2.9.1/libecasound/dynamic-parameters.h0000644000076400007640000000332610765532076016522 00000000000000#ifndef INCLUDED_DYNAMIC_PARAMETERS_H #define INCLUDED_DYNAMIC_PARAMETERS_H #include #include /** * Virtual template class that provides a system for dynamically * controlling a set of parameters. Supports getting and setting * parameter values, verbose parameter names, etc. * * @author Kai Vehmanen */ template class DYNAMIC_PARAMETERS { public: typedef T parameter_t; public: virtual ~DYNAMIC_PARAMETERS (void) {} /** * Gets the total number of of parameters. */ int number_of_params(void) const { return kvu_get_number_of_arguments(parameter_names()); } /** * Whether parameters (and number_of_params()) may be added * during object life-cycle. */ virtual bool variable_params(void) const { return false; } /** * Gets name of parameter with index 'id'. * @param id parameter id number * */ std::string get_parameter_name(int id) const { return(kvu_get_argument_number(id, parameter_names())); } /** * A comma-separated list of parameters names. Derived classes * must implement this. */ virtual std::string parameter_names(void) const = 0; /** * Sets the parameter value. Implementations should be able to * handle arbitrary values of 'value'. Argument validity * can be tested by a combination of set_parameter() and * get_parameter() calls. Parameter value is valid, if * get_parameter() returns it without changes. * * @param param parameter id, require: param > 0 * @param value new value */ virtual void set_parameter(int param, T value) = 0; /** * Get parameter value * * @param param parameter id, require: param > 0 */ virtual T get_parameter(int param) const = 0; }; #endif ecasound-2.9.1/libecasound/audiofx_ladspa.h0000644000076400007640000000453511053763201015706 00000000000000#ifndef INCLUDED_AUDIOFX_LADSPA_H #define INCLUDED_AUDIOFX_LADSPA_H #include #include #include "audiofx.h" /* prefer already installed LADSPA header over the * version shipped with ecasound */ #ifdef HAVE_LADSPA_H #include #else #include "ladspa.h" #endif class SAMPLE_BUFFER; /** * Wrapper class for LADSPA plugins * @author Kai Vehmanen */ class EFFECT_LADSPA : public EFFECT_BASE { public: EFFECT_LADSPA (const LADSPA_Descriptor *plugin_desc = 0) throw(ECA_ERROR&); virtual ~EFFECT_LADSPA (void); EFFECT_LADSPA* clone(void) const; EFFECT_LADSPA* new_expr(void) const { return new EFFECT_LADSPA(plugin_desc); } virtual std::string name(void) const { return(name_rep); } virtual std::string description(void) const; virtual std::string parameter_names(void) const { return(param_names_rep); } /** * This identifier can be used as a unique, case-sensitive * identifier for the plugin type within the plugin file. * Labels must not contain white-space characters. */ std::string unique(void) const { return(unique_rep); } /** * This numeric identifier indicates the plugin type * uniquely. Plugin programmers may reserve ranges of IDs from a * central body to avoid clashes. Hosts may assume that IDs are * below 0x1000000. */ long int unique_number(void) const { return(unique_number_rep); } virtual int output_channels(int i_channels) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); private: EFFECT_LADSPA (const EFFECT_LADSPA& x) { } EFFECT_LADSPA& operator=(const EFFECT_LADSPA& x) { return *this; } private: SAMPLE_BUFFER* buffer_repp; const LADSPA_Descriptor *plugin_desc; std::vector plugins_rep; unsigned long port_count_rep; int in_audio_ports; int out_audio_ports; long unique_number_rep; std::string name_rep, maker_rep, unique_rep, param_names_rep; std::vector params; std::vector param_descs_rep; void init_ports(void); void parse_parameter_hint_information(int portnum, int paramnum, struct PARAM_DESCRIPTION *pd); }; #endif ecasound-2.9.1/libecasound/eca-osc.h0000644000076400007640000000423511172651507014241 00000000000000// ------------------------------------------------------------------------ // eca-osc.h: Class implementing the Ecasound OSC interface // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #ifndef INCLUDED_ECA_OSC_H #define INCLUDED_ECA_OSC_H class ECA_CONTROL_MT; #ifdef ECA_USE_LIBLO #include /** * Ecasound Open Source Control Control (OSC) interface * * The interface is documented in Ecasound codebase: * - ecasound/Documentation/ecasound_osc_interface.txt * - http://ecasound.git.sourceforge.net/git/gitweb.cgi?p=ecasound;a=blob;f=Documentation/ecasound_osc_interface.txt;hb=HEAD */ class ECA_OSC_INTERFACE { friend int cb_lo_method_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data); public: ECA_OSC_INTERFACE(ECA_CONTROL_MT *ecacontrol, int port = -1); ~ECA_OSC_INTERFACE(void); void start(void); void stop(void); bool is_running(void) const; private: int parse_path_param(const std::string &path, int *param); int handle_chain_message(const string &path, const char *types, lo_arg **argv, int argc); int handle_osc_message(const char *path, const char *types, lo_arg **argv, int argc); ECA_CONTROL_MT* ec_repp; bool running_rep; int udp_port_rep; lo_server_thread lo_thr_repp; lo_method method_all_repp; }; #else /* !ECA_USE_LIBLO */ class ECA_OSC_INTERFACE; #endif /* ECA_USE_LIBLO */ #endif /* INCLUDED_ECA_OSC_H */ ecasound-2.9.1/libecasound/audioio-ogg.cpp0000644000076400007640000001722211137153033015455 00000000000000// ------------------------------------------------------------------------ // audioio-ogg.cpp: Interface for ogg vorbis decoders and encoders. // Copyright (C) 2000-2002,2004-2006,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include /* atol() */ #include /* stat() */ #include /* stat() */ #include #include #include "audioio-ogg.h" #include "eca-logger.h" string OGG_VORBIS_INTERFACE::default_input_cmd = "ogg123 -d raw -o byteorder:%E --file=- %f"; string OGG_VORBIS_INTERFACE::default_output_cmd = "oggenc -b %B --raw --raw-bits=%b --raw-chan=%c --raw-rate=%s --raw-endianness 0 --output=%f -"; long int OGG_VORBIS_INTERFACE::default_output_default_bitrate = 128000; void OGG_VORBIS_INTERFACE::set_input_cmd(const std::string& value) { OGG_VORBIS_INTERFACE::default_input_cmd = value; } void OGG_VORBIS_INTERFACE::set_output_cmd(const std::string& value) { OGG_VORBIS_INTERFACE::default_output_cmd = value; } OGG_VORBIS_INTERFACE::OGG_VORBIS_INTERFACE(const std::string& name) : triggered_rep(false), finished_rep(false) { set_label(name); bitrate_rep = OGG_VORBIS_INTERFACE::default_output_default_bitrate; } OGG_VORBIS_INTERFACE::~OGG_VORBIS_INTERFACE(void) { clean_child(true); if (is_open() == true) { close(); } } void OGG_VORBIS_INTERFACE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { std::string urlprefix; triggered_rep = false; finished_rep = false; if (io_mode() == io_read) { struct stat buf; int ret = ::stat(label().c_str(), &buf); if (ret != 0) { size_t offset = label().find_first_of("://"); if (offset == std::string::npos) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-OGG: Can't open file " + label() + ".")); } else { urlprefix = std::string(label(), 0, offset); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found url; protocol '" + urlprefix + "'."); } } /* decoder supports: nothing configurable nor fixed * * FIXME: we have no idea about the audio format of the * stream we get from the decoder... ybe we should force the decoder * to generate RIFF wave to a named pipe and parse the header...? */ } else { /* encoder supports: coding, channel-count and srate configurable, * fixed to little endian */ ECA_AUDIO_FORMAT::set_sample_endianess(ECA_AUDIO_FORMAT::se_little); } AUDIO_IO::open(); } void OGG_VORBIS_INTERFACE::close(void) { if (pid_of_child() > 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + "."); clean_child(); triggered_rep = false; } AUDIO_IO::close(); } long int OGG_VORBIS_INTERFACE::read_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_input_process(); } if (f1_rep != 0) { bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, f1_rep); } else { bytes_rep = 0; } if (bytes_rep < samples * frame_size() || bytes_rep == 0) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::info, "Can't start process \"" + fork_command() + "\". Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; } else finished_rep = false; return bytes_rep / frame_size(); } void OGG_VORBIS_INTERFACE::write_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_output_process(); } if (wait_for_child() != true) { finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Attempt to write after child process has terminated."); } else { if (filedes_rep > 0) { bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples); } else { bytes_rep = 0; } if (bytes_rep < frame_size() * samples) { finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Error in writing to child process (to write " + kvu_numtostr(frame_size() * samples) + ", result " + kvu_numtostr(bytes_rep) + ")."); } else finished_rep = false; } } void OGG_VORBIS_INTERFACE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: long int numvalue = atol(value.c_str()); if (numvalue > 0) bitrate_rep = numvalue; else bitrate_rep = OGG_VORBIS_INTERFACE::default_output_default_bitrate; break; } } string OGG_VORBIS_INTERFACE::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return kvu_numtostr(bitrate_rep); } return ""; } void OGG_VORBIS_INTERFACE::fork_input_process(void) { string command = OGG_VORBIS_INTERFACE::default_input_cmd; // replace with 'little/big' byteorder if (command.find("%E") != string::npos) { string byteorder ("big"); if (sample_endianess() == ECA_AUDIO_FORMAT::se_little) byteorder = "little"; command.replace(command.find("%E"), 2, byteorder); } set_fork_command(command); set_fork_file_name(label()); set_fork_pipe_name(); fork_child_for_read(); if (child_fork_succeeded() == true) { /* NOTE: the file description will be closed by * AUDIO_IO_FORKED_STREAM::clean_child() */ filedes_rep = file_descriptor(); f1_rep = fdopen(filedes_rep, "r"); /* not part of */ if (f1_rep == 0) { finished_rep = true; triggered_rep = false; } } else f1_rep = 0; } void OGG_VORBIS_INTERFACE::fork_output_process(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Starting to encode " + label() + " with vorbize."); string command = OGG_VORBIS_INTERFACE::default_output_cmd; // replace with bitrate if (command.find("%B") != string::npos) { command.replace(command.find("%B"), 2, kvu_numtostr((long int)(bitrate_rep / 1000))); } set_fork_command(command); set_fork_file_name(label()); set_fork_bits(bits()); set_fork_channels(channels()); set_fork_sample_rate(samples_per_second()); fork_child_for_write(); if (child_fork_succeeded() == true) { filedes_rep = file_descriptor(); } else { filedes_rep = 0; } } void OGG_VORBIS_INTERFACE::start_io(void) { if (triggered_rep != true) { if (io_mode() == io_read) fork_input_process(); else fork_output_process(); triggered_rep = true; } } void OGG_VORBIS_INTERFACE::stop_io(void) { if (triggered_rep == true) { if (io_mode() == io_read) { fclose(f1_rep); f1_rep = 0; clean_child(true); } else clean_child(false); triggered_rep = false; } } ecasound-2.9.1/libecasound/midi-server.cpp0000644000076400007640000003267610664032032015511 00000000000000// ------------------------------------------------------------------------ // midi-server.cpp: MIDI i/o engine serving generic clients. // Copyright (C) 2001-2002,2005,2007 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include "midi-parser.h" #include "midi-server.h" #include "eca-logger.h" const unsigned int MIDI_SERVER::max_queue_size_rep = 32768; /** * Helper function for starting the slave thread. */ void* start_midi_server_io_thread(void *ptr) { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigprocmask(SIG_BLOCK, &sigset, 0); MIDI_SERVER* mserver = static_cast(ptr); if (mserver->schedrealtime_rep == true) { if (kvu_set_thread_scheduling(SCHED_FIFO, mserver->schedpriority_rep) != 0) ECA_LOG_MSG(ECA_LOGGER::system_objects, "Unable to change scheduling policy!"); else ECA_LOG_MSG(ECA_LOGGER::info, std::string("Using realtime-scheduling (SCHED_FIFO:") + kvu_numtostr(mserver->schedpriority_rep) + ")."); } /* launch the worker thread */ mserver->io_thread(); return 0; } /** * Slave thread. */ void MIDI_SERVER::io_thread(void) { fd_set fds; unsigned char buf[16]; struct timeval tv; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Hey, in the I/O loop!"); while(true) { if (running_rep.get() == 0 || clients_rep[0]->is_open() != true) { usleep(50000); if (exit_request_rep.get() == 1) break; continue; } DBC_CHECK(clients_rep.size() > 0); DBC_CHECK(clients_rep[0]->supports_nonblocking_mode() == true); // FIXME: add support for multiple clients; gather poll // descriptors from all clients and create the 'fds' set int fd = clients_rep[0]->poll_descriptor(); FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = 1; tv.tv_usec = 0; int retval = select(fd + 1 , &fds, NULL, NULL, &tv); // FIXME: add multiple client support, go through // all the fds int read_bytes = 0; if (retval) { if (FD_ISSET(fd, &fds) == true) { read_bytes = clients_rep[0]->read_bytes(buf, 16); //std::cerr << "TRACE: Read from MIDI-device (bytes): " << read_bytes << "." << std::endl; } } if (read_bytes < 0) { std::cerr << "ERROR: Can't read from MIDI-device: " << clients_rep[0]->label() << "." << std::endl; break; } else { // cerr << "(midi-server) read bytes: " << read_bytes << endl; for(int n = 0; n < read_bytes; n++) { buffer_rep.push_back(buf[n]); while(buffer_rep.size() > max_queue_size_rep) { std::cerr << "(eca-midi) dropping midi bytes" << std::endl; buffer_rep.pop_front(); } for(unsigned int m = 0; m < handlers_rep.size(); m++) { MIDI_HANDLER* p = handlers_rep[m]; if (p != 0) p->insert(buf[n]); } } parse_receive_queue(); } if (stop_request_rep.get() == 1) { stop_request_rep.set(0); running_rep.set(0); } } ECA_LOG_MSG(ECA_LOGGER::system_objects, "exiting MIDI-server thread"); } /** * Constructor. */ MIDI_SERVER::MIDI_SERVER (void) { running_status_rep = 0; current_ctrl_channel_rep = -1; current_ctrl_number = -1; thread_running_rep = false; running_rep.set(0); stop_request_rep.set(0); exit_request_rep.set(0); } /** * Destructor. Doesn't delete any client objects. */ MIDI_SERVER::~MIDI_SERVER(void) { if (is_enabled() == true) disable(); } /** * Starts the MIDI server. * * ensure * is_running() == true */ void MIDI_SERVER::start(void) { stop_request_rep.set(0); running_rep.set(1); ECA_LOG_MSG(ECA_LOGGER::user_objects, "starting processing"); send_mmc_start(); if (is_midi_sync_send_enabled() == true) send_midi_start(); // -------- DBC_ENSURE(is_running() == true); // -------- } /** * Stops the MIDI-server. Note that this routine only * initializes the stop procedure. Processing will * stop once the i/o-thread acknowledges the stop request. */ void MIDI_SERVER::stop(void) { stop_request_rep.set(1); ECA_LOG_MSG(ECA_LOGGER::user_objects, "stopping processing"); send_mmc_stop(); if (is_midi_sync_send_enabled() == true) send_midi_stop(); } /** * Initializes the MIDI-server by resetting * all MIDI-related state info. */ void MIDI_SERVER::init(void) { running_status_rep = 0; current_ctrl_channel_rep = -1; current_ctrl_number = -1; } /** * Enables the MIDI-server subsystems and prepared them for * processing. * * Use the set_schedrealtime() and set_schedpriority() functions * to set the MIDI subsystem scheduling priority. These settings * are set at enable(). * * ensure: * is_enabled() == true */ void MIDI_SERVER::enable(void) { init(); running_rep.set(0); stop_request_rep.set(0); exit_request_rep.set(0); if (thread_running_rep != true) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "enabling"); int ret = pthread_create(&io_thread_rep, 0, start_midi_server_io_thread, static_cast(this)); if (ret != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "pthread_create failed, exiting"); exit(1); } thread_running_rep = true; } // -------- DBC_ENSURE(is_enabled() == true); // -------- } /** * Whether MIDI-server is enabled? */ bool MIDI_SERVER::is_enabled(void) const { return thread_running_rep; } /** * Disables the MIDI-server subsystems. * * require: * is_enabled() == true * * ensure: * is_running() != true * is_enabled() != true */ void MIDI_SERVER::disable(void) { // -------- DBC_REQUIRE(is_enabled() == true); // -------- ECA_LOG_MSG(ECA_LOGGER::user_objects, "disabling"); stop_request_rep.set(1); exit_request_rep.set(1); if (thread_running_rep == true) { ::pthread_join(io_thread_rep, 0); } thread_running_rep = false; // -------- DBC_ENSURE(is_running() != true); DBC_ENSURE(is_enabled() != true); // -------- } /** * Whether the MIDI server has been started? */ bool MIDI_SERVER::is_running(void) const { if (running_rep.get() == 0) return false; return true; } /** * Registers a new client object. Midi server doesn't * handle initializing and opening of client objects. */ void MIDI_SERVER::register_client(MIDI_IO* mobject) { clients_rep.push_back(mobject); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Registering client " + kvu_numtostr(clients_rep.size() - 1) + "."); } /** * Unregisters the client object given as the argument. No * resources are freed during this call. */ void MIDI_SERVER::unregister_client(MIDI_IO* mobject) { for(unsigned int n = 0; n < clients_rep.size(); n++) { if (clients_rep[n] == mobject) { clients_rep[n] = 0; break; } } } /** * Registers a new MIDI-handler. The server will send * all received MIDI-data to the handler. */ void MIDI_SERVER::register_handler(MIDI_HANDLER* object) { handlers_rep.push_back(object); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Registering handler " + kvu_numtostr(handlers_rep.size() - 1) + "."); } /** * Unregisters the handler object given as the argument. No * resources are freed during this call. */ void MIDI_SERVER::unregister_handler(MIDI_HANDLER* object) { for(unsigned int n = 0; n < handlers_rep.size(); n++) { if (handlers_rep[n] == object) { handlers_rep[n] = 0; break; } } } /** * Adds a new client to which MMC-messages are sent * during processing. * * Note! Id '127' is specified as the all-device * id-number in the MMC-spec. */ void MIDI_SERVER::add_mmc_send_id(int id) { mmc_send_ids_rep.push_back(id); } /** * Removes a MMC-message client. */ void MIDI_SERVER::remove_mmc_send_id(int id) { mmc_send_ids_rep.remove(id); } /** * Sends MMC-start to all MMC-send client device ids. * * require: * is_enabled() == true */ void MIDI_SERVER::send_midi_bytes(int dev_id, unsigned char* buf, int bytes) { // -------- DBC_REQUIRE(is_enabled() == true); // -------- if (clients_rep[dev_id - 1]->is_open() == true) { DBC_CHECK(static_cast(clients_rep.size()) >= dev_id); DBC_CHECK(clients_rep[dev_id - 1]->supports_nonblocking_mode() == true); int err = clients_rep[dev_id - 1]->write_bytes(buf, bytes); DBC_CHECK(err == bytes); } } /** * Sends an MMC-command to all MMC-send client device ids. */ void MIDI_SERVER::send_mmc_command(unsigned int cmd) { unsigned char buf[6]; buf[0] = 0xf0; buf[1] = 0x7f; buf[2] = 0x00; /* dev-id */ buf[3] = 0x06; buf[4] = cmd; buf[5] = 0xf7; std::list::const_iterator p = mmc_send_ids_rep.begin(); while(p != mmc_send_ids_rep.end()) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Sending MMC message " + kvu_numtostr(cmd) + " to device-id " + kvu_numtostr(*p) + "."); buf[2] = static_cast(*p); send_midi_bytes(1, buf, 6); ++p; } } /** * Sends MMC-start to all MMC-send client device ids. */ void MIDI_SERVER::send_mmc_start(void) { /* FIXME: should this be 0x03 (deferred play)? */ // send_mmc_command(0x02); send_mmc_command(0x03); } /** * Sends MMC-stop to all MMC-send client device ids. */ void MIDI_SERVER::send_mmc_stop(void) { send_mmc_command(0x01); } /** * Sends a MIDI-start message. */ void MIDI_SERVER::send_midi_start(void) { unsigned char byte[1] = { 0xfa }; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Sending MIDI-start message."); send_midi_bytes(1, byte, 1); } /** * Sends a MIDI-continue message. */ void MIDI_SERVER::send_midi_continue(void) { unsigned char byte[1] = { 0xfb }; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Sending MIDI-continue message."); send_midi_bytes(1, byte, 1); } /** * Sends a MIDI-stop message. */ void MIDI_SERVER::send_midi_stop(void) { unsigned char byte[1] = { 0xfc }; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Sending MIDI-stop message."); send_midi_bytes(1, byte, 1); } /** * Requests that server will follow the latest value of * controller 'ctrl' on channel 'channel'. */ void MIDI_SERVER::add_controller_trace(int channel, int ctrl, int initial_value) { controller_values_rep[std::pair(channel,ctrl)] = initial_value; } /** * Requests that server stops following the latest value of * controller 'ctrl' on channel 'channel'. */ void MIDI_SERVER::remove_controller_trace(int channel, int controller) { std::map,int>::iterator p = controller_values_rep.find(std::pair(channel,controller)); if (p != controller_values_rep.end()) { controller_values_rep.erase(p); } } /** * Returns the latest traced value of controller 'ctrl' on * channel 'channel'. * * @return -1 is returned on error */ int MIDI_SERVER::last_controller_value(int channel, int ctrl) const { std::map,int>::iterator p = controller_values_rep.find(std::pair(channel,ctrl)); if (p != controller_values_rep.end()) { return controller_values_rep[std::pair(channel,ctrl)]; } return -1; } /** * Parses the received MIDI date. */ void MIDI_SERVER::parse_receive_queue(void) { while(buffer_rep.size() > 0) { unsigned char byte = buffer_rep.front(); buffer_rep.pop_front(); if (MIDI_PARSER::is_status_byte(byte) == true) { if (MIDI_PARSER::is_voice_category_status_byte(byte) == true) { running_status_rep = byte; if ((running_status_rep & 0xb0) == 0xb0) current_ctrl_channel_rep = static_cast((byte & 15)); } else if (MIDI_PARSER::is_system_common_category_status_byte(byte) == true) { current_ctrl_channel_rep = -1; running_status_rep = 0; } } else { /* non-status bytes */ /** * Any data bytes are ignored if no running status */ if (running_status_rep != 0) { /** * Check for 'controller messages' (status 0xb0 to 0xbf and * two data bytes) */ if (current_ctrl_channel_rep != -1) { if (current_ctrl_number == -1) { current_ctrl_number = static_cast(byte); // cerr << endl << "C:" << current_ctrl_number << "."; } else { if (controller_values_rep.find(std::pair(current_ctrl_channel_rep,current_ctrl_number)) != controller_values_rep.end()) { controller_values_rep[std::pair(current_ctrl_channel_rep,current_ctrl_number)] = static_cast(byte); // std::cerr << std::endl << "(midi-server) Value:" // << controller_values_rep[std::pair(current_ctrl_channel_rep,current_ctrl_number)] // << ", ch:" << current_ctrl_channel_rep << ", ctrl:" << current_ctrl_number << "."; } // else { // cerr << endl << "E:" << " found an entry we are not following..." << endl; // } current_ctrl_number = -1; } } } } } } ecasound-2.9.1/libecasound/osc-sine.h0000644000076400007640000000137311034533077014445 00000000000000#ifndef INCLUDED_SINE_OSCILLATOR_H #define INCLUDED_SINE_OSCILLATOR_H #include #include "oscillator.h" /** * Sine oscillator */ class SINE_OSCILLATOR : public OSCILLATOR { public: virtual void init(void); virtual parameter_t value(double pos); std::string parameter_names(void) const { return("freq,phase-offset"); } void set_parameter(int param, parameter_t value); parameter_t get_parameter(int param) const; std::string name(void) const { return("Sine oscillator"); } SINE_OSCILLATOR* clone(void) const { return new SINE_OSCILLATOR(*this); } SINE_OSCILLATOR* new_expr(void) const { return new SINE_OSCILLATOR(); } SINE_OSCILLATOR (double freq = 0, double initial_phase = 0); private: double period_len_rep; }; #endif ecasound-2.9.1/libecasound/eca-logger-wellformed.cpp0000644000076400007640000000550610664032032017416 00000000000000// ------------------------------------------------------------------------ // eca-logger-wellformed.cpp: Logging implementation that outputs // messages in a well-formed format. // Copyright (C) 2002-2004 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "eca-logger-wellformed.h" using namespace std; ECA_LOGGER_WELLFORMED::ECA_LOGGER_WELLFORMED(void) { } ECA_LOGGER_WELLFORMED::~ECA_LOGGER_WELLFORMED(void) { } /** * Prints the given log message in well-formed * format. * * See section "Ecasound Interactive Mode - * Well-Formed Output Mode" in the Ecasound * Programmer's Guide for more detailed documentation. */ void ECA_LOGGER_WELLFORMED::do_msg(ECA_LOGGER::Msg_level_t level, const string& module_name, const string& log_message) { if (is_log_level_set(level) == true) { cout << ECA_LOGGER_WELLFORMED::create_wellformed_message(level, log_message); } } void ECA_LOGGER_WELLFORMED::do_flush(void) { } void ECA_LOGGER_WELLFORMED::do_log_level_changed(void) { } string ECA_LOGGER_WELLFORMED::create_wellformed_message(ECA_LOGGER::Msg_level_t level, const string& message) { string result, rettype; string::const_iterator p = message.begin(); size_t msglen = message.size(); /* 1. loglevel */ result += kvu_numtostr(static_cast(level)); /* 2. space */ result += " "; if (level == ECA_LOGGER::eiam_return_values) { while(p != message.end()) { msglen--; if (isspace(*p) != 0) { rettype = string(message.begin(), p); p++; /* skip space to reach start of actual msg */ break; } ++p; } } /* 3. message size */ result += kvu_numtostr(msglen); if (level == ECA_LOGGER::eiam_return_values) { /* 4. space */ result += " "; /* 5. return type */ result += rettype; } /* 6. contentblock */ result += "\r\n"; result += string(p,message.end()); result += "\r\n\r\n"; return result; } ecasound-2.9.1/libecasound/eca-chainsetup-bufparams.cpp0000644000076400007640000001024410664032032020115 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup-bufparams.cpp: Container for chainsetup buffering params. // Copyright (C) 2001, 2007 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include /* kvu_get_argument_number */ #include #include "eca-chainsetup-bufparams.h" ECA_CHAINSETUP_BUFPARAMS::ECA_CHAINSETUP_BUFPARAMS(void) { set_buffersize_rep = false; set_raisedpriority_rep = false; set_sched_priority_rep = false; set_double_buffering_rep = false; set_double_buffer_size_rep = false; set_max_buffers_rep = false; } /** * Sets all buffering parameters based on 'paramstr'. * * @arg paramstr "int_buffersize, bool_raisedprio, int_schedprio, * bool_db, int_db-bufsize, int_buffersize" */ void ECA_CHAINSETUP_BUFPARAMS::set_all(const string& paramstr) { set_buffersize(atoi(kvu_get_argument_number(1, paramstr).c_str())); toggle_raised_priority(kvu_get_argument_number(2, paramstr) == "true"); set_sched_priority(atoi(kvu_get_argument_number(3, paramstr).c_str())); toggle_double_buffering(kvu_get_argument_number(4, paramstr) == "true"); set_double_buffer_size(atol(kvu_get_argument_number(5, paramstr).c_str())); toggle_max_buffers(kvu_get_argument_number(6, paramstr) == "true"); } /** * Returns number of distinct set parameters. */ int ECA_CHAINSETUP_BUFPARAMS::number_of_set(void) const { int res = 0; if (set_buffersize_rep == true) res++; if (set_raisedpriority_rep == true) res++; if (set_sched_priority_rep == true) res++; if (set_double_buffering_rep == true) res++; if (set_double_buffer_size_rep == true) res++; if (set_max_buffers_rep == true) res++; return res; } string ECA_CHAINSETUP_BUFPARAMS::to_string(void) const { string result; result += "\nbuffersize: "; result += kvu_numtostr(buffersize_rep); result += "\nraised_priority: "; result += kvu_numtostr((int)raisedpriority_rep); result += "\nsched_priority: "; result += kvu_numtostr((int)sched_priority_rep); result += "\ndouble buffering: "; result += kvu_numtostr((int)double_buffering_rep); result += "\ndouble buffer size: "; result += kvu_numtostr((int)double_buffer_size_rep); result += "\nmax buffers: "; result += kvu_numtostr(max_buffers_rep); return result; } bool ECA_CHAINSETUP_BUFPARAMS::are_all_set(void) const { if (set_buffersize_rep == true && set_raisedpriority_rep == true && set_sched_priority_rep == true && set_double_buffering_rep == true && set_double_buffer_size_rep == true && set_max_buffers_rep == true) return true; return false; } void ECA_CHAINSETUP_BUFPARAMS::set_buffersize(long int value) { buffersize_rep = value; set_buffersize_rep = true; } void ECA_CHAINSETUP_BUFPARAMS::toggle_raised_priority(bool value) { raisedpriority_rep = value; set_raisedpriority_rep = true; } void ECA_CHAINSETUP_BUFPARAMS::set_sched_priority(int prio) { sched_priority_rep = prio; set_sched_priority_rep = true; } void ECA_CHAINSETUP_BUFPARAMS::toggle_double_buffering(bool value) { double_buffering_rep = value; set_double_buffering_rep = true; } void ECA_CHAINSETUP_BUFPARAMS::set_double_buffer_size(long int v) { double_buffer_size_rep = v; set_double_buffer_size_rep = true; } void ECA_CHAINSETUP_BUFPARAMS::toggle_max_buffers(bool v) { max_buffers_rep = v; set_max_buffers_rep = true; } ecasound-2.9.1/libecasound/audioio-db-client.h0000644000076400007640000000501711141363244016210 00000000000000#ifndef INCLUDED_AUDIOIO_DB_CLIENT_H #define INCLUDED_AUDIOIO_DB_CLIENT_H #include #include #include "audioio-proxy.h" #include "audioio-db-server.h" class SAMPLE_BUFFER; /** * Client class for double-buffering providing * additional layer of buffering for objects * derived from AUDIO_IO. * * The buffering subsystem has been optimized for * reliable streaming performance. Because of this some * operations like random seeks are considerably slower * than with direct access. * * Related design patterns: * - Proxy (GoF207) * * @author Kai Vehmanen */ class AUDIO_IO_DB_CLIENT : public AUDIO_IO_PROXY { public: /** @name Public functions */ /*@{*/ AUDIO_IO_DB_CLIENT (AUDIO_IO_DB_SERVER *pserver, AUDIO_IO* aobject, bool transfer_ownership); virtual ~AUDIO_IO_DB_CLIENT(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return(string("DB => ") + child()->name()); } virtual std::string description(void) const { return(child()->description()); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ /* none */ /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ AUDIO_IO_DB_CLIENT* clone(void) const { std::cerr << __FILE__ << ": Not implemented!" << std::endl; return 0; } AUDIO_IO_DB_CLIENT* new_expr(void) const { std::cerr << __FILE__ << ": Not implemented!" << std::endl; return 0; } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ /** @name Reimplemented functions from AUDIO_IO_BARRIER */ /*@{*/ virtual void start_io(void); virtual void stop_io(void); /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual bool finished(void) const; /*@}*/ private: AUDIO_IO_DB_SERVER* pserver_repp; AUDIO_IO_DB_BUFFER* pbuffer_repp; AUDIO_IO_DB_CLIENT& operator=(const AUDIO_IO_DB_CLIENT& x) { return *this; } AUDIO_IO_DB_CLIENT (const AUDIO_IO_DB_CLIENT& x) { } int xruns_rep; bool finished_rep; bool free_child_rep; bool recursing_rep; void fetch_initial_child_data(void); bool pause_db_server_if_running(void); void restore_db_server_state(bool was_running); }; #endif ecasound-2.9.1/libecasound/audioio-acseq.cpp0000644000076400007640000001444711433027220016000 00000000000000// ------------------------------------------------------------------------ // audioio-audioseq.cpp: Audio clip sequencer class. // Copyright (C) 2008,2010 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include #include #include #include #include "eca-object-factory.h" #include "samplebuffer.h" #include "audioio-acseq.h" #include "eca-error.h" #include "eca-logger.h" using std::cout; using std::endl; using SAMPLE_SPECS::sample_pos_t; /** * FIXME notes (last update 2008-03-04) * * - None. */ AUDIO_CLIP_SEQUENCER::AUDIO_CLIP_SEQUENCER () { set_label("audiocseq"); /* note: index of last sequencer parameter (one if no * extra parameters); params beyond this value are * passed on to the child object */ child_param_offset_rep = 1; cseq_mode_rep = AUDIO_CLIP_SEQUENCER::cseq_none; } AUDIO_CLIP_SEQUENCER::~AUDIO_CLIP_SEQUENCER(void) { } AUDIO_CLIP_SEQUENCER* AUDIO_CLIP_SEQUENCER::clone(void) const { AUDIO_CLIP_SEQUENCER* target = new AUDIO_CLIP_SEQUENCER(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIO_CLIP_SEQUENCER::open(void) throw(AUDIO_IO::SETUP_ERROR &) { if (io_mode() != AUDIO_IO::io_read) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ACLIPSEQ: Only read mode supported.")); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Opening audio clip sequencer in mode: " + get_parameter(1)); /* note: change behaviour based on first param */ if (cseq_mode_rep == AUDIO_CLIP_SEQUENCER::cseq_loop) { /* following is specific to looping */ AUDIO_SEQUENCER_BASE::toggle_looping(true); DBC_CHECK(finite_length_stream() != true); AUDIO_SEQUENCER_BASE::set_child_object_string( child_params_as_string(1 + child_param_offset_rep, ¶ms_rep)); } else if (cseq_mode_rep == AUDIO_CLIP_SEQUENCER::cseq_select) { AUDIO_SEQUENCER_BASE::toggle_looping(false); AUDIO_SEQUENCER_BASE::set_child_start_position(get_parameter(2)); AUDIO_SEQUENCER_BASE::set_child_length(get_parameter(3)); AUDIO_SEQUENCER_BASE::set_child_object_string( child_params_as_string(1 + child_param_offset_rep, ¶ms_rep)); } else if (cseq_mode_rep == AUDIO_CLIP_SEQUENCER::cseq_play_at) { /* following is specific to play-at */ AUDIO_SEQUENCER_BASE::toggle_looping(false); AUDIO_SEQUENCER_BASE::set_child_offset(get_parameter(2)); AUDIO_SEQUENCER_BASE::set_child_object_string( child_params_as_string(1 + child_param_offset_rep, ¶ms_rep)); } else throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ACLIPSEQ: Unknown audio sequencing mode (loop, select, ...).")); AUDIO_SEQUENCER_BASE::open(); /* step: set additional child params (if any) */ int numparams = child()->number_of_params(); for(int n = 0; n < numparams; n++) { child()->set_parameter(n + 1, get_parameter(n + 1 + child_param_offset_rep)); if (child()->variable_params()) numparams = child()->number_of_params(); } } void AUDIO_CLIP_SEQUENCER::close(void) { AUDIO_SEQUENCER_BASE::close(); } std::string AUDIO_CLIP_SEQUENCER::parameter_names(void) const { std::string baseparams; if (cseq_mode_rep == AUDIO_CLIP_SEQUENCER::cseq_loop) baseparams += std::string("audioloop"); else if (cseq_mode_rep == AUDIO_CLIP_SEQUENCER::cseq_select) baseparams += std::string("select,start-sec,dur-sec"); else if (cseq_mode_rep == AUDIO_CLIP_SEQUENCER::cseq_play_at) baseparams += std::string("playat,pos-sec"); else baseparams += std::string("acseqtype"); if (is_child_initialized() == true) { baseparams += "," + child()->parameter_names(); } else { /* create a generic parameter name list */ for (size_t i = 1; i < params_rep.size(); i++) { baseparams += ",param" + kvu_numtostr(i); } } ECA_LOG_MSG(ECA_LOGGER::system_objects, "param list: " + baseparams); return baseparams; } void AUDIO_CLIP_SEQUENCER::set_parameter(int param, string value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, AUDIO_IO::parameter_set_to_string(param, value)); if (param > static_cast(params_rep.size())) params_rep.resize(param); if (param > 0) params_rep[param - 1] = value; if (param == 1) { set_label(value); if (value == "audioloop") { cseq_mode_rep = AUDIO_CLIP_SEQUENCER::cseq_loop; child_param_offset_rep = 1; } else if (value == "select") { cseq_mode_rep = AUDIO_CLIP_SEQUENCER::cseq_select; child_param_offset_rep = 3; } else if (value == "playat") { cseq_mode_rep = AUDIO_CLIP_SEQUENCER::cseq_play_at; child_param_offset_rep = 2; } else { cseq_mode_rep = AUDIO_CLIP_SEQUENCER::cseq_none; child_param_offset_rep = 1; } } if (param > child_param_offset_rep && is_child_initialized() == true) { child()->set_parameter(param - child_param_offset_rep, value); } AUDIO_IO::set_parameter(param, value); } string AUDIO_CLIP_SEQUENCER::get_parameter(int param) const { ECA_LOG_MSG(ECA_LOGGER::system_objects, AUDIO_IO::parameter_get_to_string(param)); if (param > 0 && param < static_cast(params_rep.size()) + 1) { if (param > child_param_offset_rep && is_child_initialized() == true) { params_rep[param - 1] = child()->get_parameter(param - child_param_offset_rep); } return params_rep[param - 1]; } return ""; } ecasound-2.9.1/libecasound/generic-linear-envelope.h0000644000076400007640000000237711544706671017441 00000000000000#ifndef INCLUDED_GENERIC_LINEAR_ENVELOPE_H #define INCLUDED_GENERIC_LINEAR_ENVELOPE_H #include #include #include "ctrl-source.h" #include "eca-audio-position.h" /** * Generic multi-stage linear envelope */ class GENERIC_LINEAR_ENVELOPE : public CONTROLLER_SOURCE { public: GENERIC_LINEAR_ENVELOPE(void); virtual ~GENERIC_LINEAR_ENVELOPE(void); GENERIC_LINEAR_ENVELOPE* clone(void) const { return new GENERIC_LINEAR_ENVELOPE(*this); } GENERIC_LINEAR_ENVELOPE* new_expr(void) const { return new GENERIC_LINEAR_ENVELOPE(); } virtual void init(void); virtual parameter_t value(double pos); virtual void set_initial_value(parameter_t arg) {} virtual bool variable_params(void) const { return true; } virtual std::string parameter_names(void) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual std::string name(void) const { return("Generic linear envelope"); } private: std::vector pos_rep; std::vector val_rep; parameter_t curval; int curstage; std::string param_names_rep; bool is_valid_for_stage(double pos, int stage) const; void set_stage(double pos); void set_param_count(int params); }; #endif ecasound-2.9.1/libecasound/preset.h0000644000076400007640000000431510664032032014217 00000000000000#ifndef INCLUDED_PRESET_H #define INCLUDED_PRESET_H #include #include class PRESET_impl; class CHAIN; class SAMPLE_BUFFER; #include "eca-chainop.h" #include "eca-samplerate-aware.h" /** * Class for representing effect presets * * @author Arto Hamara * @author Kai Vehmanen */ class PRESET : public CHAIN_OPERATOR, public ECA_SAMPLERATE_AWARE { public: /** @name Public virtual functions to notify about changes * (Reimplemented from ECA_SAMPLERATE_AWARE) */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ /** @name Constructors and destructors */ /*@{*/ PRESET(void); PRESET(const std::string& formatted_string); /*@}*/ /** @name Public API functions */ /*@{*/ virtual PRESET* clone(void) const; virtual PRESET* new_expr(void) const; virtual ~PRESET (void); virtual std::string name(void) const; virtual std::string description(void) const; void set_name(const std::string& v); virtual void init(SAMPLE_BUFFER* sbuf); virtual void release(void); virtual void process(void); virtual std::string parameter_names(void) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; void parse(const std::string& formatted_string); bool is_parsed(void) const; /*@}*/ private: PRESET_impl* impl_repp; SAMPLE_BUFFER* first_buffer; std::vector buffers; std::vector chains; bool is_preset_option(const std::string& arg) const; void add_chain(void); void extend_pardesc_vector(int number); void parse_preset_option(const std::string& arg); void parse_operator_option(const std::string& arg); void set_preset_defaults(const std::vector& args); void set_preset_param_names(const std::vector& args); void set_preset_lower_bounds(const std::vector& args); void set_preset_upper_bounds(const std::vector& args); void set_preset_toggles(const std::vector& args); PRESET& operator=(const PRESET& x) { return *this; } PRESET(const PRESET& x) { } }; #endif ecasound-2.9.1/libecasound/eca-version.h0000644000076400007640000000150710664032032015130 00000000000000#ifndef INCLUDED_ECA_VERSION_H #define INCLUDED_ECA_VERSION_H /** * Ecasound library version as a formatted std::string. * * "vX.Y[.Z[.R]][-extraT]" : * * X = major version - the overall development status * * Y = minor version - represents a set of planned features (see TODO) * * Z = micro version - small changes to major.minor version * * R = revision - urgent fixes to normal releases (optional) * * extraT - beta, pre and rc releases that are in * preparation of major releases */ extern const char* ecasound_library_version; /** * Ecasound library libtool version number (current:revision:age) */ extern const long int ecasound_library_version_current; extern const long int ecasound_library_version_revision; extern const long int ecasound_library_version_age; #endif ecasound-2.9.1/libecasound/eca-chainsetup.cpp0000644000076400007640000021703712260762753016166 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup.cpp: Class representing an ecasound chainsetup object. // Copyright (C) 1999-2006,2008,2009,2011-2013 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include /* find() */ #include #include #include #include #include /* POSIX: getpid() */ #include /* POSIX: getpid() */ #ifdef HAVE_SYS_MMAN_H #include /* POSIX: for mlockall() */ #endif #ifdef ECA_COMPILE_JACK #include #endif #include #include #include #include #include #include "eca-resources.h" #include "eca-session.h" #include "generic-controller.h" #include "eca-chainop.h" #include "eca-chain.h" #include "audioio.h" #include "audioio-manager.h" #include "audioio-device.h" #include "audioio-buffered.h" #include "audioio-loop.h" #include "audioio-null.h" #include "audioio-resample.h" #include "eca-engine-driver.h" #include "eca-object-factory.h" #include "eca-object-map.h" #include "midiio.h" #include "midi-client.h" #include "eca-object-factory.h" #include "eca-chainsetup-position.h" #include "sample-specs.h" #include "eca-error.h" #include "eca-logger.h" #include "eca-chainsetup.h" #include "eca-chainsetup_impl.h" using std::cerr; using std::endl; using namespace ECA; const string ECA_CHAINSETUP::default_audio_format_const = "s16_le,2,44100,i"; const string ECA_CHAINSETUP::default_bmode_nonrt_const = "1024,false,50,false,100000,true"; const string ECA_CHAINSETUP::default_bmode_rt_const = "1024,true,50,true,100000,true"; const string ECA_CHAINSETUP::default_bmode_rtlowlatency_const = "256,true,50,true,100000,false"; static void priv_erase_object(std::vector* vec, const AUDIO_IO* obj); /** * Construct from a vector of options. * * If any invalid options are passed us argument, * interpret_result() will be 'false', and * interpret_result_verbose() contains more detailed * error description. */ ECA_CHAINSETUP::ECA_CHAINSETUP(const vector& opts) : cparser_rep(this), is_enabled_rep(false) { impl_repp = new ECA_CHAINSETUP_impl; // FIXME: set default audio format here! setup_name_rep = "untitled-chainsetup"; setup_filename_rep = ""; set_defaults(); vector options (opts); cparser_rep.preprocess_options(options); interpret_options(options); if (interpret_result() == true) { /* do not add default if there were parsing errors as * it might hide real problems */ add_default_output(); add_default_midi_device(); } ECA_LOG_MSG(ECA_LOGGER::info, "Chainsetup \"" + setup_name_rep + "\""); } /** * Constructs an empty chainsetup. * * @post buffersize != 0 */ ECA_CHAINSETUP::ECA_CHAINSETUP(void) : cparser_rep(this), is_enabled_rep(false) { impl_repp = new ECA_CHAINSETUP_impl; setup_name_rep = ""; set_defaults(); ECA_LOG_MSG(ECA_LOGGER::info, "Chainsetup created (empty)"); } /** * Construct from a chainsetup file. * * If any invalid options are passed us argument, * interpret_result() will be 'false', and * interpret_result_verbose() contains more detailed * error description. * * @post buffersize != 0 */ ECA_CHAINSETUP::ECA_CHAINSETUP(const string& setup_file) : cparser_rep(this), is_enabled_rep(false) { impl_repp = new ECA_CHAINSETUP_impl; setup_name_rep = ""; set_defaults(); vector options; load_from_file(setup_file, options); set_filename(setup_file); if (name() == "") set_name(setup_file); cparser_rep.preprocess_options(options); interpret_options(options); if (interpret_result() == true) { /* do not add default if there were parsing errors as * it might hide real problems */ add_default_output(); } ECA_LOG_MSG(ECA_LOGGER::info, "Chainsetup \"" + name() + "\" created (file: " + setup_file + ")"); } /** * Destructor */ ECA_CHAINSETUP::~ECA_CHAINSETUP(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects,"ECA_CHAINSETUP destructor-in"); DBC_CHECK(is_locked() != true); if (is_enabled() == true) { disable(); } DBC_CHECK(is_enabled() != true); /* delete chain objects */ for(vector::iterator q = chains.begin(); q != chains.end(); q++) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting chain \"" + (*q)->name() + "\"."); delete *q; *q = 0; } /* delete input db objects; reset all pointers to null */ for(vector::iterator q = inputs.begin(); q != inputs.end(); q++) { if (dynamic_cast(*q) != 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting audio db-client \"" + (*q)->label() + "\"."); delete *q; } *q = 0; } /* delete all actual audio input objects except loop devices; reset all pointers to null */ for(vector::iterator q = inputs_direct_rep.begin(); q != inputs_direct_rep.end(); q++) { if (dynamic_cast(*q) == 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting audio object \"" + (*q)->label() + "\"."); delete *q; } *q = 0; } /* delete output db objects; reset all pointers to null */ for(vector::iterator q = outputs.begin(); q != outputs.end(); q++) { if (dynamic_cast(*q) != 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting audio db-client \"" + (*q)->label() + "\"."); delete *q; } *q = 0; } /* delete all actual audio output objects except loop devices; reset all pointers to null */ for(vector::iterator q = outputs_direct_rep.begin(); q != outputs_direct_rep.end(); q++) { // trouble with dynamic_cast with libecasoundc apps like ecalength? if (dynamic_cast(*q) == 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting audio object \"" + (*q)->label() + "\"."); delete *q; *q = 0; } } /* delete loop objects */ for(map::iterator q = loop_map.begin(); q != loop_map.end(); q++) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting loop device \"" + q->second->label() + "\"."); delete q->second; q->second = 0; } /* delete aio manager objects */ for(vector::iterator q = aio_managers_rep.begin(); q != aio_managers_rep.end(); q++) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Deleting audio manager \"" + (*q)->name() + "\"."); delete *q; *q = 0; } delete impl_repp; ECA_LOG_MSG(ECA_LOGGER::system_objects,"ECA_CHAINSETUP destructor-out"); } /** * Sets default values. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::set_defaults(void) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- /* note: defaults are set as specified in ecasoundrc(5) */ precise_sample_rates_rep = false; ignore_xruns_rep = true; pserver_repp = &impl_repp->pserver_rep; midi_server_repp = &impl_repp->midi_server_rep; engine_driver_repp = 0; if (kvu_check_for_sched_fifo() == true) { rtcaps_rep = true; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Rtcaps detected."); } else rtcaps_rep = false; db_clients_rep = 0; multitrack_mode_rep = false; multitrack_mode_override_rep = false; memory_locked_rep = false; midi_server_needed_rep = false; is_locked_rep = false; selected_chain_index_rep = 0; selected_ctrl_index_rep = 0; selected_ctrl_param_index_rep = 0; multitrack_mode_offset_rep = -1; buffering_mode_rep = cs_bmode_auto; active_buffering_mode_rep = cs_bmode_none; set_output_openmode(AUDIO_IO::io_readwrite); ECA_RESOURCES ecaresources; if (ecaresources.has_any() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Unable to read global resources. May result in incorrect behaviour."); } set_default_midi_device(ecaresources.resource("midi-device")); string rc_temp = set_resource_helper(ecaresources, "default-audio-format", ECA_CHAINSETUP::default_audio_format_const); cparser_rep.interpret_object_option("-f:" + rc_temp); set_samples_per_second(default_audio_format().samples_per_second()); toggle_precise_sample_rates(ecaresources.boolean_resource("default-to-precise-sample-rates")); rc_temp = set_resource_helper(ecaresources, "default-mix-mode", "avg"); cparser_rep.interpret_object_option("-z:mixmode," + rc_temp); impl_repp->bmode_nonrt_rep.set_all(set_resource_helper(ecaresources, "bmode-defaults-nonrt", ECA_CHAINSETUP::default_bmode_nonrt_const)); impl_repp->bmode_rt_rep.set_all(set_resource_helper(ecaresources, "bmode-defaults-rt", ECA_CHAINSETUP::default_bmode_rt_const)); impl_repp->bmode_rtlowlatency_rep.set_all(set_resource_helper(ecaresources, "bmode-defaults-rtlowlatency", ECA_CHAINSETUP::default_bmode_rtlowlatency_const)); impl_repp->bmode_active_rep = impl_repp->bmode_nonrt_rep; } /** * Sets a resource value. * * Only used by ECA_CHAINSETUP::set_defaults. */ string ECA_CHAINSETUP::set_resource_helper(const ECA_RESOURCES& ecaresources, const string& tag, const string& alternative) { if (ecaresources.has(tag) == true) { return ecaresources.resource(tag); } else { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Using hardcoded defaults for \"" + tag + "\"."); return alternative; } } /** * Tests whether chainsetup is in a valid state. */ bool ECA_CHAINSETUP::is_valid(void) const { return is_valid_for_connection(false); } /** * Checks whether chainsetup is valid for enabling/connecting. * If chainsetup is not valid and 'verbose' is true, detected * errors are reported via the logging subsystem. */ bool ECA_CHAINSETUP::is_valid_for_connection(bool verbose) const { bool result = true; if (inputs.size() == 0) { if (verbose) ECA_LOG_MSG(ECA_LOGGER::info, "Unable to connect: No inputs in the current chainsetup. (1.1-NO-INPUTS)"); result = false; } else if (outputs.size() == 0) { if (verbose) ECA_LOG_MSG(ECA_LOGGER::info, "Unable to connect: No outputs in the current chainsetup. (1.2-NO-OUTPUTS)"); result = false; } else if (chains.size() == 0) { if (verbose) ECA_LOG_MSG(ECA_LOGGER::info, "Unable to connect: No chains in the current chainsetup. (1.3-NO-CHAINS)"); result = false; } else { list conn_inputs, conn_outputs; for(vector::const_iterator q = chains.begin(); q != chains.end(); q++) { /* log messages printed in CHAIN::is_valid() */ int id = (*q)->connected_input(); if (id > -1) conn_inputs.push_back(id); if ((*q)->is_valid() == false) { result = false; if (verbose) ECA_LOG_MSG(ECA_LOGGER::info, "Unable to connect: Chain \"" + (*q)->name() + "\" is not valid. Following errors were detected:"); if (verbose && id == -1) { ECA_LOG_MSG(ECA_LOGGER::info, "Chain \"" + (*q)->name() + "\" is not connected to any input. " "All chains must have exactly one valid input. (2.1-NO-CHAIN-INPUT)"); } } id = (*q)->connected_output(); if (id > -1) conn_outputs.push_back(id); if (verbose && (*q)->is_valid() == false) { if (id == -1) { ECA_LOG_MSG(ECA_LOGGER::info, "Chain \"" + (*q)->name() + "\" is not connected to any output. " "All chains must have exactly one valid output. (2.2-NO-CHAIN-OUTPUT)"); } } } // FIXME: doesn't work yet if (verbose) { for(int n = 0; n < static_cast(inputs.size()); n++) { if (std::find(conn_inputs.begin(), conn_inputs.end(), n) == conn_inputs.end()) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Input \"" + inputs[n]->label() + "\" is not connected to any chain. (3.1-DISCON-INPUT)"); } } for(int n = 0; n < static_cast(outputs.size()); n++) { if (std::find(conn_outputs.begin(), conn_outputs.end(), n) == conn_outputs.end()) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Output \"" + outputs[n]->label() + "\" is not connected to any chain. (3.2-DISCON-OUTPUT)"); } } } } /* (verbose == true) */ return result; } void ECA_CHAINSETUP::set_buffering_mode(Buffering_mode_t value) { if (value == ECA_CHAINSETUP::cs_bmode_none) buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_auto; else buffering_mode_rep = value; } /** * Sets audio i/o manager option for manager * object type 'mgrname' to be 'optionstr'. * Previously set option string is overwritten. */ void ECA_CHAINSETUP::set_audio_io_manager_option(const string& mgrname, const string& optionstr) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Set manager \"" + mgrname + "\" option string to \"" + optionstr + "\"."); aio_manager_option_map_rep[mgrname] = optionstr; propagate_audio_io_manager_options(); } /** * Determinates the active buffering parameters based on * defaults, user overrides and analyzing the current * chainsetup configuration. If the resulting parameters * are different from current ones, a state change is * performed. */ void ECA_CHAINSETUP::select_active_buffering_mode(void) { if (buffering_mode() == ECA_CHAINSETUP::cs_bmode_none) { active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_auto; } if (!(multitrack_mode_override_rep == true && multitrack_mode_rep != true) && ((multitrack_mode_override_rep == true && multitrack_mode_rep == true) || (number_of_realtime_inputs() > 0 && number_of_realtime_outputs() > 0 && number_of_non_realtime_inputs() > 0 && number_of_non_realtime_outputs() > 0 && chains.size() > 1))) { ECA_LOG_MSG(ECA_LOGGER::info, "Multitrack-mode enabled."); multitrack_mode_rep = true; } else multitrack_mode_rep = false; if (buffering_mode() == ECA_CHAINSETUP::cs_bmode_auto) { /* initialize to 'nonrt', mt-disabled */ active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_nonrt; if (has_realtime_objects() == true) { /* case 1: a multitrack setup */ if (multitrack_mode_rep == true) { active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_rt; ECA_LOG_MSG(ECA_LOGGER::system_objects, "bmode-selection case-1"); } /* case 2: rt-objects without priviledges for rt-scheduling */ else if (rtcaps_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "NOTE: Real-time configuration, but insufficient privileges to utilize real-time scheduling (SCHED_FIFO). With small buffersizes, this may cause audible glitches during processing."); toggle_raised_priority(false); active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_rt; ECA_LOG_MSG(ECA_LOGGER::system_objects, "bmode-selection case-2"); } /* case 3: no chain operators and "one-way rt-operation" */ else if (number_of_chain_operators() == 0 && (number_of_realtime_inputs() == 0 || number_of_realtime_outputs() == 0)) { active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_rt; ECA_LOG_MSG(ECA_LOGGER::system_objects, "bmode-selection case-3"); } /* case 4: default for rt-setups */ else { active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_rtlowlatency; ECA_LOG_MSG(ECA_LOGGER::system_objects, "bmode-selection case-4"); } } else { /* case 5: no rt-objects */ active_buffering_mode_rep = ECA_CHAINSETUP::cs_bmode_nonrt; ECA_LOG_MSG(ECA_LOGGER::system_objects, "bmode-selection case-5"); } } else { /* user has explicitly selected the buffering mode */ active_buffering_mode_rep = buffering_mode(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "bmode-selection explicit"); } switch(active_buffering_mode_rep) { case ECA_CHAINSETUP::cs_bmode_nonrt: { impl_repp->bmode_active_rep = impl_repp->bmode_nonrt_rep; ECA_LOG_MSG(ECA_LOGGER::info, "\"nonrt\" buffering mode selected."); break; } case ECA_CHAINSETUP::cs_bmode_rt: { impl_repp->bmode_active_rep = impl_repp->bmode_rt_rep; ECA_LOG_MSG(ECA_LOGGER::info, "\"rt\" buffering mode selected."); break; } case ECA_CHAINSETUP::cs_bmode_rtlowlatency: { impl_repp->bmode_active_rep = impl_repp->bmode_rtlowlatency_rep; ECA_LOG_MSG(ECA_LOGGER::info, "\"rtlowlatency\" buffering mode selected."); break; } default: { /* error! */ } } ECA_LOG_MSG(ECA_LOGGER::system_objects, "Set buffering parameters to: \n--cut--" + impl_repp->bmode_active_rep.to_string() +"\n--cut--"); } /** * Enable chosen active buffering mode. * * Called only from enable(). */ void ECA_CHAINSETUP::enable_active_buffering_mode(void) { /* 1. if requested, lock all memory */ if (raised_priority() == true) { lock_all_memory(); } else { unlock_all_memory(); } /* 2. if necessary, switch between different db and direct modes */ if (double_buffering() == true) { if (has_realtime_objects() != true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "No realtime objects; switching to direct mode."); switch_to_direct_mode(); impl_repp->bmode_active_rep.toggle_double_buffering(false); } else if (has_nonrealtime_objects() != true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Only realtime objects; switching to direct mode."); switch_to_direct_mode(); impl_repp->bmode_active_rep.toggle_double_buffering(false); } else if (db_clients_rep == 0) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Switching to db mode."); switch_to_db_mode(); } if (buffersize() != 0) { impl_repp->pserver_rep.set_buffer_defaults(double_buffer_size() / buffersize(), buffersize()); } else { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Buffersize set to 0."); impl_repp->pserver_rep.set_buffer_defaults(0, 0); } } else { /* double_buffering() != true */ if (db_clients_rep > 0) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Switching to direct mode."); switch_to_direct_mode(); } } /* 3. propagate buffersize value to all dependent objects */ /* FIXME: create a system for tracking buffesize aware objs */ } void ECA_CHAINSETUP::switch_to_direct_mode(void) { switch_to_direct_mode_helper(&inputs, inputs_direct_rep); switch_to_direct_mode_helper(&outputs, outputs_direct_rep); // -- DBC_ENSURE(db_clients_rep == 0); // -- } void ECA_CHAINSETUP::switch_to_direct_mode_helper(vector* objs, const vector& directobjs) { // -- DBC_CHECK(objs->size() == directobjs.size()); // -- for(size_t n = 0; n < objs->size(); n++) { AUDIO_IO_DB_CLIENT* pobj = dynamic_cast((*objs)[n]); if (pobj != 0) { delete (*objs)[n]; (*objs)[n] = directobjs[n]; --db_clients_rep; } } } void ECA_CHAINSETUP::switch_to_db_mode(void) { switch_to_db_mode_helper(&inputs, inputs_direct_rep); switch_to_db_mode_helper(&outputs, outputs_direct_rep); } void ECA_CHAINSETUP::switch_to_db_mode_helper(vector* objs, const vector& directobjs) { // -- DBC_REQUIRE(db_clients_rep == 0); DBC_CHECK(objs->size() == directobjs.size()); // -- for(size_t n = 0; n < directobjs.size(); n++) { (*objs)[n] = add_audio_object_helper(directobjs[n]); } } /** * Locks all memory with mlockall(). */ void ECA_CHAINSETUP::lock_all_memory(void) { #ifdef HAVE_MLOCKALL if (::mlockall (MCL_CURRENT|MCL_FUTURE)) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Couldn't lock all memory!"); } else { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Memory locked!"); memory_locked_rep = true; } #else ECA_LOG_MSG(ECA_LOGGER::info, "Memory locking not available."); #endif } /** * Unlocks all memory with munlockall(). */ void ECA_CHAINSETUP::unlock_all_memory(void) { #ifdef HAVE_MUNLOCKALL if (memory_locked_rep == true) { if (::munlockall()) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "WARNING: Couldn't unlock all memory!"); } else ECA_LOG_MSG(ECA_LOGGER::system_objects, "Memory unlocked!"); memory_locked_rep = false; } #else memory_locked_rep = false; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Memory unlocking not available."); #endif } /** * Adds a "default" chain to this chainsetup. * * @pre buffersize >= 0 && chains.size() == 0 * @pre is_locked() != true * * @post chains.back()->name() == "default" && * @post active_chainids.back() == "default" */ void ECA_CHAINSETUP::add_default_chain(void) { // -------- DBC_REQUIRE(buffersize() >= 0); DBC_REQUIRE(chains.size() == 0); DBC_REQUIRE(is_locked() != true); // -------- add_chain_helper("default"); selected_chainids.push_back("default"); // -------- DBC_ENSURE(chains.back()->name() == "default"); DBC_ENSURE(selected_chainids.back() == "default"); // -------- } /** * Adds new chains to this chainsetup. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::add_new_chains(const vector& newchains) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- for(vector::const_iterator p = newchains.begin(); p != newchains.end(); p++) { bool exists = false; for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*p == (*q)->name()) exists = true; } if (exists == false) { add_chain_helper(*p); } } } void ECA_CHAINSETUP::add_chain_helper(const string& name) { chains.push_back(new CHAIN()); chains.back()->name(name); chains.back()->set_samples_per_second(samples_per_second()); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Chain \"" + name + "\" created."); } /** * Removes all selected chains from this chainsetup. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::remove_chains(void) { // -------- DBC_REQUIRE(is_enabled() != true); DBC_DECLARE(size_t old_chains_size = chains.size()); DBC_DECLARE(size_t sel_chains_size = selected_chainids.size()); // -------- for(vector::const_iterator a = selected_chainids.begin(); a != selected_chainids.end(); a++) { vector::iterator q = chains.begin(); while(q != chains.end()) { if (*a == (*q)->name()) { delete *q; chains.erase(q); break; } ++q; } } selected_chainids.resize(0); // -- DBC_ENSURE(chains.size() == old_chains_size - sel_chains_size); // -- } /** * Clears all selected chains. Removes all chain operators * and controllers. * * @pre is_locked() != true */ void ECA_CHAINSETUP::clear_chains(void) { // -------- DBC_REQUIRE(is_locked() != true); // -------- for(vector::const_iterator a = selected_chainids.begin(); a != selected_chainids.end(); a++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*a == (*q)->name()) { (*q)->clear(); } } } } /** * Renames the first selected chain. */ void ECA_CHAINSETUP::rename_chain(const string& name) { for(vector::const_iterator a = selected_chainids.begin(); a != selected_chainids.end(); a++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*a == (*q)->name()) { (*q)->name(name); return; } } } } /** * Selects all chains present in this chainsetup. */ void ECA_CHAINSETUP::select_all_chains(void) { vector::const_iterator p = chains.begin(); selected_chainids.resize(0); while(p != chains.end()) { selected_chainids.push_back((*p)->name()); ++p; } } /** * Returns the index number of first selected chains. If no chains * are selected, returns 'last_index + 1' (==chains.size()). */ unsigned int ECA_CHAINSETUP::first_selected_chain(void) const { const vector& schains = selected_chains(); vector::const_iterator o = schains.begin(); unsigned int p = chains.size(); while(o != schains.end()) { for(p = 0; p != chains.size(); p++) { if (chains[p]->name() == *o) return p; } ++o; } return p; } /** * Toggles chain muting of all selected chains. * * @pre is_locked() != true */ void ECA_CHAINSETUP::toggle_chain_muting(void) { // --- DBC_REQUIRE(is_locked() != true); // --- for(vector::const_iterator a = selected_chainids.begin(); a != selected_chainids.end(); a++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*a == (*q)->name()) { (*q)->set_mute(-1); } } } } /** * Toggles chain bypass of all selected chains. * * @pre is_locked() != true */ void ECA_CHAINSETUP::toggle_chain_bypass(void) { // --- DBC_REQUIRE(is_locked() != true); // --- for(vector::const_iterator a = selected_chainids.begin(); a != selected_chainids.end(); a++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*a == (*q)->name()) { (*q)->set_bypass(-1); } } } } const ECA_CHAINSETUP_BUFPARAMS& ECA_CHAINSETUP::active_buffering_parameters(void) const { return impl_repp->bmode_active_rep; } const ECA_CHAINSETUP_BUFPARAMS& ECA_CHAINSETUP::override_buffering_parameters(void) const { return impl_repp->bmode_override_rep; } vector ECA_CHAINSETUP::chain_names(void) const { vector result; vector::const_iterator p = chains.begin(); while(p != chains.end()) { result.push_back((*p)->name()); ++p; } return result; } vector ECA_CHAINSETUP::audio_input_names(void) const { vector result; vector::const_iterator p = inputs.begin(); while(p != inputs.end()) { result.push_back((*p)->label()); ++p; } return result; } vector ECA_CHAINSETUP::audio_output_names(void) const { vector result; vector::const_iterator p = outputs.begin(); while(p != outputs.end()) { result.push_back((*p)->label()); ++p; } return result; } vector ECA_CHAINSETUP::get_attached_chains_to_input(AUDIO_IO* aiod) const { vector res; vector::const_iterator q = chains.begin(); while(q != chains.end()) { if (aiod == inputs[(*q)->connected_input()]) { res.push_back((*q)->name()); } ++q; } return res; } vector ECA_CHAINSETUP::get_attached_chains_to_output(AUDIO_IO* aiod) const { vector res; vector::const_iterator q = chains.begin(); while(q != chains.end()) { if (aiod == outputs[(*q)->connected_output()]) { res.push_back((*q)->name()); } ++q; } return(res); } int ECA_CHAINSETUP::number_of_attached_chains_to_input(AUDIO_IO* aiod) const { int count = 0; vector::const_iterator q = chains.begin(); while(q != chains.end()) { if (aiod == inputs[(*q)->connected_input()]) { ++count; } ++q; } return count; } int ECA_CHAINSETUP::number_of_attached_chains_to_output(AUDIO_IO* aiod) const { int count = 0; vector::const_iterator q = chains.begin(); while(q != chains.end()) { if (aiod == outputs[(*q)->connected_output()]) { ++count; } ++q; } return count; } /** * Output object is realtime target if it is not * connected to any chains with non-realtime inputs. * In other words all data coming to a rt target * output comes from realtime devices. */ bool ECA_CHAINSETUP::is_realtime_target_output(int output_id) const { bool result = true; bool output_found = false; vector::const_iterator q = chains.begin(); while(q != chains.end()) { if ((*q)->connected_output() == output_id) { output_found = true; AUDIO_IO_DEVICE* p = dynamic_cast(inputs[(*q)->connected_input()]); if (p == 0) { result = false; } } ++q; } if (output_found == true && result == true) ECA_LOG_MSG(ECA_LOGGER::system_objects,"slave output detected: " + outputs[output_id]->label()); else result = false; return result; } vector ECA_CHAINSETUP::get_attached_chains_to_iodev(const string& filename) const { vector::size_type p; p = 0; while (p < inputs.size()) { if (inputs[p]->label() == filename) return get_attached_chains_to_input(inputs[p]); ++p; } p = 0; while (p < outputs.size()) { if (outputs[p]->label() == filename) return get_attached_chains_to_output(outputs[p]); ++p; } return vector (0); } /** * Returns number of realtime audio input objects. */ int ECA_CHAINSETUP::number_of_chain_operators(void) const { int cops = 0; vector::const_iterator q = chains.begin(); while(q != chains.end()) { cops += (*q)->number_of_chain_operators(); ++q; } return cops; } /** * Returns true if the connected chainsetup contains at least * one realtime audio input or output. */ bool ECA_CHAINSETUP::has_realtime_objects(void) const { if (number_of_realtime_inputs() > 0 || number_of_realtime_outputs() > 0) return true; return false; } /** * Returns true if the connected chainsetup contains at least * one nonrealtime audio input or output. */ bool ECA_CHAINSETUP::has_nonrealtime_objects(void) const { if (static_cast(inputs_direct_rep.size() + outputs_direct_rep.size()) > number_of_realtime_inputs() + number_of_realtime_outputs()) return true; return false; } /** * Returns a string containing currently active chainsetup * options and settings. Syntax is the same as used for * saved chainsetup files. */ string ECA_CHAINSETUP::options_to_string(void) const { return cparser_rep.general_options_to_string(); } /** * Returns number of realtime audio input objects. */ int ECA_CHAINSETUP::number_of_realtime_inputs(void) const { int res = 0; for(size_t n = 0; n < inputs_direct_rep.size(); n++) { AUDIO_IO_DEVICE* p = dynamic_cast(inputs_direct_rep[n]); if (p != 0) res++; } return res; } /** * Returns number of realtime audio output objects. */ int ECA_CHAINSETUP::number_of_realtime_outputs(void) const { int res = 0; for(size_t n = 0; n < outputs_direct_rep.size(); n++) { AUDIO_IO_DEVICE* p = dynamic_cast(outputs_direct_rep[n]); if (p != 0) res++; } return res; } /** * Returns number of non-realtime audio input objects. */ int ECA_CHAINSETUP::number_of_non_realtime_inputs(void) const { return inputs.size() - number_of_realtime_inputs(); } /** * Returns number of non-realtime audio input objects. */ int ECA_CHAINSETUP::number_of_non_realtime_outputs(void) const { return outputs.size() - number_of_realtime_outputs(); } /** * Returns a pointer to the manager handling audio object 'aobj'. * * @return 0 if 'aobj' is not handled by any manager */ AUDIO_IO_MANAGER* ECA_CHAINSETUP::get_audio_object_manager(AUDIO_IO* aio) const { for(vector::const_iterator q = aio_managers_rep.begin(); q != aio_managers_rep.end(); q++) { if ((*q)->is_managed_type(aio) && (*q)->get_object_id(aio) != -1) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Found object manager \"" + (*q)->name() + "\" for aio \"" + aio->label() + "\"."); return *q; } } return 0; } /** * Returns a pointer to the manager handling audio * objects of type 'aobj'. * * @return 0 if 'aobj' type is not handled by any manager */ AUDIO_IO_MANAGER* ECA_CHAINSETUP::get_audio_object_type_manager(AUDIO_IO* aio) const { for(vector::const_iterator q = aio_managers_rep.begin(); q != aio_managers_rep.end(); q++) { if ((*q)->is_managed_type(aio) == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Found object manager \"" + (*q)->name() + "\" for aio type \"" + aio->name() + "\"."); return *q; } } return 0; } /** * If 'amgr' implements the ECA_ENGINE_DRIVER interface, * it is registered as the active driver. */ void ECA_CHAINSETUP::register_engine_driver(AUDIO_IO_MANAGER* amgr) { ECA_ENGINE_DRIVER* driver = dynamic_cast(amgr); if (driver != 0) { engine_driver_repp = driver; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Registered audio i/o manager \"" + amgr->name() + "\" as the current engine driver."); } } /** * Registers audio object to a manager. If no managers are * available for object's type, and it can create one, * a new manager is created. */ void ECA_CHAINSETUP::register_audio_object_to_manager(AUDIO_IO* aio) { AUDIO_IO_MANAGER* mgr = get_audio_object_type_manager(aio); if (mgr == 0) { mgr = aio->create_object_manager(); if (mgr != 0) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Creating object manager \"" + mgr->name() + "\" for aio \"" + aio->name() + "\"."); aio_managers_rep.push_back(mgr); propagate_audio_io_manager_options(); mgr->register_object(aio); /* in case manager is also a driver */ register_engine_driver(mgr); } } else { mgr->register_object(aio); } } /** * Unregisters audio object from manager. */ void ECA_CHAINSETUP::unregister_audio_object_from_manager(AUDIO_IO* aio) { AUDIO_IO_MANAGER* mgr = get_audio_object_manager(aio); if (mgr != 0) { int id = mgr->get_object_id(aio); if (id != -1) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Unregistering object \"" + aio->name() + "\" from manager \"" + mgr->name() + "\"."); mgr->unregister_object(id); } } } /** * Propagates to set manager options to all existing * audio i/o manager objects. */ void ECA_CHAINSETUP::propagate_audio_io_manager_options(void) { for(vector::const_iterator q = aio_managers_rep.begin(); q != aio_managers_rep.end(); q++) { if (aio_manager_option_map_rep.find((*q)->name()) != aio_manager_option_map_rep.end()) { const string& optstring = aio_manager_option_map_rep[(*q)->name()]; int numparams = (*q)->number_of_params(); for(int n = 0; n < numparams; n++) { (*q)->set_parameter(n + 1, kvu_get_argument_number(n + 1, optstring)); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Manager \"" + (*q)->name() + "\", " + kvu_numtostr(n + 1) + ". parameter set to \"" + (*q)->get_parameter(n + 1) + "\"."); } } } } /** * Helper function used by add_input() and add_output(). * * All audio object creates go through this function, * so this is good place to do global operations that * apply to both inputs and outputs. */ AUDIO_IO* ECA_CHAINSETUP::add_audio_object_helper(AUDIO_IO* aio) { AUDIO_IO* retobj = aio; AUDIO_IO_DEVICE* p = dynamic_cast(aio); LOOP_DEVICE* q = dynamic_cast(aio); if (p == 0 && q == 0) { /* not a realtime or loop device */ retobj = new AUDIO_IO_DB_CLIENT(&impl_repp->pserver_rep, aio, false); ++db_clients_rep; } return retobj; } /** * Helper function used by remove_audio_object(). */ void ECA_CHAINSETUP::remove_audio_object_proxy(AUDIO_IO* aio) { AUDIO_IO_DB_CLIENT* p = dynamic_cast(aio); if (p != 0) { /* a proxied object */ ECA_LOG_MSG(ECA_LOGGER::user_objects, "Delete proxy object " + aio->label() + "."); delete aio; --db_clients_rep; } } /** * Helper function used bu remove_audio_object() to remove input * and output loop devices. */ void ECA_CHAINSETUP::remove_audio_object_loop(const AUDIO_IO* aobj, AUDIO_IO* loop_aio, int dir) { int rdir = (dir == cs_dir_input ? cs_dir_output : cs_dir_input); /* loop devices are registered simultaneously to both input * and output object vectors, so they have to be removed * from both, but deleted only once */ remove_audio_object_impl(aobj, rdir, false); /* we also need to remove the loop device from * the loop_map table */ map::iterator iter = loop_map.begin(); while(iter != loop_map.end()) { if (iter->second == loop_aio) { loop_map.erase(iter); break; } ++iter; } } /** * Adds a new input object and attaches it to selected chains. * * If double-buffering is enabled (double_buffering() == true), * and the object in question is not a realtime object, it * is wrapped in a AUDIO_IO_DB_CLIENT object before * inserted to the chainsetup. Otherwise object is added * as is. * * Ownership of the insert object is transfered to * ECA_CHAINSETUP. * * @pre aiod != 0 * @pre is_enabled() != true * @post inputs.size() == old(inputs.size() + 1 */ void ECA_CHAINSETUP::add_input(AUDIO_IO* aio) { // -------- DBC_REQUIRE(aio != 0); DBC_REQUIRE(is_enabled() != true); DBC_DECLARE(size_t old_inputs_size = inputs.size()); // -------- aio->set_io_mode(AUDIO_IO::io_read); aio->set_audio_format(default_audio_format()); aio->set_buffersize(buffersize()); register_audio_object_to_manager(aio); AUDIO_IO* layerobj = add_audio_object_helper(aio); inputs.push_back(layerobj); inputs_direct_rep.push_back(aio); input_start_pos.push_back(0); attach_input_to_selected_chains(layerobj); // -------- DBC_ENSURE(inputs.size() == old_inputs_size + 1); DBC_ENSURE(inputs.size() == inputs_direct_rep.size()); // -------- } /** * Add a new output object and attach it to selected chains. * * If double-buffering is enabled (double_buffering() == true), * and the object in question is not a realtime object, it * is wrapped in a AUDIO_IO_DB_CLIENT object before * inserted to the chainsetup. Otherwise object is added * as is. * * Ownership of the insert object is transfered to * ECA_CHAINSETUP. * * @pre aiod != 0 * @pre is_enabled() != true * @post outputs.size() == outputs_direct_rep.size() */ void ECA_CHAINSETUP::add_output(AUDIO_IO* aio, bool truncate) { // -------- DBC_REQUIRE(aio != 0); DBC_REQUIRE(is_enabled() != true); DBC_DECLARE(size_t old_outputs_size = outputs.size()); // -------- aio->set_audio_format(default_audio_format()); aio->set_buffersize(buffersize()); if (truncate == true) aio->set_io_mode(AUDIO_IO::io_write); else aio->set_io_mode(AUDIO_IO::io_readwrite); register_audio_object_to_manager(aio); AUDIO_IO* layerobj = add_audio_object_helper(aio); outputs.push_back(layerobj); outputs_direct_rep.push_back(aio); output_start_pos.push_back(0); attach_output_to_selected_chains(layerobj); // --- DBC_ENSURE(outputs.size() == old_outputs_size + 1); DBC_ENSURE(outputs.size() == outputs_direct_rep.size()); // --- } /** * Erases an element matching 'obj' from 'vec'. At most one element * is removed. The function does not delete the referred object, just * removes it from the vector. */ static void priv_erase_object(std::vector* vec, const AUDIO_IO* obj) { vector::iterator p = vec->begin(); while(p != vec->end()) { if (*p == obj) { vec->erase(p); break; } ++p; } } /** * Removes the labeled audio object from this chainsetup. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::remove_audio_object_impl(const AUDIO_IO* aobj, int dir, bool destroy) { // --- DBC_REQUIRE(is_enabled() != true); // --- vector *objs = (dir == cs_dir_input ? &inputs : &outputs); vector *objs_dir = (dir == cs_dir_input ? &inputs_direct_rep : &outputs_direct_rep); DBC_DECLARE(size_t oldsize = objs->size()); AUDIO_IO *obj_to_remove = 0, *obj_dir_to_remove = NULL; int remove_index = -1; /* Notes * - objs and objs_dir vectors are always of the same size * - for non-proxied objects 'objs[n] == objs_dir[n]' for all n */ for(size_t n = 0; n < objs->size(); n++) { if ((*objs)[n] == aobj) { obj_to_remove = (*objs)[n]; obj_dir_to_remove = (*objs_dir)[n]; remove_index = static_cast(n); } } if (obj_to_remove) { DBC_CHECK(remove_index >= 0); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Removing object " + obj_to_remove->label() + "."); /* disconnect object from chains and update * references to modified input/output tables */ vector::iterator q = chains.begin(); while(q != chains.end()) { if (dir == cs_dir_input) { (*q)->input_removed(remove_index); } else { (*q)->output_removed(remove_index); } ++q; } /* unregister from manager (always the objs_dir object) */ unregister_audio_object_from_manager((*objs_dir)[remove_index]); /* delete proxy object if any */ if (obj_to_remove != obj_dir_to_remove) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Audio object proxied: " + obj_to_remove->label()); remove_audio_object_proxy(obj_to_remove); } priv_erase_object(objs, obj_to_remove); priv_erase_object(objs_dir, obj_dir_to_remove); LOOP_DEVICE* loop_dev = dynamic_cast(obj_dir_to_remove); if (loop_dev != 0 && destroy == true) { /* note: destroy must be true to limit recursion */ remove_audio_object_loop(aobj, obj_dir_to_remove, dir); } /* finally actually delete the object */ if (destroy == true) delete obj_dir_to_remove; } // --- DBC_ENSURE(objs->size() == objs_dir->size()); DBC_ENSURE(oldsize == objs->size() + 1); // --- } /** * Removes the labeled audio input from this chainsetup. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::remove_audio_input(const AUDIO_IO* aobj) { // --- DBC_REQUIRE(is_enabled() != true); DBC_DECLARE(size_t oldsize = inputs.size()); // --- remove_audio_object_impl(aobj, cs_dir_input, true); // --- DBC_ENSURE(inputs.size() == inputs_direct_rep.size()); DBC_ENSURE(oldsize == inputs.size() + 1); // --- } /** * Removes the labeled audio output from this chainsetup. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::remove_audio_output(const AUDIO_IO* aobj) { // -------- DBC_REQUIRE(is_enabled() != true); DBC_DECLARE(size_t oldsize = outputs.size()); // -------- remove_audio_object_impl(aobj, cs_dir_output, true); // --- DBC_ENSURE(outputs.size() == outputs_direct_rep.size()); DBC_ENSURE(oldsize == outputs.size() + 1); // --- } /** * Print trace messages when opening audio file 'aio'. * * @pre aio != 0 */ void ECA_CHAINSETUP::audio_object_open_info(const AUDIO_IO* aio) { // -------- DBC_REQUIRE(aio != 0); // -------- string temp = "Opened "; temp += (aio->io_mode() == AUDIO_IO::io_read) ? "input" : "output"; temp += " \"" + aio->label(); temp += "\", mode \""; if (aio->io_mode() == AUDIO_IO::io_read) temp += "read"; if (aio->io_mode() == AUDIO_IO::io_write) temp += "write"; if (aio->io_mode() == AUDIO_IO::io_readwrite) temp += "read/write (update)"; temp += "\". "; temp += aio->format_info(); ECA_LOG_MSG(ECA_LOGGER::info, temp); } /** * Adds a new MIDI-device object. * * @pre mididev != 0 * @pre is_enabled() != true * @post midi_devices.size() > 0 */ void ECA_CHAINSETUP::add_midi_device(MIDI_IO* mididev) { // -------- DBC_REQUIRE(mididev != 0); DBC_REQUIRE(is_enabled() != true); // -------- midi_devices.push_back(mididev); impl_repp->midi_server_rep.register_client(mididev); // -------- DBC_ENSURE(midi_devices.size() > 0); // -------- } /** * Remove an MIDI-device by the name 'mdev_name'. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::remove_midi_device(const string& mdev_name) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- for(vector::iterator q = midi_devices.begin(); q != midi_devices.end(); q++) { if (mdev_name == (*q)->label()) { delete *q; midi_devices.erase(q); break; } } } const CHAIN* ECA_CHAINSETUP::get_chain_with_name(const string& name) const { vector::const_iterator p = chains.begin(); while(p != chains.end()) { if ((*p)->name() == name) return(*p); ++p; } return 0; } /** * Returns a non-zero index for chain 'name'. If the chain * does not exist, -1 is returned. * * The chain index can be used with ECA::chainsetup_edit_t * items passed to ECA_CHAINSETUP::execute_edit(). * * Note: Mapping of chain names to indices can change if any * chains are either added or removed. If that happens, * the indices need to be recalculated. */ int ECA_CHAINSETUP::get_chain_index(const string& name) const { int retval = -1; vector::const_iterator p = chains.begin(); for(int n = 1; p != chains.end(); n++) { if ((*p)->name() == name) { retval = n; break; } ++p; } return retval; } /** * Attaches input 'obj' to all selected chains. * * @pre is_locked() != true */ void ECA_CHAINSETUP::attach_input_to_selected_chains(const AUDIO_IO* obj) { // -------- DBC_REQUIRE(obj != 0); DBC_REQUIRE(is_locked() != true); // -------- string temp; vector::size_type c = 0; while (c < inputs.size()) { if (inputs[c] == obj) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if ((*q)->connected_input() == static_cast(c)) { (*q)->disconnect_input(); } } temp += "Assigning file to chains:"; for(vector::const_iterator p = selected_chainids.begin(); p!= selected_chainids.end(); p++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*p == (*q)->name()) { (*q)->connect_input(c); temp += " " + *p; } } } } ++c; } ECA_LOG_MSG(ECA_LOGGER::system_objects, temp); } /** * Attaches output 'obj' to all selected chains. * * @pre is_locked() != true */ void ECA_CHAINSETUP::attach_output_to_selected_chains(const AUDIO_IO* obj) { // -------- DBC_REQUIRE(obj != 0); DBC_REQUIRE(is_locked() != true); // -------- string temp; vector::size_type c = 0; while (c < outputs.size()) { if (outputs[c] == obj) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if ((*q)->connected_output() == static_cast(c)) { (*q)->disconnect_output(); } } temp += "Assigning file to chains:"; for(vector::const_iterator p = selected_chainids.begin(); p!= selected_chainids.end(); p++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*p == (*q)->name()) { (*q)->connect_output(static_cast(c)); temp += " " + *p; } } } } ++c; } ECA_LOG_MSG(ECA_LOGGER::system_objects, temp); } /** * Returns true if 'aobj' is a pointer to some input * or output object. */ bool ECA_CHAINSETUP::ok_audio_object(const AUDIO_IO* aobj) const { if (ok_audio_object_helper(aobj, inputs) == true || ok_audio_object_helper(aobj, outputs) == true ) return(true); return false; } bool ECA_CHAINSETUP::ok_audio_object_helper(const AUDIO_IO* aobj, const vector& aobjs) { for(size_t n = 0; n < aobjs.size(); n++) { if (aobjs[n] == aobj) return(true); } return false; } void ECA_CHAINSETUP::check_object_samplerate(const AUDIO_IO* obj, SAMPLE_SPECS::sample_rate_t srate) throw(ECA_ERROR&) { if (obj->samples_per_second() != srate) { throw(ECA_ERROR("ECA-CHAINSETUP", string("All audio objects must have a common") + " sampling rate; sampling rate of audio object \"" + obj->label() + "\" differs from engine rate (" + kvu_numtostr(obj->samples_per_second()) + " <-> " + kvu_numtostr(srate) + "); unable to continue.")); } } void ECA_CHAINSETUP::enable_audio_object_helper(AUDIO_IO* aobj) const { aobj->set_buffersize(buffersize()); AUDIO_IO_DEVICE* dev = dynamic_cast(aobj); if (dev != 0) { dev->toggle_max_buffers(max_buffers()); dev->toggle_ignore_xruns(ignore_xruns()); } if (aobj->is_open() == false) { const std::string req_format = ECA_OBJECT_FACTORY::audio_object_format_to_eos(aobj); aobj->open(); const std::string act_format = ECA_OBJECT_FACTORY::audio_object_format_to_eos(aobj); if (act_format != req_format) { DBC_CHECK(aobj->locked_audio_format() == true); ECA_LOG_MSG(ECA_LOGGER::info, "NOTE: using existing audio parameters " + act_format + " for object '" + aobj->label() + "' (tried to open with " + req_format + ")."); } } if (aobj->is_open() == true) { aobj->seek_position_in_samples(aobj->position_in_samples()); audio_object_open_info(aobj); } } /** * Enable chainsetup. Opens all devices and reinitializes all * chain operators if necessary. * * This action is performed before connecting the chainsetup * to a engine object (for instance ECA_ENGINE). * * @pre is_locked() != true * @post is_enabled() == true */ void ECA_CHAINSETUP::enable(void) throw(ECA_ERROR&) { // -------- DBC_REQUIRE(is_locked() != true); // -------- try { if (is_enabled_rep != true) { /* 1. check that current buffersize is supported by all devices */ long int locked_bsize = check_for_locked_buffersize(); if (locked_bsize != -1) { set_buffersize(locked_bsize); } /* 2. select and enable buffering parameters */ select_active_buffering_mode(); enable_active_buffering_mode(); /* 3.1 open input devices */ for(vector::iterator q = inputs.begin(); q != inputs.end(); q++) { enable_audio_object_helper(*q); if ((*q)->is_open() != true) { throw(ECA_ERROR("ECA-CHAINSETUP", "Open failed without explicit exception!")); } } /* 3.2. make sure that all input devices have a common * sampling rate */ SAMPLE_SPECS::sample_rate_t first_locked_srate = 0; for(vector::iterator q = inputs.begin(); q != inputs.end(); q++) { if (first_locked_srate == 0) { if ((*q)->locked_audio_format() == true) { first_locked_srate = (*q)->samples_per_second(); /* set chainsetup sampling rate to 'first_srate'. */ set_samples_per_second(first_locked_srate); } } else { check_object_samplerate(*q, first_locked_srate); } } /* 4. open output devices */ for(vector::iterator q = outputs.begin(); q != outputs.end(); q++) { enable_audio_object_helper(*q); if ((*q)->is_open() != true) { throw(ECA_ERROR("ECA-CHAINSETUP", "Open failed without explicit exception!")); } if (first_locked_srate == 0) { if ((*q)->locked_audio_format() == true) { first_locked_srate = (*q)->samples_per_second(); /* set chainsetup sampling rate to 'first_srate'. */ set_samples_per_second(first_locked_srate); } } else { check_object_samplerate(*q, first_locked_srate); } } /* 5. in case there were no objects with locked srates */ if (first_locked_srate == 0) { if (inputs.size() > 0) { /* set chainsetup srate to that of the first input */ set_samples_per_second(inputs[0]->samples_per_second()); } } /* 6. enable the MIDI server */ if (impl_repp->midi_server_rep.is_enabled() != true && midi_devices.size() > 0) { impl_repp->midi_server_rep.set_schedrealtime(raised_priority()); impl_repp->midi_server_rep.set_schedpriority(get_sched_priority()); impl_repp->midi_server_rep.enable(); } /* 7. enable all MIDI-devices */ for(vector::iterator q = midi_devices.begin(); q != midi_devices.end(); q++) { (*q)->toggle_nonblocking_mode(true); if ((*q)->is_open() != true) { (*q)->open(); if ((*q)->is_open() != true) { throw(ECA_ERROR("ECA-CHAINSETUP", string("Unable to open MIDI-device: ") + (*q)->label() + ".")); } } } /* 8. calculate chainsetup length */ calculate_processing_length(); } is_enabled_rep = true; } catch(AUDIO_IO::SETUP_ERROR& e) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Connecting chainsetup failed, throwing an SETUP_ERROR exception."); throw(ECA_ERROR("ECA-CHAINSETUP", string("Enabling chainsetup: ") + e.message())); } catch(...) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Connecting chainsetup failed, throwing a generic exception."); throw; } // -------- DBC_ENSURE(is_enabled() == true); // -------- } /** * Disable chainsetup. Closes all devices. * * This action is performed before disconnecting the * chainsetup from a engine object (for instance * ECA_ENGINE). * * @pre is_locked() != true * @post is_enabled() != true */ void ECA_CHAINSETUP::disable(void) { // -------- DBC_REQUIRE(is_locked() != true); // -------- /* calculate chainsetup length in case it has changed during processing */ calculate_processing_length(); if (is_enabled_rep == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Closing chainsetup \"" + name() + "\""); for(vector::iterator q = inputs.begin(); q != inputs.end(); q++) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Closing audio device/file \"" + (*q)->label() + "\"."); if ((*q)->is_open() == true) (*q)->close(); } for(vector::iterator q = outputs.begin(); q != outputs.end(); q++) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Closing audio device/file \"" + (*q)->label() + "\"."); if ((*q)->is_open() == true) (*q)->close(); } if (impl_repp->midi_server_rep.is_enabled() == true) impl_repp->midi_server_rep.disable(); for(vector::iterator q = midi_devices.begin(); q != midi_devices.end(); q++) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Closing midi device \"" + (*q)->label() + "\"."); if ((*q)->is_open() == true) (*q)->close(); } is_enabled_rep = false; } // -------- DBC_ENSURE(is_enabled() != true); // -------- } /** * Executes chainsetup edit 'edit'. * * @return true if succesful, false if edit cannot * be performed */ bool ECA_CHAINSETUP::execute_edit(const chainsetup_edit_t& edit) { bool retval = true; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Executing edit type of " + kvu_numtostr(static_cast(edit.type))); if (edit.cs_ptr != this) { ECA_LOG_MSG(ECA_LOGGER::errors, "ERROR: chainsetup edit executed on wrong object"); return false; } switch(edit.type) { case edit_c_bypass: { if (edit.m.c_bypass.chain < 1 || edit.m.c_bypass.chain > static_cast(chains.size())) { retval = false; break; } CHAIN *ch = chains[edit.m.c_bypass.chain - 1]; ch->set_bypass(edit.m.c_bypass.val); break; } case edit_c_muting: { if (edit.m.c_muting.chain < 1 || edit.m.c_muting.chain > static_cast(chains.size())) { retval = false; break; } CHAIN *ch = chains[edit.m.c_muting.chain - 1]; ch->set_mute(edit.m.c_muting.val); break; } #if NOT_YET_IMPLEMENTED case edit_cop_remove: case edit_ctrl_remove: // pass through on purpose #endif case edit_cop_add: case edit_ctrl_add: { if ((edit.m.c_generic_param.chain < 1) || (edit.m.c_generic_param.chain > static_cast(chains.size()))) { retval = false; break; } bool locked = is_locked_rep; is_locked_rep = false; const string& params = edit.param; if (params.size() > 0 && params[0] == '-') cparser_rep.interpret_object_option(params); else cparser_rep.interpret_object_option(string("-") + edit.param); if (interpret_result() != true) { ECA_LOG_MSG(ECA_LOGGER::errors, "cop-add error " + interpret_result_verbose()); retval = false; } is_locked_rep = locked; break; } case edit_cop_set_param: { if (edit.m.cop_set_param.chain < 1 || edit.m.cop_set_param.chain > static_cast(chains.size())) { retval = false; break; } CHAIN *ch = chains[edit.m.cop_set_param.chain - 1]; ch->set_parameter(edit.m.cop_set_param.op, edit.m.cop_set_param.param, edit.m.cop_set_param.value); break; } case edit_cop_bypass: { if (edit.m.cop_bypass.chain < 1 || edit.m.cop_bypass.chain > static_cast(chains.size())) { retval = false; break; } CHAIN *ch = chains[edit.m.cop_bypass.chain - 1]; ch->bypass_operator(edit.m.cop_bypass.op, edit.m.cop_bypass.bypass); break; } case edit_ctrl_set_param: { if (edit.m.ctrl_set_param.chain < 1 || edit.m.ctrl_set_param.chain > static_cast(chains.size())) { retval = false; break; } CHAIN *ch = chains[edit.m.ctrl_set_param.chain - 1]; ch->set_controller_parameter(edit.m.ctrl_set_param.op, edit.m.ctrl_set_param.param, edit.m.ctrl_set_param.value); break; } default: { DBC_NEVER_REACHED(); retval = false; ECA_LOG_MSG(ECA_LOGGER::info, "Unknown edit of type " + kvu_numtostr(static_cast(edit.type))); break; } } return retval; } /** * Updates the chainsetup processing length based on * 1) requested length, 2) lengths of individual * input objects, and 3) looping settings. */ void ECA_CHAINSETUP::calculate_processing_length(void) { long int max_input_length = 0; for(unsigned int n = 0; n < inputs.size(); n++) { if (inputs[n]->length_in_samples() > max_input_length) max_input_length = inputs[n]->length_in_samples(); } /* note! here we set the _actual_ length of the * chainsetup */ set_length_in_samples(max_input_length); if (looping_enabled() == true) { if (max_length_set() != true && max_input_length > 0) { /* looping but length not set */ ECA_LOG_MSG(ECA_LOGGER::info, "Setting loop point to " + kvu_numtostr(length_in_seconds_exact()) + "."); set_max_length_in_samples(max_input_length); } } } /** * Check whether the buffersize is locked to some * specific value. * * @return -1 if not locked, otherwise the locked * value */ long int ECA_CHAINSETUP::check_for_locked_buffersize(void) const { long int result = -1; #ifdef ECA_COMPILE_JACK int pid = getpid(); string cname = "ecasound-ctrl-" + kvu_numtostr(pid); int jackobjs = 0; for(size_t n = 0; n < inputs_direct_rep.size(); n++) { if (inputs_direct_rep[n]->name() == "JACK interface") ++jackobjs; } for(size_t n = 0; n < outputs_direct_rep.size(); n++) { if (outputs_direct_rep[n]->name() == "JACK interface") ++jackobjs; } /* contact jackd only if there is at least one jack audio object * present */ if (jackobjs > 0) { jack_client_t *client = jack_client_open(cname.c_str(), JackNullOption, NULL); if (client != 0) { // xxx = static_cast(jack_get_sample_rate(client); result = static_cast(jack_get_buffer_size(client)); ECA_LOG_MSG(ECA_LOGGER::user_objects, "jackd buffersize check returned " + kvu_numtostr(result) + "."); jack_client_close(client); client = 0; } else { ECA_LOG_MSG(ECA_LOGGER::user_objects, "unable to perform jackd buffersize check."); } DBC_CHECK(client == 0); } #endif return result; } /** * Reimplemented from ECA_CHAINSETUP_POSITION. */ void ECA_CHAINSETUP::set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value) { /* not necessarily a problem */ DBC_CHECK(is_locked() != true); ECA_LOG_MSG(ECA_LOGGER::user_objects, "sample rate change, chainsetup " + name() + " to rate " + kvu_numtostr(new_value) + "."); for(vector::iterator q = inputs.begin(); q != inputs.end(); q++) { (*q)->set_samples_per_second(new_value); } for(vector::iterator q = outputs.begin(); q != outputs.end(); q++) { (*q)->set_samples_per_second(new_value); } for(vector::iterator q = chains.begin(); q != chains.end(); q++) { (*q)->set_samples_per_second(new_value); } ECA_CHAINSETUP_POSITION::set_samples_per_second(new_value); } static void priv_seek_position_helper(std::vector* objs, SAMPLE_SPECS::sample_pos_t pos, const std::string& tag) { for(vector::iterator q = objs->begin(); q != objs->end(); q++) { /* note: don't try to seek real-time devices (only * allowed exception, try seeking all other * objects */ if (dynamic_cast(*q) == 0) { (*q)->seek_position_in_samples(pos); /* note: report if object claims it supports seeking, but * in fact the seek failed */ if ((*q)->supports_seeking() == true) { if (pos <= (*q)->length_in_samples() && (*q)->position_in_samples() != pos) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: sample accurate seek failed with " + tag + " \"" + (*q)->name() + "\""); } } } } /** * Reimplemented from ECA_AUDIO_POSITION. */ SAMPLE_SPECS::sample_pos_t ECA_CHAINSETUP::seek_position(SAMPLE_SPECS::sample_pos_t pos) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "seek position, chainsetup \"" + name() + "\" to pos in samples " + kvu_numtostr(pos) + "."); if (is_enabled() == true) { if (double_buffering() == true) pserver_repp->flush(); } priv_seek_position_helper(&inputs, pos, "input"); priv_seek_position_helper(&outputs, pos, "output"); for(vector::iterator q = chains.begin(); q != chains.end(); q++) { (*q)->seek_position_in_samples(pos); if ((*q)->position_in_samples() != pos) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: sample accurate seek failed with chainop \"" + (*q)->name() + "\""); } return pos; } /** * Interprets one option. This is the most generic variant of * the interpretation routines; both global and object specific * options are handled. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre is_enabled() != true * * @post (option successfully interpreted && interpret_result() == true) || * (unknown or invalid option && interpret_result() != true) */ void ECA_CHAINSETUP::interpret_option (const string& arg) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- cparser_rep.interpret_option(arg); } /** * Interprets one option. All non-global options are ignored. Global * options can be interpreted multiple times and in any order. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre is_enabled() != true * @post (option successfully interpreted && interpretation_result() == true) || * (unknown or invalid option && interpretation_result() == false) */ void ECA_CHAINSETUP::interpret_global_option (const string& arg) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- cparser_rep.interpret_global_option(arg); } /** * Interprets one option. All options not directly related to * ecasound objects are ignored. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre is_enabled() != true * * @post (option successfully interpreted && interpretation_result() == true) || * (unknown or invalid option && interpretation_result() == false) */ void ECA_CHAINSETUP::interpret_object_option (const string& arg) { // -------- // FIXME: this requirement is broken by eca-control.h (for // adding effects on-the-fly, just stopping the engine) // DBC_REQUIRE(is_enabled() != true); // -------- cparser_rep.interpret_object_option(arg); } /** * Interpret a vector of options. * * If any invalid options are passed us argument, * interpret_result() will be 'false', and * interpret_result_verbose() contains more detailed * error description. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::interpret_options(const vector& opts) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- cparser_rep.interpret_options(opts); } void ECA_CHAINSETUP::set_buffersize(long int value) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "overriding buffersize."); impl_repp->bmode_override_rep.set_buffersize(value); } void ECA_CHAINSETUP::toggle_raised_priority(bool value) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "overriding raised priority."); impl_repp->bmode_override_rep.toggle_raised_priority(value); } void ECA_CHAINSETUP::set_sched_priority(int value) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "sched_priority."); impl_repp->bmode_override_rep.set_sched_priority(value); } void ECA_CHAINSETUP::toggle_double_buffering(bool value) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "overriding doublebuffering."); impl_repp->bmode_override_rep.toggle_double_buffering(value); } void ECA_CHAINSETUP::set_double_buffer_size(long int v) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "overriding db-size."); impl_repp->bmode_override_rep.set_double_buffer_size(v); } void ECA_CHAINSETUP::toggle_max_buffers(bool v) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "overriding max_buffers."); impl_repp->bmode_override_rep.toggle_max_buffers(v); } long int ECA_CHAINSETUP::buffersize(void) const { if (impl_repp->bmode_override_rep.is_set_buffersize() == true) return impl_repp->bmode_override_rep.buffersize(); return impl_repp->bmode_active_rep.buffersize(); } bool ECA_CHAINSETUP::raised_priority(void) const { if (impl_repp->bmode_override_rep.is_set_raised_priority() == true) return impl_repp->bmode_override_rep.raised_priority(); return impl_repp->bmode_active_rep.raised_priority(); } int ECA_CHAINSETUP::get_sched_priority(void) const { if (impl_repp->bmode_override_rep.is_set_sched_priority() == true) return impl_repp->bmode_override_rep.get_sched_priority(); return impl_repp->bmode_active_rep.get_sched_priority(); } bool ECA_CHAINSETUP::double_buffering(void) const { if (impl_repp->bmode_override_rep.is_set_double_buffering() == true) return impl_repp->bmode_override_rep.double_buffering(); return impl_repp->bmode_active_rep.double_buffering(); } long int ECA_CHAINSETUP::double_buffer_size(void) const { if (impl_repp->bmode_override_rep.is_set_double_buffer_size() == true) return impl_repp->bmode_override_rep.double_buffer_size(); return impl_repp->bmode_active_rep.double_buffer_size(); } bool ECA_CHAINSETUP::max_buffers(void) const { if (impl_repp->bmode_override_rep.is_set_max_buffers() == true) return impl_repp->bmode_override_rep.max_buffers(); return impl_repp->bmode_active_rep.max_buffers(); } void ECA_CHAINSETUP::set_default_audio_format(ECA_AUDIO_FORMAT& value) { impl_repp->default_audio_format_rep = value; } const ECA_AUDIO_FORMAT& ECA_CHAINSETUP::default_audio_format(void) const { return impl_repp->default_audio_format_rep; } /** * Select controllers as targets for parameter control */ void ECA_CHAINSETUP::set_target_to_controller(void) { vector schains = selected_chains(); for(vector::const_iterator a = schains.begin(); a != schains.end(); a++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*a == (*q)->name()) { (*q)->selected_controller_as_target(); return; } } } } /** * Add general controller to selected chainop. * * @pre csrc != 0 * @pre is_locked() != true * @pre selected_chains().size() == 1 */ void ECA_CHAINSETUP::add_controller(GENERIC_CONTROLLER* csrc) { // -------- DBC_REQUIRE(csrc != 0); DBC_REQUIRE(is_locked() != true); DBC_REQUIRE(selected_chains().size() == 1); // -------- #ifndef ECA_DISABLE_EFFECTS AUDIO_STAMP_CLIENT* p = dynamic_cast(csrc->source_pointer()); if (p != 0) { p->register_server(&impl_repp->stamp_server_rep); } #endif DBC_CHECK(buffersize() != 0); DBC_CHECK(samples_per_second() != 0); vector schains = selected_chains(); for(vector::const_iterator a = schains.begin(); a != schains.end(); a++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*a == (*q)->name()) { if ((*q)->selected_target() == 0) return; (*q)->add_controller(csrc); return; } } } } /** * Add chain operator to selected chain. * * @pre cotmp != 0 * @pre is_locked() != true * @pre selected_chains().size() == 1 */ void ECA_CHAINSETUP::add_chain_operator(CHAIN_OPERATOR* cotmp) { // -------- DBC_REQUIRE(cotmp != 0); DBC_REQUIRE(is_locked() != true); DBC_REQUIRE(selected_chains().size() == 1); // -------- #ifndef ECA_DISABLE_EFFECTS AUDIO_STAMP* p = dynamic_cast(cotmp); if (p != 0) { impl_repp->stamp_server_rep.register_stamp(p); } #endif vector schains = selected_chains(); for(vector::const_iterator p = schains.begin(); p != schains.end(); p++) { for(vector::iterator q = chains.begin(); q != chains.end(); q++) { if (*p == (*q)->name()) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Adding chainop to chain " + (*q)->name() + "."); (*q)->add_chain_operator(cotmp); (*q)->selected_chain_operator_as_target(); return; } } } } /** * If chainsetup has inputs, but no outputs, a default output is * added. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::add_default_output(void) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- if (inputs.size() > 0 && outputs.size() == 0) { // No -o[:] options specified; let's use the default output select_all_chains(); interpret_object_option(string("-o:") + ECA_OBJECT_FACTORY::probe_default_output_device()); } } /** * If chainsetup has objects that need MIDI services, * but no MIDI-devices defined, a default MIDI-device is * added. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::add_default_midi_device(void) { if (midi_server_needed_rep == true && midi_devices.size() == 0) { cparser_rep.interpret_object_option("-Md:" + default_midi_device()); } } /** * Loads chainsetup options from file. * * @pre is_enabled() != true */ void ECA_CHAINSETUP::load_from_file(const string& filename, vector& opts) const throw(ECA_ERROR&) { // -------- DBC_REQUIRE(is_enabled() != true); // -------- std::ifstream fin (filename.c_str()); if (!fin) throw(ECA_ERROR("ECA_CHAINSETUP", "Couldn't open setup read file: \"" + filename + "\".", ECA_ERROR::retry)); vector options; string temp; while(getline(fin,temp)) { if (temp.size() > 0 && temp[0] == '#') { continue; } // FIXME: we should add quoting when saving the chainsetup or // give on quoting altogether... vector words = kvu_string_to_tokens_quoted(temp); for(unsigned int n = 0; n < words.size(); n++) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Adding \"" + words[n] + "\" to options (loaded from \"" + filename + "\"."); options.push_back(words[n]); } } fin.close(); opts = COMMAND_LINE::combine(options); } void ECA_CHAINSETUP::save(void) throw(ECA_ERROR&) { if (setup_filename_rep.empty() == true) setup_filename_rep = setup_name_rep + ".ecs"; save_to_file(setup_filename_rep); } void ECA_CHAINSETUP::save_to_file(const string& filename) throw(ECA_ERROR&) { // make sure that all overrides are processed select_active_buffering_mode(); std::ofstream fout (filename.c_str()); if (!fout) { cerr << "Going to throw an exception...\n"; throw(ECA_ERROR("ECA_CHAINSETUP", "Couldn't open setup save file: \"" + filename + "\".", ECA_ERROR::retry)); } else { fout << "# ecasound chainsetup file" << endl; fout << endl; fout << "# general " << endl; fout << cparser_rep.general_options_to_string() << endl; fout << endl; string tmpstr = cparser_rep.midi_to_string(); if (tmpstr.size() > 0) { fout << "# MIDI " << endl; fout << tmpstr << endl; fout << endl; } fout << "# audio inputs " << endl; fout << cparser_rep.inputs_to_string() << endl; fout << endl; fout << "# audio outputs " << endl; fout << cparser_rep.outputs_to_string() << endl; fout << endl; tmpstr = cparser_rep.chains_to_string(); if (tmpstr.size() > 0) { fout << "# chain operators and controllers " << endl; fout << tmpstr << endl; fout << endl; } fout.close(); set_filename(filename); } } ecasound-2.9.1/libecasound/eca-control-main.h0000644000076400007640000001027411762413277016064 00000000000000// ------------------------------------------------------------------------ // eca-control-main.h: ECA_CONTROL_MAIN class // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #ifndef INCLUDED_ECA_CONTROL_MAIN_H #define INCLUDED_ECA_CONTROL_MAIN_H #include #include #include "eca-chainsetup-edit.h" struct eci_return_value { enum { retval_none = 0, retval_string_list, retval_string, retval_float, retval_integer, retval_long_integer, retval_error } type; std::vector string_list_val; std::string string_val; union { double float_val; int int_val; long int long_int_val; } m; }; /** * High-level interface for using libecasound functionality * * This class is the abstract interface. Actual implementations * are done in subclasses - e.g. ECA_CONTROL and * ECA_CONTROL_MT (multi-threaded). * * Related design patters: Facade (GoF185) */ class ECA_CONTROL_MAIN { public: /** @name Constructors and dtors */ /*@{*/ virtual ~ECA_CONTROL_MAIN(void); /*@}*/ // ------------------------------------------------------------------- /** @name Runtime control */ /*@{*/ virtual void engine_start(void) = 0; virtual int start(void) = 0; virtual void stop(void) = 0; virtual void stop_on_condition(void) = 0; virtual int run(bool batchmode = true) = 0; virtual void quit(void) = 0; virtual void quit_async(void) = 0; virtual bool is_running(void) const = 0; virtual bool is_connected(void) const = 0; virtual bool is_selected(void) const = 0; virtual bool is_finished(void) const = 0; virtual bool is_valid(void) const = 0; virtual bool is_engine_created(void) const = 0; virtual bool is_engine_ready_for_commands(void) const = 0; virtual const ECA_CHAINSETUP* get_connected_chainsetup(void) const = 0; virtual void connect_chainsetup(struct eci_return_value *retval) = 0; virtual void disconnect_chainsetup(void) = 0; /*@}*/ // ------------------------------------------------------------------- /** @name Execute edit objects */ /*@{*/ virtual bool execute_edit_on_connected(const ECA::chainsetup_edit_t& edit) = 0; virtual bool execute_edit_on_selected(const ECA::chainsetup_edit_t& edit, int index = -1) = 0; /*@}*/ /** @name Building blocks for ECI -Ecasound Control Interface */ /*@{*/ /** * Parses and executes a string containing a single Ecasound * Interactive Mode (EIAM) command and its arguments. * * Result of the command is stored to 'retval'. */ virtual void command(const std::string& cmd_and_args, struct eci_return_value *retval) = 0; /** * A special version of 'command()' which parses a command taking * a single double parameter. * * Result of the command is stored to 'retval'. */ virtual void command_float_arg(const std::string& cmd, double arg, struct eci_return_value *retval) = 0; virtual void print_last_value(struct eci_return_value *retval) const = 0; /*@}*/ // ------------------------------------------------------------------- /** @name Static helper functions */ /*@{*/ static std::string return_value_to_string(const struct eci_return_value *retval, int float_precision = 9); static const char* return_value_type_to_string(const struct eci_return_value *retval); static void clear_return_value(struct eci_return_value *retval); /*@}*/ // ------------------------------------------------------------------- }; #endif /* INCLUDED_ECA_CONTROL_MAIN_H */ ecasound-2.9.1/libecasound/audiofx_lv2_world.cpp0000644000076400007640000000622311747070242016711 00000000000000// ------------------------------------------------------------------------ // audiofx_lv2_world.cpp: Utility class for LV2 plugin loading // Copyright (C) 2000-2004, 2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #if ECA_USE_LIBLILV #include "audiofx_lv2_world.h" #define LV2PREFIX "http://lv2plug.in/ns/lv2core#" #define IN_PLACE_BROKEN_URI LV2PREFIX "inPlaceBroken" #define SAMPLERATE_URI LV2PREFIX "sampleRate" #define TOGGLED_URI LV2PREFIX "toggled" #define INTEGER_URI LV2PREFIX "integer" #define LOGARITHMIC_URI "http://lv2plug.in/ns/dev/extportinfo#" #define CONNECTION_OPTIONAL_URI LV2PREFIX "connectionOptional" ECA_LV2_WORLD ECA_LV2_WORLD::i=ECA_LV2_WORLD(); ECA_LV2_WORLD::ECA_LV2_WORLD() { lilvworld =0; audioclassnode=0; controlclassnode=0; inputclassnode=0; outputclassnode=0; inplacebrokennode=0; porttogglednode=0; portintegernode=0; portlogarithmicnode=0; portsampleratedependentnode=0; portconnectionoptionalnode=0; } ECA_LV2_WORLD::~ECA_LV2_WORLD() { lilv_world_free(lilvworld); } #define DECLARE_ACESSOR(TYPE,METHODNAME,VARIABLENAME,VALUE) \ TYPE* ECA_LV2_WORLD::METHODNAME() { \ if(i.VARIABLENAME == 0){ \ i.VARIABLENAME = VALUE; \ } \ return i.VARIABLENAME; \ } DECLARE_ACESSOR(LilvWorld, World, lilvworld, lilv_world_new()) DECLARE_ACESSOR(LilvNode, AudioClassNode,audioclassnode,lilv_new_uri(World(),LILV_URI_AUDIO_PORT)) DECLARE_ACESSOR(LilvNode, ControlClassNode,controlclassnode,lilv_new_uri(World(),LILV_URI_CONTROL_PORT)) DECLARE_ACESSOR(LilvNode, InputClassNode,inputclassnode,lilv_new_uri(World(),LILV_URI_INPUT_PORT)) DECLARE_ACESSOR(LilvNode, OutputClassNode,outputclassnode,lilv_new_uri(World(),LILV_URI_OUTPUT_PORT)) DECLARE_ACESSOR(LilvNode, InPlaceBrokenNode,inplacebrokennode,lilv_new_uri(World(),IN_PLACE_BROKEN_URI)) DECLARE_ACESSOR(LilvNode, PortToggledNode,porttogglednode,lilv_new_uri(World(),TOGGLED_URI)) DECLARE_ACESSOR(LilvNode, PortIntegerNode,portintegernode,lilv_new_uri(World(),INTEGER_URI)) DECLARE_ACESSOR(LilvNode, PortLogarithmicNode,portlogarithmicnode,lilv_new_uri(World(),LOGARITHMIC_URI)) DECLARE_ACESSOR(LilvNode, PortSamplerateDependentNode,portsampleratedependentnode,lilv_new_uri(World(),SAMPLERATE_URI)) DECLARE_ACESSOR(LilvNode, PortConnectionOptionalNode,portconnectionoptionalnode,lilv_new_uri(World(),CONNECTION_OPTIONAL_URI)) #endif /* ECA_USE_LIBLILV */ ecasound-2.9.1/libecasound/eca-test-case.cpp0000644000076400007640000000566111541135170015675 00000000000000// ------------------------------------------------------------------------ // eca-test-case.cpp: Abstract interface for implementing // test cases for component testing. // Copyright (C) 2002,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include "kvu_numtostr.h" #include "kvu_dbc.h" #include "eca-test-case.h" using namespace std; ECA_TEST_CASE::ECA_TEST_CASE(void) { success_rep = false; } ECA_TEST_CASE::~ECA_TEST_CASE(void) { } void ECA_TEST_CASE::run_common_before(void) { failures_rep.clear(); success_rep = false; DBC_CHECK(failures_rep.size() == 0); } void ECA_TEST_CASE::run_common_after(void) { if (failures_rep.size() > 0) { success_rep = false; } else { success_rep = true; } } /** * Runs the test case. */ void ECA_TEST_CASE::run(void) { run_common_before(); /* actual test implemention defined in a subclass */ do_run(); run_common_after(); } /** * Runs the test cases passing a name argument. */ void ECA_TEST_CASE::run(const std::string &name) { run_common_before(); /* actual test implemention defined in a subclass */ do_run(name); run_common_after(); } /** * Returns the test case name. */ string ECA_TEST_CASE::name(void) const { return do_name(); } /** * Whether test was run successfully. */ bool ECA_TEST_CASE::success(void) const { return success_rep; } /** * Returns a list of string describing all * failed assertations that occured during * testing. */ const std::list& ECA_TEST_CASE::failures(void) const { return failures_rep; } void ECA_TEST_CASE::do_run(const std::string& name) { do_run(); } /** * Reports a failed assertions. * * @param filename filename where failure occured * @param lineno line number * @param description what kind of failure * * @see ECA_TEST_FAILURE */ void ECA_TEST_CASE::report_failure(const string& filename, int lineno, const string& description) { string failure (filename + ":" + kvu_numtostr(lineno) + " " + description); cerr << failure << endl; failures_rep.push_back(filename + ":" + kvu_numtostr(lineno) + " " + description); } ecasound-2.9.1/libecasound/audioio-mikmod.cpp0000644000076400007640000001166611137153267016200 00000000000000// ------------------------------------------------------------------------ // audioio-mikmod.cpp: Interface class for MikMod input. Uses FIFO pipes. // Copyright (C) 1999-2000,2004-2006,2008,2009 Kai Vehmanen // // 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 #include /* stat() */ #include /* stat() */ #include #include "audioio-mikmod.h" #include "eca-logger.h" using namespace std; string MIKMOD_INTERFACE::default_mikmod_cmd = "mikmod -d stdout -o 16s -q -f %s -p 0 --noloops %f"; void MIKMOD_INTERFACE::set_mikmod_cmd(const std::string& value) { MIKMOD_INTERFACE::default_mikmod_cmd = value; } MIKMOD_INTERFACE::MIKMOD_INTERFACE(const std::string& name) : triggered_rep(false), finished_rep(false) { } MIKMOD_INTERFACE::~MIKMOD_INTERFACE(void) { clean_child(true); if (is_open() == true) { close(); } } void MIKMOD_INTERFACE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { std::string urlprefix; triggered_rep = false; finished_rep = false; string real_filename = label(); if (real_filename == "mikmod") { real_filename = opt_filename_rep; } struct stat buf; int ret = ::stat(real_filename.c_str(), &buf); if (ret != 0) { size_t offset = real_filename.find_first_of("://"); if (offset == std::string::npos) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-MIKMOD: Can't open file " + real_filename + ".")); } else { urlprefix = std::string(real_filename, 0, offset); ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-mikmod) Found url; protocol '" + urlprefix + "'."); } } /* decoder supports: s16 samples, 2 channels, srate configurable no support for: endianess (use native) */ set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16); set_channels(2); AUDIO_IO::open(); } void MIKMOD_INTERFACE::close(void) { if (pid_of_child() > 0) { if (io_mode() == io_read) { kill_mikmod(); } } AUDIO_IO::close(); } long int MIKMOD_INTERFACE::read_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_mikmod(); } bytes_read_rep = ::fread(target_buffer, 1, frame_size() * samples, f1_rep); if (bytes_read_rep < samples * frame_size() || bytes_read_rep == 0) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::info, "(audioio-mikmod) Can't start process \"" + MIKMOD_INTERFACE::default_mikmod_cmd + "\". Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; } else finished_rep = false; return(bytes_read_rep / frame_size()); } void MIKMOD_INTERFACE::kill_mikmod(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-mikmod) Cleaning mikmod-child with pid " + kvu_numtostr(pid_of_child()) + "."); clean_child(); triggered_rep = false; } void MIKMOD_INTERFACE::fork_mikmod(void) { string real_filename = label(); if (real_filename == "mikmod") { real_filename = opt_filename_rep; } set_fork_command(MIKMOD_INTERFACE::default_mikmod_cmd); set_fork_file_name(real_filename); set_fork_sample_rate(samples_per_second()); fork_child_for_read(); if (child_fork_succeeded() == true) { /* NOTE: the file description will be closed by * AUDIO_IO_FORKED_STREAM::clean_child() */ filedes_rep = file_descriptor(); f1_rep = fdopen(filedes_rep, "r"); /* not part of */ if (f1_rep == 0) { finished_rep = true; triggered_rep = false; } } } void MIKMOD_INTERFACE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: opt_filename_rep = value; break; } } string MIKMOD_INTERFACE::get_parameter(int param) const { switch (param) { case 1: return(label()); case 2: return(opt_filename_rep); } return(""); } void MIKMOD_INTERFACE::start_io(void) { if (triggered_rep != true) { if (io_mode() == io_read) fork_mikmod(); triggered_rep = true; } } void MIKMOD_INTERFACE::stop_io(void) { if (triggered_rep == true) { if (io_mode() == io_read) clean_child(true); triggered_rep = false; } } ecasound-2.9.1/libecasound/eca-object-factory_test.h0000644000076400007640000001713312260762753017435 00000000000000// ------------------------------------------------------------------------ // eca-object-factory_test.h: Unit test for ECA_OBJECT_FACTORY // Copyright (C) 2002,2008,2009,2012 Kai Vehmanen // // 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 /* std::fabs() */ #include #include #include /* typeid() */ #ifdef HAVE_CONFIG_H #include #endif #include "kvu_numtostr.h" #include "audioio.h" #include "audioio-device.h" #include "eca-chainop.h" #include "audiofx_ladspa.h" #include "audiofx_lv2.h" #include "preset.h" #include "generic-controller.h" #include "midiio.h" #include "eca-operator.h" #include "eca-object-factory.h" #include "eca-object-map.h" #include "eca-preset-map.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_OBJECT_FACTORY. * * 1. Checks that all factory object maps have * at least one registered object. * 2. Creates one instance of each object and * verifies that DYNAMIC_OBJECT::new_expr() and * DYNAMIC_OBJECT::clone() member functions * are correctly defined. * 3. Checks that LADSPA id and unique_name * maps have same number of registered objects. */ class ECA_OBJECT_FACTORY_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("ECA_OBJECT_FACTORY_TEST"); } virtual void do_run(void); public: virtual ~ECA_OBJECT_FACTORY_TEST(void) { } private: template void test_map(const ECA_OBJECT_MAP& objmap); template void test_object_types(const T* source, const T* target, const string& description); }; template void ECA_OBJECT_FACTORY_TEST::test_object_types(const T* source, const T* target, const string& description) { if (target == 0) { ECA_TEST_FAILURE("Unable to create object (" + description + ") of type \"" + source->name() + "\""); } else if (target->name() != source->name()) { ECA_TEST_FAILURE("Type mismatch (name) between (" + description + ") and original object; type name \"" + source->name() + "\""); } else if (typeid(target) != typeid(source)) { ECA_TEST_FAILURE("Type mismatch (type_id) between (" + description + ") and original object; type name \"" + source->name() + "\""); } } template void ECA_OBJECT_FACTORY_TEST::test_map(const ECA_OBJECT_MAP& objmap) { const list& regobjs = objmap.registered_objects(); list::const_iterator p = regobjs.begin(); while(p != regobjs.end()) { const T* obj = dynamic_cast(objmap.object(*p)); if (obj == 0) { ECA_TEST_FAILURE("Unable to create object from keyword \"" + *p + "\""); } else { ECA_LOG_MSG(ECA_LOGGER::user_objects, "libecasound_tester: Object type \"" + obj->name() + "\" successfully created."); T* target = dynamic_cast(obj->new_expr()); test_object_types(obj, target, "new_expr"); if (target != 0) delete target; target = dynamic_cast(obj->clone()); test_object_types(obj, target, "clone"); if (target != 0) { if (obj->number_of_params() != target->number_of_params() && target->variable_params() != true) { ECA_TEST_FAILURE("Cloned object has different number of arguments " "than original object; type name \"" + obj->name() + "\"."); } else { const OPERATOR* operator_source = dynamic_cast(obj); OPERATOR* operator_target = dynamic_cast(target); const AUDIO_IO* audioio_source = dynamic_cast(obj); AUDIO_IO* audioio_target = dynamic_cast(target); for(int n = 0; n < obj->number_of_params(); n++) { if (obj->get_parameter_name(n + 1) != target->get_parameter_name(n + 1)) { ECA_TEST_FAILURE("Cloned object has different parameter name \"" + target->get_parameter_name(n + 1) + "\" than that of original object \"" + obj->get_parameter_name(n + 1) + "\"; type name \"" + obj->name() + "\"."); } else { if (operator_source != 0 && operator_target != 0) { /* OPERATOR binds parameter type to 'SAMPLE_SPECS::sample_t' (float) */ SAMPLE_SPECS::sample_t diffval = std::fabs(operator_source->get_parameter(n + 1) - operator_target->get_parameter(n + 1)); if (diffval > 0.1f) { ECA_TEST_FAILURE("Cloned object has different parameter value \"" + kvu_numtostr(operator_target->get_parameter(n + 1)) + "\" than that of the original object \"" + kvu_numtostr(operator_source->get_parameter(n + 1)) + "\", diff " + kvu_numtostr(diffval) + "; type name \"" + operator_source->name() + "\"."); } } else if (audioio_source != 0 && audioio_target != 0) { /* AUDIO_IO binds parameter type to 'std::string' */ if (audioio_source->get_parameter(n + 1) != audioio_target->get_parameter(n + 1)) { ECA_TEST_FAILURE("Cloned object has different parameter value \"" + audioio_target->get_parameter(n + 1) + "\" than that of the original object \"" + audioio_source->get_parameter(n + 1) + "\"; type name \"" + audioio_source->name() + "\"."); } } } } } } delete target; } ++p; } } void ECA_OBJECT_FACTORY_TEST::do_run(void) { ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - rt-map"); ECA_OBJECT_MAP& rt_map = ECA_OBJECT_FACTORY::audio_io_rt_map(); test_map(rt_map); ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - nonrt-map"); ECA_OBJECT_MAP& nonrt_map = ECA_OBJECT_FACTORY::audio_io_nonrt_map(); test_map(nonrt_map); ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - chainop-map"); ECA_OBJECT_MAP& chainop_map = ECA_OBJECT_FACTORY::chain_operator_map(); test_map(chainop_map); ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - LADSPA-map"); ECA_OBJECT_MAP& ladspa_map = ECA_OBJECT_FACTORY::ladspa_plugin_map(); test_map(ladspa_map); ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - LADSPA-id-map"); ECA_OBJECT_MAP& ladspa_id_map = ECA_OBJECT_FACTORY::ladspa_plugin_id_map(); test_map(ladspa_id_map); if (ladspa_map.registered_objects().size() != ladspa_id_map.registered_objects().size()) { ECA_TEST_FAILURE("LADSPA plugin name and id maps have different number of plugins!"); } #if ECA_USE_LIBLILV ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - LV2-map"); ECA_OBJECT_MAP& lv2_map = ECA_OBJECT_FACTORY::lv2_plugin_map(); test_map(lv2_map); #endif ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factories - preset-map"); ECA_PRESET_MAP& preset_map = ECA_OBJECT_FACTORY::preset_map(); test_map(preset_map); ECA_LOG_MSG(ECA_LOGGER::info, "libecasound_tester: object factory test done"); } ecasound-2.9.1/libecasound/eca-fileio.h0000644000076400007640000000224510664032032014712 00000000000000#ifndef INCLUDED_FILEIO_H #define INCLUDED_FILEIO_H #include #include #include /* off_t */ /** * Interface for blocking file input/output with buffering */ class ECA_FILE_IO { public: virtual ~ECA_FILE_IO(void) { } // ----- // Open/close routines virtual void open_file(const std::string& fname, const std::string& fmode) = 0; virtual void open_stdin(void) = 0; virtual void open_stdout(void) = 0; virtual void open_stderr(void) = 0; virtual void close_file(void) = 0; // ---- // Normal file operations virtual void read_to_buffer(void* obuf, off_t bytes) = 0; virtual void write_from_buffer(void* obuf, off_t bytes) = 0; virtual void set_file_position(off_t newpos) = 0; virtual void set_file_position_advance(off_t fw) = 0; virtual void set_file_position_end(void) = 0; virtual off_t get_file_position(void) const = 0; virtual off_t get_file_length(void) const = 0; // ----- // Status virtual bool is_file_ready(void) const = 0; virtual bool is_file_error(void) const = 0; virtual off_t file_bytes_processed(void) const = 0; virtual const std::string& file_mode(void) const = 0; }; #endif ecasound-2.9.1/libecasound/two-stage-linear-envelope.h0000644000076400007640000000165511034531732017721 00000000000000#ifndef INCLUDED_TWO_STAGE_LINEAR_ENVELOPE_H #define INCLUDED_TWO_STAGE_LINEAR_ENVELOPE_H #include #include "ctrl-source.h" /** * Two-stage linear envelope */ class TWO_STAGE_LINEAR_ENVELOPE : public CONTROLLER_SOURCE { public: std::string name(void) const { return("Two-stage linear envelope"); } virtual parameter_t value(double pos_secs); virtual void set_initial_value(parameter_t arg) {} virtual void init(void); std::string parameter_names(void) const { return("1st-stage-sec,2nd-stage-sec"); } void set_parameter(int param, parameter_t value); parameter_t get_parameter(int param) const; TWO_STAGE_LINEAR_ENVELOPE(void); TWO_STAGE_LINEAR_ENVELOPE* clone(void) const { return new TWO_STAGE_LINEAR_ENVELOPE(*this); } TWO_STAGE_LINEAR_ENVELOPE* new_expr(void) const { return new TWO_STAGE_LINEAR_ENVELOPE(); } private: parameter_t first_stage_length_rep, second_stage_length_rep; }; #endif ecasound-2.9.1/libecasound/eca-operator.h0000644000076400007640000000426610664032032015303 00000000000000#ifndef INCLUDED_OPERATOR_H #define INCLUDED_OPERATOR_H #include "sample-specs.h" #include "dynamic-object.h" /** * All ecasound objects which can be used as targets * for dynamic control, are called operators. * * @author Kai Vehmanen */ class OPERATOR : public DYNAMIC_OBJECT { public: typedef SAMPLE_SPECS::sample_t parameter_t; /** * Structure describing one operator parameter. */ struct PARAM_DESCRIPTION { /** * A reasonable default value. */ parameter_t default_value; /** * Parameter description. */ std::string description; /** * Is parameter bounded above? */ bool bounded_above; /** * If 'bounded_above', contains the bound value. */ parameter_t upper_bound; /** * Is parameter bounded below? */ bool bounded_below; /** * If 'bounded_below', contains the bound value. */ parameter_t lower_bound; /** * Whether parameter should be treated as a boolean toggle? * Parameter value of less than or equal to zero (x <= 0) should * be considered `off' or `false,' and value above zero (x > 0) * should be considered `on' or `true. */ bool toggled; /** * Parameter value is best represented as an integer. */ bool integer; /** * Value range from lower_bound to upper_bound is best * represented on a logarithmic scale. */ bool logarithmic; /** * Parameter value can change during operation. This * makes it possible to have separate parameters for * storing processing results. */ bool output; }; /** * An optional function for querying parameter descriptions. * This is meant primarily for building generic user-interfaces. * It's important to note that these values only serve as hints, * they are not meant to be absolute. * * @param param parameter id * @pre param > 0 && param <= number_of_params() */ virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual OPERATOR* clone(void) const = 0; virtual OPERATOR* new_expr(void) const = 0; virtual ~OPERATOR (void); }; #endif ecasound-2.9.1/libecasound/eca-object-map.cpp0000644000076400007640000001410411141424206016013 00000000000000// ------------------------------------------------------------------------ // eca-object-map: A virtual base for dynamic object maps // Copyright (C) 2000-2004,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include #include "eca-object-map.h" #include "eca-logger.h" using std::find; using std::map; using std::string; using std::list; ECA_OBJECT_MAP::ECA_OBJECT_MAP(void) : expr_case_sensitive_rep(false) { } ECA_OBJECT_MAP::~ECA_OBJECT_MAP(void) { map::iterator p = object_map.begin(); while(p != object_map.end()) { if (p->second != 0) { ECA_OBJECT* next_obj = p->second; // std::cerr << "Deleting " << next_obj->name() << "." << std::endl; map::iterator q = p; ++q; while(q != object_map.end()) { if (q->second != 0 && q->second == p->second) { // std::cerr << "Deleting sub-object with keyword " << q->first << "." << std::endl; q->second = 0; } ++q; } p->second = 0; delete next_obj; } ++p; } } void ECA_OBJECT_MAP::toggle_case_sensitive_expressions(bool v) { expr_case_sensitive_rep = v; } bool ECA_OBJECT_MAP::case_sensitive_expressions(void) const { return expr_case_sensitive_rep; } /** * Registers a new object to the object map. Map object will take care * of deleting the registered objects. Notice that it's possible * to register the same physical object with different keywords. * Object map will take care that objects with multiple registered * keywords are destructed properly. * * @arg keyword tag string that identifies the registered object * @arg expr regex that is used to map strings to objects * (note! 'keyword' should match 'expr') */ void ECA_OBJECT_MAP::register_object(const string& keyword, const string& expr, ECA_OBJECT* object) { object_keywords_rep.push_back(keyword); object_map[keyword] = object; object_expr_map[keyword] = expr; if (expr_to_keyword(keyword) != keyword && object != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Registered keyword " + keyword + " doesn't match the associated regex " + expr + ", for object '" + object->name() + "' (" + expr_to_keyword(expr) + ")."); } } /** * Unregisters object with keyword 'keyword'. Does not physically * delete the assigned object, because one object can be * registered with multiple keywords. */ void ECA_OBJECT_MAP::unregister_object(const string& keyword) { object_keywords_rep.remove(keyword); object_map[keyword] = 0; object_expr_map[keyword] = ""; } /** * Returns a list of registered objects. */ const list& ECA_OBJECT_MAP::registered_objects(void) const { return object_keywords_rep; } bool ECA_OBJECT_MAP::has_keyword(const std::string& keyword) const { if (find(object_keywords_rep.begin(), object_keywords_rep.end(), keyword) == object_keywords_rep.end()) return false; return true; } bool ECA_OBJECT_MAP::has_object(const ECA_OBJECT* obj) const { map::const_iterator p = object_map.begin(); while(p != object_map.end()) { if (obj->name() == p->second->name()) { return true; } ++p; } return false; } /** * Returns the object identified by 'keyword'. If no keyword * matches, 0 is returned. * * As a const object pointer is returned, clone() and new_expr() * methods should be used to create new non-const objects of * the returned type. */ const ECA_OBJECT* ECA_OBJECT_MAP::object(const string& keyword) const { const ECA_OBJECT* object = 0; if (object_map.find(keyword) != object_map.end()) { object = object_map[keyword]; } return object; } /** * A convenience function which directly returns an object matching * search string 'input'. */ const ECA_OBJECT* ECA_OBJECT_MAP::object_expr(const string& input) const { return object(expr_to_keyword(input)); } /** * Returns the identifying keyword for input string 'input'. * * If 'case_sensitive_expressions() != true', the pattern * matching will be case insensitive. */ string ECA_OBJECT_MAP::expr_to_keyword(const string& input) const { map::const_iterator p = object_expr_map.begin(); regex_t preg; string result; while(p != object_expr_map.end()) { int cflags = REG_EXTENDED | REG_NOSUB; if (case_sensitive_expressions() != true) cflags |= REG_ICASE; regcomp(&preg, p->second.c_str(), cflags); if (regexec(&preg, input.c_str(), 0, 0, 0) == 0) { ECA_LOG_MSG(ECA_LOGGER::functions, "match (1): " + input + " to regexp " + p->second); result = p->first; regfree(&preg); break; } regfree(&preg); ++p; } return result; } /** * Returns the identifying keyword that matches the expression 'expr'. */ string ECA_OBJECT_MAP::keyword_to_expr(const string& keyword) const { if (object_expr_map.find(keyword) != object_expr_map.end()) return object_expr_map[keyword]; return ""; } /** * Returns the matching identifying keyword for 'object'. */ string ECA_OBJECT_MAP::object_identifier(const ECA_OBJECT* object) const { map::const_iterator p = object_map.begin(); while(p != object_map.end()) { if (object->name() == p->second->name()) { return p->first; } ++p; } return ""; } ecasound-2.9.1/libecasound/eca-object.h0000644000076400007640000000116710765306237014730 00000000000000#ifndef INCLUDED_ECA_OBJECT_H #define INCLUDED_ECA_OBJECT_H #include using std::string; /** * Virtual class for ecasound objects * * @author Kai Vehmanen */ class ECA_OBJECT { public: virtual ~ECA_OBJECT (void) {} /** * Object name used to identify the object type. In most * cases, object name is same for all class instances. * Must be implemented in all subclasses. */ virtual std::string name(void) const = 0; /** * Object description. Description should be short, informative * and unformatted. */ virtual std::string description(void) const { return(name()); } }; #endif ecasound-2.9.1/libecasound/audioio-barrier.h0000644000076400007640000000140210765306273016001 00000000000000#ifndef INCLUDED_AUDIO_IO_BARRIER_H #define INCLUDED_AUDIO_IO_BARRIER_H /** * Interface class that introduces audio i/o barriers. * The barriers are used to signal that processing * will be started or stopped. */ class AUDIO_IO_BARRIER { public: /** * Starts I/O processing. * * The read_buffer()/write_buffer() functions will not be called * before I/O started. Also, it is guaranteed that stop_io() will * be called from the same thread as start_io() was called from. */ virtual void start_io(void) = 0; /** * Stops I/O processing. * * The read_buffer()/write_buffer() functions will not be called * after I/O has been stopped. */ virtual void stop_io(void) = 0; virtual ~AUDIO_IO_BARRIER(void) {} }; #endif ecasound-2.9.1/libecasound/audioio-db-server.h0000644000076400007640000000427010664032032016235 00000000000000#ifndef INCLUDED_AUDIOIO_DB_SERVER_H #define INCLUDED_AUDIOIO_DB_SERVER_H #include #include "audioio.h" #include "audioio-db-buffer.h" class AUDIO_IO_DB_SERVER_impl; /** * Audio i/o engine. Meant for serving all double-buffered client * audio objects (AUDIO_IO_DB_CLIENT). * * @author Kai Vehmanen */ class AUDIO_IO_DB_SERVER { friend void* start_db_server_io_thread(void *ptr); public: /** @name Constructors and dtors */ /*@{*/ AUDIO_IO_DB_SERVER (void); ~AUDIO_IO_DB_SERVER(void); /*@}*/ /** @name Public functions for acquiring status information */ /*@{*/ bool is_running(void) const; bool is_full(void) const; /*@}*/ /** @name Public functions for transport control */ /*@{*/ void start(void); void stop(void); void flush(void); /*@}*/ /** @name Public functions for reporting client activity */ /*@{*/ void signal_client_activity(void); /*@}*/ /** @name Public functions for waiting on server conditions */ /*@{*/ void wait_for_full(void); void wait_for_stop(void); void wait_for_flush(void); /*@}*/ /** @name Public functions for configuration */ /*@{*/ void set_buffer_defaults(int buffers, long int buffersize); void register_client(AUDIO_IO* abject); void unregister_client(AUDIO_IO* abject); AUDIO_IO_DB_BUFFER* get_client_buffer(AUDIO_IO* abject); /*@}*/ private: static const int buffercount_default; static const long int buffersize_default; std::vector buffers_rep; std::vector clients_rep; std::map client_map_rep; AUDIO_IO_DB_SERVER_impl* impl_repp; bool thread_running_rep; ATOMIC_INTEGER exit_ok_rep; ATOMIC_INTEGER exit_request_rep; ATOMIC_INTEGER stop_request_rep; ATOMIC_INTEGER running_rep; ATOMIC_INTEGER full_rep; int buffercount_rep; long int buffersize_rep; int schedpriority_rep; AUDIO_IO_DB_SERVER& operator=(const AUDIO_IO_DB_SERVER& x) { return *this; } AUDIO_IO_DB_SERVER (const AUDIO_IO_DB_SERVER& x) { } void io_thread(void); void wait_for_client_activity(void); void signal_full(void); void signal_stop(void); void signal_flush(void); void dump_profile_counters(void); }; #endif ecasound-2.9.1/libecasound/eca-iamode-parser_impl.h0000644000076400007640000000743411742360471017232 00000000000000#ifndef INCLUDED_ECA_IAMODE_PARSER_IMPL_H #define INCLUDED_ECA_IAMODE_PARSER_IMPL_H class ECA_IAMODE_PARSER_COMMANDS { protected: enum Commands { ec_unknown, // -- ec_help, ec_exit, ec_start, ec_stop, ec_stop_sync, ec_run, ec_debug, ec_resource_file, // -- ec_engine_status, ec_engine_launch, ec_engine_halt, // -- ec_cs_add, ec_cs_remove, ec_cs_list, ec_cs_select, ec_cs_selected, ec_cs_index_select, ec_cs_load, ec_cs_save, ec_cs_save_as, ec_cs_edit, ec_cs_is_valid, ec_cs_connect, ec_cs_connected, ec_cs_disconnect, ec_cs_set_param, ec_cs_set_audio_format, ec_cs_status, ec_cs_rewind, ec_cs_forward, ec_cs_set_position, ec_cs_set_position_samples, ec_cs_get_position, ec_cs_get_position_samples, ec_cs_get_length, ec_cs_get_length_samples, ec_cs_set_length, ec_cs_set_length_samples, ec_cs_toggle_loop, ec_cs_option, // -- ec_c_add, ec_c_remove, ec_c_list, ec_c_select, ec_c_selected, ec_c_select_all, ec_c_select_add, ec_c_index_select, ec_c_deselect, ec_c_clear, ec_c_rename, ec_c_muting, ec_c_bypass, ec_c_status, ec_c_is_bypassed, ec_c_is_muted, // -- ec_aio_register, ec_aio_status, // -- ec_ai_add, ec_ai_describe, ec_ai_remove, ec_ai_list, ec_ai_select, ec_ai_selected, ec_ai_index_select, ec_ai_attach, ec_ai_status, ec_ai_forward, ec_ai_rewind, ec_ai_set_position, ec_ai_set_position_samples, ec_ai_get_position, ec_ai_get_position_samples, ec_ai_get_length, ec_ai_get_length_samples, ec_ai_get_format, ec_ai_wave_edit, // -- ec_ao_add, ec_ao_add_default, ec_ao_describe, ec_ao_remove, ec_ao_list, ec_ao_select, ec_ao_selected, ec_ao_index_select, ec_ao_attach, ec_ao_status, ec_ao_forward, ec_ao_rewind, ec_ao_set_position, ec_ao_set_position_samples, ec_ao_get_position, ec_ao_get_position_samples, ec_ao_get_length, ec_ao_get_length_samples, ec_ao_get_format, ec_ao_wave_edit, // -- ec_cop_add, ec_cop_bypass, ec_cop_describe, ec_cop_is_bypassed, ec_cop_remove, ec_cop_list, ec_cop_select, ec_cop_selected, ec_cop_set, ec_cop_get, ec_cop_status, ec_cop_register, ec_copp_list, ec_copp_select, ec_copp_selected, ec_copp_set, ec_copp_get, // -- ec_ladspa_register, ec_preset_register, ec_lv2_register, // -- ec_ctrl_add, ec_ctrl_describe, ec_ctrl_remove, ec_ctrl_list, ec_ctrl_select, ec_ctrl_selected, ec_ctrl_status, ec_ctrl_register, ec_ctrlp_list, ec_ctrlp_select, ec_ctrlp_selected, ec_ctrlp_set, ec_ctrlp_get, ec_ctrl_get_target, // [spa] added new command // -- ec_int_cmd_list, ec_int_log_history, ec_int_output_mode_wellformed, ec_int_set_float_to_string_precision, ec_int_set_log_history_length, ec_int_version_string, ec_int_version_lib_current, ec_int_version_lib_revision, ec_int_version_lib_age, // -- ec_map_cop_list, ec_map_preset_list, ec_map_ladspa_list, ec_map_ladspa_id_list, ec_map_lv2_list, ec_map_ctrl_list, // -- ec_dump_target, ec_dump_status, ec_dump_position, ec_dump_length, ec_dump_cs_status, ec_dump_c_selected, ec_dump_ai_selected, ec_dump_ai_position, ec_dump_ai_length, ec_dump_ai_open_state, ec_dump_ao_selected, ec_dump_ao_position, ec_dump_ao_length, ec_dump_ao_open_state, ec_dump_cop_value, // -- ec_jack_connect, ec_jack_disconnect, ec_jack_list_connections, // -- ec_invalid }; }; #endif ecasound-2.9.1/libecasound/eca-osc.cpp0000644000076400007640000002172711747067333014607 00000000000000// ------------------------------------------------------------------------ // eca-osc.cpp: Class implementing the Ecasound OSC interface // Copyright (C) 2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // References: // - liblo: // http://liblo.sourceforge.net/ // http://liblo.sourceforge.net/docs/ // - Open Source Control (OSC): // http://opensoundcontrol.org/ // http://archive.cnmat.berkeley.edu/OpenSoundControl/ // http://en.wikipedia.org/wiki/OpenSound_Control // // 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, see . // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #ifdef ECA_USE_LIBLO #include #include #include #include #include #include "eca-control-mt.h" #include "eca-chainsetup-edit.h" #include "eca-chainsetup.h" #include "eca-logger.h" #include "eca-osc.h" // #define VERBOSE_FOR_DEBUGGING 1 #undef VERBOSE_FOR_DEBUGGING using namespace std; const std::string eca_osc_interface_namespace_const ("ecasound"); static void cb_lo_err_handler(int num, const char *msg, const char *where) { std::fprintf(stderr, "lo_error: num=%d, msg=%s, where=%s.\n", num, msg, where); } int cb_lo_method_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { ECA_OSC_INTERFACE* self = reinterpret_cast(user_data); #ifdef VERBOSE_FOR_DEBUGGING std::fprintf(stdout, "lo_method: path=%s, types=%s, args=%d, userdata=%p.\n", path, types, argc, user_data); #endif int retval = self->handle_osc_message(path, types, argv, argc); #ifdef VERBOSE_FOR_DEBUGGING for(int n = 0; n < argc; n++) { switch (types[n]) { case 'i': std::fprintf(stdout, "lo_arg #%d %c=<%d>\n", n, types[n], argv[n]->i); break; case 'f': std::fprintf(stdout, "lo_arg #%d %c=<%.03f>\n", n, types[n], argv[n]->f); break; default: std::fprintf(stdout, "lo_arg #%d %c=\n", n, types[n], *(uint32_t*)argv[n]); break; } } #endif /* note: doesn't seem to work in 0.23 (at least when messages are sent with oscsend from 0.26) */ // lo_message_pp(msg); return retval; } /** * Constructor * * If any other object may use the control object, passed to * ECA_OSC_INTERFACE, at the same time, ECA_CONTROL_MT should * be used to guarantee thread-safety access to control * functions. * * @param ecacontrol if the control object is u */ ECA_OSC_INTERFACE::ECA_OSC_INTERFACE(ECA_CONTROL_MT *ecacontrol, int port) : ec_repp(ecacontrol), running_rep(false), udp_port_rep(port), lo_thr_repp(0) { } ECA_OSC_INTERFACE::~ECA_OSC_INTERFACE(void) { if (is_running() == true) { stop(); } } void ECA_OSC_INTERFACE::start(void) { const char* port_str = 0; if (udp_port_rep > 0) { port_str = kvu_numtostr(udp_port_rep).c_str(); } /* FIXME: move to after opening and acquire port * with lo_server_thread_get_port */ ECA_LOG_MSG(ECA_LOGGER::info, "started OSC interface at UDP port " + kvu_numtostr(udp_port_rep)); lo_thr_repp = lo_server_thread_new(port_str, cb_lo_err_handler); if (lo_thr_repp) { /* note: in liblo 0.23 function returns voide, but * in 0.26 in returns an int */ lo_server_thread_start(lo_thr_repp); method_all_repp = lo_server_thread_add_method(lo_thr_repp, NULL, NULL, cb_lo_method_handler, this); running_rep = true; } ECA_LOG_MSG(ECA_LOGGER::user_objects, "server thread started with status " + kvu_numtostr(running_rep)); } void ECA_OSC_INTERFACE::stop(void) { if (running_rep == true) { /* note: in liblo 0.23 function returns voide, but * in 0.26 in returns an int */ lo_server_thread_stop(lo_thr_repp); lo_server_thread_free(lo_thr_repp); method_all_repp = 0; lo_thr_repp = 0; running_rep = false; } } bool ECA_OSC_INTERFACE::is_running(void) const { return running_rep; } /** For "foo/bar/yeah", returns "foo" */ static string priv_path_get_front(const string &path) { return string (path, 0, path.find("/")); } /** For "foo/bar/yeah", returns "bar/yeah" */ static string priv_path_pop_front(const std::string &path) { size_t marker = path.find("/"); if (marker != string::npos) return string(path, marker + 1); return path; } /** * Parses path with syntax "param/X" and writes X to 'param'. * * @return 0 on success, negative error code otherwise */ int ECA_OSC_INTERFACE::parse_path_param(const std::string &path, int *param) { if (priv_path_get_front(string(path)) == "param") { string left_s = priv_path_pop_front(path); string param_s = priv_path_get_front(left_s); if (param_s.size() > 0 && param != 0) { *param = std::atoi(param_s.c_str()); return 0; } } return -1; } int ECA_OSC_INTERFACE::handle_chain_message(const std::string &path, const char *types, lo_arg **argv, int argc) { int retval = -1; string chain_s = priv_path_get_front(path); ec_repp->lock_control(); const ECA_CHAINSETUP *cs = ec_repp->get_connected_chainsetup(); int c_index = cs ? cs->get_chain_index(chain_s) : -1; if (c_index > 0) { ECA::chainsetup_edit_t edit; edit.cs_ptr = cs; string left_s = priv_path_pop_front(path); string action = priv_path_get_front(left_s); if (action == "op") { left_s = priv_path_pop_front(left_s); string op_s = priv_path_get_front(left_s); int param = -1; int p_res = parse_path_param(priv_path_pop_front(left_s), ¶m); if (argc > 0 && p_res == 0) { DBC_CHECK(types[0] == 'f'); edit.type = ECA::edit_cop_set_param; edit.m.cop_set_param.chain = c_index; edit.m.cop_set_param.op = std::atoi(op_s.c_str()); edit.m.cop_set_param.param = param; edit.m.cop_set_param.value = argv[0]->f; #ifdef VERBOSE_FOR_DEBUGGING std::fprintf(stdout, "chain=%s (id=%d), op=%d, param=%d to %.03f\n", chain_s.c_str(), c_index, edit.m.cop_set_param.op, edit.m.cop_set_param.param, edit.m.cop_set_param.value); #endif ec_repp->execute_edit_on_connected(edit); retval = 0; } } else if (action == "ctrl") { left_s = priv_path_pop_front(left_s); string ctrl_s = priv_path_get_front(left_s); int param = -1; int p_res = parse_path_param(priv_path_pop_front(left_s), ¶m); if (argc > 0 && p_res == 0) { DBC_CHECK(types[0] == 'f'); edit.type = ECA::edit_ctrl_set_param; edit.m.ctrl_set_param.chain = c_index; edit.m.ctrl_set_param.op = std::atoi(ctrl_s.c_str()); edit.m.ctrl_set_param.param = param; edit.m.ctrl_set_param.value = argv[0]->f; #ifdef VERBOSE_FOR_DEBUGGING std::fprintf(stdout, "chain=%s (id=%d), ctrl=%d, param=%d to %.03f\n", chain_s.c_str(), c_index, edit.m.ctrl_set_param.op, edit.m.ctrl_set_param.param, edit.m.ctrl_set_param.value); #endif ec_repp->execute_edit_on_connected(edit); retval = 0; } } else { DBC_NEVER_REACHED(); } } else { #ifdef VERBOSE_FOR_DEBUGGING std::fprintf(stdout, "full=%s, chain=%s (id=%d), op=-, param=- to -\n", path.c_str(),chain_s.c_str(), c_index); #endif } ec_repp->unlock_control(); if (cs == 0) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: no chainsetup connected, so ignoring OSC message \"" + path + "\""); } return retval; } int ECA_OSC_INTERFACE::handle_osc_message(const char *path, const char *types, lo_arg **argv, int argc) { int retval = -1; DBC_CHECK(path[0] == '/'); string left_s = priv_path_pop_front(string(path)); string namespace_s = priv_path_get_front(left_s); if (namespace_s == eca_osc_interface_namespace_const) { left_s = priv_path_pop_front(left_s); string component_s = priv_path_get_front(left_s); #ifdef VERBOSE_FOR_DEBUGGING std::fprintf(stdout, "full=%s, left=%s, component=%s\n", path, left_s.c_str(), component_s.c_str()); #endif if (component_s == "chain") { left_s = priv_path_pop_front(left_s); retval = handle_chain_message(left_s, types, argv, argc); } } else { #ifdef VERBOSE_FOR_DEBUGGING std::fprintf(stdout, "full=%s, left=%s, ignoring...\n", path, left_s.c_str()); #endif retval = -1; } return retval; } #endif /* ECA_USE_LIBLO */ ecasound-2.9.1/libecasound/audioio-manager.h0000644000076400007640000000414210765307210015761 00000000000000#ifndef INCLUDED_AUDIOIO_MANAGER_H #define INCLUDED_AUDIOIO_MANAGER_H #include #include class AUDIO_IO; /** * Virtual base class for implementing audio object managers. * * Key tasks of an object manager are to recognize * AUDIO_IO objects that are of the type it manages, * provide a communication platform for inter-object * communication, and tracking of objects. * * Related design patterns: * - Mediator (GoF273) * * @author Kai Vehmanen */ class AUDIO_IO_MANAGER : public DYNAMIC_OBJECT { public: /** @name Public API */ /*@{*/ /** * Object name used to identify the object type. In most * cases, object name is same for all class instances. * Must be implemented in all subclasses. */ virtual std::string name(void) const = 0; /** * More verbose description of the manager type. */ virtual std::string description(void) const = 0; /** * Whether 'aobj' is of the type handled by this * manager object? * * @pre aobj != 0 */ virtual bool is_managed_type(const AUDIO_IO* aobj) const = 0; /** * Registers a new managed object. * * Ownership of the object is not transfered to this * manager object. It's therefore important to release * all managed objects before they are allocated. * Otherwise the manager object could end up referencing * invalid memory regions. * * @pre aobj != 0 * @post is_managed_type(aobj) == true */ virtual void register_object(AUDIO_IO* aobj) = 0; /** * Gets an integer id of the registered object 'aobj'. * * @return -1 if not a registered object * * @pre is_managed_type(aobj) == true * @pre aobj != 0 */ virtual int get_object_id(const AUDIO_IO* aobj) const = 0; /** * Returns a list of all registered object ids. */ virtual std::list get_object_list(void) const = 0; /** * Unregisters object identified by 'id'. * * @post std::count(get_object_list().begin(), get_object_list().end(), id) == 0 */ virtual void unregister_object(int id) = 0; virtual ~AUDIO_IO_MANAGER(void) {} /*@}*/ }; #endif ecasound-2.9.1/libecasound/audioio.cpp0000644000076400007640000003112611501245107014701 00000000000000// ------------------------------------------------------------------------ // audioio.cpp: Routines common for all audio IO-devices. // Copyright (C) 1999-2004,2008,2009,2010 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include "eca-error.h" #include "audioio.h" #include "eca-logger.h" /** * FIXME notes (last update 2008-03-11) * * - Modify default implementation of set_label()/label() so * that is mapped directly to set/get_parameter(1, ...). */ const string& AUDIO_IO::SETUP_ERROR::message(void) const { return message_rep; } AUDIO_IO::SETUP_ERROR::Error_type AUDIO_IO::SETUP_ERROR::type(void) const { return type_rep; } AUDIO_IO::SETUP_ERROR::SETUP_ERROR(AUDIO_IO::SETUP_ERROR::Error_type type, const string& message) : type_rep(type), message_rep(message) { } // =================================================================== // Constructors and destructors AUDIO_IO::~AUDIO_IO(void) { if (is_open() == true) close(); } AUDIO_IO::AUDIO_IO(const string& name, int mode) { set_label(name); set_io_mode(mode); nonblocking_rep = false; open_rep = false; } // =================================================================== // Attributes /** * Returns info about supported I/O modes (bitwise-OR) * * Note that return value may change after device is * opened (some objects will refine their attributes after * external resources are acquired). * * By default, all I/O modes are supported. */ int AUDIO_IO::supported_io_modes(void) const { return (io_read | io_readwrite | io_write); } /** * Whether device supports non-blocking I/O mode. * * Note that return value may change after device is * opened (some objects will refine their attributes after * external resources are acquired). * * By default, nonblocking mode is not supported. */ bool AUDIO_IO::supports_nonblocking_mode(void) const { return false; } /** * Whether device supports seeking. * * Note that return value may change after device is * opened (some objects will refine their attributes after * external resources are acquired). * * By default, seeking is supported. * * @see supports_seeking_sample_accurate() */ bool AUDIO_IO::supports_seeking(void) const { return true; } /** * Whether device supports sample accurate seeking. * * @see supports_seeking() * * Note that return value may change after device is * opened (some objects will refine their attributes after * external resources are acquired). * * By default, sample accurate seeking is supported if * supports_seeking() returns 'true'. */ bool AUDIO_IO::supports_seeking_sample_accurate(void) const { return AUDIO_IO::supports_seeking(); } /** * Whether audio stream has a distinct length. It's important * to note the difference between this attribute and * 'supports_seeking()'. For example, a file read through * a pipe mechanism is not seekable and its length is not * known until 'finished()´ becomes true, but still, it is * of finite length. A sine oscillator on the other hand * can go on producing a signal forever, and is thus infinite. * * This attributes directly affects how 'finished()' should * to be interpreted. @see finished(). * * Note that return value may change after device is * opened (some objects will refine their attributes after * external resources are acquired). * * By default, audio streams are finite length. */ bool AUDIO_IO::finite_length_stream(void) const { return true; } /** * Whether audio format is fully or partially locked. If this is true, * audio object has a known audio format, and may not allow to * override some or all of the values. * * Example 1: When working with existing audio files (reading * or updating), the audio parameters are locked to values * specified in the file header. * * Example 2: File format (or audio subsystem interface specification) * may hardcode some of the parameters (e.g. only support * float samples). In these cases locked_audio_format() * will return true, although some of the parameters may * still be freely set. Client should check after open() * which values were set according to its wishes, and which * were limited by the audio object implementation. * * By default, audio format is not locked. */ bool AUDIO_IO::locked_audio_format(void) const { return false; } // =================================================================== // Configuration (setting and getting configuration parameters) /** * Returns info about the current I/O mode. */ int AUDIO_IO::io_mode(void) const { return io_mode_rep; } /** * Set object input/output-mode. If the requested mode isn't * supported, the nearest supported mode is used. Because * of this, it's wise to afterwards check whether the requested * mode was accepted. * * require: * is_open() != true */ void AUDIO_IO::set_io_mode(int mode) { io_mode_rep = mode; } /** * Sets the object label. Label is used to identify the object instance. * Unlike ECA_OBJECT::name(), which is typically the same for all * instances of the class, label() is instance specific. Still it * is not guaranteed to be unique for each object. Device and file * names are typical label values. * * require: * is_open() != true */ void AUDIO_IO::set_label(const string& id_label) { id_label_rep = id_label; } /** * Enable/disbale nonblocking mode. * * require: * is_open() != true */ void AUDIO_IO::toggle_nonblocking_mode(bool value) { nonblocking_rep = value; } /** * Returns the current label. See documentation for * label(const string&). */ const string& AUDIO_IO::label(void) const { return id_label_rep; } /** * Returns a string containing info about sample format parameters. */ string AUDIO_IO::format_info(void) const { MESSAGE_ITEM otemp; if (locked_audio_format() == true && is_open() != true) { otemp << "Using audio format specified in file header data (file not yet opened)."; } else { otemp << "Format: " << format_string(); otemp << ", channels " << channels(); otemp << ", srate " << samples_per_second(); if (interleaved_channels() == true) otemp << ", interleaved"; else otemp << ", noninterleaved"; if (locked_audio_format() == true) otemp << " (locked params)."; else otemp << "."; } return otemp.to_string(); } void AUDIO_IO::set_parameter(int param, string value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, AUDIO_IO::parameter_set_to_string(param, value)); if (param == 1) set_label(value); } string AUDIO_IO::get_parameter(int param) const { ECA_LOG_MSG(ECA_LOGGER::system_objects, AUDIO_IO::parameter_get_to_string(param)); if (param == 1) return label(); return ""; } /** * Returns a debugging string for a parameter value change. */ string AUDIO_IO::parameter_get_to_string(int param) const { return string("get param ") + kvu_numtostr(param) + " of \"" + label() + "\": \"" + kvu_numtostr(param) + "\""; } /** * Returns a debugging string for a parameter value change. */ string AUDIO_IO::parameter_set_to_string(int param, string value) const { return string("set param ") + kvu_numtostr(param) + " of \"" + label() + "\" to \"" + value + "\""; } // =================================================================== // Main functionality void AUDIO_IO::open(void) throw (AUDIO_IO::SETUP_ERROR &) { DBC_REQUIRE(is_open() != true); DBC_CHECK(channels() > 0); DBC_CHECK(sample_format() != ECA_AUDIO_FORMAT::sfmt_none); DBC_CHECK(samples_per_second() > 0); open_rep = true; if (supports_seeking() == true) seek_position(position_in_samples()); else /* note: if seeking is not supported, object always starts * at position 0 when opened */ set_position_in_samples(0); } void AUDIO_IO::close(void) { DBC_REQUIRE(is_open() == true); open_rep = false; } // =================================================================== // Runtime information /** * If applicable, returns total length of the audio data stored * into current audio object. In many situations it's impossible * enquire the whole length of the object. For instance, if the * object is streaming a finite length audio stream audio object * from other applications using some type of standard IPC, * the actual length won't be known until the whole stream has * been read. As a general rule, if 'supports_seeking() == true', * length can be known right after initialization. Then again, * if 'finite_length_stream() == true', the whole stream must * be processed before we know the actual length. In other * cases, length is unknown or infinite. */ ECA_AUDIO_TIME AUDIO_IO::length(void) const { return ECA_AUDIO_TIME(length_in_samples(), samples_per_second()); } /** * Returns the current position. */ ECA_AUDIO_TIME AUDIO_IO::position(void) const { return ECA_AUDIO_TIME(position_in_samples(), samples_per_second()); } /** * Is nonblocking mode is enabled? */ bool AUDIO_IO::nonblocking_mode(void) const { return nonblocking_rep; } /** * Is the audio object ready for reading? */ bool AUDIO_IO::readable(void) const { return is_open() && io_mode() != io_write; } /** * Is the audio object ready for writing? */ bool AUDIO_IO::writable(void) const { return is_open() && io_mode() != io_read; } /** * Sets the total length of audio object data. */ void AUDIO_IO::length(const ECA_AUDIO_TIME& v) { set_length_in_samples(v.samples()); } /** * Sets the current position. */ void AUDIO_IO::position(const ECA_AUDIO_TIME& v) { if (v.samples_per_second() == samples_per_second()) set_position_in_samples(v.samples()); else { ECA_AUDIO_TIME modified (v); modified.set_samples_per_second_keeptime(samples_per_second()); set_position_in_samples(modified.samples()); } } /** * Optional status string * * An unformatted text string describing the state and status of * the current object. */ string AUDIO_IO::status(void) const { MESSAGE_ITEM mitem; mitem.setprecision(3); mitem << "position (" << position_in_seconds_exact() << "/"; if (finite_length_stream() == true) mitem << length_in_seconds_exact(); else mitem << "inf"; mitem << ") seconds.\n -> "; if (is_open() == true) mitem << "open, "; else mitem << "closed"; if (locked_audio_format() == true && is_open() != true) { mitem << ", audio format not available until object is opened."; } else { mitem << ", " << format_string() << "/" << channels() << "ch/" << samples_per_second(); mitem << "Hz, buffer " << buffersize() << "."; } return mitem.to_string(); } /** * Overrides the non-virtaul function * ECA_SAMPLERATE_AWARE::samples_per_second(), that is * present (through inheritance) in both ECA_AUDIO_FORMAT * and ECA_AUDIO_POSITION. */ SAMPLE_SPECS::sample_rate_t AUDIO_IO::samples_per_second(void) const { DBC_CHECK(ECA_AUDIO_FORMAT::samples_per_second() == ECA_AUDIO_POSITION::samples_per_second()); return ECA_AUDIO_FORMAT::samples_per_second(); } void AUDIO_IO::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { ECA_AUDIO_FORMAT::set_samples_per_second(v); ECA_AUDIO_POSITION::set_samples_per_second(v); ECA_LOG_MSG(ECA_LOGGER::system_objects, "set srate, aobj \"" + name() + ":" + label() + "\" to " + kvu_numtostr(v) + "."); } void AUDIO_IO::set_audio_format(const ECA_AUDIO_FORMAT& f_str) { ECA_AUDIO_FORMAT::set_audio_format(f_str); ECA_AUDIO_POSITION::set_samples_per_second(f_str.samples_per_second()); } SAMPLE_SPECS::sample_pos_t AUDIO_IO::seek_position(SAMPLE_SPECS::sample_pos_t pos) { if (supports_seeking() != true && pos != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: seeking not supported by audio objects of type \"" + name() + "\"."); return position_in_samples(); } return pos; } ecasound-2.9.1/libecasound/audioio-reverse.cpp0000644000076400007640000001575011161513103016353 00000000000000// ------------------------------------------------------------------------ // audioio-reverse.cpp: A proxy class that reverts the child // object's data. // Copyright (C) 2002,2005,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include "audioio-reverse.h" #include "audioio-resample.h" #include "eca-logger.h" #include "eca-object-factory.h" #include "samplebuffer.h" /** * Constructor. */ AUDIO_IO_REVERSE::AUDIO_IO_REVERSE (void) { tempbuf_repp = new SAMPLE_BUFFER(); init_rep = false; finished_rep = false; } /** * Destructor. */ AUDIO_IO_REVERSE::~AUDIO_IO_REVERSE (void) { } AUDIO_IO_REVERSE* AUDIO_IO_REVERSE::clone(void) const { AUDIO_IO_REVERSE* target = new AUDIO_IO_REVERSE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIO_IO_REVERSE::open(void) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "open " + label() + "."); if (io_mode() != AUDIO_IO::io_read) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-REVERSE: Reversed writing not supported!")); } if (init_rep != true) { AUDIO_IO* tmp = 0; const string& objname = child_params_as_string(1 + AUDIO_IO_REVERSE::child_parameter_offset, ¶ms_rep); if (objname.size() > 0) tmp = ECA_OBJECT_FACTORY::create_audio_object(objname); if (tmp == 0) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-REVERSE: unable to open child object '" + objname + "'")); set_child(tmp); int numparams = child()->number_of_params(); for(int n = 0; n < numparams; n++) { child()->set_parameter(n + 1, get_parameter(n + 1 + AUDIO_IO_REVERSE::child_parameter_offset)); if (child()->variable_params()) numparams = child()->number_of_params(); } init_rep = true; /* must be set after dyn. parameters */ } ECA_LOG_MSG(ECA_LOGGER::user_objects, "checking whether child is a finite object"); pre_child_open(); child()->open(); post_child_open(); if (child()->finite_length_stream() != true) { child()->close(); throw(SETUP_ERROR(SETUP_ERROR::dynamic_params, "AUDIOIO-REVERSE: Unable to reverse an infinite length audio object " + child()->label() + ".")); } if (dynamic_cast(child()) != 0) { child()->close(); throw(SETUP_ERROR(SETUP_ERROR::dynamic_params, "AUDIOIO-REVERSE: 'resample' objects not supported")); } if (child()->supports_seeking() != true) { child()->close(); throw(SETUP_ERROR(SETUP_ERROR::dynamic_params, "AUDIOIO-REVERSE: Unable to reverse audio object types that don't support seek (" + child()->label() + ").")); } AUDIO_IO::open(); } void AUDIO_IO_REVERSE::close(void) { if (child()->is_open() == true) child()->close(); AUDIO_IO::close(); } bool AUDIO_IO_REVERSE::finished(void) const { return finished_rep; } string AUDIO_IO_REVERSE::parameter_names(void) const { return string("reverse,") + child()->parameter_names(); } void AUDIO_IO_REVERSE::set_parameter(int param, string value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "set_parameter " + label() + "."); /* total of n+1 params, where n is number of childobj params */ if (param > static_cast(params_rep.size())) params_rep.resize(param); if (param > 0) { params_rep[param - 1] = value; } if (param > AUDIO_IO_REVERSE::child_parameter_offset && init_rep == true) { child()->set_parameter(param - AUDIO_IO_REVERSE::child_parameter_offset, value); } } string AUDIO_IO_REVERSE::get_parameter(int param) const { ECA_LOG_MSG(ECA_LOGGER::user_objects, "get_parameter " + label() + "."); if (param > 0 && param < static_cast(params_rep.size()) + 1) { if (param > AUDIO_IO_REVERSE::child_parameter_offset && init_rep == true) { params_rep[param - 1] = child()->get_parameter(param - AUDIO_IO_REVERSE::child_parameter_offset); } return params_rep[param - 1]; } return ""; } SAMPLE_SPECS::sample_pos_t AUDIO_IO_REVERSE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { finished_rep = false; ECA_LOG_MSG(ECA_LOGGER::user_objects, "seek_position " + kvu_numtostr(pos) + "."); return AUDIO_IO_PROXY::seek_position(pos); } void AUDIO_IO_REVERSE::read_buffer(SAMPLE_BUFFER* sbuf) { tempbuf_repp->number_of_channels(channels()); sbuf->number_of_channels(channels()); SAMPLE_BUFFER::buf_size_t read_count = buffersize(); /* phase 1: Seek to correct position and read one buffer */ SAMPLE_SPECS::sample_pos_t curpos = position_in_samples(); SAMPLE_SPECS::sample_pos_t newpos = child()->length_in_samples() - curpos - buffersize(); if (newpos <= 0) { child()->seek_position_in_samples(0); read_count = -newpos; finished_rep = true; } else { child()->seek_position_in_samples(newpos); } /* phase 2: Copy the data in reversed order from tempbuf * to sbuf. As we cannot have any gaps between * the blocks before reversing, we try to read * multiple times until we get the full block * of data (at least buffersize() worth of samples). */ const int max_loops = 3; SAMPLE_BUFFER::buf_size_t read_sofar = 0; /* this is how much reverse samples we will produce */ sbuf->length_in_samples(read_count); for(int i = 0; i < max_loops; i++) { child()->read_buffer(tempbuf_repp); if (tempbuf_repp->length_in_samples() + read_sofar > read_count) tempbuf_repp->length_in_samples(read_count - read_sofar); for(int c = 0; c < sbuf->number_of_channels(); c++) { SAMPLE_BUFFER::buf_size_t src = 0; SAMPLE_BUFFER::buf_size_t dst = (read_count - read_sofar - tempbuf_repp->length_in_samples()); for(; src < tempbuf_repp->length_in_samples(); src++, dst++) { sbuf->buffer[c][dst] = tempbuf_repp->buffer[c][tempbuf_repp->length_in_samples() - src - 1]; } } read_sofar += tempbuf_repp->length_in_samples(); if (read_sofar >= read_count) break; } DBC_CHECK(read_sofar <= buffersize()); DBC_CHECK(sbuf->length_in_samples() == read_count); curpos += read_sofar; set_position_in_samples(curpos); DBC_ENSURE(sbuf->number_of_channels() == channels()); } ecasound-2.9.1/libecasound/two-stage-linear-envelope.cpp0000644000076400007640000000530411034532156020250 00000000000000// ------------------------------------------------------------------------ // two-stage-linear-envelope.cpp: Two-stage linear envelope // Copyright (C) 2000-2002,2005,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // This program is fre 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 #include #include #include "two-stage-linear-envelope.h" #include "eca-logger.h" CONTROLLER_SOURCE::parameter_t TWO_STAGE_LINEAR_ENVELOPE::value(double pos_secs) { parameter_t stages_len = first_stage_length_rep + second_stage_length_rep; parameter_t retval; /* note: position may go beyond stages_len_rep */ /* phase: hold start value */ if (pos_secs < first_stage_length_rep) { retval = 0.0f; } /* phase: linear fade */ else if (pos_secs < stages_len) { DBC_CHECK(second_stage_length_rep > 0); retval = ((pos_secs - first_stage_length_rep) / second_stage_length_rep); } /* phase: hold end value */ else retval = 1.0; return retval; } TWO_STAGE_LINEAR_ENVELOPE::TWO_STAGE_LINEAR_ENVELOPE(void) { first_stage_length_rep = 0; second_stage_length_rep = 0; } void TWO_STAGE_LINEAR_ENVELOPE::init(void) { MESSAGE_ITEM otemp; otemp << "Two-stage envelope initialized: "; otemp.setprecision(3); otemp << "1. initial hold " << get_parameter(1) << "secs, 2. linear ramp len " << get_parameter(2) << "secs."; ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } void TWO_STAGE_LINEAR_ENVELOPE::set_parameter(int param, CONTROLLER_SOURCE::parameter_t value) { switch (param) { case 1: { first_stage_length_rep = value; break; } case 2: { second_stage_length_rep = value; break; } } } CONTROLLER_SOURCE::parameter_t TWO_STAGE_LINEAR_ENVELOPE::get_parameter(int param) const { switch (param) { case 1: return first_stage_length_rep; case 2: return second_stage_length_rep; } return 0.0; } ecasound-2.9.1/libecasound/audioio-ewf.h0000644000076400007640000000457010765534163015146 00000000000000#ifndef INCLUDED_AUDIOIO_EWF_H #define INCLUDED_AUDIOIO_EWF_H #include #include "audioio-seqbase.h" #include "samplebuffer.h" #include "eca-audio-time.h" #include "resource-file.h" /** * Ecasound Wave File - a simple wrapper class for handling * other audio objects. When writing .ewf files, it's possible to * seek beyond end position. When first write_buffer() call is issued, * current sample offset is stored into the .ewf file and corresponding * child object is opened for writing. Read_buffer() calls return silent * buffers until sample_offset is reached. After that, audio object is * processed normally. Similarly .ewf supports audio relocation, looping, etc... * * Related design patterns: * - Proxy (GoF207 * * @author Kai Vehmanen */ class EWFFILE : public AUDIO_SEQUENCER_BASE { public: /** @name Public functions */ /*@{*/ EWFFILE (void); virtual ~EWFFILE(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return("Ecasound wave file"); } virtual std::string description(void) const { return("Special format acts as a wrapper for other file formats. It can used for looping, audio data relocation and other special tasks."); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual std::string parameter_names(void) const; virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual EWFFILE* clone(void) const; virtual EWFFILE* new_expr(void) const { return new EWFFILE(); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ /* none */ /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); /*@}*/ /** @name New functions */ /*@{*/ /*@}*/ private: RESOURCE_FILE ewf_rc; void dump_child_debug(void); void read_ewf_data(void) throw(ECA_ERROR&); void write_ewf_data(void); void init_default_child(void) throw(ECA_ERROR&); SAMPLE_SPECS::sample_pos_t priv_public_to_child_pos(SAMPLE_SPECS::sample_pos_t pubpos) const; EWFFILE& operator=(const EWFFILE& x) { return *this; } EWFFILE (const EWFFILE& x) { } }; #endif ecasound-2.9.1/libecasound/eca-chainsetup-parser.cpp0000644000076400007640000010300711740524567017450 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup-parser.cpp: Functionality for parsing chainsetup // option syntax. // Copyright (C) 2001-2006 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include /* find() */ #include /* DBC_* */ #include #include #include #include "audioio.h" #include "file-preset.h" #include "global-preset.h" #include "midiio.h" #include "midi-client.h" #include "midi-server.h" #include "generic-controller.h" #include "eca-chain.h" #include "eca-logger.h" #include "eca-object-factory.h" #include "eca-preset-map.h" #include "eca-chainsetup.h" #include "eca-chainsetup-parser.h" #include "eca-chainsetup-bufparams.h" using std::string; ECA_CHAINSETUP_PARSER::ECA_CHAINSETUP_PARSER(ECA_CHAINSETUP* csetup) : csetup_repp(csetup), last_audio_add_vector_repp(0) { } /** * Interprets one option. This is the most generic variant of * the interpretation routines; both global and object specific * options are handled. * * @pre argu.size() > 0 * @pre argu[0] == '-' * * @post (option successfully interpreted && interpret_result() == true) || * (unknown or invalid option && interpret_result() != true) */ void ECA_CHAINSETUP_PARSER::interpret_option (const string& arg) { interpret_entry(); istatus_rep = false; interpret_global_option(arg); if (istatus_rep != true) interpret_object_option(arg); interpret_exit(arg); } /** * Interprets one option. All non-global options are ignored. Global * options can be interpreted multiple times and in any order. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @post (option successfully interpreted && interpretation_result() == true) || * (unknown or invalid option && interpretation_result() == false) */ void ECA_CHAINSETUP_PARSER::interpret_global_option (const string& arg) { interpret_entry(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Interpreting global option \"" + arg + "\"."); if (istatus_rep == false) interpret_general_option(arg); if (istatus_rep == false) interpret_processing_control(arg); if (istatus_rep == false) interpret_chains(arg); interpret_exit(arg); } /** * Interprets one option. All options not directly related to * ecasound objects are ignored. * * @pre argu.size() > 0 * @pre argu[0] == '-' * * @post (option successfully interpreted && interpretation_result() == true) || * (unknown or invalid option && interpretation_result() == false) */ void ECA_CHAINSETUP_PARSER::interpret_object_option (const string& arg) { interpret_entry(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Interpreting object option \"" + arg + "\"."); interpret_chains(arg); if (istatus_rep == false) interpret_audio_format(arg); if (istatus_rep == false) interpret_audioio_device(arg); if (istatus_rep == false) interpret_audioio_manager(arg); if (istatus_rep == false) interpret_midi_device(arg); if (istatus_rep == false) interpret_chain_operator(arg); if (istatus_rep == false) interpret_controller(arg); interpret_exit(arg); } /** * Interpret a vector of options. */ void ECA_CHAINSETUP_PARSER::interpret_options(const std::vector& opts) { int optcount = static_cast(opts.size()); int global_matches = 0; int other_matches = 0; interpret_set_result(true, ""); /* if opts.size() == 0 */ /* * phase1: parse global options only */ std::vector::const_iterator p = opts.begin(); while(p != opts.end()) { interpret_global_option(*p); /* note! below we make sure we don't calculate chain * definitions twice */ if (interpret_match_found() == true && !((*p)[0] == '-' && (*p)[1] == 'a')) global_matches++; ++p; } if (csetup_repp->chains.size() == 0) csetup_repp->add_default_chain(); /* * phase2: parse all options, including processing * the global options again */ p = opts.begin(); while(p != opts.end()) { interpret_object_option(*p); if (interpret_match_found() == true) { other_matches++; if (interpret_result() != true) { /* invalid option format */ break; } } else { /* hack to avoid printing the same info multiple times */ int dlevel = ECA_LOGGER::instance().get_log_level_bitmask(); ECA_LOGGER::instance().disable(); interpret_global_option(*p); ECA_LOGGER::instance().set_log_level_bitmask(dlevel); if (interpret_match_found() != true) { interpret_set_result(false, string("Invalid argument, unable to parse: \"") + *p + "\""); break; } else { if (interpret_result() != true) { /* invalid option format */ break; } } } ++p; } if (other_matches + global_matches != optcount) { ECA_LOG_MSG(ECA_LOGGER::info, string("WARNING: Only ") + kvu_numtostr(other_matches) + "+" + kvu_numtostr(global_matches) + " of the expected " + kvu_numtostr(optcount) + " parameters were recognized successfully."); } } void ECA_CHAINSETUP_PARSER::reset_interpret_status(void) { istatus_rep = false; } /** * Preprocesses a set of options. * * Notes! See also ECA_SESSION::preprocess_options() * * @post all options valid for interpret_option() */ void ECA_CHAINSETUP_PARSER::preprocess_options(std::vector& opts) const { std::vector::iterator p = opts.begin(); while(p != opts.end()) { /* handle options not starting with an '-' sign */ if (p->size() > 0 && (*p)[0] != '-') { /* hack1: rest as "-i:file" */ ECA_LOG_MSG(ECA_LOGGER::info, "NOTE: Interpreting option " + *p + " as -i:" + *p + "."); *p = "-i:" + *p; } ++p; } } /** * Resets the interpretation logic. * * @post interpret_status() != true */ void ECA_CHAINSETUP_PARSER::interpret_entry(void) { istatus_rep = false; interpret_set_result(true, ""); DBC_ENSURE(interpret_match_found() != true); } /** * Exits the interpretation logic. * * @post interpret_result() == true && interpret_result_verbose() == "" || * interpret_result() == false && interpret_result_verbose() != "" */ void ECA_CHAINSETUP_PARSER::interpret_exit(const string& arg) { if (istatus_rep != true) { /* option 'arg' was not found */ interpret_set_result(false, string("Interpreting option \"") + arg + "\" failed."); } else { /* option 'arg' was found, but incorrect */ if (interpret_result() != true) { if (interpret_result_verbose() == "") { interpret_set_result(false, string("Interpreting option \"") + arg + "\" failed."); } /* else -> otherwise error code is already set */ } } DBC_ENSURE((interpret_result() == true && interpret_result_verbose() == "") || (interpret_result() == false && interpret_result_verbose() != "")); } /** * Handle general options. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_general_option (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); DBC_REQUIRE(csetup_repp->is_enabled() != true); // -------- bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 'b': { int bsize = atoi(kvu_get_argument_number(1, argu).c_str()); if (bsize > 0) { csetup_repp->set_buffersize(bsize); MESSAGE_ITEM mitemb; mitemb << "Setting buffersize to (samples) " << bsize << "."; ECA_LOG_MSG(ECA_LOGGER::info, mitemb.to_string()); } else { ECA_LOG_MSG(ECA_LOGGER::info, "Invalid buffersize given; using default value."); } break; } case 'B': { string temp = kvu_get_argument_number(1, argu); if (temp == "auto") { csetup_repp->set_buffering_mode(ECA_CHAINSETUP::cs_bmode_auto); ECA_LOG_MSG(ECA_LOGGER::info, "Buffering mode is selected automatically."); } else if (temp == "nonrt") { csetup_repp->set_buffering_mode(ECA_CHAINSETUP::cs_bmode_nonrt); ECA_LOG_MSG(ECA_LOGGER::info, "Buffering mode 'nonrt' selected."); } else if (temp == "rt") { csetup_repp->set_buffering_mode(ECA_CHAINSETUP::cs_bmode_rt); ECA_LOG_MSG(ECA_LOGGER::info, "Buffering mode 'rt' selected."); } else if (temp == "rtlowlatency") { csetup_repp->set_buffering_mode(ECA_CHAINSETUP::cs_bmode_rtlowlatency); ECA_LOG_MSG(ECA_LOGGER::info, "Buffering mode 'rtlowlatency' selected."); } else { csetup_repp->set_buffering_mode(ECA_CHAINSETUP::cs_bmode_auto); ECA_LOG_MSG(ECA_LOGGER::info, "Unknown buffering mode; 'auto' mode is used instead."); } break; } case 'n': { csetup_repp->set_name(kvu_get_argument_number(1, argu)); ECA_LOG_MSG(ECA_LOGGER::info, "Setting chainsetup name to \"" + csetup_repp->name() + "\"."); break; } case 'r': { int prio = ::atoi(kvu_get_argument_number(1, argu).c_str()); if (prio < 0) { ECA_LOG_MSG(ECA_LOGGER::info, "Raised-priority mode disabled."); csetup_repp->toggle_raised_priority(false); } else { if (prio == 0) prio = 50; csetup_repp->set_sched_priority(prio); ECA_LOG_MSG(ECA_LOGGER::info, "Raised-priority mode enabled. (prio:" + kvu_numtostr(prio) + ")"); csetup_repp->toggle_raised_priority(true); } break; } case 's': { if (argu.size() > 2 && argu[2] == 'r') { ECA_LOG_MSG(ECA_LOGGER::info, "Option '-sr' is obsolete. Use syntax '-f:sfmt,channels,srate,ileaving' instead."); } break; } case 'x': { ECA_LOG_MSG(ECA_LOGGER::info, "Truncating outputs (overwrite-mode)."); csetup_repp->set_output_openmode(AUDIO_IO::io_write); break; } case 'X': { ECA_LOG_MSG(ECA_LOGGER::info, "Updating outputs (rw-mode)."); csetup_repp->set_output_openmode(AUDIO_IO::io_readwrite); break; } case 'z': { string first_arg (kvu_get_argument_number(1, argu)); if (first_arg == "db") { long int bufs = atol(kvu_get_argument_number(2, argu).c_str()); if (bufs == 0) bufs = 100000; csetup_repp->set_double_buffer_size(bufs); ECA_LOG_MSG(ECA_LOGGER::info, "Using double-buffer of " + kvu_numtostr(bufs) + " sample frames."); csetup_repp->toggle_double_buffering(true); } else if (first_arg == "nodb") { ECA_LOG_MSG(ECA_LOGGER::info, "Double-buffering disabled."); csetup_repp->toggle_double_buffering(false); } else if (first_arg == "intbuf") { ECA_LOG_MSG(ECA_LOGGER::info, "Enabling extra buffering on realtime devices."); csetup_repp->toggle_max_buffers(true); } else if (first_arg == "nointbuf") { ECA_LOG_MSG(ECA_LOGGER::info, "Disabling extra buffering on realtime devices."); csetup_repp->toggle_max_buffers(false); } else if (first_arg == "multitrack") { ECA_LOG_MSG(ECA_LOGGER::info, "Enabling multitrack-mode (override)."); long int samples = -1; if (kvu_get_number_of_arguments(argu) > 1) { /* -z:multitrack,XXX */ samples = atol(kvu_get_argument_number(2, argu).c_str()); } csetup_repp->multitrack_mode_offset_rep = samples; csetup_repp->multitrack_mode_override_rep = true; csetup_repp->multitrack_mode_rep = true; } else if (first_arg == "nomultitrack") { ECA_LOG_MSG(ECA_LOGGER::info, "Disabling multitrack-mode (override)."); csetup_repp->multitrack_mode_override_rep = true; csetup_repp->multitrack_mode_offset_rep = 0; csetup_repp->multitrack_mode_rep = false; } else if (first_arg == "psr") { ECA_LOG_MSG(ECA_LOGGER::info, "Enabling precise-sample-rates with OSS audio devices."); csetup_repp->toggle_precise_sample_rates(true); } else if (first_arg == "nopsr") { ECA_LOG_MSG(ECA_LOGGER::info, "Disabling precise-sample-rates with OSS audio devices."); csetup_repp->toggle_precise_sample_rates(false); } else if (first_arg == "xruns") { ECA_LOG_MSG(ECA_LOGGER::info, "Processing is stopped if an xrun occurs."); csetup_repp->toggle_ignore_xruns(false); } else if (first_arg == "noxruns") { ECA_LOG_MSG(ECA_LOGGER::info, "Ignoring xruns during processing."); csetup_repp->toggle_ignore_xruns(true); } else if (first_arg == "mixmode") { if (kvu_get_argument_number(2, argu) == "sum") { ECA_LOG_MSG(ECA_LOGGER::info, "Enabling 'sum' mixmode."); csetup_repp->set_mix_mode(ECA_CHAINSETUP::cs_mmode_sum); } else { ECA_LOG_MSG(ECA_LOGGER::info, "Enabling 'avg' mixmode."); csetup_repp->set_mix_mode(ECA_CHAINSETUP::cs_mmode_avg); } } break; } default: { match = false; } } if (match == true) istatus_rep = true; } /** * Handle processing control * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_processing_control (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 't': { if (argu.size() < 3) return; switch(argu[2]) { case ':': { /* note! here we set the _maximum_ length of the chainsetup */ csetup_repp->set_max_length_in_seconds(atof(kvu_get_argument_number(1, argu).c_str())); ECA_LOG_MSG(ECA_LOGGER::info, "Set processing time to " + kvu_numtostr(csetup_repp->max_length_in_seconds_exact()) + "."); break; } case 'l': { csetup_repp->toggle_looping(true); if (csetup_repp->max_length_set() != true) ECA_LOG_MSG(ECA_LOGGER::info, "Looping enabled. Length of input objects will be used to set the loop point."); else ECA_LOG_MSG(ECA_LOGGER::info, "Looping enabled."); break; } } break; } default: { match = false; } } if (match == true) istatus_rep = true; } /** * Handle chain options. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_chains (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 'a': { DBC_CHECK(csetup_repp->is_enabled() != true); std::vector schains = kvu_get_arguments(argu); if (std::find(schains.begin(), schains.end(), "all") != schains.end()) { csetup_repp->select_all_chains(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Selected all chains."); } else { csetup_repp->select_chains(schains); csetup_repp->add_new_chains(schains); MESSAGE_ITEM mtempa; mtempa << "Selected chain ids: "; for (std::vector::const_iterator p = schains.begin(); p != schains.end(); p++) { mtempa << *p << " "; } ECA_LOG_MSG(ECA_LOGGER::system_objects, mtempa.to_string()); } break; } default: { match = false; } } if (match == true) istatus_rep = true; } /** * Handle chainsetup options. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_audio_format (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 'f': { ECA_AUDIO_FORMAT active_sinfo; int channels = atoi(kvu_get_argument_number(2, argu).c_str()); long int srate = atol(kvu_get_argument_number(3, argu).c_str()); string sample_fmt = kvu_get_argument_number(1, argu); /* initialize to current defaults */ active_sinfo.set_audio_format(csetup_repp->default_audio_format()); try { if (sample_fmt.size() > 0) active_sinfo.set_sample_format_string(sample_fmt); } catch(ECA_ERROR& e) { interpret_set_result(false, string("Unable to parse sample format \"") + sample_fmt + "\" passed to -f."); istatus_rep = true; return; } if (channels > 0) active_sinfo.set_channels(channels); if (srate > 0) active_sinfo.set_samples_per_second(srate); if (kvu_get_argument_number(4, argu) == "n") active_sinfo.toggle_interleaved_channels(false); else active_sinfo.toggle_interleaved_channels(true); /* modify the defaults */ csetup_repp->set_default_audio_format(active_sinfo); MESSAGE_ITEM ftemp; ftemp << "Changed active format to (bits/channels/srate/interleave): "; ftemp << csetup_repp->default_audio_format().format_string() << "/" << csetup_repp->default_audio_format().channels() << "/" << csetup_repp->default_audio_format().samples_per_second(); if (csetup_repp->default_audio_format().interleaved_channels() == true) { ftemp << "/i"; } else { ftemp << "/n"; } ECA_LOG_MSG(ECA_LOGGER::user_objects, ftemp.to_string()); break; } default: { match = false; } } if (match == true) istatus_rep = true; } /** * Handle effect preset options. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_effect_preset (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 'p': { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Interpreting preset \"" + argu + "\"."); CHAIN_OPERATOR* cop = 0; if (csetup_repp->selected_chainids.size() != 1) { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Exactly one chain should be selected when adding chain operators."); match = false; } if (argu.size() < 3) return; switch(argu[2]) { case 'f': { #ifndef ECA_DISABLE_EFFECTS cop = dynamic_cast(new FILE_PRESET(kvu_get_argument_number(1,argu))); #endif break; } case 'n': { #ifndef ECA_DISABLE_EFFECTS string name = kvu_get_argument_number(1,argu); const PRESET* preset = dynamic_cast(ECA_OBJECT_FACTORY::preset_map().object(name)); if (preset != 0) cop = dynamic_cast(preset->new_expr()); else cop = 0; #endif break; } default: { } } if (cop != 0) { for(int n = 0; n < cop->number_of_params(); n++) { cop->set_parameter(n + 1, atof(kvu_get_argument_number(n + 2, argu).c_str())); } csetup_repp->add_chain_operator(cop); } break; } default: { match = false; } } if (match == true) istatus_rep = true; } /** * Handle audio-IO-devices and files. * * @pre argu.size() > 0 * @pre argu[0] == '-' */ void ECA_CHAINSETUP_PARSER::interpret_audioio_device (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- string tname = kvu_get_argument_number(1, argu); bool match = true; bool print_error = false; if (argu.size() < 2) return; switch(argu[1]) { case 'i': { DBC_CHECK(csetup_repp->is_enabled() != true); AUDIO_IO* audio_input = ECA_OBJECT_FACTORY::create_audio_object(argu); if (audio_input == 0) audio_input = ECA_OBJECT_FACTORY::create_loop_input(argu, &csetup_repp->loop_map); if (audio_input != 0) { if ((audio_input->supported_io_modes() & AUDIO_IO::io_read) != AUDIO_IO::io_read) { interpret_set_result(false, string("Audio object \"") + tname + "\" cannot be opened for input."); } else { ECA_LOG_MSG(ECA_LOGGER::system_objects,"adding file \"" + tname + "\"."); csetup_repp->add_input(audio_input); last_audio_add_vector_repp = &csetup_repp->inputs; /* for -y parsing */ } } else { print_error = true; } break; } case 'o': { DBC_CHECK(csetup_repp->is_enabled() != true); AUDIO_IO* audio_output = ECA_OBJECT_FACTORY::create_audio_object(argu); if (audio_output == 0) audio_output = ECA_OBJECT_FACTORY::create_loop_output(argu, &csetup_repp->loop_map); if (audio_output != 0) { bool truncate = false; int mode_tmp = csetup_repp->output_openmode(); if (mode_tmp == AUDIO_IO::io_readwrite) { if ((audio_output->supported_io_modes() & AUDIO_IO::io_readwrite) != AUDIO_IO::io_readwrite) { mode_tmp = AUDIO_IO::io_write; truncate = true; } } else { truncate = true; } if (((audio_output->supported_io_modes() & mode_tmp) != mode_tmp)) { interpret_set_result(false, string("io_write/io_readwrite access modes not supported by output \"") + audio_output->name() + "\"."); } else { ECA_LOG_MSG(ECA_LOGGER::system_objects,"adding file \"" + tname + "\"."); csetup_repp->add_output(audio_output, truncate); last_audio_add_vector_repp = &csetup_repp->outputs; /* for -y parsing */ } } else { print_error = true; } break; } case 'y': { DBC_CHECK(csetup_repp->is_enabled() != true); if (last_audio_add_vector_repp == 0) { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Non-existant last audio object."); } else { AUDIO_IO* last_object = (*last_audio_add_vector_repp).back(); double newpos = atof(kvu_get_argument_number(1, argu).c_str()); if (newpos > 0.0f && last_object && last_object->supports_seeking() != true) { interpret_set_result(false, string("Audio object does not support seeking, unable to set a non-zero starting offset. Object generating the error is \"") + last_object->name() + "\"."); } else { last_object->seek_position_in_seconds(newpos); if (last_object->io_mode() == AUDIO_IO::io_read) { csetup_repp->input_start_pos[csetup_repp->input_start_pos.size() - 1] = last_object->position_in_seconds_exact(); } else { csetup_repp->output_start_pos[csetup_repp->output_start_pos.size() - 1] = last_object->position_in_seconds_exact(); } ECA_LOG_MSG(ECA_LOGGER::info, "Setting starting position for audio object \"" + last_object->label() + "\": " + kvu_numtostr(last_object->position_in_seconds_exact()) + " seconds."); } break; } } default: { match = false; } } if (match == true) istatus_rep = true; if (print_error == true) { interpret_set_result(false, string("Audio object \"") + tname + "\" does not match any of the known audio device types or " "file formats. You can check the list of supported " "audio object types by issuing the command 'aio-register' in " "ecasound's interactive mode."); } } /** * Handles audio-IO manager options. * * @pre argu.size() > 0 * @pre argu[0] == '-' */ void ECA_CHAINSETUP_PARSER::interpret_audioio_manager(const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- string tname = kvu_get_argument_number(1, argu); bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 'G': { DBC_CHECK(csetup_repp->is_enabled() != true); std::vector args = kvu_get_arguments(argu); args.erase(args.begin()); DBC_CHECK(args.size() == kvu_get_arguments(argu).size() - 1); csetup_repp->set_audio_io_manager_option(tname, kvu_vector_to_string(args, ",")); break; } default: { match = false; } } if (match == true) istatus_rep = true; } /** * Handles MIDI-IO devices. * * @pre argu.size() > 0 * @pre argu[0] == '-' */ void ECA_CHAINSETUP_PARSER::interpret_midi_device (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- bool match = true; if (argu.size() < 2) return; switch(argu[1]) { case 'M': { if (argu.size() < 3) return; switch(argu[2]) { case 'd': { string tname = kvu_get_argument_number(1, argu); ECA_LOG_MSG(ECA_LOGGER::system_objects,"MIDI-config: Adding device \"" + tname + "\"."); MIDI_IO* mdev = 0; mdev = ECA_OBJECT_FACTORY::create_midi_device(argu); if (mdev != 0) { if ((mdev->supported_io_modes() & MIDI_IO::io_readwrite) == MIDI_IO::io_readwrite) { mdev->io_mode(MIDI_IO::io_readwrite); csetup_repp->add_midi_device(mdev); csetup_repp->midi_server_needed_rep = true; } else { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: I/O-mode 'io_readwrite' not supported by MIDI-device " + mdev->name()); } } break; } case 'm': { if (argu.size() < 4) return; switch(argu[3]) { case 'r': { // FIXME: not implemented! int id = atoi(kvu_get_argument_number(1, argu).c_str()); ECA_LOG_MSG(ECA_LOGGER::info, "MIDI-config: Receiving MMC messages with id \"" + kvu_numtostr(id) + "\"."); csetup_repp->midi_server_repp->set_mmc_receive_id(id); csetup_repp->midi_server_needed_rep = true; break; } case 's': { int id = atoi(kvu_get_argument_number(1, argu).c_str()); ECA_LOG_MSG(ECA_LOGGER::info, "MIDI-config: Adding MMC-send to device id \"" + kvu_numtostr(id) + "\"."); csetup_repp->midi_server_repp->add_mmc_send_id(id); csetup_repp->midi_server_needed_rep = true; break; } } break; } case 's': { if (argu.size() < 4) return; switch(argu[3]) { case 'r': { // FIXME: not implemented ECA_LOG_MSG(ECA_LOGGER::info, "MIDI-config: Receiving MIDI-sync."); csetup_repp->midi_server_needed_rep = true; csetup_repp->midi_server_repp->toggle_midi_sync_receive(true); break; } case 's': { // FIXME: not implemented ECA_LOG_MSG(ECA_LOGGER::info, "MIDI-config: Sending MIDI-sync."); csetup_repp->midi_server_repp->toggle_midi_sync_send(true); csetup_repp->midi_server_needed_rep = true; break; } } break; } } break; } default: { match = false; } } if (match == true) istatus_rep = true; return; } /** * Handle chain operator options (chain operators, presets * and plugins) * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_chain_operator (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- CHAIN_OPERATOR* t = ECA_OBJECT_FACTORY::create_chain_operator(argu); if (t == 0) t = ECA_OBJECT_FACTORY::create_ladspa_plugin(argu); if (t == 0) t=ECA_OBJECT_FACTORY::create_lv2_plugin(argu); if (t != 0) { if (csetup_repp->selected_chainids.size() == 1) { csetup_repp->add_chain_operator(t); istatus_rep = true; } else { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Exactly one chain should be selected when adding chain operators."); delete t; } } else interpret_effect_preset(argu); } /** * Handle controller sources and general controllers. * * @pre argu.size() > 0 * @pre argu[0] == '-' * @pre istatus_rep == false */ void ECA_CHAINSETUP_PARSER::interpret_controller (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); DBC_REQUIRE(istatus_rep == false); // -------- string prefix = kvu_get_argument_prefix(argu); if (prefix == "kx") { csetup_repp->set_target_to_controller(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Selected controllers as parameter control targets."); istatus_rep = true; } else { GENERIC_CONTROLLER* t = ECA_OBJECT_FACTORY::create_controller(argu); if (t != 0) { if (csetup_repp->selected_chainids.size() != 1) { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Exactly one chain should be selected when adding controllers."); delete t; } else { MIDI_CLIENT* p = dynamic_cast(t->source_pointer()); if (p != 0) { csetup_repp->midi_server_needed_rep = true; p->register_server(csetup_repp->midi_server_repp); } csetup_repp->add_controller(t); istatus_rep = true; } } } } string ECA_CHAINSETUP_PARSER::general_options_to_string(void) const { MESSAGE_ITEM t; int setparams = csetup_repp->override_buffering_parameters().number_of_set(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "genopts tostring - " + kvu_numtostr(setparams) + " overridden parameters."); if (setparams > 0) { t << "-b:" << csetup_repp->buffersize(); if (csetup_repp->raised_priority() == true) t << " -r:" << csetup_repp->get_sched_priority(); else t << " -r:-1"; if (csetup_repp->max_buffers() == true) t << " -z:intbuf"; else t << " -z:nointbuf"; if (csetup_repp->double_buffering() == true) t << " -z:db," << csetup_repp->double_buffer_size(); else t << " -z:nodb"; } else { ECA_CHAINSETUP::Buffering_mode_t bmode = csetup_repp->buffering_mode_rep; if (csetup_repp->active_buffering_mode_rep != ECA_CHAINSETUP::cs_bmode_none) bmode = csetup_repp->active_buffering_mode_rep; switch(bmode) { case ECA_CHAINSETUP::cs_bmode_nonrt: { t << "-B:nonrt"; break; } case ECA_CHAINSETUP::cs_bmode_rt: { t << "-B:rt"; break; } case ECA_CHAINSETUP::cs_bmode_rtlowlatency: { t << "-B:rtlowlatency"; break; } default: { t << " -B:auto"; } } } t << " -n:\"" << csetup_repp->name() << "\""; if (csetup_repp->output_openmode() == AUDIO_IO::io_write) t << " -x"; else t << " -X"; if (csetup_repp->multitrack_mode_override_rep == true) { if (csetup_repp->multitrack_mode() == true) { t << "-z:multitrack"; if (csetup_repp->multitrack_mode_offset_rep != -1) { t << "," << csetup_repp->multitrack_mode_offset_rep; } } else { t << "-z:nomultitrack"; } } if (csetup_repp->ignore_xruns() == true) t << " -z:noxruns"; else t << " -z:xruns"; if (csetup_repp->precise_sample_rates() == true) t << " -z:psr"; else t << " -z:nopsr"; if (csetup_repp->mix_mode() == ECA_CHAINSETUP::cs_mmode_avg) t << " -z:mixmode,avg"; else t << " -z:mixmode,sum"; t.setprecision(3); if (csetup_repp->max_length_set()) { t << " -t:" << csetup_repp->max_length_in_seconds_exact(); } if (csetup_repp->looping_enabled()) t << " -tl"; return t.to_string(); } string ECA_CHAINSETUP_PARSER::midi_to_string(void) const { MESSAGE_ITEM t; t.setprecision(3); std::vector::size_type p = 0; while (p < csetup_repp->midi_devices.size()) { t << "-Md:"; for(int n = 0; n < csetup_repp->midi_devices[p]->number_of_params(); n++) { // FIXME: should quote/escape possible commas and whitespace t << csetup_repp->midi_devices[p]->get_parameter(n + 1); if (n + 1 < csetup_repp->midi_devices[p]->number_of_params()) t << ","; } ++p; if (p < csetup_repp->midi_devices.size()) t << " "; } return t.to_string(); } string ECA_CHAINSETUP_PARSER::inputs_to_string(void) const { MESSAGE_ITEM t; t.setprecision(3); size_t p = 0; while (p < csetup_repp->inputs.size()) { t << "-a:"; std::vector c = csetup_repp->get_attached_chains_to_input(csetup_repp->inputs[p]); std::vector::const_iterator cp = c.begin(); while (cp != c.end()) { t << *cp; ++cp; if (cp != c.end()) t << ","; } t << " " << ECA_OBJECT_FACTORY::audio_object_format_to_eos(csetup_repp->inputs[p]) << " " << ECA_OBJECT_FACTORY::audio_object_to_eos(csetup_repp->inputs[p], "i"); if (csetup_repp->input_start_pos[p] != 0) { t << " -y:" << csetup_repp->input_start_pos[p]; } ++p; if (p < csetup_repp->inputs.size()) t << "\n"; } return t.to_string(); } string ECA_CHAINSETUP_PARSER::outputs_to_string(void) const { MESSAGE_ITEM t; t.setprecision(3); std::vector::size_type p = 0; while (p < csetup_repp->outputs.size()) { t << "-a:"; std::vector c = csetup_repp->get_attached_chains_to_output(csetup_repp->outputs[p]); std::vector::const_iterator cp = c.begin(); while (cp != c.end()) { t << *cp; ++cp; if (cp != c.end()) t << ","; } t << " " << ECA_OBJECT_FACTORY::audio_object_format_to_eos(csetup_repp->outputs[p]) << " " << ECA_OBJECT_FACTORY::audio_object_to_eos(csetup_repp->outputs[p], "o"); if (csetup_repp->output_start_pos[p] != 0) { t << " -y:" << csetup_repp->output_start_pos[p]; } ++p; if (p < csetup_repp->outputs.size()) t << "\n"; } return t.to_string(); } string ECA_CHAINSETUP_PARSER::chains_to_string(void) const { MESSAGE_ITEM t; std::vector::size_type p = 0; while (p < csetup_repp->chains.size()) { string tmpstr = csetup_repp->chains[p]->to_string(); if (tmpstr.size() > 0) { t << "-a:" << csetup_repp->chains[p]->name() << " "; t << tmpstr; if (p + 1 < csetup_repp->chains.size()) t << "\n"; } ++p; } return t.to_string(); } ecasound-2.9.1/libecasound/preset_impl.h0000644000076400007640000000202711166150245015243 00000000000000#ifndef INCLUDED_PRESET_IMPL_H #define INCLUDED_PRESET_IMPL_H #include #include #include "eca-chainop.h" #include "sample-specs.h" using std::string; using std::vector; class AUDIO_IO; class GENERIC_CONTROLLER; class OPERATOR; class PRESET_impl { public: friend class PRESET; private: vector preset_param_names_rep; /** * maps preset's public params 1...N (parent) to params * of slave objects (one-to-many mapping as multiple * slave params can be associated with the same preset * param */ vector > slave_param_indices_rep; /** * maps preset's public params 1...N (parent) to slave * objects (see slave_param_indices_rep) */ vector* > > slave_param_objects_rep; vector gctrls_rep; vector pardesclist_rep; bool parsed_rep; std::string parse_string_rep; std::string name_rep; std::string description_rep; }; #endif /* INCLUDED_PRESET_IMPL_H */ ecasound-2.9.1/libecasound/eca-logger-interface.h0000644000076400007640000000542011172717317016671 00000000000000// ------------------------------------------------------------------------ // eca-logger-interface.h: Logging subsystem interface // Copyright (C) 2002-2004,2009 Kai Vehmanen // // Attributes: // eca-style-version: 2 // // 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 INCLUDE_ECA_LOGGER_INTERFACE_H #define INCLUDE_ECA_LOGGER_INTERFACE_H #include /* remove me */ #include #include #include "eca-logger.h" /** * Virtual base class for logging subsystem implementations. * * @author Kai Vehmanen */ class ECA_LOGGER_INTERFACE { public: ECA_LOGGER_INTERFACE(void); virtual ~ECA_LOGGER_INTERFACE(void); void msg(ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message); void flush(void); void disable(void); void set_log_history_length(int len); void set_log_level(ECA_LOGGER::Msg_level_t level, bool enabled); const std::list& log_history(void) const { return log_history_rep; } /** * Gets current log level bitmask. */ int get_log_level_bitmask(void) const { return debug_value_rep; } /** * Sets state of all logging types according to 'bitmask'. */ void set_log_level_bitmask(int level_bitmask) { debug_value_rep = static_cast(level_bitmask); } /** * Whether 'level' is set or not? */ bool is_log_level_set(ECA_LOGGER::Msg_level_t level) const { return (level & debug_value_rep) > 0 ? true : false; } protected: virtual void do_msg(ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message) = 0; virtual void do_flush(void) = 0; virtual void do_log_level_changed(void) = 0; static std::string filter_module_name(const std::string& rawmodule); static void format_log_msg(std::string *logmsg, ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message); private: int debug_value_rep; int log_history_len_rep; std::list log_history_rep; int extlog_debug_level_rep; FILE *extlog_file_repp; }; #endif ecasound-2.9.1/libecasound/audioio-proxy.h0000644000076400007640000000770011433043167015534 00000000000000#ifndef INCLUDED_AUDIO_IO_PROXY_H #define INCLUDED_AUDIO_IO_PROXY_H #include #include "audioio.h" #include "audioio-barrier.h" class SAMPLE_BUFFER; /** * Generic interface for objects that act as * proxies for other objects of type AUDIO_IO. * * Related design patterns: * - Proxy (GoF207 * * Guide lines for subclassing: * - reimplement (or explicitly use the existing implementation) * all public getter and setter functions * -> rationale: otherwise the class might return invalid * data not related to the proxied child object, or setting * parameters never affect the proxy target * * @author Kai Vehmanen */ class AUDIO_IO_PROXY : public AUDIO_IO, public AUDIO_IO_BARRIER { public: /** @name Public functions */ /*@{*/ AUDIO_IO_PROXY (void); virtual ~AUDIO_IO_PROXY(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return(string("Proxy => ") + child_repp->name()); } virtual std::string description(void) const { return(child_repp->description()); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual bool variable_params(void) const { return true; } virtual std::string parameter_names(void) const; virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_IO_PROXY* clone(void) const { return(new AUDIO_IO_PROXY()); } virtual AUDIO_IO_PROXY* new_expr(void) const { return(new AUDIO_IO_PROXY()); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos) { return child_repp->seek_position(pos); } virtual bool supports_seeking(void) const { return child_repp->supports_seeking(); } virtual bool supports_seeking_sample_accurate(void) const { return child_repp->supports_seeking_sample_accurate(); } /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return(child_repp->supported_io_modes()); } virtual bool supports_nonblocking_mode(void) const { return(child_repp->supports_nonblocking_mode()); } virtual bool finite_length_stream(void) const { return( child_repp->finite_length_stream()); } virtual bool locked_audio_format(void) const { return(child_repp->locked_audio_format()); } virtual void set_buffersize(long int samples); virtual long int buffersize(void) const { return(buffersize_rep); } virtual void read_buffer(SAMPLE_BUFFER* sbuf) { child_repp->read_buffer(sbuf); } virtual void write_buffer(SAMPLE_BUFFER* sbuf) { child_repp->write_buffer(sbuf); } virtual bool finished(void) const { return(child_repp->finished()); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_FORMAT */ /*@{*/ virtual void set_channels(SAMPLE_SPECS::channel_t v); virtual void set_sample_format(Sample_format v) throw(ECA_ERROR&); virtual void set_audio_format(const ECA_AUDIO_FORMAT& f_str); virtual void toggle_interleaved_channels(bool v); /*@}*/ /** @name Reimplemented functions from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ /** @name Reimplemented functions from AUDIO_IO_BARRIER */ /*@{*/ virtual void start_io(void); virtual void stop_io(void); /*@}*/ protected: void set_child(AUDIO_IO* v); void release_child_no_delete(void); void pre_child_open(void); void post_child_open(void); bool is_child_initialized(void) const { return child_initialized_rep; } std::string child_params_as_string(int first, std::vector* params); AUDIO_IO* child(void) const { return child_repp; } private: AUDIO_IO* child_repp; long int buffersize_rep; bool child_initialized_rep; }; #endif // INCLUDED_AUDIO_IO_PROXY ecasound-2.9.1/libecasound/audiogate.h0000644000076400007640000001034311432766437014676 00000000000000#ifndef INCLUDED_AUDIO_GATE_H #define INCLUDED_AUDIO_GATE_H #include #include "eca-chainop.h" #include "eca-samplerate-aware.h" class SAMPLE_BUFFER; /** * Interface to gate effects. Gate processes sample data, but * doesn't modify it. Gate is either open or closed. */ class GATE_BASE : public CHAIN_OPERATOR { private: bool gate_open; SAMPLE_BUFFER* target; protected: void close_gate(void) { gate_open = false; } void open_gate(void) { gate_open = true; } public: inline bool is_open(void) const { return(gate_open); } virtual void init(SAMPLE_BUFFER* sbuf); virtual void process(void); virtual void analyze(SAMPLE_BUFFER* sbuf) = 0; virtual GATE_BASE* clone(void) const = 0; virtual ~GATE_BASE(void); GATE_BASE(void) { close_gate(); } }; /** * A time crop gate. Initially the gate is closed, but is opened after * 'open_at' seconds has elapsed. Gate remains open for * 'duration' seconds. If 'duration' is 0, gate will stay open * forever. */ class TIME_CROP_GATE : public GATE_BASE, public ECA_SAMPLERATE_AWARE { public: // Functions returning info about effect and its parameters. // --- parameter_t get_parameter(int param) const; void set_parameter(int param, parameter_t value); std::string name(void) const { return("Time crop gate"); } std::string parameter_names(void) const { return("open-at-sec,duration-sec"); } void analyze(SAMPLE_BUFFER* insample); /** @name Functions reimplemented from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value); /*@}*/ TIME_CROP_GATE* clone(void) const { return new TIME_CROP_GATE(*this); } TIME_CROP_GATE* new_expr(void) const { return new TIME_CROP_GATE(); } TIME_CROP_GATE (parameter_t open_at, parameter_t duration); TIME_CROP_GATE (void) : position_in_samples_rep(0), begtime_rep(0.0), durtime_rep(0.0) { close_gate(); } private: SAMPLE_SPECS::sample_pos_t position_in_samples_rep; parameter_t begtime_rep, durtime_rep; }; /** * A threshold open gate. When the average volume goes * over 'threshold_openlevel', gate is opened. In the * same way, when the average volume drops below * 'threshold_closelevel', gate is closed. Either * peak or RMS level is used for calculating average * volume. The thresholds are given in percents. Unlike * noise gates, threshold gate is opened and closed * only once. */ class THRESHOLD_GATE : public GATE_BASE { public: // Functions returning info about effect and its parameters. // --- virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* sbuf); virtual std::string name(void) const { return("Threshold gate"); } virtual std::string parameter_names(void) const { return("threshold-openlevel-%,threshold-closelevel-%,rms-enabled,reopen-count"); } virtual void analyze(SAMPLE_BUFFER* insample); THRESHOLD_GATE* clone(void) const { return new THRESHOLD_GATE(*this); } THRESHOLD_GATE* new_expr(void) const { return new THRESHOLD_GATE(); } THRESHOLD_GATE (parameter_t threshold_openlevel, parameter_t threshold_closelevel, bool use_rms = false); THRESHOLD_GATE (void) : openlevel_rep(0.0), closelevel_rep(0.0), reopen_count_param_rep(0), reopens_left_rep(0), rms_rep(false), is_opened_rep(false), is_closed_rep(false) { } private: parameter_t openlevel_rep, closelevel_rep, avolume_rep; int reopen_count_param_rep, reopens_left_rep; bool rms_rep; bool is_opened_rep, is_closed_rep; }; /** * Manual gate. * * A trivial object that ly changes gate state */ class MANUAL_GATE : public GATE_BASE { public: // Functions returning info about effect and its parameters. // --- virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual std::string name(void) const { return("Manual gate"); } virtual std::string parameter_names(void) const { return("state"); } virtual void analyze(SAMPLE_BUFFER* insample); MANUAL_GATE* clone(void) const { return new MANUAL_GATE(*this); } MANUAL_GATE* new_expr(void) const { return new MANUAL_GATE(); } MANUAL_GATE (void) : open_rep(true) {} private: bool open_rep; }; #endif ecasound-2.9.1/libecasound/eca-session_test.h0000644000076400007640000000372011166145462016176 00000000000000// ------------------------------------------------------------------------ // eca-session_test.h: Unit test for ECA_SESSION // Copyright (C) 2003,2009 Kai Vehmanen // // 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 #include "kvu_utils.h" /* kvu_sleep() */ #include "eca-control.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_SESSION. * * FIXME: implementation not ready */ class ECA_SESSION_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for ECA_SESSION"); } virtual void do_run(void); public: virtual ~ECA_SESSION_TEST(void) { } private: void do_run_chainsetup_creation(void); }; void ECA_SESSION_TEST::do_run(void) { cout << "libecasound_tester: eca-session - exception test" << endl; COMMAND_LINE cmdline; cmdline.push_back("-d:511"); cmdline.push_back("-i:invalidinvalidinvalid"); bool exceptionseen = false; try { ECA_SESSION *esession = new ECA_SESSION(cmdline); delete esession; } catch(...) { cerr << "libecasound_tester: catched exception" << endl; exceptionseen = true; } if (exceptionseen != true) { ECA_TEST_FAILURE("No exception raised when parsing an invalid chainsetup."); } } ecasound-2.9.1/libecasound/audioio-flac.h0000644000076400007640000000441511141362402015250 00000000000000#ifndef INCLUDED_AUDIOIO_FLAC_H #define INCLUDED_AUDIOIO_FLAC_H #include #include #include "audioio-buffered.h" #include "audioio-forked-stream.h" /** * Interface to FLAC decoders and encoders using UNIX pipe i/o. * * @author Kai Vehmanen */ class FLAC_FORKED_INTERFACE : public AUDIO_IO_BUFFERED, public AUDIO_IO_FORKED_STREAM { private: static std::string default_input_cmd; static std::string default_output_cmd; public: static void set_input_cmd(const std::string& value); static void set_output_cmd(const std::string& value); public: FLAC_FORKED_INTERFACE (const std::string& name = ""); virtual ~FLAC_FORKED_INTERFACE(void); virtual FLAC_FORKED_INTERFACE* clone(void) const { return new FLAC_FORKED_INTERFACE(*this); } virtual FLAC_FORKED_INTERFACE* new_expr(void) const { return new FLAC_FORKED_INTERFACE(*this); } virtual std::string name(void) const { return("FLAC stream"); } virtual std::string description(void) const { return("Interface to FLAC decoders and encoders using UNIX pipe i/o."); } virtual std::string parameter_names(void) const { return("label"); } virtual bool locked_audio_format(void) const { return(true); } virtual int supported_io_modes(void) const { return(io_read | io_write); } virtual bool supports_seeking(void) const { return(false); } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const { return(finished_rep); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; virtual void start_io(void); virtual void stop_io(void); protected: /* functions called by AUDIO_IO_FORKED_STREAM that require * the use of AUDIO_IO methods */ virtual bool do_supports_seeking(void) const { return supports_seeking(); } virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { set_position_in_samples(pos); } private: bool triggered_rep; bool finished_rep; long int bytes_rep; int filedes_rep; FILE* f1_rep; void fork_input_process(void); void fork_output_process(void); }; #endif ecasound-2.9.1/libecasound/audiofx_lv2_world.h0000644000076400007640000000177411740524567016373 00000000000000#ifndef ECA_LV2_WORLD_H #define ECA_LV2_WORLD_H #if ECA_USE_LIBLILV #include class ECA_LV2_WORLD { static ECA_LV2_WORLD i; public: static LilvWorld* World(); static LilvNode* AudioClassNode(); static LilvNode* ControlClassNode(); static LilvNode* InputClassNode(); static LilvNode* OutputClassNode(); static LilvNode* InPlaceBrokenNode(); static LilvNode* PortToggledNode(); static LilvNode* PortIntegerNode(); static LilvNode* PortLogarithmicNode(); static LilvNode* PortSamplerateDependentNode(); static LilvNode* PortConnectionOptionalNode(); private: ECA_LV2_WORLD(); ~ECA_LV2_WORLD(); LilvWorld* lilvworld; LilvNode* audioclassnode; LilvNode* controlclassnode; LilvNode* inputclassnode; LilvNode* outputclassnode; LilvNode* inplacebrokennode; LilvNode* porttogglednode; LilvNode* portintegernode; LilvNode* portlogarithmicnode; LilvNode* portsampleratedependentnode; LilvNode* portconnectionoptionalnode; }; #endif /* ECA_USE_LIBLILV */ #endif // ECA_LV2_WORLD_H ecasound-2.9.1/libecasound/audiofx.h0000644000076400007640000000203210664032032014346 00000000000000#ifndef INCLUDED_AUDIOFX_H #define INCLUDED_AUDIOFX_H #include "eca-chainop.h" #include "eca-samplerate-aware.h" /** * Virtual base for all audio effect classes. * * @author Kai Vehmanen */ class EFFECT_BASE : public CHAIN_OPERATOR, public ECA_SAMPLERATE_AWARE { public: /** @name Constructors and destructors */ /*@{*/ EFFECT_BASE(void); virtual ~EFFECT_BASE(void); /*@}*/ protected: /** @name Protected functions for storing channel count */ /*@{*/ void set_channels(int v); /*@}*/ public: /** @name Public virtual functions to notify about changes * (Reimplemented from ECA_SAMPLERATE_AWARE) */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ /** @name Public virtual functions for initialization * (Reimplemented from CHAIN_OPERATOR) */ /*@{*/ virtual void init(SAMPLE_BUFFER* sbuf); /*@}*/ /** @name Public non-virtual functions */ /*@{*/ int channels(void) const; /*@}*/ private: int channels_rep; }; #endif ecasound-2.9.1/libecasound/eca-error.h0000644000076400007640000000220410664032032014567 00000000000000#ifndef INCLUDED_ECA_ERROR_H #define INCLUDED_ECA_ERROR_H #include using std::string; /** * A general exception class for error reporting. */ class ECA_ERROR { public: // ------------------------------ // error type / suggested action: // ------------------------------ // stop = a critical error (can't allocate memory, etc), program // should exit at once // retry = action failed (badly formatted data, invalid user input, // etc), no need to stop the whole program // notice = action succeeded but something unusual occured enum Action { stop, retry, notice }; private: std::string esection_rep; std::string eerrormsg_rep; Action eaction_rep; public: const std::string& error_section(void) const { return(esection_rep); } const std::string& error_message(void) const { return(eerrormsg_rep); } const Action& error_action(void) const { return(eaction_rep); } ECA_ERROR(const std::string& section, const std::string& errormsg, const Action action = ECA_ERROR::retry) { esection_rep = section; eerrormsg_rep = errormsg; eaction_rep = action; } }; #endif ecasound-2.9.1/libecasound/audioio-db-buffer.h0000644000076400007640000000124211162535466016211 00000000000000#ifndef INCLUDED_AUDIOIO_DB_BUFFER_H #define INCLUDED_AUDIOIO_DB_BUFFER_H #include #include "audioio.h" class SAMPLE_BUFFER; /** * Buffer used between db server and client */ class AUDIO_IO_DB_BUFFER { public: ATOMIC_INTEGER readptr_rep; ATOMIC_INTEGER writeptr_rep; ATOMIC_INTEGER finished_rep; std::vector sbufs_rep; AUDIO_IO::Io_mode io_mode_rep; void reset(void); int read_space(void); int write_space(void); void advance_read_pointer(void); void advance_write_pointer(void); AUDIO_IO_DB_BUFFER(int number_of_buffers, long int buffersize, int channels); ~AUDIO_IO_DB_BUFFER(void); }; #endif ecasound-2.9.1/libecasound/eca-chainsetup-position.cpp0000644000076400007640000000506112201477764020020 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup-position.cpp: Global chainsetup position // Copyright (C) 1999-2003 Kai Vehmanen // // 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 #include /* ceil() */ #include "eca-chainsetup-position.h" ECA_CHAINSETUP_POSITION::ECA_CHAINSETUP_POSITION(void) { looping_rep = false; max_length_set_rep = false; } ECA_CHAINSETUP_POSITION::~ECA_CHAINSETUP_POSITION(void) { } SAMPLE_SPECS::sample_pos_t ECA_CHAINSETUP_POSITION::max_length_in_samples(void) const { return(max_length_in_samples_rep); } double ECA_CHAINSETUP_POSITION::max_length_in_seconds_exact(void) const { return((double)max_length_in_samples_rep / (double)samples_per_second()); } /** * Explicitly sets the chainsetup length (in seconds). * * A special-case value of '-1 * srate' can be used to override * a previously set chainsetup length. * * @post ((pos == -1 * samples_per_second()) && (max_length_set() != true)) || * (max_length_set() == true) */ void ECA_CHAINSETUP_POSITION::set_max_length_in_samples(SAMPLE_SPECS::sample_pos_t pos) { max_length_in_samples_rep = pos; if (pos != -1 * samples_per_second()) { max_length_set_rep = true; } else { max_length_set_rep = false; } } void ECA_CHAINSETUP_POSITION::set_max_length_in_seconds(double pos_in_seconds) { set_max_length_in_samples(static_cast(pos_in_seconds * samples_per_second())); } void ECA_CHAINSETUP_POSITION::set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value) { if (max_length_set() == true) { double ratio (new_value); ratio /= samples_per_second(); set_max_length_in_samples(static_cast(max_length_in_samples() * ratio)); } ECA_AUDIO_POSITION::set_samples_per_second(new_value); } ecasound-2.9.1/libecasound/audiofx_misc.h0000644000076400007640000000641110765534164015405 00000000000000#ifndef INCLUDED_AUDIOFX_MISC_H #define INCLUDED_AUDIOFX_MISC_H #include #include "sample-specs.h" #include "samplebuffer_iterators.h" #include "audio-stamp.h" #include "audiofx.h" /** * Adjusts DC-offset. * @author Kai Vehmanen */ class EFFECT_DCFIX : public EFFECT_BASE { private: std::vector deltafixes_rep; SAMPLE_ITERATOR_CHANNEL i_rep; public: virtual std::string name(void) const { return("DC-Fix"); } virtual std::string description(void) const { return("Adjusts DC-offset."); } virtual bool variable_params(void) const { return true; } virtual std::string parameter_names(void) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_DCFIX* clone(void) const { return new EFFECT_DCFIX(*this); } EFFECT_DCFIX* new_expr(void) const { return new EFFECT_DCFIX(); } EFFECT_DCFIX (const EFFECT_DCFIX& x); EFFECT_DCFIX (void); }; /** * Modify audio pitch by altering its length * @author Kai Vehmanen */ class EFFECT_PITCH_SHIFT : public EFFECT_BASE { private: parameter_t pmod_rep; long int target_rate_rep; SAMPLE_BUFFER* sbuf_repp; public: static const int resample_low_limit; virtual std::string name(void) const { return("Pitch shifter"); } virtual std::string description(void) const { return("Modify audio pitch by altering its length."); } virtual std::string parameter_names(void) const { return("change-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); virtual long int max_output_samples(long int i_samples) const; EFFECT_PITCH_SHIFT(void) : pmod_rep(100.0), target_rate_rep(0), sbuf_repp(0) { } EFFECT_PITCH_SHIFT (const EFFECT_PITCH_SHIFT& x); EFFECT_PITCH_SHIFT* clone(void) const { return new EFFECT_PITCH_SHIFT(*this); } EFFECT_PITCH_SHIFT* new_expr(void) const { return new EFFECT_PITCH_SHIFT(); } }; /** * Store an audio stamp object. Otherwise just let's the audio go through. * @author Kai Vehmanen */ class EFFECT_AUDIO_STAMP : public EFFECT_BASE, public AUDIO_STAMP { SAMPLE_BUFFER* sbuf_repp; public: virtual std::string name(void) const { return("Audio stamp"); } virtual std::string description(void) const { return("Takes a snapshot of passing audio buffers."); } virtual std::string parameter_names(void) const { return("stamp-id"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); EFFECT_AUDIO_STAMP(void); EFFECT_AUDIO_STAMP(const EFFECT_AUDIO_STAMP& arg); EFFECT_AUDIO_STAMP* clone(void) const { return new EFFECT_AUDIO_STAMP(*this); } EFFECT_AUDIO_STAMP* new_expr(void) const { return new EFFECT_AUDIO_STAMP(); } }; #endif ecasound-2.9.1/libecasound/generic-controller.cpp0000644000076400007640000000776311034750412017060 00000000000000// ------------------------------------------------------------------------ // generic_controller.cpp: General sources for control signals // Copyright (C) 1999-2002,2005,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include "generic-controller.h" #include "eca-chainop.h" #include "eca-logger.h" /* Debug controller source values */ // #define DEBUG_CONTROLLERS 1 #ifdef DEBUG_CONTROLLERS #define DEBUG_CTRL_STATEMENT(x) x #else #define DEBUG_CTRL_STATEMENT(x) ((void)0) #endif GENERIC_CONTROLLER::GENERIC_CONTROLLER(CONTROLLER_SOURCE* src, OPERATOR* dobj, int par_id, double range_low, double range_high) { source = src; target = dobj; init_called_rep = false; param_id_rep = par_id; rangelow_rep = range_low; rangehigh_rep = range_high; last_value_pos_rep = -1; } void GENERIC_CONTROLLER::init(void) { source->init(); double init_value = target->get_parameter(param_id_rep); init_value = (init_value - rangelow_rep) / (rangehigh_rep - rangelow_rep); source->set_initial_value(init_value); DEBUG_CTRL_STATEMENT(std::cerr << "generic-controller: init type '" << source->name() << "', init_value " << init_value << "." << std::endl); init_called_rep = true; last_value_pos_rep = -1; } CONTROLLER_SOURCE::parameter_t GENERIC_CONTROLLER::value(double pos) { // -------- DBC_REQUIRE(is_valid() == true); // -------- double new_value = rangelow_rep + (source->value(pos) * (rangehigh_rep - rangelow_rep)); DEBUG_CTRL_STATEMENT(std::cerr << "generic-controller: type '" << source->name() << "', pos_sec " << pos << ", source_value " << source->value(pos) << ", scaled_value " << new_value << "." << std::endl); target->set_parameter(param_id_rep, new_value); last_value_pos_rep = pos; return new_value; } string GENERIC_CONTROLLER::status(void) const { if (is_valid() == true) { double value = -1.0f; if (last_value_pos_rep > 0) { value = source->value(last_value_pos_rep); } return "Source \"" + source->name() + "\" connected to target \"" + target->name() + "\"." + " Current source value is " + kvu_numtostr(value) + " and target " + kvu_numtostr(target->get_parameter(param_id_rep)) + "."; } else { return "Controller not valid."; } } void GENERIC_CONTROLLER::assign_target(OPERATOR* obj) { target = obj; } void GENERIC_CONTROLLER::assign_source(CONTROLLER_SOURCE* obj) { if (init_called_rep == true && source != obj) init(); source = obj; } void GENERIC_CONTROLLER::set_parameter(int param, CHAIN_OPERATOR::parameter_t v) { switch (param) { case 1: param_id_rep = static_cast(v); break; case 2: rangelow_rep = v; break; case 3: rangehigh_rep = v; break; default: source->set_parameter(param - 3, v); } } CHAIN_OPERATOR::parameter_t GENERIC_CONTROLLER::get_parameter(int param) const { switch (param) { case 1: return static_cast(param_id_rep); case 2: return rangelow_rep; case 3: return rangehigh_rep; default: return source->get_parameter(param - 3); } return 0.0; } ecasound-2.9.1/libecasound/sample-ops_impl.h0000644000076400007640000000330410664032032016013 00000000000000// ------------------------------------------------------------------------ // sample-ops_impl.h: Sample value defaults and constants. // Copyright (C) 2004 Kai Vehmanen // Copyright (C) 2004 Steve Harris, Tim Blechmann // // Attributes: // eca-style-version: 2 // public-libecasound-API: no // // 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 INCLUDED_SAMPLE_OPS_IMPL_H #define INCLUDED_SAMPLE_OPS_IMPL_H #include /* 32 bit "pointer cast" union */ typedef union { float f; int32_t i; } ls_pcast32; /** * Truncates small float values 'f' to zero to avoid * denormal floats in processing. * * Taken from swh-plugins 0.4.11 package (ladspa-util.h). * * @author Steve Harris * @author Tim Blechmann */ static inline float ecaops_flush_to_zero(float f) { ls_pcast32 v; v.f = f; // original: return (v.i & 0x7f800000) == 0 ? 0.0f : f; // version from Tim Blechmann return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f; } #endif ecasound-2.9.1/libecasound/audioio-device_test.h0000644000076400007640000000354610664032032016647 00000000000000// ------------------------------------------------------------------------ // audioio-device_test.h: Unit test for AUDIO_IO_DEVICE // Copyright (C) 2002 Kai Vehmanen // // 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 #include "audioio-device.h" #include "eca-object-factory.h" #include "eca-object-map.h" #include "kvu_numtostr.h" #include "eca-logger.h" #include "eca-test-case.h" using namespace std; /** * Unit test for AUDIO_IO_DEVICE. * * FIXME: implementation not ready */ class AUDIO_IO_DEVICE_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for AUDIO_IO_DEVICE"); } virtual void do_run(void); public: virtual ~AUDIO_IO_DEVICE(void) { } }; void AUDIO_IO_DEVICETEST::do_run(void) { /** * - like audioio_test.h, but with additional tests for prepare, * start and stop member functions * - generate different permutations of 'audio_format' and * 'buffersize' - especially buffersize can cause problems * to devices * - test prefilling (if supported) * - verify that position_in_samples increases during * processing */ } ecasound-2.9.1/libecasound/audiofx_amplitude_test.h0000644000076400007640000000732711167617621017501 00000000000000// ------------------------------------------------------------------------ // audiofx_amplitu_test.h: Unit tests for EFFECT_AMPLIFY* classes // Copyright (C) 2009 Kai Vehmanen // // 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 #include #include #include #include #include #include "kvu_dbc.h" #include "kvu_inttypes.h" #include "audiofx_amplitude.h" #include "samplebuffer_functions.h" #include "eca-test-case.h" using namespace std; /** * Unit test for EFFECT_AMPLIFY */ class EFFECT_AMPLIFY_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("EFFECT_AMPLIFY"); } virtual void do_run(void); public: virtual ~EFFECT_AMPLIFY_TEST(void) { } private: }; void EFFECT_AMPLIFY_TEST::do_run(void) { const int bufsize = 1024; const int channels = 12; const SAMPLE_BUFFER::sample_t multiplier = 112.1f; std::fprintf(stdout, "%s: tests for %s class\n", name().c_str(), __FILE__); /* case: multiply_by */ { std::fprintf(stdout, "%s: EFFECT_AMPLIFY::process\n", __FILE__); SAMPLE_BUFFER sbuf_test (bufsize, channels); SAMPLE_BUFFER sbuf_ref (bufsize, channels); EFFECT_AMPLIFY amp_test; EFFECT_AMPLIFY amp_ref; SAMPLE_BUFFER_FUNCTIONS::fill_with_random_samples(&sbuf_ref); sbuf_test.copy_all_content(sbuf_ref); amp_test.init(&sbuf_test); amp_ref.init(&sbuf_ref); amp_test.set_parameter(1, multiplier); amp_ref.set_parameter(1, multiplier); amp_test.process(); amp_ref.process_ref(); if (SAMPLE_BUFFER_FUNCTIONS::is_almost_equal(sbuf_ref, sbuf_test) != true) { ECA_TEST_FAILURE("optimized EFFECT_AMPLIFY"); } } } /** * Unit test for EFFECT_AMPLIFY_CHANNEL */ class EFFECT_AMPLIFY_CHANNEL_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("EFFECT_AMPLIFY_CHANNEL"); } virtual void do_run(void); public: virtual ~EFFECT_AMPLIFY_CHANNEL_TEST(void) { } private: }; void EFFECT_AMPLIFY_CHANNEL_TEST::do_run(void) { const int bufsize = 1024; const int channels = 12; const SAMPLE_BUFFER::sample_t multiplier = 112.1f; std::fprintf(stdout, "%s: tests for %s class\n", name().c_str(), __FILE__); /* case: process() */ { std::fprintf(stdout, "%s: process()\n", __FILE__); SAMPLE_BUFFER sbuf_test (bufsize, channels); SAMPLE_BUFFER sbuf_ref (bufsize, channels); EFFECT_AMPLIFY_CHANNEL amp_test; EFFECT_AMPLIFY_CHANNEL amp_ref; SAMPLE_BUFFER_FUNCTIONS::fill_with_random_samples(&sbuf_ref); sbuf_test.copy_all_content(sbuf_ref); amp_test.init(&sbuf_test); amp_ref.init(&sbuf_ref); amp_test.set_parameter(1, multiplier); amp_test.set_parameter(2, 3); amp_ref.set_parameter(1, multiplier); amp_ref.set_parameter(2, 3); amp_test.process(); amp_ref.process_ref(); if (SAMPLE_BUFFER_FUNCTIONS::is_almost_equal(sbuf_ref, sbuf_test) != true) { ECA_TEST_FAILURE("optimized process()"); } } } ecasound-2.9.1/libecasound/eca-iamode-parser.cpp0000644000076400007640000005075011762501733016543 00000000000000// ------------------------------------------------------------------------ // eca-iamode-parser.cpp: Class that handles registering and querying // interactive mode commands. // Copyright (C) 1999-2005,2008,2012 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "kvu_message_item.h" #include "kvu_locks.h" #include "eca-iamode-parser.h" #include "eca-logger.h" using namespace std; map* ECA_IAMODE_PARSER::cmd_map_repp = 0; pthread_mutex_t ECA_IAMODE_PARSER::lock_rep = PTHREAD_MUTEX_INITIALIZER; ECA_IAMODE_PARSER::ECA_IAMODE_PARSER(void) { } ECA_IAMODE_PARSER::~ECA_IAMODE_PARSER(void) { } const map& ECA_IAMODE_PARSER::registered_commands(void) { // // Note! Below we use the Double-Checked Locking Pattern // to protect against concurrent access if (cmd_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_IAMODE_PARSER::lock_rep); if (cmd_map_repp == 0) { cmd_map_repp = new map; register_commands_misc(); register_commands_cs(); register_commands_c(); register_commands_aio(); register_commands_ai(); register_commands_ao(); register_commands_cop(); register_commands_copp(); register_commands_ctrl(); register_commands_ctrlp(); register_commands_dump(); register_commands_external(); } } return *cmd_map_repp; } vector ECA_IAMODE_PARSER::registered_commands_list(void) { vector cmdlist; const map& map_ref = ECA_IAMODE_PARSER::registered_commands(); map::const_iterator p = map_ref.begin(); while (p != map_ref.end()) { cmdlist.push_back(p->first); ++p; } return cmdlist; } void ECA_IAMODE_PARSER::register_commands_misc(void) { (*cmd_map_repp)["help"] = ec_help; (*cmd_map_repp)["?"] = ec_help; (*cmd_map_repp)["h"] = ec_help; (*cmd_map_repp)["quit"] = ec_exit; (*cmd_map_repp)["q"] = ec_exit; (*cmd_map_repp)["start"] = ec_start; (*cmd_map_repp)["t"] = ec_start; (*cmd_map_repp)["stop"] = ec_stop; (*cmd_map_repp)["s"] = ec_stop; (*cmd_map_repp)["stop-sync"] = ec_stop_sync; (*cmd_map_repp)["run"] = ec_run; (*cmd_map_repp)["debug"] = ec_debug; (*cmd_map_repp)["resource-file"] = ec_resource_file; (*cmd_map_repp)["engine-launch"] = ec_engine_launch; (*cmd_map_repp)["engine-halt"] = ec_engine_halt; (*cmd_map_repp)["engine-status"] = ec_engine_status; (*cmd_map_repp)["status"] = ec_cs_status; (*cmd_map_repp)["st"] = ec_cs_status; (*cmd_map_repp)["cs"] = ec_c_status; (*cmd_map_repp)["es"] = ec_cop_status; (*cmd_map_repp)["fs"] = ec_aio_status; (*cmd_map_repp)["int-cmd-list"] = ec_int_cmd_list; (*cmd_map_repp)["int-log-history"] = ec_int_log_history; (*cmd_map_repp)["int-output-mode-wellformed"] = ec_int_output_mode_wellformed; (*cmd_map_repp)["int-set-float-to-string-precision"] = ec_int_set_float_to_string_precision; (*cmd_map_repp)["int-set-log-history-length"] = ec_int_set_log_history_length; (*cmd_map_repp)["int-version-string"] = ec_int_version_string; (*cmd_map_repp)["int-version-lib-current"] = ec_int_version_lib_current; (*cmd_map_repp)["int-version-lib-revision"] = ec_int_version_lib_revision; (*cmd_map_repp)["int-version-lib-age"] = ec_int_version_lib_age; (*cmd_map_repp)["preset-register"] = ec_preset_register; (*cmd_map_repp)["ladspa-register"] = ec_ladspa_register; (*cmd_map_repp)["lv2-register"] = ec_lv2_register; (*cmd_map_repp)["map-cop-list"] = ec_map_cop_list; (*cmd_map_repp)["map-preset-list"] = ec_map_preset_list; (*cmd_map_repp)["map-ladspa-list"] = ec_map_ladspa_list; (*cmd_map_repp)["map-ladspa-id-list"] = ec_map_ladspa_id_list; (*cmd_map_repp)["map-lv2-list"] = ec_map_lv2_list; (*cmd_map_repp)["map-ctrl-list"] = ec_map_ctrl_list; } void ECA_IAMODE_PARSER::register_commands_cs(void) { (*cmd_map_repp)["cs-add"] = ec_cs_add; (*cmd_map_repp)["cs-remove"] = ec_cs_remove; (*cmd_map_repp)["cs-list"] = ec_cs_list; (*cmd_map_repp)["cs-select"] = ec_cs_select; (*cmd_map_repp)["cs-selected"] = ec_cs_selected; (*cmd_map_repp)["cs-index-select"] = ec_cs_index_select; (*cmd_map_repp)["cs-iselect"] = ec_cs_index_select; (*cmd_map_repp)["cs-load"] = ec_cs_load; (*cmd_map_repp)["cs-save"] = ec_cs_save; (*cmd_map_repp)["cs-save-as"] = ec_cs_save_as; (*cmd_map_repp)["cs-edit"] = ec_cs_edit; (*cmd_map_repp)["cs-is-valid"] = ec_cs_is_valid; (*cmd_map_repp)["cs-connect"] = ec_cs_connect; (*cmd_map_repp)["cs-connected"] = ec_cs_connected; (*cmd_map_repp)["cs-disconnect"] = ec_cs_disconnect; (*cmd_map_repp)["cs-set-param"] = ec_cs_set_param; (*cmd_map_repp)["cs-set-audio-format"] = ec_cs_set_audio_format; (*cmd_map_repp)["cs-status"] = ec_cs_status; (*cmd_map_repp)["cs-rewind"] = ec_cs_rewind; (*cmd_map_repp)["rewind"] = ec_cs_rewind; (*cmd_map_repp)["rw"] = ec_cs_rewind; (*cmd_map_repp)["cs-forward"] = ec_cs_forward; (*cmd_map_repp)["forward"] = ec_cs_forward; (*cmd_map_repp)["fw"] = ec_cs_forward; (*cmd_map_repp)["cs-setpos"] = ec_cs_set_position; (*cmd_map_repp)["cs-set-position"] = ec_cs_set_position; (*cmd_map_repp)["cs-set-position-samples"] = ec_cs_set_position_samples; (*cmd_map_repp)["setpos"] = ec_cs_set_position; (*cmd_map_repp)["set-position"] = ec_cs_set_position; (*cmd_map_repp)["cs-getpos"] = ec_cs_get_position; (*cmd_map_repp)["cs-get-position"] = ec_cs_get_position; (*cmd_map_repp)["cs-get-position-samples"] = ec_cs_get_position_samples; (*cmd_map_repp)["getpos"] = ec_cs_get_position; (*cmd_map_repp)["get-position"] = ec_cs_get_position; (*cmd_map_repp)["cs-get-length"] = ec_cs_get_length; (*cmd_map_repp)["cs-get-length-samples"] = ec_cs_get_length_samples; (*cmd_map_repp)["get-length"] = ec_cs_get_length; (*cmd_map_repp)["cs-set-length"] = ec_cs_set_length; (*cmd_map_repp)["cs-set-length-samples"] = ec_cs_set_length_samples; (*cmd_map_repp)["cs-toggle-loop"] = ec_cs_toggle_loop; (*cmd_map_repp)["cs-option"] = ec_cs_option; } void ECA_IAMODE_PARSER::register_commands_c(void) { (*cmd_map_repp)["c-add"] = ec_c_add; (*cmd_map_repp)["c-remove"] = ec_c_remove; (*cmd_map_repp)["c-list"] = ec_c_list; (*cmd_map_repp)["c-select"] = ec_c_select; (*cmd_map_repp)["c-selected"] = ec_c_selected; (*cmd_map_repp)["c-index-select"] = ec_c_index_select; (*cmd_map_repp)["c-iselect"] = ec_c_index_select; (*cmd_map_repp)["c-deselect"] = ec_c_deselect; (*cmd_map_repp)["c-selected"] = ec_c_selected; (*cmd_map_repp)["c-select-all"] = ec_c_select_all; (*cmd_map_repp)["c-select-add"] = ec_c_select_add; (*cmd_map_repp)["c-clear"] = ec_c_clear; (*cmd_map_repp)["c-rename"] = ec_c_rename; (*cmd_map_repp)["c-muting"] = ec_c_muting; (*cmd_map_repp)["c-mute"] = ec_c_muting; (*cmd_map_repp)["c-bypass"] = ec_c_bypass; (*cmd_map_repp)["c-status"] = ec_c_status; (*cmd_map_repp)["c-is-muted"] = ec_c_is_muted; (*cmd_map_repp)["c-is-bypassed"] = ec_c_is_bypassed; } void ECA_IAMODE_PARSER::register_commands_aio(void) { (*cmd_map_repp)["aio-register"] = ec_aio_register; (*cmd_map_repp)["aio-status"] = ec_aio_status; } void ECA_IAMODE_PARSER::register_commands_ai(void) { (*cmd_map_repp)["ai-add"] = ec_ai_add; (*cmd_map_repp)["ai-describe"] = ec_ai_describe; (*cmd_map_repp)["ai-remove"] = ec_ai_remove; (*cmd_map_repp)["ai-list"] = ec_ai_list; (*cmd_map_repp)["ai-select"] = ec_ai_select; (*cmd_map_repp)["ai-index-select"] = ec_ai_index_select; (*cmd_map_repp)["ai-iselect"] = ec_ai_index_select; (*cmd_map_repp)["ai-selected"] = ec_ai_selected; (*cmd_map_repp)["ai-attach"] = ec_ai_attach; (*cmd_map_repp)["ai-status"] = ec_ai_status; (*cmd_map_repp)["ai-forward"] = ec_ai_forward; (*cmd_map_repp)["ai-rewind"] = ec_ai_rewind; (*cmd_map_repp)["ai-setpos"] = ec_ai_set_position; (*cmd_map_repp)["ai-set-position"] = ec_ai_set_position; (*cmd_map_repp)["ai-set-position-samples"] = ec_ai_set_position_samples; (*cmd_map_repp)["ai-getpos"] = ec_ai_get_position; (*cmd_map_repp)["ai-get-position"] = ec_ai_get_position; (*cmd_map_repp)["ai-get-position-samples"] = ec_ai_get_position_samples; (*cmd_map_repp)["ai-get-length"] = ec_ai_get_length; (*cmd_map_repp)["ai-get-length-samples"] = ec_ai_get_length_samples; (*cmd_map_repp)["ai-get-format"] = ec_ai_get_format; (*cmd_map_repp)["ai-wave-edit"] = ec_ai_wave_edit; } void ECA_IAMODE_PARSER::register_commands_ao(void) { (*cmd_map_repp)["ao-add"] = ec_ao_add; (*cmd_map_repp)["ao-add-default"] = ec_ao_add_default; (*cmd_map_repp)["ao-describe"] = ec_ao_describe; (*cmd_map_repp)["ao-list"] = ec_ao_list; (*cmd_map_repp)["ao-select"] = ec_ao_select; (*cmd_map_repp)["ao-index-select"] = ec_ao_index_select; (*cmd_map_repp)["ao-iselect"] = ec_ao_index_select; (*cmd_map_repp)["ao-selected"] = ec_ao_selected; (*cmd_map_repp)["ao-attach"] = ec_ao_attach; (*cmd_map_repp)["ao-remove"] = ec_ao_remove; (*cmd_map_repp)["ao-status"] = ec_ao_status; (*cmd_map_repp)["ao-forward"] = ec_ao_forward; (*cmd_map_repp)["ao-rewind"] = ec_ao_rewind; (*cmd_map_repp)["ao-setpos"] = ec_ao_set_position; (*cmd_map_repp)["ao-set-position"] = ec_ao_set_position; (*cmd_map_repp)["ao-set-position-samples"] = ec_ao_set_position_samples; (*cmd_map_repp)["ao-getpos"] = ec_ao_get_position; (*cmd_map_repp)["ao-get-position"] = ec_ao_get_position; (*cmd_map_repp)["ao-get-position-samples"] = ec_ao_get_position_samples; (*cmd_map_repp)["ao-get-length"] = ec_ao_get_length; (*cmd_map_repp)["ao-get-length-samples"] = ec_ao_get_length_samples; (*cmd_map_repp)["ao-get-format"] = ec_ao_get_format; (*cmd_map_repp)["ao-wave-edit"] = ec_ao_wave_edit; } void ECA_IAMODE_PARSER::register_commands_cop(void) { (*cmd_map_repp)["cop-add"] = ec_cop_add; (*cmd_map_repp)["cop-bypass"] = ec_cop_bypass; (*cmd_map_repp)["cop-describe"] = ec_cop_describe; (*cmd_map_repp)["cop-remove"] = ec_cop_remove; (*cmd_map_repp)["cop-list"] = ec_cop_list; (*cmd_map_repp)["cop-select"] = ec_cop_select; (*cmd_map_repp)["cop-index-select"] = ec_cop_select; (*cmd_map_repp)["cop-iselect"] = ec_cop_select; (*cmd_map_repp)["cop-is-bypassed"] = ec_cop_is_bypassed; (*cmd_map_repp)["cop-register"] = ec_cop_register; (*cmd_map_repp)["cop-selected"] = ec_cop_selected; (*cmd_map_repp)["cop-set"] = ec_cop_set; (*cmd_map_repp)["cop-get"] = ec_cop_get; (*cmd_map_repp)["cop-status"] = ec_cop_status; } void ECA_IAMODE_PARSER::register_commands_copp(void) { (*cmd_map_repp)["copp-list"] = ec_copp_list; (*cmd_map_repp)["copp-select"] = ec_copp_select; (*cmd_map_repp)["copp-index-select"] = ec_copp_select; (*cmd_map_repp)["copp-iselect"] = ec_copp_select; (*cmd_map_repp)["copp-selected"] = ec_copp_selected; (*cmd_map_repp)["copp-set"] = ec_copp_set; (*cmd_map_repp)["copp-get"] = ec_copp_get; } void ECA_IAMODE_PARSER::register_commands_ctrl(void) { (*cmd_map_repp)["ctrl-add"] = ec_ctrl_add; (*cmd_map_repp)["ctrl-describe"] = ec_ctrl_describe; (*cmd_map_repp)["ctrl-remove"] = ec_ctrl_remove; (*cmd_map_repp)["ctrl-list"] = ec_ctrl_list; (*cmd_map_repp)["ctrl-select"] = ec_ctrl_select; (*cmd_map_repp)["ctrl-index-select"] = ec_ctrl_select; (*cmd_map_repp)["ctrl-iselect"] = ec_ctrl_select; (*cmd_map_repp)["ctrl-register"] = ec_ctrl_register; (*cmd_map_repp)["ctrl-selected"] = ec_ctrl_selected; (*cmd_map_repp)["ctrl-status"] = ec_ctrl_status; (*cmd_map_repp)["ctrl-get-target"] = ec_ctrl_get_target; } void ECA_IAMODE_PARSER::register_commands_ctrlp(void) { (*cmd_map_repp)["ctrlp-list"] = ec_ctrlp_list; (*cmd_map_repp)["ctrlp-select"] = ec_ctrlp_select; (*cmd_map_repp)["ctrlp-selected"] = ec_ctrlp_selected; (*cmd_map_repp)["ctrlp-get"] = ec_ctrlp_get; (*cmd_map_repp)["ctrlp-set"] = ec_ctrlp_set; } void ECA_IAMODE_PARSER::register_commands_dump(void) { (*cmd_map_repp)["dump-target"] = ec_dump_target; (*cmd_map_repp)["dump-status"] = ec_dump_status; (*cmd_map_repp)["dump-position"] = ec_dump_position; (*cmd_map_repp)["dump-length"] = ec_dump_length; (*cmd_map_repp)["dump-cs-status"] = ec_dump_cs_status; (*cmd_map_repp)["dump-c-selected"] = ec_dump_c_selected; (*cmd_map_repp)["dump-ai-selected"] = ec_dump_ai_selected; (*cmd_map_repp)["dump-ai-position"] = ec_dump_ai_position; (*cmd_map_repp)["dump-ai-length"] = ec_dump_ai_length; (*cmd_map_repp)["dump-ai-open-state"] = ec_dump_ai_open_state; (*cmd_map_repp)["dump-ao-selected"] = ec_dump_ao_selected; (*cmd_map_repp)["dump-ao-position"] = ec_dump_ao_position; (*cmd_map_repp)["dump-ao-length"] = ec_dump_ao_length; (*cmd_map_repp)["dump-ao-open-state"] = ec_dump_ao_open_state; (*cmd_map_repp)["dump-cop-value"] = ec_dump_cop_value; } void ECA_IAMODE_PARSER::register_commands_external(void) { #if ECA_COMPILE_JACK (*cmd_map_repp)["jack-connect"] = ec_jack_connect; (*cmd_map_repp)["jack-disconnect"] = ec_jack_disconnect; (*cmd_map_repp)["jack-list-connections"] = ec_jack_list_connections; #endif } int ECA_IAMODE_PARSER::command_to_action_id(const std::string& cmdstring) { return (*cmd_map_repp)[cmdstring]; } bool ECA_IAMODE_PARSER::action_requires_params(int id) { switch(id) { case ec_debug: case ec_cs_add: case ec_cs_select: case ec_cs_index_select: case ec_cs_load: case ec_cs_save_as: case ec_cs_set_param: case ec_cs_set_audio_format: case ec_cs_set_length: case ec_cs_set_length_samples: case ec_cs_rewind: case ec_cs_forward: case ec_cs_set_position: case ec_cs_option: case ec_c_add: case ec_c_select: case ec_c_index_select: case ec_c_deselect: case ec_c_select_add: case ec_c_rename: case ec_ai_add: case ec_ai_select: case ec_ai_index_select: case ec_ai_forward: case ec_ai_rewind: case ec_ai_set_position: case ec_ai_set_position_samples: case ec_ao_add: case ec_ao_select: case ec_ao_index_select: case ec_ao_forward: case ec_ao_rewind: case ec_ao_set_position: case ec_ao_set_position_samples: case ec_cop_add: case ec_cop_select: case ec_cop_set: case ec_cop_get: case ec_copp_select: case ec_copp_set: case ec_ctrl_add: case ec_ctrl_select: case ec_int_set_float_to_string_precision: case ec_dump_target: case ec_dump_cop_value: case ec_jack_connect: case ec_jack_disconnect: return true; default: break; } return false; } bool ECA_IAMODE_PARSER::action_requires_connected(int id) { switch(id) { case ec_engine_launch: case ec_engine_halt: case ec_start: case ec_run: case ec_cs_disconnect: case ec_cs_set_position: case ec_cs_set_position_samples: return true; default: break; } return false; } bool ECA_IAMODE_PARSER::action_requires_selected(int id) { switch(id) { case ec_cs_remove: case ec_cs_edit: case ec_cs_is_valid: case ec_cs_save: case ec_cs_save_as: case ec_cs_connect: case ec_cs_set_param: case ec_cs_rewind: case ec_cs_forward: case ec_cs_set_position: case ec_cs_set_position_samples: case ec_cs_get_position: case ec_cs_get_position_samples: case ec_cs_get_length: case ec_cs_get_length_samples: case ec_cs_set_length: case ec_cs_set_length_samples: case ec_cs_toggle_loop: case ec_cs_option: case ec_c_remove: case ec_c_clear: case ec_c_rename: case ec_c_muting: case ec_c_bypass: case ec_c_status: case ec_c_list: case ec_c_select: case ec_c_selected: case ec_aio_status: case ec_ai_add: case ec_ai_select: case ec_ai_selected: case ec_ai_index_select: case ec_ai_remove: case ec_ai_attach: case ec_ai_status: case ec_ai_forward: case ec_ai_rewind: case ec_ai_set_position: case ec_ai_set_position_samples: case ec_ai_get_position: case ec_ai_get_position_samples: case ec_ai_get_length: case ec_ai_get_length_samples: case ec_ai_get_format: case ec_ai_wave_edit: case ec_ao_add: case ec_ao_add_default: case ec_ao_select: case ec_ao_selected: case ec_ao_index_select: case ec_ao_remove: case ec_ao_attach: case ec_ao_status: case ec_ao_forward: case ec_ao_rewind: case ec_ao_set_position: case ec_ao_set_position_samples: case ec_ao_get_position: case ec_ao_get_position_samples: case ec_ao_get_length: case ec_ao_get_length_samples: case ec_ao_get_format: case ec_ao_wave_edit: case ec_cop_add: case ec_cop_bypass: case ec_cop_is_bypassed: case ec_cop_list: case ec_cop_select: case ec_cop_selected: case ec_cop_set: case ec_cop_get: case ec_cop_status: case ec_copp_list: case ec_copp_select: case ec_copp_selected: case ec_copp_set: case ec_ctrl_add: case ec_ctrl_select: case ec_ctrl_selected: case ec_ctrl_status: return true; default: break; } return false; } bool ECA_IAMODE_PARSER::action_requires_selected_not_connected(int id) { switch(id) { case ec_cs_remove: case ec_cs_set_length: case ec_cs_set_length_samples: case ec_cs_toggle_loop: case ec_cs_set_param: case ec_cs_option: case ec_c_add: case ec_c_remove: case ec_c_rename: case ec_c_clear: case ec_cop_remove: case ec_ctrl_remove: case ec_ai_add: case ec_ai_remove: case ec_ai_attach: case ec_ai_forward: case ec_ai_rewind: case ec_ai_set_position: case ec_ai_set_position_samples: case ec_ai_wave_edit: case ec_ao_add: case ec_ao_add_default: case ec_ao_remove: case ec_ao_attach: case ec_ao_forward: case ec_ao_rewind: case ec_ao_set_position: case ec_ao_set_position_samples: case ec_ao_wave_edit: return true; default: break; } return false; } bool ECA_IAMODE_PARSER::action_requires_selected_audio_input(int id) { switch(id) { case ec_ai_describe: case ec_ai_remove: case ec_ai_attach: case ec_ai_forward: case ec_ai_rewind: case ec_ai_set_position: case ec_ai_set_position_samples: case ec_ai_get_position: case ec_ai_get_position_samples: case ec_ai_selected: case ec_ai_get_length: case ec_ai_get_length_samples: case ec_ai_get_format: case ec_ai_wave_edit: return true; default: break; } return false; } bool ECA_IAMODE_PARSER::action_requires_selected_audio_output(int id) { switch(id) { case ec_ao_describe: case ec_ao_remove: case ec_ao_attach: case ec_ao_forward: case ec_ao_rewind: case ec_ao_set_position: case ec_ao_set_position_samples: case ec_ao_get_position: case ec_ao_get_position_samples: case ec_ao_selected: case ec_ao_get_length: case ec_ao_get_length_samples: case ec_ao_get_format: case ec_ao_wave_edit: return true; default: break; } return false; } void show_controller_help(void) { MESSAGE_ITEM mitem; mitem << "\n-------------------------------------------------------------------"; mitem << "\n ecasound interactive-mode - command reference"; mitem << "\n-------------------------------------------------------------------"; mitem << "\n'q' - Quits ecasound"; mitem << "\n'start', 't' - Processing is started (play)"; mitem << "\n'stop', 's' - Stops processing"; mitem << "\n'rewind time-in-seconds', 'rw time-in-seconds' - Rewind"; mitem << "\n'forward time-in-seconds', 'fw time-in-seconds' - Forward"; mitem << "\n'setpos time-in-seconds' - Sets the current position to 'time-in-seconds' seconds from the beginning."; mitem << "\n'engine-launch' - Initialize and start engine"; mitem << "\n'engine-status' - Engine status"; mitem << "\n'cs-status', 'st' - Chainsetup status"; mitem << "\n'c-status', 'cs' - Chain status"; mitem << "\n'cop-status', 'es' - Chain operator status"; mitem << "\n'ctrl-status' - Controller status"; mitem << "\n'aio-status', 'fs' - Audio input/output status"; mitem << "\n--- see ecasound-iam(1) manual page for more info -----------------\n"; // mitem << "\n'chain chainname', 'c chainname' - Enable/disable the the chain 'chainname'"; ECA_LOG_MSG(ECA_LOGGER::info, mitem.to_string()); } ecasound-2.9.1/libecasound/eca-audio-format.h0000644000076400007640000001047311501252010016023 00000000000000#ifndef INCLUDED_ECA_AUDIO_FORMAT_H #define INCLUDED_ECA_AUDIO_FORMAT_H #include #include "sample-specs.h" #include "eca-samplerate-aware.h" #include "eca-error.h" /** * Class that represents audio format parameters. Audio format * is based on: * * - number of channels * * - channels interleaving * * - representation of individual sample */ class ECA_AUDIO_FORMAT : public ECA_SAMPLERATE_AWARE { public: /** @name Public type definitions and constants */ /*@{*/ /* FIXME: move the Sample* enums to sample-specs.h */ enum Sample_format { sfmt_none, sfmt_u8, sfmt_s8, sfmt_s16, sfmt_s16_le, sfmt_s16_be, sfmt_s24, sfmt_s24_le, sfmt_s24_be, sfmt_s32, sfmt_s32_le, sfmt_s32_be, sfmt_f32, sfmt_f32_le, sfmt_f32_be, sfmt_f64, sfmt_f64_le, sfmt_f64_be }; enum Sample_endianess { se_native, se_big, se_little }; enum Sample_coding { sc_signed, sc_unsigned, sc_float }; /*@}*/ public: /*@}*/ /** @name Constructors and destructors */ /*@{*/ ECA_AUDIO_FORMAT (int ch, long int srate, Sample_format format, bool ileaved = false); ECA_AUDIO_FORMAT (void); virtual ~ECA_AUDIO_FORMAT (void); /*@}*/ /** @name Public functions for getting audio format information */ /*@{*/ /** * Returns frame size in bytes (sample size * channels) */ int frame_size(void) const { return align_rep * channels_rep; } /** * Returns sample size in bytes (size of individual sample value) */ int sample_size(void) const { return align_rep; } /** * How many bits are used to represent one sample value. * Notice! This isn't necessarily sample_size() / 8. For example, * 24bit samples are represented with 32bit values. */ int bits(void) const; /** * Returns sample format specification. See @ref Sample_format */ Sample_format sample_format(void) const; /** * Returns sample coding. See @ref Sample_coding */ Sample_coding sample_coding(void) const { return sc_rep ; } /** * Returns sample endianess. See @ref Sample_endianess */ Sample_endianess sample_endianess(void) const { return se_rep; } /** * Returns sampling rate in bytes per second (data transfer * rate). */ long int bytes_per_second(void) const { return samples_per_second() * align_rep * channels_rep; } /** * Returns number of channels. */ SAMPLE_SPECS::channel_t channels(void) const { return channels_rep; } /** * Are channels interleaved? */ bool interleaved_channels(void) const { return ileaved_rep; } /** * Returns an identical audio format object */ ECA_AUDIO_FORMAT audio_format(void) const; /** * Return the current sample format as a formatted std::string. * * @see set_sample_format */ std::string format_string(void) const; /*@}*/ /** @name Public virtual functions for setting audio format information */ /*@{*/ virtual void set_channels(SAMPLE_SPECS::channel_t v); virtual void set_sample_format(Sample_format v) throw(ECA_ERROR&); virtual void set_audio_format(const ECA_AUDIO_FORMAT& f_str); virtual void toggle_interleaved_channels(bool v); /*@}*/ /** @name Public functions for setting audio format information */ /*@{*/ /** * Sets sample type based on the formatted std::string given as * argument. * * The first letter is either "u", "s" and "f" (unsigned, * signed, floating point). * * The following number specifies sample size in bits. * * If sample is little endian, "_le" is added to the end. * Similarly if big endian, "_be" is added. This postfix * can be omitted if applicable. */ void set_sample_format_string(const std::string& f_str) throw(ECA_ERROR&); /** * Sets the sample endianess to big endian. */ void set_sample_coding(Sample_coding v); /** * Sets the sample endianess to big endian. */ void set_sample_endianess(Sample_endianess v); /*@}*/ private: Sample_format string_to_sample_format(const std::string& str) const throw(ECA_ERROR&); void update_sample_endianess(Sample_endianess v); bool ileaved_rep; SAMPLE_SPECS::channel_t channels_rep; size_t align_rep; // the size of one sample value in bytes Sample_coding sc_rep; Sample_endianess se_rep; }; #endif ecasound-2.9.1/libecasound/audioio-mp3_impl.h0000644000076400007640000000012410664032032016056 00000000000000#ifndef _AUDIOIO_MP3_IMPL_H #define _AUDIOIO_MP3_IMPL_H #include "layer.h" #endif ecasound-2.9.1/libecasound/eca-audio-time_test.h0000644000076400007640000000367311172665015016555 00000000000000// ------------------------------------------------------------------------ // eca-audio-time_test.h: Unit test for ECA_AUDIO_TIME // Copyright (C) 2008 Kai Vehmanen // // 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 #include "kvu_utils.h" /* kvu_sleep() */ #include "eca-audio-time.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_CONTROL. * * FIXME: implementation not ready */ class ECA_AUDIO_TIME_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for ECA_AUDIO_TIME"); } virtual void do_run(void); public: virtual ~ECA_AUDIO_TIME_TEST(void) { } private: }; void ECA_AUDIO_TIME_TEST::do_run(void) { cerr << "libecasound_tester: eca-audio-time" << endl; ECA_AUDIO_TIME v ("88200sa"); v.set_samples_per_second(44100); if (v.samples() != 88200) ECA_TEST_FAILURE("Incorrect sample count (from-samples)."); if (v.seconds() != 2.0f) ECA_TEST_FAILURE("Incorrect time in seconds (from-samples)."); v.set_time_string("2.0"); if (v.samples() != 88200) ECA_TEST_FAILURE("Incorrect sample count (from-secs)."); if (v.seconds() != 2.0f) ECA_TEST_FAILURE("Incorrect time in seconds (from-secs)."); } ecasound-2.9.1/libecasound/midi-cc.cpp0000644000076400007640000000715411034532045014562 00000000000000// ------------------------------------------------------------------------ // midi-cc.cpp: Interface to MIDI continuous controllers // Copyright (C) 1999,2001-2002,2005,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // This program is fre 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 #include #include #include // #include "eca-midi.h" #include "midi-client.h" #include "midi-server.h" #include "midi-cc.h" #include "eca-logger.h" CONTROLLER_SOURCE::parameter_t MIDI_CONTROLLER::value(double pos) { DBC_CHECK(server() != 0); parameter_t value_rep = init_value_rep; if (server() != 0) { if (trace_request_rep == true) { server()->add_controller_trace(channel_rep, controller_rep, static_cast(value_rep * 127.0)); trace_request_rep = false; } value_rep = static_cast(server()->last_controller_value(channel_rep, controller_rep)); value_rep /= 127.0; } return value_rep; } void MIDI_CONTROLLER::set_initial_value(parameter_t arg) { init_value_rep = arg; if (server() != 0) { server()->add_controller_trace(channel_rep, controller_rep, static_cast(init_value_rep * 127.0)); } else { /* add controller trace when server is available */ trace_request_rep = true; } } MIDI_CONTROLLER::MIDI_CONTROLLER(int controller_number, int midi_channel) : controller_rep(controller_number), channel_rep(midi_channel), init_value_rep(0.0), trace_request_rep(false) { } void MIDI_CONTROLLER::init(void) { MESSAGE_ITEM otemp; otemp << "MIDI-controller initialized using controller "; otemp.setprecision(0); otemp << controller_rep << " and channel " << channel_rep << "."; ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } void MIDI_CONTROLLER::set_parameter(int param, CONTROLLER_SOURCE::parameter_t value) { /* FIXME: we should really remove unused ctrl+channel traces */ switch (param) { case 1: controller_rep = static_cast(value); if (controller_rep < 0 || controller_rep > 127) { controller_rep = 1; ECA_LOG_MSG(ECA_LOGGER::info, "(midi-cc) Controller number must be a number between 0 and 127. Defaulting to controller 0"); } break; case 2: channel_rep = static_cast(value); if (channel_rep < 1 || channel_rep > 16) { channel_rep = 1; ECA_LOG_MSG(ECA_LOGGER::info, "(midi-cc) MIDI-channel must be a number between 1 and 16. Defaulting to channel 1."); } --channel_rep; /* map from 1...16 -> 0...15 */ break; } trace_request_rep = true; } CONTROLLER_SOURCE::parameter_t MIDI_CONTROLLER::get_parameter(int param) const { switch (param) { case 1: return static_cast(controller_rep); case 2: /* map from 0...15 -> 1...16 */ return static_cast(channel_rep + 1); } return 0.0; } ecasound-2.9.1/libecasound/eca-version.cpp0000644000076400007640000000050010664032032015453 00000000000000#ifdef HAVE_CONFIG_H #include #endif #include "eca-version.h" const long int ecasound_library_version_current = LIBECASOUND_VERSION; const long int ecasound_library_version_revision = 0; const long int ecasound_library_version_age = LIBECASOUND_VERSION_AGE; const char* ecasound_library_version = VERSION; ecasound-2.9.1/libecasound/eca-sample-conversion_test.h0000644000076400007640000001456711501140617020160 00000000000000// ------------------------------------------------------------------------ // eca-sample-conversion_test.h: Unit test for sample conversion routines // Copyright (C) 2002,2010 Kai Vehmanen // // 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 #include #include "eca-sample-conversion.h" #include "kvu_numtostr.h" #include "eca-logger.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_SAMPLE-CONVERSION. */ class ECA_SAMPLE_CONVERSION_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for eca-sample-conversion"); } virtual void do_run(void); public: virtual ~ECA_SAMPLE_CONVERSION_TEST(void) { } }; void ECA_SAMPLE_CONVERSION_TEST::do_run(void) { double dmax = 1.0f; double dmin = -1.0f; double dzero = 0.0f; bool verbose = false; if (getenv("V") != NULL) verbose = true; uint8_t u8min = eca_sample_convert_float_to_u8(dmin); if (verbose) cout << "-unity to u8 =" << (int)u8min << "\n"; if (abs((int)(u8min - UINT8_MIN)) > 1) { ECA_TEST_FAILURE("abs(u8min - UINT8_MIN) > 1"); } uint8_t u8max = eca_sample_convert_float_to_u8(dmax); if (verbose) cout << "unity to u8 =" << (int)u8max << "\n"; if (abs((int)(u8max - UINT8_MAX)) > 1) { ECA_TEST_FAILURE("abs(u8max - UINT8_MAX) > 1"); } uint8_t u8zero = eca_sample_convert_float_to_u8(dzero); if (verbose) cout << "zero to u8 =" << (int)u8zero << "\n"; if (u8zero != 128) { ECA_TEST_FAILURE("u8zero != 128"); } int16_t s16min = eca_sample_convert_float_to_s16(dmin); if (verbose) cout << "-unity to s16 =" << s16min << "\n"; if (abs(s16min - INT16_MIN) > 1) { ECA_TEST_FAILURE("abs(s16min - INT16_MIN) > 1"); } int16_t s16max = eca_sample_convert_float_to_s16(dmax); if (verbose) cout << "unity to s16 =" << s16max << "\n"; if (abs(s16max - INT16_MAX) > 1) { ECA_TEST_FAILURE("abs(s16max - INT16_MAX) > 1"); } int16_t s16zero = eca_sample_convert_float_to_s16(dzero); if (verbose) cout << "zero to s16 =" << s16zero << "\n"; if (s16zero != 0) { ECA_TEST_FAILURE("s16zero != 0"); } int32_t s32min = eca_sample_convert_float_to_s32(dmin); if (verbose) cout << "-unity to s32 =" << s32min << "\n"; if (labs(s32min - INT32_MIN) > 1) { ECA_TEST_FAILURE("labs(s32min - INT32_MIN) > 1"); } int32_t s32max = eca_sample_convert_float_to_s32(dmax); if (verbose) cout << "unity to s32 =" << s32max << "\n"; if (labs(s32max - INT32_MAX) > 1) { ECA_TEST_FAILURE("labs(s32max - INT32_MAX) > 1"); } int32_t s32zero = eca_sample_convert_float_to_s32(dzero); if (verbose) cout << "zero to s32 =" << s16zero << "\n"; if (s32zero != 0) { ECA_TEST_FAILURE("s32zero != 0"); } float cur = eca_sample_convert_u8_to_float(UINT8_MIN); if (verbose) cout << "u8min to float =" << cur << "\n"; if (cur > -1.0f || cur < -1.0f) { ECA_TEST_FAILURE("to_float: u8min"); } cur = eca_sample_convert_u8_to_float(UINT8_MAX); if (verbose) cout << "u8max to float =" << cur << "\n"; if (cur > 1.0f) { ECA_TEST_FAILURE("to_float: u8max"); } cur = eca_sample_convert_s16_to_float(INT16_MIN); if (verbose) cout << "s16min to float =" << cur << "\n"; if (cur > -1.0f || cur < -1.0f) { if (verbose) cout << "s16min to float: WARNING, suspect value\n"; // ECA_TEST_FAILURE("to_float: s16min"); } cur = eca_sample_convert_s16_to_float(INT16_MIN + 1); if (verbose) cout << "s16min+1 to float =" << cur << "\n"; if (cur > -1.0f || cur < -1.0f) { if (verbose) cout << "s16min+1 to float: WARNING, suspect value\n"; // ECA_TEST_FAILURE("to_float: s16min"); } cur = eca_sample_convert_s16_to_float(INT16_MAX); if (verbose) cout << "s16max to float =" << cur << "\n"; if (cur > 1.0f) { ECA_TEST_FAILURE("to_float: s16max"); } cur = eca_sample_convert_s32_to_float(INT32_MIN + 1); if (verbose) cout << "s32min+1 to float =" << cur << "\n"; if (cur > -1.0f || cur < -1.0f) { ECA_TEST_FAILURE("to_float: s32min+1"); } cur = eca_sample_convert_s32_to_float(INT32_MIN); if (verbose) cout << "s32min to float =" << cur << "\n"; if (cur > -1.0f || cur < -1.0f) { ECA_TEST_FAILURE("to_float: s32min"); } cur = eca_sample_convert_s32_to_float(INT32_MAX); if (verbose) cout << "s32max to float =" << cur << "\n"; if (cur < 1.0f || cur > 1.0f) { ECA_TEST_FAILURE("to_float: s32max"); } #define S16INTFLOATINT(y) \ { \ float mid = eca_sample_convert_s16_to_float(y); \ int16_t res = eca_sample_convert_float_to_s16(mid); \ if (verbose) cout << "s16 ifi " << (y) << " to " << mid << " to " << res << endl; \ if (res != (y)) { \ if (verbose) cout << "s16 ifi: WARNING, suspect value\n"; \ /* report_failure(__FILE__, __LINE__, "s16 ifi" + kvu_numtostr(y)); */ \ } \ } S16INTFLOATINT(INT16_MAX); S16INTFLOATINT(-INT16_MAX); S16INTFLOATINT(INT16_MIN); S16INTFLOATINT(0); S16INTFLOATINT(1); S16INTFLOATINT(1 << 8); S16INTFLOATINT(-1); S16INTFLOATINT(-1 << 8); #define S32INTFLOATINT(y) \ { \ float mid = eca_sample_convert_s32_to_float(y); \ int32_t res = eca_sample_convert_float_to_s32(mid); \ cout << "s32 ifi " << (y) << " to " << mid << " to " << res << endl; \ if (res != (y)) { \ if (verbose) cout << "s32 ifi: WARNING, suspect value\n"; \ /*report_failure(__FILE__, __LINE__, "s32 ifi " + kvu_numtostr(y)); */ \ } \ } S32INTFLOATINT(INT32_MAX); S32INTFLOATINT(-INT32_MAX); S32INTFLOATINT(INT32_MIN); S32INTFLOATINT(0); S32INTFLOATINT(1); S32INTFLOATINT(1 << 8); S32INTFLOATINT(1 << 16); S32INTFLOATINT(-1 << 20); S32INTFLOATINT(-1); S32INTFLOATINT(-1 << 8); S32INTFLOATINT(-1 << 16); S32INTFLOATINT(-1 << 20); } ecasound-2.9.1/libecasound/eca-object-factory.h0000644000076400007640000000704111740524567016374 00000000000000#ifndef INCLUDED_ECA_OBJECT_FACTORY_H #define INCLUDED_ECA_OBJECT_FACTORY_H #include #include #include #include /** * Forward declarations */ class AUDIO_IO; class CHAIN_OPERATOR; class ECA_AUDIO_FORMAT; class ECA_OBJECT; class ECA_OBJECT_MAP; class ECA_PRESET_MAP; class EFFECT_LADSPA; class GENERIC_CONTROLLER; class OPERATOR; class LOOP_DEVICE; class MIDI_IO; class PRESET; /** * Abstract factory for creating libecasound objects. * Implemented as a static singleton class. * * Related design patterns: * - Abstract Factory (GoF87) * - Singleton (GoF127) * * @author Kai Vehmanen */ class ECA_OBJECT_FACTORY { public: /** * @name Functions for accessing object map instances * * Note! Return value is a reference to avoid * accidental deletion of the singleton objects. **/ /*@{*/ static ECA_OBJECT_MAP& audio_io_rt_map(void); static ECA_OBJECT_MAP& audio_io_nonrt_map(void); static ECA_OBJECT_MAP& chain_operator_map(void); static ECA_OBJECT_MAP& lv2_plugin_map(void); static ECA_OBJECT_MAP& ladspa_plugin_map(void); static ECA_OBJECT_MAP& ladspa_plugin_id_map(void); static ECA_PRESET_MAP& preset_map(void); static ECA_OBJECT_MAP& controller_map(void); static ECA_OBJECT_MAP& midi_device_map(void); /*@}*/ /** @name Functions for creating objects based on EOS (Ecasound Option Syntax) strings. */ /*@{*/ static AUDIO_IO* create_audio_object(const std::string& arg); static MIDI_IO* create_midi_device(const std::string& arg); static AUDIO_IO* create_loop_output(const std::string& argu, std::map* loop_map); static AUDIO_IO* create_loop_input(const std::string& argu, std::map* loop_map); static CHAIN_OPERATOR* create_chain_operator (const std::string& arg); static CHAIN_OPERATOR* create_ladspa_plugin (const std::string& arg); static CHAIN_OPERATOR* create_lv2_plugin (const std::string& arg); static GENERIC_CONTROLLER* create_controller (const std::string& arg); /*@}*/ /** @name Functions for creating EOS strings */ /*@{*/ static std::string probe_default_output_device(void); /*@}*/ /** @name Functions for describing existing objects with EOS strings */ /*@{*/ static std::string chain_operator_to_eos(const CHAIN_OPERATOR* chainop); static std::string controller_to_eos(const GENERIC_CONTROLLER* gctrl); static std::string operator_parameters_to_eos(const OPERATOR* chainop); static std::string audio_format_to_eos(const ECA_AUDIO_FORMAT* aformat); static std::string audio_object_to_eos(const AUDIO_IO* aiod, const std::string& direction); static std::string audio_object_format_to_eos(const AUDIO_IO* aiod); /*@}*/ private: static ECA_OBJECT_MAP* audio_io_rt_map_repp; static ECA_OBJECT_MAP* audio_io_nonrt_map_repp; static ECA_OBJECT_MAP* chain_operator_map_repp; static ECA_OBJECT_MAP* lv2_plugin_map_repp; static ECA_OBJECT_MAP* ladspa_plugin_map_repp; static ECA_OBJECT_MAP* ladspa_plugin_id_map_repp; static ECA_PRESET_MAP* preset_map_repp; static ECA_OBJECT_MAP* controller_map_repp; static ECA_OBJECT_MAP* midi_device_map_repp; static pthread_mutex_t lock_rep; /** * @name Constructors and destructors * * To prevent accidental use, located in private scope and * without a valid definition. */ /*@{*/ ECA_OBJECT_FACTORY(void); ECA_OBJECT_FACTORY(const ECA_OBJECT_FACTORY&); ECA_OBJECT_FACTORY& operator=(const ECA_OBJECT_FACTORY&); ~ECA_OBJECT_FACTORY(void); /*@}*/ }; #endif /* INCLUDED_ECA_OBJECT_FACTORY_H */ ecasound-2.9.1/libecasound/audioio-oss.cpp0000644000076400007640000002343711053111343015505 00000000000000// ------------------------------------------------------------------------ // audioio-oss.cpp: OSS (/dev/dsp) input/output. // Copyright (C) 1999-2004,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "audioio-oss_impl.h" #include "audioio-oss.h" #include "eca-error.h" #include "eca-logger.h" OSSDEVICE::OSSDEVICE(const std::string& name, bool precise_sample_rates) { set_label(name); precise_srate_mode = precise_sample_rates; } OSSDEVICE::~OSSDEVICE(void) { if (is_open() == true && is_running()) stop(); if (is_open() == true) { close(); } } OSSDEVICE* OSSDEVICE::clone(void) const { OSSDEVICE* target = new OSSDEVICE(label(), precise_srate_mode); return target; } void OSSDEVICE::open(void) throw(AUDIO_IO::SETUP_ERROR &) { if (io_mode() == io_read) { if ((audio_fd = ::open(label().c_str(), O_RDONLY, 0)) == -1) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-OSS: unable to open OSS-device to O_RDONLY (" + kvu_numtostr(errno) + ")")); } } else if (io_mode() == io_write) { if ((audio_fd = ::open(label().c_str(), O_WRONLY, 0)) == -1) { // Opening device failed perror("(eca-oss)"); throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-OSS: unable to open OSS-device to O_RWONLY (" + kvu_numtostr(errno) + ")")); } } else { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-OSS: Simultanious intput/output not supported.")); } // ------------------------------------------------------------------- // Check capabilities if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &oss_caps) == -1) { oss_caps = 0; ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: OSS-device doesn't support SNDCTL_DSP_GETCAPS."); } // ------------------------------------------------------------------- // Set triggering #ifndef ECA_DISABLE_OSS_TRIGGER if ((oss_caps & DSP_CAP_TRIGGER) == DSP_CAP_TRIGGER) { if (io_mode() == io_read) { int enable_bits = ~PCM_ENABLE_INPUT; // This disables recording if (::ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-OSS: OSS-device doesn't support SNDCTL_DSP_SETTRIGGER (" + kvu_numtostr(errno) + ")")); } else if (io_mode() == io_write) { int enable_bits = ~PCM_ENABLE_OUTPUT; // This disables playback if (::ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-OSS: OSS-device doesn't support SNDCTL_DSP_SETTRIGGER (" + kvu_numtostr(errno) + ")")); } } else { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: OSS-device doesn't support SNDCTL_DSP_SETTRIGGER!"); } #endif // ------------------------------------------------------------------- // Set fragment size. if (buffersize() == 0) throw(SETUP_ERROR(SETUP_ERROR::buffersize, "AUDIOIO-OSS: Buffersize() is 0!")); if (max_buffers() == true) fragment_count = (1 << 15) / buffersize() / frame_size(); // 0x7fff = not limited else fragment_count = 3; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Setting OSS fragment size according to " + kvu_numtostr(buffersize()) + "."); // fr_size == 4 -> the minimum fragment size: 2^4 = 16 bytes unsigned short int fr_size = 4; for(int fragtotal = 16; fragtotal < static_cast(buffersize() * frame_size()); fr_size++) fragtotal = fragtotal * 2; int fragsize = ((fragment_count << 16) | fr_size); if (::ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)==-1) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: OSS-device doesn't support SNDCTL_DSP_SETFRAGMENT!"); ECA_LOG_MSG(ECA_LOGGER::user_objects, "set OSS fragment size to (2^x) " + kvu_numtostr(fr_size) + "."); // ------------------------------------------------------------------- // Select audio format int format; switch(sample_format()) { case ECA_AUDIO_FORMAT::sfmt_u8: { format = AFMT_U8; break; } case ECA_AUDIO_FORMAT::sfmt_s8: { format = AFMT_S8; break; } case ECA_AUDIO_FORMAT::sfmt_s16_le: { format = AFMT_S16_LE; break; } case ECA_AUDIO_FORMAT::sfmt_s16_be: { format = AFMT_S16_BE; break; } case ECA_AUDIO_FORMAT::sfmt_s32_le: { format = AFMT_S32_LE; break; } case ECA_AUDIO_FORMAT::sfmt_s32_be: { format = AFMT_S32_BE; break; } default: { throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-OSS: audio format not supported (1)")); } } int f = format; if (::ioctl(audio_fd, SNDCTL_DSP_SETFMT, &f)==-1) throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-OSS: audio format not supported (2)")); if (f != format) throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-OSS: audio format not supported (2)")); // ------------------------------------------------------------------- // Select number of channels int stereo; /* 0=mono, 1=stereo */ if (channels() > 1) stereo = 1; else stereo = 0; int t = stereo; if (::ioctl(audio_fd, SNDCTL_DSP_STEREO, &t)==-1) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Error when setting sample rate."); if (stereo != t) throw(SETUP_ERROR(SETUP_ERROR::channels, "AUDIOIO-OSS: audio format not supported SNDCTL_DSP_STEREO")); // ------------------------------------------------------------------- // Select sample rate // --- int speed = samples_per_second(); if (::ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed) == -1) throw(SETUP_ERROR(SETUP_ERROR::sample_rate, "AUDIOIO-OSS: audio format not supported SNDCTL_DSP_SPEED")); if (speed != samples_per_second()) { if (precise_srate_mode) { throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-OSS: Requested sample rate is not supported. Audio device suggests sample rate of " + kvu_numtostr(speed) + ". Disable precise-sample-rate mode to ignore the difference.")); } else { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Requested sample rate is not supported. Ignoring the the difference between requested (" + kvu_numtostr(samples_per_second()) + ") and suggested (" + kvu_numtostr(speed) + ") sample rates."); } } // ------------------------------------------------------------------- // Get fragment size. if (::ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size) == -1) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: SNDCTL_DSP_GETBLKSIZE ioctl failed. Might affect OSS audio input/output."); ECA_LOG_MSG(ECA_LOGGER::user_objects, "OSS set to use fragment size of " + kvu_numtostr(fragment_size) + "."); /* SNDCTL_DSP_GET[IO]PTR report offset since device was opened */ set_position_in_samples(0); AUDIO_IO_DEVICE::open(); } void OSSDEVICE::stop(void) { // FIXME: should close and re-open the device - otherwise triggering // won't work properly (see OSS adv.prog.guide) ::ioctl(audio_fd, SNDCTL_DSP_POST, 0); ECA_LOG_MSG(ECA_LOGGER::user_objects,"Audio device \"" + label() + "\" disabled."); AUDIO_IO_DEVICE::stop(); } void OSSDEVICE::close(void) { if (is_prepared() == true && is_running() == true) stop(); ::close(audio_fd); AUDIO_IO_DEVICE::close(); } void OSSDEVICE::start(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects,"Audio device \"" + label() + "\" started."); #ifndef ECA_DISABLE_OSS_TRIGGER if ((oss_caps & DSP_CAP_TRIGGER) == DSP_CAP_TRIGGER) { int enable_bits; if (io_mode() == io_read) enable_bits = PCM_ENABLE_INPUT; else if (io_mode() == io_write) enable_bits = PCM_ENABLE_OUTPUT; ::ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &enable_bits); } #endif gettimeofday(&start_time, NULL); AUDIO_IO_DEVICE::start(); } long int OSSDEVICE::delay(void) const { long int delay = 0; if (is_running() == true) { if ((oss_caps & DSP_CAP_REALTIME) == DSP_CAP_REALTIME) { count_info info; info.bytes = 0; if (io_mode() == io_read) { ::ioctl(audio_fd, SNDCTL_DSP_GETIPTR, &info); delay = static_cast (info.bytes / frame_size()) - position_in_samples(); } else { ::ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info); delay = position_in_samples() - static_cast(info.bytes / frame_size()); } } else { struct timeval now; gettimeofday(&now, NULL); double time = now.tv_sec * 1000000.0 + now.tv_usec - start_time.tv_sec * 1000000.0 - start_time.tv_usec; if (io_mode() == io_read) delay = static_cast(time * samples_per_second() / 1000000.0) - position_in_samples(); else delay = position_in_samples() - static_cast(time * samples_per_second() / 1000000.0); } } DBC_CHECK(delay >= 0); return delay; } long int OSSDEVICE::read_samples(void* target_buffer, long int samples) { return ::read(audio_fd,target_buffer, frame_size() * samples) / frame_size(); } void OSSDEVICE::write_samples(void* target_buffer, long int samples) { ::write(audio_fd, target_buffer, frame_size() * samples); } ecasound-2.9.1/libecasound/eca-control_test.h0000644000076400007640000000617411172665025016200 00000000000000// ------------------------------------------------------------------------ // eca-control_test.h: Unit test for ECA_CONTROL // Copyright (C) 2002 Kai Vehmanen // // 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 #include "kvu_utils.h" /* kvu_sleep() */ #include "eca-session.h" #include "eca-control.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_CONTROL. * * FIXME: implementation not ready */ class ECA_CONTROL_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for ECA_CONTROL"); } virtual void do_run(void); public: virtual ~ECA_CONTROL_TEST(void) { } private: void do_run_chainsetup_creation(void); }; void ECA_CONTROL_TEST::do_run(void) { cout << "libecasound_tester: eca-control - chainsetup creation stress test" << endl; do_run_chainsetup_creation(); } void ECA_CONTROL_TEST::do_run_chainsetup_creation(void) { ECA_SESSION *esession = new ECA_SESSION(); ECA_CONTROL *ectrl = new ECA_CONTROL(esession); int iterations = 15; for(int i = 0; i < iterations; i++) { cout << "libecasound_tester: do_run_chainsetup_creation() iteration " << i + 1 << " of " << iterations << "." << endl; ectrl->add_chainsetup("default"); if (ectrl->is_selected() != true) ECA_TEST_FAILURE("Chainsetup creation failed."); ectrl->add_chain("default"); if (ectrl->selected_chains().size() != 1 || ectrl->selected_chains()[0] != "default") ECA_TEST_FAILURE("Chain addition failed."); ectrl->add_audio_input("null"); ectrl->add_audio_output("null"); ectrl->add_chain_operator("-ea:100"); if (ectrl->selected_chain_operator() < 0 || ectrl->selected_chain_operator() > 1) ECA_TEST_FAILURE("Chain operator addition failed."); ectrl->connect_chainsetup(0); if (ectrl->is_connected() != true) ECA_TEST_FAILURE("Chainsetup connection failed."); ectrl->start(); kvu_sleep(0, 200000000); /* 200ms */ if (ectrl->is_running() != true) ECA_TEST_FAILURE("Chainsetup start failed."); ectrl->stop_on_condition(); if (ectrl->is_running() == true) ECA_TEST_FAILURE("Chainsetup stop failed."); ectrl->disconnect_chainsetup(); if (ectrl->is_connected() == true) ECA_TEST_FAILURE("Chainsetup disconnection failed."); ectrl->remove_chainsetup(); if (ectrl->chainsetup_names().size() > 0) ECA_TEST_FAILURE("Chainsetup removal failed."); } delete ectrl; delete esession; } ecasound-2.9.1/libecasound/audioio-seqbase.h0000644000076400007640000001052011433025723015766 00000000000000#ifndef INCLUDED_AUDIOIO_SEQUENCER_BASE_H #define INCLUDED_AUDIOIO_SEQUENCER_BASE_H #include #include "audioio-proxy.h" #include "samplebuffer.h" #include "eca-audio-time.h" /** * Base class for audio sequencer objects. * * Audio sequencer objects open one or more child objects * and alter the sequence of audio that is read from them. * Common operations are changing the position (inserting * silence at start, slicing), and looping of segments. * * The child objects also implement the AUDIO_IO interface, * or one of the more specialized subclasses. * * Related design patterns: * - Proxy (GoF207) * * @author Kai Vehmanen */ class AUDIO_SEQUENCER_BASE : public AUDIO_IO_PROXY { public: /** @name Public functions */ /*@{*/ AUDIO_SEQUENCER_BASE (); virtual ~AUDIO_SEQUENCER_BASE(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ /* Pure virtual class, not implemented */ /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ /* none */ /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_SEQUENCER_BASE* clone(void) const; virtual AUDIO_SEQUENCER_BASE* new_expr(void) const { return new AUDIO_SEQUENCER_BASE(); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual bool finite_length_stream(void) const; virtual bool finished(void) const; virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); /*@}*/ /** @name New functions */ /*@{*/ /** * Sets the child object to open. Argument 'v' should * be a string suitable for passing to ECA_OBJECT_MAP::object(), * i.e. a Ecasound Option Syntax (EOS) string. */ void set_child_object_string(const std::string& v); const std::string& child_object_string(void) const { return child_object_str_rep; } /** * Sets start offset for the child object. * * At this offset, samples from the child start to * be read. * * If not set, defaults to zero offset (start * consuming child object samples from the beginning). */ void set_child_offset(const ECA_AUDIO_TIME& v); const ECA_AUDIO_TIME& child_offset(void) const { return child_offset_rep; } /** * Set start position inside child object. * * This is the position, within the child object, where * first samples will be read. * * If not set, defaults to zero (read from start of * child object). */ void set_child_start_position(const ECA_AUDIO_TIME& v); const ECA_AUDIO_TIME& child_start_position(void) const { return child_start_pos_rep; } /** * Set the child length. * * If not set, defaults to the total length of * the child object. * * @see reset_child_length(void); */ void set_child_length(const ECA_AUDIO_TIME& v); /** * Returns the child length. * * Note that in the case that child length is infinite, * the returned object may be invalid (ECA_AUDIO_TIME::valid() * returns false). So caller must check validity of * the returned value before using it. */ ECA_AUDIO_TIME child_length(void) const; /** * Toggle whether child object data is looped. */ void toggle_looping(bool v) { child_looping_rep = v; } bool child_looping(void) const { return child_looping_rep; } /*@}*/ protected: void dump_child_debug(const char *tag); void set_child_length_private(const ECA_AUDIO_TIME& v); SAMPLE_SPECS::sample_pos_t priv_public_to_child_pos(SAMPLE_SPECS::sample_pos_t pubpos) const; private: SAMPLE_BUFFER tmp_buffer; bool child_looping_rep; ECA_AUDIO_TIME child_offset_rep, child_start_pos_rep, child_length_rep; bool child_length_set_by_client_rep; std::string child_object_str_rep; long int buffersize_rep; bool child_write_started; bool init_rep; void change_child_name(const string& child_name) throw(AUDIO_IO::SETUP_ERROR &); AUDIO_SEQUENCER_BASE& operator=(const AUDIO_SEQUENCER_BASE& x) { return *this; } AUDIO_SEQUENCER_BASE (const AUDIO_SEQUENCER_BASE& x) { } }; #endif ecasound-2.9.1/libecasound/audiofx_reverb.cpp0000644000076400007640000001337111755705076016277 00000000000000// ------------------------------------------------------------------------ // audiofx_reverb.cpp: Reverb effect // Copyright (C) 2000 Stefan Fendt // Copyright (C) 2000,2003,2008 Kai Vehmanen (C++ version) // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // // ------------------------------------------------------------------------ // History: // // 2003-01-19 Kai Vehmanen // - Added param hint information. // 2002-12-04 Hans-Georg Fischer // - Fixed a bug in initializing the delay line, which cause // unwanted audible noise at start of processing. // 2000-06-06 Kai Vehmanen // - Initial version. Based on Stefan M. Fendt's reverb // code. // ------------------------------------------------------------------------ #include #include "sample-ops_impl.h" #include "samplebuffer_iterators.h" #include "sample-specs.h" #include "audiofx_reverb.h" ADVANCED_REVERB::ADVANCED_REVERB (parameter_t roomsize, parameter_t feedback_percent, parameter_t wet_percent) { set_parameter(1, roomsize); set_parameter(2, feedback_percent); set_parameter(3, wet_percent); } void ADVANCED_REVERB::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 10.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; // pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 2: pd->default_value = 50.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 3: pd->default_value = 50.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: {} } } CHAIN_OPERATOR::parameter_t ADVANCED_REVERB::get_parameter(int param) const { switch (param) { case 1: return roomsize_rep; case 2: return feedback_rep * 100.0; case 3: return wet_rep * 100.0; } return 0.0; } void ADVANCED_REVERB::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: roomsize_rep = value; break; case 2: if (value == 0) feedback_rep = 0.001; else feedback_rep = value / 100.0; break; case 3: wet_rep = value / 100.0; break; } if (param == 1 || param == 2) { std::vector::iterator p = cdata.begin(); while(p != cdata.end()) { p->oldvalue=0.0; p->lpvalue=0.0; p->dpos[0] = static_cast(roomsize_rep * samples_per_second() / 333); p->mul[0] = 0.035; p->bufferpos_rep = 0; for(int i = 1; i < 64; i++) { p->dpos[i] = p->dpos[i-1] + (rand() & 511); p->mul[i] = p->mul[i-1] * (1 - 1 / feedback_rep / 1000); } ++p; } } } void ADVANCED_REVERB::init(SAMPLE_BUFFER *insample) { i_channels.init(insample); cdata.resize(insample->number_of_channels()); std::vector::iterator p = cdata.begin(); while(p != cdata.end()) { p->oldvalue=0.0; p->lpvalue=0.0; p->dpos[0] = static_cast(roomsize_rep * samples_per_second() / 333); p->mul[0] = 0.035; p->bufferpos_rep = 0; for(size_t i = 0; i < p->buffer.size(); i++) p->buffer[i] = 0.0f; for(int i = 1; i < 64; i++) { p->dpos[i] = p->dpos[i-1] + (rand() & 511); p->mul[i] = p->mul[i-1] * (1 - 1 / feedback_rep / 1000); } ++p; } } void ADVANCED_REVERB::process(void) { i_channels.begin(); while(!i_channels.end()) { int ch = i_channels.channel(); cdata[ch].bufferpos_rep++; cdata[ch].bufferpos_rep &= 65535; double old_value = cdata[ch].oldvalue; cdata[ch].buffer[cdata[ch].bufferpos_rep] = ecaops_flush_to_zero(*i_channels.current() + old_value); old_value = 0.0; for(int i = 0; i < 64; i++) { old_value += static_cast(cdata[ch].buffer[(cdata[ch].bufferpos_rep - cdata[ch].dpos[i]) & 65535] * cdata[ch].mul[i]); } /** * This is just a very simple high-pass-filter to remove offsets * which can accour during calculation of the echos */ cdata[ch].lpvalue = ecaops_flush_to_zero(cdata[ch].lpvalue * 0.99 + old_value * 0.01); old_value = old_value - cdata[ch].lpvalue; /** * This is a simple lowpass to make the apearence of the reverb * more realistic... (Walls do not reflect high frequencies very * well at all...) */ cdata[ch].oldvalue = ecaops_flush_to_zero(cdata[ch].oldvalue * 0.75 + old_value * 0.25); *i_channels.current() = cdata[ch].oldvalue * wet_rep + *i_channels.current() * (1 - wet_rep); i_channels.next(); } } ecasound-2.9.1/libecasound/audiofx_lv2.cpp0000644000076400007640000002413011744575411015504 00000000000000// ------------------------------------------------------------------------ // audiofx_lv2.cpp: Wrapper class for LV2 plugins // Copyright (C) 2000-2004, 2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #if ECA_USE_LIBLILV #include #include #include #include #include "samplebuffer.h" #include "audiofx_lv2.h" #include "audiofx_lv2_world.h" #include "eca-error.h" #include "eca-logger.h" EFFECT_LV2::EFFECT_LV2 (Lilv::Plugin pdesc) throw(ECA_ERROR&) :plugin_desc(pdesc) { bool inplacebroken=plugin_desc.has_feature(ECA_LV2_WORLD::InPlaceBrokenNode()); if (inplacebroken) { throw(ECA_ERROR("AUDIOFX_LV2", "Inplace-broken plugins not supported.")); } /* FIXME: strip linefeeds and other forbidden characters; write down to * to ECA_OBJECT docs what chars are allowed and what are not... */ Lilv::Node name(plugin_desc.get_name()); name_rep = string(name.as_string()); unique_rep = string(plugin_desc.get_uri().as_string()); Lilv::Node author(plugin_desc.get_author_name()); if(author) { maker_rep = string(author.as_string()); } else { maker_rep = string(); } buffer_repp = 0; init_ports(); } EFFECT_LV2::~EFFECT_LV2 (void) { release(); if (plugin_desc != 0) { for(unsigned int n = 0; n < plugins_rep.size(); n++) { lilv_instance_deactivate(plugins_rep[n]); lilv_instance_free(plugins_rep[n]); } } } std::string EFFECT_LV2::description(void) const { return name_rep + " - Author: '" + maker_rep + "'"; } void EFFECT_LV2::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { DBC_CHECK(param >= 0); DBC_CHECK(param <= static_cast(param_descs_rep.size())); *pd = param_descs_rep[param - 1]; } EFFECT_LV2* EFFECT_LV2::clone(void) const { EFFECT_LV2* result = new EFFECT_LV2(plugin_desc); for(int n = 0; n < number_of_params(); n++) { result->set_parameter(n + 1, get_parameter(n + 1)); } return result; } void EFFECT_LV2::init_ports(void) throw(ECA_ERROR&) { // note: run from plugin constructor port_count_rep = plugin_desc.get_num_ports(); in_audio_ports = 0; out_audio_ports = 0; for(unsigned long m = 0; m < port_count_rep; m++) { Lilv::Port port=plugin_desc.get_port_by_index(m); if(port.is_a(ECA_LV2_WORLD::AudioClassNode())) { if(port.is_a(ECA_LV2_WORLD::InputClassNode())) { ++in_audio_ports; } else if (port.is_a(ECA_LV2_WORLD::OutputClassNode())) { ++out_audio_ports; } } else if (port.is_a(ECA_LV2_WORLD::ControlClassNode())) { struct PARAM_DESCRIPTION pd; parse_parameter_hint_information(plugin_desc,port, &pd); params.push_back(pd.default_value); param_descs_rep.push_back(pd); if (params.size() > 1) param_names_rep += ","; string tmp (kvu_string_search_and_replace(string(pd.description), ",", "\\,")); param_names_rep += kvu_string_search_and_replace(tmp, ":", "\\:"); } else if(!port.has_property(ECA_LV2_WORLD::PortConnectionOptionalNode())){ throw(ECA_ERROR("AUDIOFX_LV2", "Plugin has required ports which are not audio or control ports.")); } } } void EFFECT_LV2::parse_parameter_hint_information(Lilv::Plugin plugin, Lilv::Port p, struct PARAM_DESCRIPTION *pd) { /* if srate not set, use 44.1kHz (used only for calculating * param hint values */ SAMPLE_SPECS::sample_rate_t srate = samples_per_second(); /* FIXME: this is just ugly! */ if (srate <= 0) { srate = 44100; } Lilv::Node name=p.get_name(); /* parameter name */ pd->description =name.as_string(); Lilv::Node deflt(NULL); Lilv::Node min(NULL); Lilv::Node max(NULL); lilv_port_get_range(plugin.me,p.me,&deflt.me,&min.me,&max.me); bool isSRRelative=p.has_property(ECA_LV2_WORLD::PortSamplerateDependentNode()); /* upper and lower bounds */ if (min) { pd->bounded_below = true; pd->lower_bound=min.as_float(); if (isSRRelative) { pd->lower_bound *= srate; } } else { pd->bounded_below = false; } if (max) { pd->bounded_above = true; pd->upper_bound=max.as_float(); if (isSRRelative) { pd->upper_bound *= srate; } } else { pd->bounded_above = false; } /* defaults - case 1 */ if (deflt) { pd->default_value=deflt.as_float(); } /* defaults - case 2 */ else if (min && !max) { if (pd->lower_bound < 0) pd->default_value = 0.0f; else pd->default_value = pd->lower_bound; } /* defaults - case 3 */ else if (!min && max) { if (pd->upper_bound > 0) pd->default_value = 0.0f; else pd->default_value = pd->upper_bound; } /* defaults - case 4 */ else if (max && min) { if (pd->lower_bound < 0 && pd->upper_bound > 0) pd->default_value = 0.0f; else if (pd->lower_bound < 0 && pd->upper_bound < 0) pd->default_value = pd->upper_bound; else pd->default_value = pd->lower_bound; } /* defaults - case 5 */ else { DBC_CHECK(!min && !max); if (isSRRelative) pd->default_value = srate; else pd->default_value = 1.0f; } if (p.has_property(ECA_LV2_WORLD::PortToggledNode())) pd->toggled = true; else pd->toggled = false; if (p.has_property(ECA_LV2_WORLD::PortIntegerNode())) pd->integer = true; else pd->integer = false; if (p.has_property(ECA_LV2_WORLD::PortLogarithmicNode())) pd->logarithmic = true; else pd->logarithmic = false; if (p.is_a(ECA_LV2_WORLD::OutputClassNode())) pd->output = true; else pd->output = false; } void EFFECT_LV2::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { if (param > 0 && (param - 1 < static_cast(params.size()))) { // cerr << "lv2: setting param " << param << " to " << value << "." << endl; params[param - 1] = value; } } CHAIN_OPERATOR::parameter_t EFFECT_LV2::get_parameter(int param) const { if (param > 0 && (param - 1 < static_cast(params.size()))) { // cerr << "lv2: getting param " << param << " with value " << params[param - 1] << "." << endl; return(params[param - 1]); } return(0.0); } int EFFECT_LV2::output_channels(int i_channels) const { // note: We have two separate cases: either one plugin // is instantiated for each channel, or one plugin // per chain. See EFFECT_LV2::init(). if (in_audio_ports > 1 || out_audio_ports > 1) { return out_audio_ports; } return i_channels; } void EFFECT_LV2::init(SAMPLE_BUFFER *insample) { EFFECT_BASE::init(insample); DBC_CHECK(samples_per_second() > 0); if (buffer_repp != insample) { release(); buffer_repp = insample; buffer_repp->get_pointer_reflock(); } if (plugin_desc != 0) { for(unsigned int n = 0; n < plugins_rep.size(); n++) { lilv_instance_deactivate(plugins_rep[n]); lilv_instance_free(plugins_rep[n]); } plugins_rep.clear(); } DBC_CHECK(plugins_rep.size() == 0); if (in_audio_ports > 1 || out_audio_ports > 1) { //Just insert into the first location plugins_rep.push_back(Lilv::Instance(plugin_desc,samples_per_second())); int inport = 0; int outport = 0; for(unsigned long m = 0; m < port_count_rep; m++) { Lilv::Port p= plugin_desc.get_port_by_index(m); if (p.is_a(ECA_LV2_WORLD::AudioClassNode())) { if (p.is_a(ECA_LV2_WORLD::InputClassNode())) { if (inport < channels()) { plugins_rep[0].connect_port(m, buffer_repp->buffer[inport]); } ++inport; } else if(p.is_a(ECA_LV2_WORLD::OutputClassNode())) { if (outport < channels()) { plugins_rep[0].connect_port(m, buffer_repp->buffer[outport]); } ++outport; } } } if (inport > channels()) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: chain has less channels than plugin has input ports (" + name() + ")."); if (outport > channels()) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: chain has less channels than plugin has output ports (" + name() + ")."); } else { for(int n = 0; n < channels(); n++) { plugins_rep.push_back(Lilv::Instance(plugin_desc,samples_per_second())); for(unsigned long m = 0; m < port_count_rep; m++) { Lilv::Port p= plugin_desc.get_port_by_index(m); if (p.is_a(ECA_LV2_WORLD::AudioClassNode())) { plugins_rep[n].connect_port(m,buffer_repp->buffer[n]); } } } } ECA_LOG_MSG(ECA_LOGGER::system_objects, "Instantiated " + kvu_numtostr(plugins_rep.size()) + " LV2 plugin(s), each with " + kvu_numtostr(in_audio_ports) + " audio input port(s) and " + kvu_numtostr(out_audio_ports) + " output port(s), to chain with " + kvu_numtostr(channels()) + " channel(s) and srate of " + kvu_numtostr(samples_per_second()) + "."); int data_index = 0; for(unsigned long m = 0; m < port_count_rep; m++) { Lilv::Port p=plugin_desc.get_port_by_index(m); if (p.is_a(ECA_LV2_WORLD::ControlClassNode())) { for(unsigned int n = 0; n < plugins_rep.size(); n++) { plugins_rep[n].connect_port(m,&(params[data_index])); } ++data_index; } } for(unsigned long m = 0; m < plugins_rep.size(); m++) plugins_rep[m].activate(); } void EFFECT_LV2::release(void) { if (buffer_repp != 0) { buffer_repp->release_pointer_reflock(); } buffer_repp = 0; } void EFFECT_LV2::process(void) { for(unsigned long m = 0; m < plugins_rep.size(); m++) lilv_instance_run(plugins_rep[m], buffer_repp->length_in_samples()); } #endif /* ECA_USE_LIBLILV */ ecasound-2.9.1/libecasound/audiofx_analysis.cpp0000644000076400007640000002704211747067761016640 00000000000000// ------------------------------------------------------------------------ // audiofx_analysis.cpp: Classes for signal analysis // Copyright (C) 1999-2002,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include "samplebuffer_iterators.h" #include "audiofx_analysis.h" #include "audiofx_amplitude.h" #include "eca-logger.h" #include "eca-error.h" using namespace std; static string priv_align_right(const string txt, int width, char padchar) { string res; int pad = width - static_cast(txt.size()); if (pad > 0) { res.resize(pad, padchar); } return res + txt; } struct bucket { const char *name; SAMPLE_SPECS::sample_t threshold; }; #define BUCKET_ENTRY_DB(x) \ { #x, EFFECT_AMPLITUDE::db_to_linear(x) } static struct bucket bucket_table[] = { BUCKET_ENTRY_DB(3), BUCKET_ENTRY_DB(0), BUCKET_ENTRY_DB(-0.1), BUCKET_ENTRY_DB(-3), BUCKET_ENTRY_DB(-6), BUCKET_ENTRY_DB(-10), BUCKET_ENTRY_DB(-20), BUCKET_ENTRY_DB(-30), BUCKET_ENTRY_DB(-60), { "-inf", -1 } }; EFFECT_ANALYSIS::~EFFECT_ANALYSIS(void) { } EFFECT_VOLUME_BUCKETS::EFFECT_VOLUME_BUCKETS (void) { reset_all_stats(); int res = pthread_mutex_init(&lock_rep, NULL); DBC_CHECK(res == 0); } EFFECT_VOLUME_BUCKETS::~EFFECT_VOLUME_BUCKETS (void) { } void EFFECT_VOLUME_BUCKETS::status_entry(const std::vector& buckets, std::string& otemp) const { /* note: is called with 'lock_rep' taken */ for(unsigned int n = 0; n < buckets.size(); n++) { string samples = kvu_numtostr(buckets[n]); otemp += priv_align_right(samples, 8, '_'); #if NEVER_USED_PRINT_PERCENTAGE otemp += " ("; otemp += priv_align_right(kvu_numtostr(100.0f * buckets[n] / num_of_samples[n], 2), 6, '_'); otemp += "%)"; #endif if (n != buckets.size()) otemp += " "; } } void EFFECT_VOLUME_BUCKETS::reset_all_stats(void) { reset_period_stats(); max_pos = max_neg = 0.0f; } void EFFECT_VOLUME_BUCKETS::reset_period_stats(void) { for(unsigned int nm = 0; nm < pos_samples_db.size(); nm++) for(unsigned int ch = 0; ch < pos_samples_db[nm].size(); ch++) pos_samples_db[nm][ch] = 0; for(unsigned int nm = 0; nm < neg_samples_db.size(); nm++) for(unsigned int ch = 0; ch < neg_samples_db[nm].size(); ch++) neg_samples_db[nm][ch] = 0; for(unsigned int nm = 0; nm < num_of_samples.size(); nm++) num_of_samples[nm] = 0; } string EFFECT_VOLUME_BUCKETS::status(void) const { int res = pthread_mutex_lock(&lock_rep); DBC_CHECK(res == 0); std::string status_str; status_str = "-- Amplitude statistics --\n"; status_str += "Pos/neg, count,(%), ch1...n"; for(unsigned j = 0; j < pos_samples_db.size(); j++) { status_str += std::string("\nPos ") + priv_align_right(bucket_table[j].name, 4, ' ') + "dB: "; status_entry(pos_samples_db[j], status_str); } for(unsigned int j = neg_samples_db.size(); j > 0; j--) { status_str += std::string("\nNeg ") + priv_align_right(bucket_table[j-1].name, 4, ' ') + "dB: "; status_entry(neg_samples_db[j-1], status_str); } status_str += std::string("\nTotal.....: "); status_entry(num_of_samples, status_str); status_str += "\n"; status_str += "(audiofx) Peak amplitude: pos=" + kvu_numtostr(max_pos,5) + " neg=" + kvu_numtostr(max_neg,5) + ".\n"; status_str += "(audiofx) Max gain without clipping: " + kvu_numtostr(max_multiplier(),5) + ".\n"; status_str += "(audiofx) -- End of statistics --\n"; res = pthread_mutex_unlock(&lock_rep); DBC_CHECK(res == 0); return status_str; } void EFFECT_VOLUME_BUCKETS::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch(param) { case 1: pd->default_value = 0; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 1.0; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = true; pd->integer = true; pd->logarithmic = false; pd->output = false; break; case 2: pd->default_value = 1.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = false; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = true; break; } } void EFFECT_VOLUME_BUCKETS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { return; } CHAIN_OPERATOR::parameter_t EFFECT_VOLUME_BUCKETS::get_parameter(int param) const { switch (param) { case 1: /* note: always enabled since 2.7.0, but keeping the parameter * still for backwards compatibility */ return 1.0f; case 2: return max_multiplier(); } return 0.0; } CHAIN_OPERATOR::parameter_t EFFECT_VOLUME_BUCKETS::max_multiplier(void) const { parameter_t k; SAMPLE_SPECS::sample_t max_peak = max_pos; if (max_neg > max_pos) max_peak = max_neg; if (max_peak != 0.0f) k = SAMPLE_SPECS::max_amplitude / max_peak; else k = 0.0f; return k; } void EFFECT_VOLUME_BUCKETS::init(SAMPLE_BUFFER* insample) { int res = pthread_mutex_lock(&lock_rep); DBC_CHECK(res == 0); i.init(insample); set_channels(insample->number_of_channels()); DBC_CHECK(channels() == insample->number_of_channels()); num_of_samples.resize(insample->number_of_channels(), 0); int entries = sizeof(bucket_table) / sizeof(struct bucket); pos_samples_db.resize(entries, std::vector (channels())); neg_samples_db.resize(entries, std::vector (channels())); reset_all_stats(); res = pthread_mutex_unlock(&lock_rep); DBC_CHECK(res == 0); EFFECT_ANALYSIS::init(insample); } void EFFECT_VOLUME_BUCKETS::process(void) { DBC_CHECK(static_cast(num_of_samples.size()) == channels()); int res = pthread_mutex_trylock(&lock_rep); if (res == 0) { i.begin(); while(!i.end()) { DBC_CHECK(num_of_samples.size() > static_cast(i.channel())); num_of_samples[i.channel()]++; if (*i.current() >= 0) { if (*i.current() > max_pos) max_pos = *i.current(); for(unsigned j = 0; j < pos_samples_db.size(); j++) { if (*i.current() > bucket_table[j].threshold) { pos_samples_db[j][i.channel()]++; break; } } } else { if (-(*i.current()) > max_neg) max_neg = -(*i.current()); for(unsigned j = 0; j < neg_samples_db.size(); j++) { if (*i.current() < -bucket_table[j].threshold) { neg_samples_db[j][i.channel()]++; break; } } } i.next(); } res = pthread_mutex_unlock(&lock_rep); DBC_CHECK(res == 0); } // else { std::cerr << "(audiofx_analysis) lock taken, skipping process().\n"; } } EFFECT_VOLUME_PEAK::EFFECT_VOLUME_PEAK (void) { max_amplitude_repp = 0; } EFFECT_VOLUME_PEAK::~EFFECT_VOLUME_PEAK (void) { if (max_amplitude_repp != 0) { delete[] max_amplitude_repp; max_amplitude_repp = 0; } } void EFFECT_VOLUME_PEAK::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { if (param > 0 && param <= channels()) { pd->default_value = 0; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = true; } } std::string EFFECT_VOLUME_PEAK::parameter_names(void) const { string params; for(int n = 0; n < channels(); n++) { params += "peak-amplitude-ch" + kvu_numtostr(n + 1); if (n + 1 < channels()) params += ","; } return params; } void EFFECT_VOLUME_PEAK::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { } CHAIN_OPERATOR::parameter_t EFFECT_VOLUME_PEAK::get_parameter(int param) const { if (param > 0 && param <= channels()) { parameter_t temp = max_amplitude_repp[param - 1]; max_amplitude_repp[param - 1] = 0.0f; return temp; } return 0.0f; } void EFFECT_VOLUME_PEAK::init(SAMPLE_BUFFER* insample) { i.init(insample); if (max_amplitude_repp != 0) { delete[] max_amplitude_repp; max_amplitude_repp = 0; } max_amplitude_repp = new parameter_t [insample->number_of_channels()]; set_channels(insample->number_of_channels()); } void EFFECT_VOLUME_PEAK::process(void) { i.begin(); while(!i.end()) { SAMPLE_SPECS::sample_t abscurrent = std::fabs(*i.current()); DBC_CHECK(i.channel() >= 0); DBC_CHECK(i.channel() < channels()); if (abscurrent > max_amplitude_repp[i.channel()]) { max_amplitude_repp[i.channel()] = std::fabs(*i.current()); } i.next(); } } EFFECT_DCFIND::EFFECT_DCFIND (void) { } string EFFECT_DCFIND::status(void) const { MESSAGE_ITEM mitem; mitem.setprecision(5); mitem << "(audiofx) Optimal value for DC-adjust: "; mitem << get_deltafix(SAMPLE_SPECS::ch_left) << " (left), "; mitem << get_deltafix(SAMPLE_SPECS::ch_right) << " (right)."; return mitem.to_string(); } string EFFECT_DCFIND::parameter_names(void) const { std::vector t; for(int n = 0; n < channels(); n++) { t.push_back("result-offset-ch" + kvu_numtostr(n + 1)); } return kvu_vector_to_string(t, ","); } CHAIN_OPERATOR::parameter_t EFFECT_DCFIND::get_deltafix(int channel) const { SAMPLE_SPECS::sample_t deltafix; if (channel < 0 || channel >= static_cast(pos_sum.size()) || channel >= static_cast(neg_sum.size())) return 0.0; if (pos_sum[channel] > neg_sum[channel]) deltafix = -(pos_sum[channel] - neg_sum[channel]) / num_of_samples[channel]; else deltafix = (neg_sum[channel] - pos_sum[channel]) / num_of_samples[channel]; return (CHAIN_OPERATOR::parameter_t)deltafix; } void EFFECT_DCFIND::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { pd->default_value = 0.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = false; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = true; } void EFFECT_DCFIND::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { } CHAIN_OPERATOR::parameter_t EFFECT_DCFIND::get_parameter(int param) const { return get_deltafix(param-1); } void EFFECT_DCFIND::init(SAMPLE_BUFFER *insample) { i.init(insample); set_channels(insample->number_of_channels()); pos_sum.resize(channels()); neg_sum.resize(channels()); num_of_samples.resize(channels()); } void EFFECT_DCFIND::process(void) { i.begin(); while(!i.end()) { tempval = *i.current(); if (tempval > SAMPLE_SPECS::silent_value) pos_sum[i.channel()] += tempval; else neg_sum[i.channel()] += fabs(tempval); num_of_samples[i.channel()]++; i.next(); } } ecasound-2.9.1/libecasound/audioio-rtnull.h0000644000076400007640000000276310664032032015671 00000000000000#ifndef INCLUDED_AUDIOIO_RTNULL_H #define INCLUDED_AUDIOIO_RTNULL_H #include #include "audioio-device.h" /** * Null audio object with realtime behaviour */ class REALTIME_NULL : public AUDIO_IO_DEVICE { public: virtual std::string name(void) const { return("Realtime null device"); } /** @name Function reimplemented from AUDIO_IO */ /*@{*/ virtual void open(void) throw (AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); /*@}*/ /** @name Function reimplemented from AUDIO_IO_DEVICE */ /*@{*/ virtual void prepare(void); virtual void stop(void); virtual void start(void); virtual long int delay(void) const; virtual long int prefill_space(void) const; /*@}*/ REALTIME_NULL(const std::string& name = "realtime null"); virtual ~REALTIME_NULL(void); REALTIME_NULL* clone(void) const { return new REALTIME_NULL(*this); } REALTIME_NULL* new_expr(void) const { return new REALTIME_NULL(); } private: void calculate_device_position(void); void calculate_available_data(void) const; void block_until_data_available(void); int total_buffers_rep; mutable int xruns_rep; struct timeval start_time_rep; struct timeval time_since_start_rep; struct timeval buffer_length_rep; struct timeval total_buffer_length_rep; struct timeval data_processed_rep; mutable struct timeval avail_data_rep; }; #endif ecasound-2.9.1/libecasound/eca-preset-map.cpp0000644000076400007640000001033610664032032016053 00000000000000// ------------------------------------------------------------------------ // eca-preset-map: Dynamic register for storing effect presets // Copyright (C) 2000-2003 Kai Vehmanen // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "eca-object.h" #include "eca-resources.h" #include "eca-preset-map.h" #include "global-preset.h" using std::find; using std::list; using std::map; using std::string; using std::vector; ECA_PRESET_MAP::ECA_PRESET_MAP(void) { #ifndef ECA_DISABLE_EFFECTS ECA_RESOURCES ecarc; string filename = ecarc.resource("user-resource-directory") + "/" + ecarc.resource("resource-file-effect-presets"); string global_filename = ecarc.resource("resource-directory") + "/" + ecarc.resource("resource-file-effect-presets"); load_preset_file(global_filename); load_preset_file(filename); #endif } ECA_PRESET_MAP::~ECA_PRESET_MAP(void) { } void ECA_PRESET_MAP::load_preset_file(const string& fname) { RESOURCE_FILE preset_file; preset_file.resource_file(fname); preset_file.load(); const vector& pmap = preset_file.keywords(); vector::const_iterator p = pmap.begin(); while(p != pmap.end()) { if (*p != "") preset_keywords_rep.push_back(*p); ++p; } } void ECA_PRESET_MAP::register_object(const string& keyword, const string& matchstr, ECA_OBJECT* object) { if (find(preset_keywords_rep.begin(), preset_keywords_rep.end(), keyword) == preset_keywords_rep.end()) preset_keywords_rep.push_back(keyword); ECA_OBJECT_MAP::register_object(keyword, matchstr, object); } void ECA_PRESET_MAP::unregister_object(const string& keyword) { preset_keywords_rep.remove(keyword); ECA_OBJECT_MAP::unregister_object(keyword); } const list& ECA_PRESET_MAP::registered_objects(void) const { return(preset_keywords_rep); } bool ECA_PRESET_MAP::has_keyword(const std::string& keyword) const { if (find(preset_keywords_rep.begin(), preset_keywords_rep.end(), keyword) == preset_keywords_rep.end()) return(false); return (true); } const ECA_OBJECT* ECA_PRESET_MAP::object_expr(const string& expr) const { if (find(preset_keywords_rep.begin(), preset_keywords_rep.end(), expr) != preset_keywords_rep.end()) { return(object(expr)); } return(0); } const ECA_OBJECT* ECA_PRESET_MAP::object(const string& keyword) const { const PRESET* retobj = 0; #ifndef ECA_DISABLE_EFFECTS if (find(preset_keywords_rep.begin(), preset_keywords_rep.end(), keyword) != preset_keywords_rep.end()) { const list& objlist = ECA_OBJECT_MAP::registered_objects(); if (find(objlist.begin(), objlist.end(), keyword) == objlist.end()) { try { PRESET* obj = dynamic_cast(new GLOBAL_PRESET(keyword)); if (obj != 0) { const_cast(this)->register_object(keyword, "^" + keyword + "$", obj); retobj = obj; // std::cerr << "(eca-preset-map) registering obj; " << keyword << ".\n"; } // else std::cerr << "(eca-preset-map) fail (3); " << keyword << ".\n"; } catch(...) { retobj = 0; } DBC_CHECK(find(objlist.begin(), objlist.end(), keyword) != objlist.end() || retobj == 0); } else { retobj = dynamic_cast(ECA_OBJECT_MAP::object(keyword)); // if (retobj == 0) std::cerr << "(eca-preset-map) fail (2); " << keyword << ".\n"; } } // else std::cerr << "(eca-preset-map) fail (1); " << keyword << ".\n"; #endif return(retobj); } ecasound-2.9.1/libecasound/audiofx_mixing.cpp0000644000076400007640000002575511170177120016276 00000000000000// ------------------------------------------------------------------------ // audiofx_mixing.cpp: Effects for channel mixing and routing // Copyright (C) 1999-2002,2006,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include "samplebuffer_iterators.h" #include "audiofx_mixing.h" static EFFECT_MIXING::ch_type priv_from_make_sane(EFFECT_MIXING::ch_type channel, SAMPLE_BUFFER *insample) { EFFECT_MIXING::ch_type channels = static_cast(insample->number_of_channels()); if (channel < 0) return 0; if (channel >= channels) return channels - 1; return channel; } static EFFECT_MIXING::ch_type priv_to_make_sane(EFFECT_MIXING::ch_type channel, SAMPLE_BUFFER *insample) { if (channel < 0) return 0; return channel; } EFFECT_MIXING::~EFFECT_MIXING(void) { } EFFECT_CHANNEL_COPY::EFFECT_CHANNEL_COPY (parameter_t from, parameter_t to) { set_parameter(1, from); set_parameter(2, to); } int EFFECT_CHANNEL_COPY::output_channels(int i_channels) const { int c = static_cast(to_channel > from_channel ? to_channel : from_channel); ++c; return c > i_channels ? c : i_channels; } void EFFECT_CHANNEL_COPY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { pd->default_value = 1; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; } void EFFECT_CHANNEL_COPY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: from_channel = static_cast(value); DBC_CHECK(from_channel > 0); from_channel--; break; case 2: to_channel = static_cast(value); DBC_CHECK(to_channel > 0); to_channel--; break; } } CHAIN_OPERATOR::parameter_t EFFECT_CHANNEL_COPY::get_parameter(int param) const { switch (param) { case 1: return from_channel + 1; case 2: return to_channel + 1; } return 0.0f; } void EFFECT_CHANNEL_COPY::init(SAMPLE_BUFFER *insample) { f_iter.init(insample); t_iter.init(insample); from_channel = priv_from_make_sane(from_channel, insample); to_channel = priv_to_make_sane(to_channel, insample); } void EFFECT_CHANNEL_COPY::process(void) { f_iter.begin(from_channel); t_iter.begin(to_channel); while(!f_iter.end() && !t_iter.end()) { *t_iter.current() = *f_iter.current(); f_iter.next(); t_iter.next(); } } EFFECT_CHANNEL_MOVE::EFFECT_CHANNEL_MOVE (parameter_t from, parameter_t to) { set_parameter(1, from); set_parameter(2, to); } int EFFECT_CHANNEL_MOVE::output_channels(int i_channels) const { int c = static_cast(to_channel > from_channel ? to_channel : from_channel); ++c; return c > i_channels ? c : i_channels; } void EFFECT_CHANNEL_MOVE::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { pd->default_value = 1; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; } void EFFECT_CHANNEL_MOVE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: from_channel = static_cast(value); DBC_CHECK(from_channel > 0); from_channel--; break; case 2: to_channel = static_cast(value); DBC_CHECK(to_channel > 0); to_channel--; break; } } CHAIN_OPERATOR::parameter_t EFFECT_CHANNEL_MOVE::get_parameter(int param) const { switch (param) { case 1: return from_channel + 1; case 2: return to_channel + 1; } return 0.0; } void EFFECT_CHANNEL_MOVE::init(SAMPLE_BUFFER *insample) { f_iter.init(insample); t_iter.init(insample); from_channel = priv_from_make_sane(from_channel, insample); to_channel = priv_to_make_sane(to_channel, insample); } void EFFECT_CHANNEL_MOVE::process(void) { f_iter.begin(from_channel); t_iter.begin(to_channel); while(!f_iter.end() && !t_iter.end()) { *t_iter.current() = *f_iter.current(); if (from_channel != to_channel) *f_iter.current() = SAMPLE_SPECS::silent_value; f_iter.next(); t_iter.next(); } } EFFECT_CHANNEL_MUTE::EFFECT_CHANNEL_MUTE (parameter_t channel) : EFFECT_AMPLIFY_CHANNEL(0, static_cast(channel)) { set_parameter(1, channel); } void EFFECT_CHANNEL_MUTE::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { pd->default_value = 1; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; } void EFFECT_CHANNEL_MUTE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { EFFECT_MIXING::ch_type from_channel; switch (param) { case 1: from_channel = static_cast(value); DBC_CHECK(from_channel > 0); EFFECT_AMPLIFY_CHANNEL::set_parameter(2, from_channel); break; } } CHAIN_OPERATOR::parameter_t EFFECT_CHANNEL_MUTE::get_parameter(int param) const { switch (param) { case 1: return EFFECT_AMPLIFY_CHANNEL::get_parameter(2); } return 0.0; } EFFECT_MIX_TO_CHANNEL::EFFECT_MIX_TO_CHANNEL (parameter_t to) { set_parameter(1, to); } int EFFECT_MIX_TO_CHANNEL::output_channels(int i_channels) const { int c = static_cast(to_channel); ++c; return(c > i_channels ? c : i_channels); } void EFFECT_MIX_TO_CHANNEL::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { pd->default_value = 1; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; } void EFFECT_MIX_TO_CHANNEL::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: to_channel = static_cast(value); DBC_CHECK(to_channel > 0); to_channel--; break; } } CHAIN_OPERATOR::parameter_t EFFECT_MIX_TO_CHANNEL::get_parameter(int param) const { switch (param) { case 1: return to_channel + 1; } return 0.0f; } void EFFECT_MIX_TO_CHANNEL::init(SAMPLE_BUFFER *insample) { i.init(insample); t_iter.init(insample); channels = insample->number_of_channels(); to_channel = priv_to_make_sane(to_channel, insample); } void EFFECT_MIX_TO_CHANNEL::process(void) { i.begin(); t_iter.begin(to_channel); while(!t_iter.end() && !i.end()) { sum = SAMPLE_SPECS::silent_value; for (int n = 0; n < channels; n++) { if (i.end()) break; sum += (*i.current(n)); } *t_iter.current() = sum / channels; i.next(); t_iter.next(); } } EFFECT_CHANNEL_ORDER::EFFECT_CHANNEL_ORDER (void) : sbuf_repp(0), out_channels_rep(0) { } EFFECT_CHANNEL_ORDER* EFFECT_CHANNEL_ORDER::clone(void) const { EFFECT_CHANNEL_ORDER *obj = new EFFECT_CHANNEL_ORDER(); /* note: obj->sbuf_repp is shared but this is ok */ return obj; } int EFFECT_CHANNEL_ORDER::output_channels(int i_channels) const { return out_channels_rep; } void EFFECT_CHANNEL_ORDER::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { /* these apply for all params */ pd->default_value = 1; pd->description = "channel"; pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; } void EFFECT_CHANNEL_ORDER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { int src_ch = static_cast(value); int dst_ch = param; if (dst_ch > 0) { if (dst_ch > static_cast(chsrc_map_rep.size())) { chsrc_map_rep.resize(dst_ch); } chsrc_map_rep[dst_ch - 1] = src_ch - 1; /* step: reset highest non-zero channel */ int n; for(n = chsrc_map_rep.size() - 1; n >= 0; n--) { if (chsrc_map_rep[n] >= 0) break; } out_channels_rep = n + 1; } } CHAIN_OPERATOR::parameter_t EFFECT_CHANNEL_ORDER::get_parameter(int param) const { /* note: we ignore zero-src channel at the end of * chsrc_map_rep to avoid infinite loops in * e.g. ECA_OBJECT_FACTORY */ if (param > 0 && param <= out_channels_rep) { DBC_CHECK(out_channels_rep <= static_cast(chsrc_map_rep.size())); /* return 1...N */ return chsrc_map_rep[param - 1] + 1; } return 0.0; } std::string EFFECT_CHANNEL_ORDER::parameter_names(void) const { std::string params; int ch = 0; while(ch < out_channels_rep) { params += "src-ch-" + kvu_numtostr(ch + 1); ++ch; if (ch != out_channels_rep) params += ","; } return params; //return param_names_rep; } void EFFECT_CHANNEL_ORDER::init(SAMPLE_BUFFER *insample) { sbuf_repp = insample; bouncebuf_rep.number_of_channels(sbuf_repp->number_of_channels()); bouncebuf_rep.length_in_samples(sbuf_repp->length_in_samples()); f_iter.init(&bouncebuf_rep); t_iter.init(insample); } void EFFECT_CHANNEL_ORDER::release(void) { sbuf_repp = 0; } void EFFECT_CHANNEL_ORDER::process(void) { /* step: copy input buffer to a temporary buffer */ bouncebuf_rep.copy_all_content(*sbuf_repp); /* step: route channels bouncebuf_rep -> sbuf_repp */ for(int dst_ch = 0; dst_ch < out_channels_rep; dst_ch++) { int src_ch = chsrc_map_rep[dst_ch]; /* for development use only */ #if 0 std::fprintf(stderr, "%sout#%d <-- in#%d (avail in=%d, out=%d)\n", dst_ch == 0 ? "---\n" : "", dst_ch, src_ch, bouncebuf_rep.number_of_channels(), sbuf_repp->number_of_channels()); #endif if (src_ch >= 0 && src_ch < bouncebuf_rep.number_of_channels()) { f_iter.begin(src_ch); t_iter.begin(dst_ch); while(!f_iter.end() && !t_iter.end()) { *t_iter.current() = *f_iter.current(); f_iter.next(); t_iter.next(); } } else { sbuf_repp->make_silent(dst_ch); } } /* step: make sure output buf has exactly N channels */ sbuf_repp->number_of_channels(out_channels_rep); } ecasound-2.9.1/libecasound/samplebuffer_iterators.cpp0000644000076400007640000000477211161425434020033 00000000000000// ------------------------------------------------------------------------ // audiofx_mixing.cpp: Effects for channel mixing and routing // Copyright (C) 1999-2005,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include "samplebuffer.h" #include "samplebuffer_iterators.h" // --------------------------------------------------------------------- void SAMPLE_ITERATOR::begin(void) { index = 0; channel_index = 0; if (target->buffersize_rep == 0) channel_index = target->channel_count_rep; } void SAMPLE_ITERATOR::next(void) { ++index; if (index == target->buffersize_rep) { ++channel_index; index = 0; } } // --------------------------------------------------------------------- void SAMPLE_ITERATOR_CHANNEL::init(SAMPLE_BUFFER* buf, int channel) { target = buf; index = 0; channel_index = channel; if (channel_index < 0 || channel_index >= target->number_of_channels()) index = target->buffersize_rep; DBC_CHECK(index == 0); } void SAMPLE_ITERATOR_CHANNEL::begin(int channel) { index = 0; channel_index = channel; if (channel_index < 0 || channel_index >= target->number_of_channels()) index = target->buffersize_rep; DBC_CHECK(index == 0); } // --------------------------------------------------------------------- void SAMPLE_ITERATOR_CHANNELS::begin(void) { index = 0; channel_index = 0; if (target->buffersize_rep == 0) channel_index = target->channel_count_rep; } void SAMPLE_ITERATOR_CHANNELS::next(void) { ++index; if (index == target->buffersize_rep) { ++channel_index; index = 0; } } // --------------------------------------------------------------------- ecasound-2.9.1/libecasound/eca-operator.cpp0000644000076400007640000000303410664032032015626 00000000000000// ------------------------------------------------------------------------ // eca-operator.cpp: Operators are ecasound objects which can be used // as targets for dynamic control. // Copyright (C) 2000 Kai Vehmanen // // 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 #include "eca-operator.h" OPERATOR::~OPERATOR (void) { } void OPERATOR::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { DBC_REQUIRE(param > 0); DBC_REQUIRE(param <= number_of_params()); pd->default_value = get_parameter(param); pd->description = get_parameter_name(param); pd->bounded_above = false; pd->upper_bound = 0.0f; pd->bounded_below = false; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; } ecasound-2.9.1/libecasound/audioio-wave.h0000644000076400007640000000672111166131303015310 00000000000000#ifndef INCLUDED_AUDIOIO_WAVE_H #define INCLUDED_AUDIOIO_WAVE_H #include #include #include #include "audioio-buffered.h" #include "samplebuffer.h" #include "eca-fileio.h" /** * Represents a RIFF WAVE -file (wav). * * This class currently supports only a limited set of features: * * Format 1 sample data: Pulse Code Modulation (PCM) Format * * Format 3 sample data: IEEE754 floats, range [-1, +1) * * - multiple channels are interleaved * * - 8, 16, 24 and 32 bit data supported * * - if more than 8 bits, least significant byte first as specified * in the stantard */ class WAVEFILE : public AUDIO_IO_BUFFERED { public: typedef struct { uint16_t format; uint16_t channels; uint32_t srate; uint32_t byte_second; uint16_t align; uint16_t bits; } RF; typedef struct { uint8_t sig[4]; uint32_t bsize; } RB; typedef struct { uint8_t id[4]; uint32_t size; uint8_t wname[4]; } RH; private: ECA_FILE_IO* fio_repp; RH riff_header_rep; RF riff_format_rep; long int data_start_position_rep; std::string mmaptoggle_rep; /** * Do a info query prior to actually opening the device. * * require: * !is_open() * * ensure: * !is_open() * fio == 0 */ void format_query(void) throw(AUDIO_IO::SETUP_ERROR&); enum Format_tags { unknown = (0x0000), pcm = (0x0001), adpcm = (0x0002), ieee_float = (0x0003), alaw = (0x0006), mulaw = (0x0007), oki_adpcm = (0x0010), ima_adpcm = (0x0011), digistd = (0x0015), digifix = (0x0016), dolby_ac2 = (0x0030), gsm610 = (0x0031), rockwell_adpcm = (0x003b), rockwell_digitalk = (0x003c), g721_adpcm = (0x0040), g728_celp = (0x0041), mpeg = (0x0050), mpeglayer3 = (0x0055), g726_adpcm = (0x0064), g722_adpcm = (0x0065) }; public: WAVEFILE (const std::string& name = ""); virtual ~WAVEFILE(void); virtual WAVEFILE* clone(void) const; virtual WAVEFILE* new_expr(void) const { return new WAVEFILE(); } virtual std::string name(void) const { return("RIFF wave file"); } virtual bool locked_audio_format(void) const { return(true); } virtual std::string parameter_names(void) const { return("filename,toggle_mmap"); } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const; virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; private: WAVEFILE(const WAVEFILE& x) { DBC_NEVER_REACHED(); } WAVEFILE& operator=(const WAVEFILE& x) { return(*this); } void update(void); void set_length_in_bytes(void); void read_riff_header (void) throw(AUDIO_IO::SETUP_ERROR&); bool next_riff_block(RB *t, off_t *offtmp); void read_riff_fmt(void) throw(AUDIO_IO::SETUP_ERROR&); void write_riff_header (void) throw(AUDIO_IO::SETUP_ERROR&); void write_riff_fmt(void); void write_riff_datablock(void); void update_riff_datablock(void); void find_riff_datablock (void) throw(AUDIO_IO::SETUP_ERROR&); bool find_block(const char* fblock, uint32_t *blksize); }; #endif ecasound-2.9.1/libecasound/audioio-resample.h0000644000076400007640000000521511161517321016156 00000000000000#ifndef INCLUDED_AUDIOIO_RESAMPLE_H #define INCLUDED_AUDIOIO_RESAMPLE_H #include #include #include #include "samplebuffer.h" #include "audioio-proxy.h" /** * A proxy class that resamples the the child * object's data. * * Related design patterns: * - Proxy (GoF207 * * @author Kai Vehmanen */ class AUDIO_IO_RESAMPLE : public AUDIO_IO_PROXY { public: /** @name Public functions */ /*@{*/ AUDIO_IO_RESAMPLE (void); virtual ~AUDIO_IO_RESAMPLE(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return(string("Resample => ") + child()->name()); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual bool variable_params(void) const { return true; } virtual std::string parameter_names(void) const; virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_IO_RESAMPLE* clone(void) const; virtual AUDIO_IO_RESAMPLE* new_expr(void) const { return(new AUDIO_IO_RESAMPLE()); } /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return(io_read); } virtual bool supports_seeking(void) const { return(true); } virtual bool finite_length_stream(void) const { return(true); } virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual void set_buffersize(long int samples); virtual long int buffersize(void) const; /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_FORMAT */ /*@{*/ virtual void set_audio_format(const ECA_AUDIO_FORMAT& f_str); /*@}*/ /** @name Reimplemented functions from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ private: void recalculate_psfactor(void); mutable std::vector params_rep; bool init_rep; SAMPLE_SPECS::sample_rate_t child_srate_conf_rep; float psfactor_rep; int quality_rep; SAMPLE_BUFFER sbuf_rep; SAMPLE_BUFFER leftoverbuf_rep; static const int child_parameter_offset = 2; AUDIO_IO_RESAMPLE& operator=(const AUDIO_IO_RESAMPLE& x) { return *this; } AUDIO_IO_RESAMPLE (const AUDIO_IO_RESAMPLE& x) { } }; #endif ecasound-2.9.1/libecasound/audiofx_timebased.cpp0000644000076400007640000006027111755705217016745 00000000000000// ------------------------------------------------------------------------ // audiofx_timebased.cpp: Routines for time-based effects. // Copyright (C) 1999-2005,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include "eca-logger.h" #include "samplebuffer_iterators.h" #include "sample-ops_impl.h" #include "audiofx_timebased.h" static void priv_check_for_zerodelay(long int *dtime, OPERATOR::parameter_t *dtime_msec, long int srate) { if (*dtime == 0) { *dtime = 1; *dtime_msec = 1 / (CHAIN_OPERATOR::parameter_t)srate * 1000.0; ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: delay of 0 samples not supported, delay set to 1 sample"); } } EFFECT_DELAY::EFFECT_DELAY (CHAIN_OPERATOR::parameter_t delay_time, int surround_mode, int num_of_delays, CHAIN_OPERATOR::parameter_t mix_percent, CHAIN_OPERATOR::parameter_t feedback_percent) { laskuri = 0.0; set_parameter(1, delay_time); set_parameter(2, surround_mode); set_parameter(3, num_of_delays); set_parameter(4, mix_percent); set_parameter(5, feedback_percent); } void EFFECT_DELAY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 100.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 2: pd->default_value = 0.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 1.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = true; pd->integer = true; pd->logarithmic = false; pd->output = false; break; case 3: pd->default_value = 1.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; // pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; break; case 4: pd->default_value = 50.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 5: pd->default_value = 100.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: {} } } CHAIN_OPERATOR::parameter_t EFFECT_DELAY::get_parameter(int param) const { switch (param) { case 1: return dtime_msec; case 2: return surround; case 3: return dnum; case 4: return mix * 100.0; case 5: return feedback * 100.0; } return 0.0; } void EFFECT_DELAY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: { dtime_msec = value; dtime = dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000; priv_check_for_zerodelay(&dtime, &dtime_msec, samples_per_second()); std::vector >::iterator p = buffer.begin(); while(p != buffer.end()) { std::vector::iterator q = p->begin(); while(q != p->end()) { if (q->size() > static_cast(dtime)) { q->resize(static_cast(dtime)); laskuri = dtime; } ++q; } ++p; } break; } case 2: surround = value; break; case 3: { if (value != 0.0) dnum = static_cast(value); else dnum = 1.0; std::vector >::iterator p = buffer.begin(); while(p != buffer.end()) { p->resize(static_cast(dnum)); ++p; } laskuri = 0; break; } case 4: mix = value / 100.0; break; case 5: if (value == 0 || value > 100) { feedback = 1.0; } else { feedback = value / 100.0; } break; } } void EFFECT_DELAY::init(SAMPLE_BUFFER* insample) { l.init(insample); r.init(insample); EFFECT_BASE::init(insample); set_parameter(1, dtime_msec); buffer.resize(2, std::vector (static_cast(dnum))); for(size_t i = 0; i < buffer.size(); i++) { for(size_t j = 0; j < buffer[i].size(); j++) { buffer[i].clear(); } } } void EFFECT_DELAY::process(void) { l.begin(SAMPLE_SPECS::ch_left); r.begin(SAMPLE_SPECS::ch_right); while(!l.end() && !r.end()) { SAMPLE_SPECS::sample_t temp2_left = 0.0; SAMPLE_SPECS::sample_t temp2_right = 0.0; // Initializing the feedback factor to one. (x*1 = x) SAMPLE_SPECS::sample_t feedfact = 1; for(int nm2 = 0; nm2 < dnum; nm2++) { SAMPLE_SPECS::sample_t temp_left = 0.0; SAMPLE_SPECS::sample_t temp_right = 0.0; // Preparing the factor... feedfact *= feedback; if (laskuri >= dtime * (nm2 + 1)) { switch ((int)surround) { case 0: { // --- // surround temp_left = buffer[SAMPLE_SPECS::ch_left][nm2].front(); temp_right = buffer[SAMPLE_SPECS::ch_right][nm2].front(); break; } case 1: { // --- // surround temp_left = buffer[SAMPLE_SPECS::ch_right][nm2].front(); temp_right = buffer[SAMPLE_SPECS::ch_left][nm2].front(); break; } case 2: { if (nm2 % 2 == 0) { temp_left = (buffer[SAMPLE_SPECS::ch_left][nm2].front() + buffer[SAMPLE_SPECS::ch_right][nm2].front()) / 2.0; temp_right = 0.0; } else { temp_right = (buffer[SAMPLE_SPECS::ch_left][nm2].front() + buffer[SAMPLE_SPECS::ch_right][nm2].front()) / 2.0; temp_left = 0.0; } break; } } // switch // Applying the reduction. temp_left *= feedfact; temp_right *= feedfact; buffer[SAMPLE_SPECS::ch_left][nm2].pop_front(); buffer[SAMPLE_SPECS::ch_right][nm2].pop_front(); } buffer[SAMPLE_SPECS::ch_left][nm2].push_back(*l.current()); buffer[SAMPLE_SPECS::ch_right][nm2].push_back(*r.current()); temp2_left += temp_left / dnum; temp2_right += temp_right / dnum; } *l.current() = (*l.current() * (1.0 - mix)) + (temp2_left * mix); *r.current() = (*r.current() * (1.0 - mix)) + (temp2_right * mix); l.next(); r.next(); if (laskuri < dtime * dnum) laskuri++; } } EFFECT_MULTITAP_DELAY::EFFECT_MULTITAP_DELAY (CHAIN_OPERATOR::parameter_t delay_time, int num_of_delays, CHAIN_OPERATOR::parameter_t mix_percent) : delay_index(0), filled (0), buffer (0) { set_parameter(1, delay_time); set_parameter(2, num_of_delays); set_parameter(3, mix_percent); } void EFFECT_MULTITAP_DELAY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 100.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 2: pd->default_value = 1.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; // pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 1.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; break; case 3: pd->default_value = 50.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: {} } } CHAIN_OPERATOR::parameter_t EFFECT_MULTITAP_DELAY::get_parameter(int param) const { switch (param) { case 1: return dtime_msec; case 2: return dnum; case 3: return mix * 100.0; } return 0.0; } void EFFECT_MULTITAP_DELAY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: { dtime_msec = value; dtime = static_cast(dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000); priv_check_for_zerodelay(&dtime, &dtime_msec, samples_per_second()); DBC_CHECK(buffer.size() == filled.size()); for(int n = 0; n < static_cast(buffer.size()); n++) { if ((dtime * dnum) > static_cast(buffer[n].size())) { buffer[n].resize(dtime * dnum); } delay_index[n] = dtime * dnum - 1; for(int m = 0; m < static_cast(filled[n].size()); m++) { filled[n][m] = false; } } break; } case 2: { if (value != 0.0) dnum = static_cast(value); else dnum = 1; DBC_CHECK(buffer.size() == filled.size()); for(int n = 0; n < static_cast(buffer.size()); n++) { if ((dtime * dnum) > static_cast(buffer[n].size())) { buffer[n].resize(dtime * dnum); } for(int m = 0; m < static_cast(filled[n].size()); m++) { filled[n][m] = false; } delay_index[n] = dtime * dnum - 1; } break; } case 3: mix = value / 100.0; break; } } void EFFECT_MULTITAP_DELAY::init(SAMPLE_BUFFER* insample) { i.init(insample); EFFECT_BASE::init(insample); set_parameter(1, dtime_msec); delay_index.resize(channels(), dtime * dnum - 1); filled.resize(channels(), std::vector (dnum, false)); buffer.resize(channels(), std::vector (dtime * dnum)); for(int i = 0; i < channels(); i++) { delay_index[i] = dtime * dnum - 1; for(size_t j = 0; j < filled[i].size(); j++) filled[i][j] = false; for(size_t j = 0; j < buffer[i].size(); j++) buffer[i][j] = 0.0f; } } void EFFECT_MULTITAP_DELAY::process(void) { long int len = dtime * dnum; i.begin(); while(!i.end()) { for(int n = 0; n < channels(); n++) { SAMPLE_SPECS::sample_t temp1 = 0.0; for(int nm2 = 0; nm2 < dnum; nm2++) { if (filled[n][nm2] == true) { DBC_CHECK((delay_index[n] + nm2 * dtime) % len >= 0); DBC_CHECK((delay_index[n] + nm2 * dtime) % len < len); temp1 += buffer[n][(delay_index[n] + nm2 * dtime) % len]; } } buffer[n][delay_index[n]] = *i.current(n); *i.current(n) = (*i.current(n) * (1.0 - mix)) + (temp1 * mix / dnum); --(delay_index[n]); for(int nm2 = 0; nm2 < dnum; nm2++) { if (delay_index[n] < len - dtime * nm2) filled[n][nm2] = true; } if (delay_index[n] == -1) delay_index[n] = len - 1; } i.next(); } } EFFECT_FAKE_STEREO::EFFECT_FAKE_STEREO (CHAIN_OPERATOR::parameter_t delay_time) { set_parameter(1, delay_time); } void EFFECT_FAKE_STEREO::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 20.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: {} } } CHAIN_OPERATOR::parameter_t EFFECT_FAKE_STEREO::get_parameter(int param) const { switch (param) { case 1: return dtime_msec; } return 0.0; } void EFFECT_FAKE_STEREO::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: dtime_msec = value; dtime = dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000; priv_check_for_zerodelay(&dtime, &dtime_msec, samples_per_second()); std::vector >::iterator p = buffer.begin(); while(p != buffer.end()) { if (p->size() > static_cast(dtime)) { p->resize(static_cast(dtime)); } ++p; } break; } } void EFFECT_FAKE_STEREO::init(SAMPLE_BUFFER* insample) { l.init(insample); r.init(insample); EFFECT_BASE::init(insample); set_parameter(1, dtime_msec); buffer.resize(2); for(size_t i = 0; i < buffer.size(); i++) { for(size_t j = 0; j < buffer[i].size(); j++) { buffer[i].clear(); } } } void EFFECT_FAKE_STEREO::process(void) { l.begin(SAMPLE_SPECS::ch_left); r.begin(SAMPLE_SPECS::ch_right); while(!l.end() && !r.end()) { SAMPLE_SPECS::sample_t temp_left = 0; SAMPLE_SPECS::sample_t temp_right = 0; if (buffer[SAMPLE_SPECS::ch_left].size() >= static_cast(dtime)) { temp_left = buffer[SAMPLE_SPECS::ch_left].front(); temp_right = buffer[SAMPLE_SPECS::ch_right].front(); temp_right = (temp_left + temp_right) / 2.0; temp_left = (*l.current() + *r.current()) / 2.0; buffer[SAMPLE_SPECS::ch_left].pop_front(); buffer[SAMPLE_SPECS::ch_right].pop_front(); } else { temp_left = (*l.current() + *r.current()) / 2.0; temp_right = 0.0; } buffer[SAMPLE_SPECS::ch_left].push_back(*l.current()); buffer[SAMPLE_SPECS::ch_right].push_back(*r.current()); *l.current() = temp_left; *r.current() = temp_right; l.next(); r.next(); } } EFFECT_REVERB::EFFECT_REVERB (CHAIN_OPERATOR::parameter_t delay_time, int surround_mode, CHAIN_OPERATOR::parameter_t feedback_percent) { set_parameter(1, delay_time); set_parameter(2, surround_mode); set_parameter(3, feedback_percent); } void EFFECT_REVERB::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 20.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; // pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 2: pd->default_value = 0.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 1.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = true; pd->integer = true; pd->logarithmic = false; pd->output = false; break; case 3: pd->default_value = 50.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: {} } } CHAIN_OPERATOR::parameter_t EFFECT_REVERB::get_parameter(int param) const { switch (param) { case 1: return dtime_msec; case 2: return surround; case 3: return feedback * 100.0; } return 0.0; } void EFFECT_REVERB::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: { dtime_msec = value; dtime = dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000; priv_check_for_zerodelay(&dtime, &dtime_msec, samples_per_second()); std::vector >::iterator p = buffer.begin(); while(p != buffer.end()) { if (p->size() > static_cast(dtime)) { p->resize(static_cast(dtime)); } ++p; } break; } case 2: surround = value; break; case 3: feedback = value / 100.0; break; } } void EFFECT_REVERB::init(SAMPLE_BUFFER* insample) { l.init(insample); r.init(insample); EFFECT_BASE::init(insample); set_parameter(1, dtime_msec); buffer.resize(2); for(size_t i = 0; i < buffer.size(); i++) { for(size_t j = 0; j < buffer[i].size(); j++) { buffer[i].clear(); } } } void EFFECT_REVERB::process(void) { l.begin(SAMPLE_SPECS::ch_left); r.begin(SAMPLE_SPECS::ch_right); while(!l.end() && !r.end()) { SAMPLE_SPECS::sample_t temp_left = 0.0; SAMPLE_SPECS::sample_t temp_right = 0.0; if (buffer[SAMPLE_SPECS::ch_left].size() >= static_cast(dtime)) { temp_left = buffer[SAMPLE_SPECS::ch_left].front(); temp_right = buffer[SAMPLE_SPECS::ch_right].front(); if (surround == 0) { *l.current() = (*l.current() * (1 - feedback)) + (temp_left * feedback); *r.current() = (*r.current() * (1 - feedback)) + (temp_right * feedback); } else { *l.current() = (*l.current() * (1 - feedback)) + (temp_right * feedback); *r.current() = (*r.current() * (1 - feedback)) + (temp_left * feedback); } buffer[SAMPLE_SPECS::ch_left].pop_front(); buffer[SAMPLE_SPECS::ch_right].pop_front(); } else { *l.current() = (*l.current() * (1 - feedback)); *r.current() = (*r.current() * (1 - feedback)); } *l.current() = ecaops_flush_to_zero(*l.current()); *r.current() = ecaops_flush_to_zero(*r.current()); buffer[SAMPLE_SPECS::ch_left].push_back(*l.current()); buffer[SAMPLE_SPECS::ch_right].push_back(*r.current()); l.next(); r.next(); } } EFFECT_MODULATING_DELAY::EFFECT_MODULATING_DELAY(CHAIN_OPERATOR::parameter_t delay_time, long int vartime_in_samples, CHAIN_OPERATOR::parameter_t feedback_percent, CHAIN_OPERATOR::parameter_t lfo_freq) { set_parameter(1, delay_time); set_parameter(2, vartime_in_samples); set_parameter(3, feedback_percent); set_parameter(4, lfo_freq); } void EFFECT_MODULATING_DELAY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { switch (param) { case 1: pd->default_value = 2.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 2: pd->default_value = 20.0f; pd->description = get_parameter_name(param); pd->bounded_above = false; // pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = true; pd->logarithmic = false; pd->output = false; break; case 3: pd->default_value = 50.0f; pd->description = get_parameter_name(param); pd->bounded_above = true; pd->upper_bound = 100.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; case 4: pd->default_value = 0.4f; pd->description = get_parameter_name(param); pd->bounded_above = false; // pd->upper_bound = 0.0f; pd->bounded_below = true; pd->lower_bound = 0.0f; pd->toggled = false; pd->integer = false; pd->logarithmic = false; pd->output = false; break; default: {} } } CHAIN_OPERATOR::parameter_t EFFECT_MODULATING_DELAY::get_parameter(int param) const { switch (param) { case 1: return dtime_msec; case 2: return vartime; case 3: return feedback * 100.0; case 4: return lfo.get_parameter(1); } return 0.0; } void EFFECT_MODULATING_DELAY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: { dtime_msec = value; dtime = static_cast(dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000); priv_check_for_zerodelay(&dtime, &dtime_msec, samples_per_second()); DBC_CHECK(buffer.size() == delay_index.size()); DBC_CHECK(buffer.size() == filled.size()); for(int n = 0; n < static_cast(buffer.size()); n++) { if (dtime * 2 > static_cast(buffer[n].size())) { buffer[n].resize(dtime * 2); } delay_index[n] = 0; filled[n] = false; } break; } case 2: vartime = value; break; case 3: feedback = value / 100.0; break; case 4: lfo.set_parameter(1, value); break; } } void EFFECT_MODULATING_DELAY::init(SAMPLE_BUFFER* insample) { i.init(insample); lfo.init(); if (samples_per_second() > 0) advance_len_secs_rep = ((double)insample->length_in_samples()) / samples_per_second(); else advance_len_secs_rep = 0; set_parameter(1, dtime_msec); EFFECT_BASE::init(insample); filled.resize(channels(), false); delay_index.resize(channels(), 2 * dtime); buffer.resize(channels(), std::vector (2 * dtime)); for(size_t i = 0; i < buffer.size(); i++) { for(size_t j = 0; j < buffer[i].size(); j++) { buffer[i][j] = 0.0f; } } } void EFFECT_MODULATING_DELAY::process(void) { lfo_pos_secs_rep += advance_len_secs_rep; } void EFFECT_FLANGER::process(void) { EFFECT_MODULATING_DELAY::process(); i.begin(); while(!i.end()) { SAMPLE_SPECS::sample_t temp1 = 0.0; parameter_t p = vartime * lfo.value(lfo_pos_secs_rep); if (filled[i.channel()] == true) { DBC_CHECK((dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2) >= 0); DBC_CHECK((dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2) < static_cast(buffer[i.channel()].size())); temp1 = buffer[i.channel()][(dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2)]; } *i.current() = ecaops_flush_to_zero((*i.current() * (1.0 - feedback)) + (temp1 * feedback)); buffer[i.channel()][delay_index[i.channel()]] = *i.current(); ++(delay_index[i.channel()]); if (delay_index[i.channel()] == 2 * dtime) { delay_index[i.channel()] = 0; filled[i.channel()] = true; } i.next(); } } void EFFECT_CHORUS::process(void) { EFFECT_MODULATING_DELAY::process(); i.begin(); while(!i.end()) { SAMPLE_SPECS::sample_t temp1 = 0.0; parameter_t p = vartime * lfo.value(lfo_pos_secs_rep); if (filled[i.channel()] == true) { DBC_CHECK((dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2) >= 0); DBC_CHECK((dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2) < static_cast(buffer[i.channel()].size())); temp1 = buffer[i.channel()][(dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2)]; } buffer[i.channel()][delay_index[i.channel()]] = *i.current(); *i.current() = (*i.current() * (1.0 - feedback)) + (temp1 * feedback); ++(delay_index[i.channel()]); if (delay_index[i.channel()] == 2 * dtime) { delay_index[i.channel()] = 0; filled[i.channel()] = true; } i.next(); } } void EFFECT_PHASER::process(void) { EFFECT_MODULATING_DELAY::process(); i.begin(); while(!i.end()) { SAMPLE_SPECS::sample_t temp1 = 0.0; parameter_t p = vartime * lfo.value(lfo_pos_secs_rep); if (filled[i.channel()] == true) { DBC_CHECK((dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2) >= 0); DBC_CHECK((dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2) < static_cast(buffer[i.channel()].size())); temp1 = buffer[i.channel()][(dtime + delay_index[i.channel()] + static_cast(p)) % (dtime * 2)]; // cerr << "b: " // << (delay_index[i.channel()] + static_cast(p)) % dtime // << "," << p << ".\n"; } *i.current() = ecaops_flush_to_zero(*i.current() * (1.0 - feedback) + (-1.0 * temp1 * feedback)); buffer[i.channel()][delay_index[i.channel()]] = *i.current(); ++(delay_index[i.channel()]); if (delay_index[i.channel()] == 2 * dtime) { delay_index[i.channel()] = 0; filled[i.channel()] = true; } i.next(); } } ecasound-2.9.1/libecasound/eca-chain.h0000644000076400007640000001610112260762753014537 00000000000000// ------------------------------------------------------------------------ // eca-chain.cpp: Class representing an abstract audio signal chain. // Copyright (C) 1999-2009,2012,2013 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #ifndef INCLUDED_CHAIN_H #define INCLUDED_CHAIN_H #include #include #include "eca-chainop.h" #include "eca-audio-position.h" class GENERIC_CONTROLLER; class OPERATOR; class SAMPLE_BUFFER; /** * Class representing an abstract audio signal chain. */ class CHAIN : public ECA_AUDIO_POSITION { public: /** @name Object construction and destruction */ /*@{*/ CHAIN (void); virtual ~CHAIN (void); /*@}*/ // ------------------------------------------------------------------- /** @name Chain state */ /*@{*/ bool is_initialized(void) const { return initialized_rep; } /** * Is chain muted? If muted, audio buffers are zeroed during * processing. */ bool is_muted(void) const { return muted_rep; } /** * Is chain muted? If muted, audio buffers are zeroed during * processing. */ bool is_operator_bypassed(int op_index) const; /** * Is processing enabled and bypassed? If bypassed, all chain * operators will be skipped during processing. */ bool is_bypassed(void) const { return bypass_rep; } void set_mute(int muted); void set_bypass(int state); std::string name(void) const { return chainname_rep; } void name(const std::string& c) { chainname_rep = c; } bool is_valid(void) const; void init(SAMPLE_BUFFER* sbuf = 0, int in_channels = 0, int out_channels = 0); void release(void); void process(void); void controller_update(void); void refresh_parameters(void); std::string to_string(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Input and output */ /*@{*/ void connect_input(int input); void disconnect_input(void); void connect_output(int output); void disconnect_output(void); void disconnect_buffer(void); void input_removed(int input); void output_removed(int input); /** * Returns an id number to input connected to this chain. If no input * is connected, -1 is returned. */ int connected_input(void) const { return input_id_rep; } /** * Returns an id number to output connected to this chain. If no input * is connected, -1 is returned. */ int connected_output(void) const { return output_id_rep; } /*@}*/ // ------------------------------------------------------------------- /** @name Access objects via stateless addressing */ /*@{*/ void clear(void); void add_chain_operator(CHAIN_OPERATOR* chainop); void add_controller(GENERIC_CONTROLLER* gcontroller); void remove_chain_operator(int op_index); void bypass_operator(int op_index, int bypassed); void set_parameter(int op_index, int param_index, CHAIN_OPERATOR::parameter_t value); int number_of_chain_operators(void) const { return chainops_rep.size(); } int number_of_chain_operator_parameters(int index) const; const CHAIN_OPERATOR* get_chain_operator(int index) const { return chainops_rep[index].cop; } const GENERIC_CONTROLLER* get_controller(int index) const { return gcontrollers_rep[index]; } int number_of_controllers(void) const { return gcontrollers_rep.size(); } void set_controller_parameter(int op_index, int param_index, CHAIN_OPERATOR::parameter_t value); /*@}*/ // ------------------------------------------------------------------- /** @name Access objects via stateful addressing */ /*@{*/ void select_chain_operator(int op_index); void select_chain_operator_parameter(int param_index); /** Index (1..N) of selected chain operator */ int selected_chain_operator(void) const { return selected_chainop_number_rep; } int selected_chain_operator_parameter(void) const { return selected_chainop_parameter_rep; } int number_of_chain_operator_parameters(void) const; CHAIN_OPERATOR::parameter_t get_parameter(void) const; std::string chain_operator_name(void) const; std::string chain_operator_parameter_name(void) const; const CHAIN_OPERATOR* get_selected_chain_operator(void) const; void remove_controller(void); void select_controller(int index); void select_controller_parameter(int index); const GENERIC_CONTROLLER* get_selected_controller(void) const { return selected_controller_repp; } int number_of_controller_parameters(void) const; std::string controller_parameter_name(void) const; CHAIN_OPERATOR::parameter_t get_controller_parameter(void) const; /** Index (1...N) of selected controller */ int selected_controller(void) const { return selected_controller_number_rep; } int selected_controller_parameter(void) const { return selected_controller_parameter_rep; } std::string controller_name(void) const; void selected_chain_operator_as_target(void); void selected_controller_as_target(void); /** * Returns the object that is the current target for * parameter control, or 0 if none selected. */ OPERATOR* selected_target(void) const { return selected_dynobj_repp; } /*@}*/ // ------------------------------------------------------------------- /** @name Functions implemented from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ /** @name Functions implemented from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); virtual bool supports_seeking(void) const { return true; } virtual bool supports_seeking_sample_accurate(void) const { return true; } /*@}*/ // ------------------------------------------------------------------- private: bool is_valid_op_index(int op_index) const; class COP_CONTAINER { public: CHAIN_OPERATOR* cop; bool bypassed; }; bool initialized_rep; std::string chainname_rep; bool muted_rep; bool bypass_rep; int in_channels_rep; int out_channels_rep; std::vector chainops_rep; std::vector gcontrollers_rep; GENERIC_CONTROLLER* selected_controller_repp; OPERATOR* selected_dynobj_repp; int selected_chainop_number_rep; int selected_chainop_parameter_rep; int selected_controller_number_rep; int selected_controller_parameter_rep; int input_id_rep; int output_id_rep; SAMPLE_BUFFER* audioslot_repp; }; #endif ecasound-2.9.1/libecasound/audioio-forked-stream.cpp0000644000076400007640000003102711565760647017467 00000000000000// ------------------------------------------------------------------------ // audioio-forked-streams.cpp: Helper class providing routines for // forking for piped input/output. // Copyright (C) 2000-2004,2006,2008,2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "eca-logger.h" #include "audioio-forked-stream.h" using namespace std; /** * Maximum number of arguments passed to exec() */ const static int afs_max_exec_args = 1024; /** * Runs exec() with the given parameters. * @return exec() return value */ static int afs_run_exec(const string& command, const string& filename) { vector temp = kvu_string_to_tokens_quoted(command); if (static_cast(temp.size()) > afs_max_exec_args) { temp.resize(afs_max_exec_args); ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: too many arguments for external application, truncating."); } const char* args[afs_max_exec_args]; vector::size_type p = 0; while(p < temp.size()) { if (temp[p].find("%f") != string::npos) { temp[p].replace(temp[p].find("%f"), 2, filename); args[p] = temp[p].c_str(); } else args[p] = temp[p].c_str(); ++p; } args[p] = 0; return execvp(temp[0].c_str(), const_cast(args)); } static int afs_fd_set_cloexec(int fd) { int flags; flags = fcntl(fd, F_GETFD); if (flags >= 0) { flags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, flags) >= 0) return 0; } ECA_LOG_MSG(ECA_LOGGER::info, "unable to set FD_CLOEXEC: " + std::string(strerror(errno))); return -1; } AUDIO_IO_FORKED_STREAM::~AUDIO_IO_FORKED_STREAM(void) { if (pid_of_child_rep > 0) clean_child(true); } void AUDIO_IO_FORKED_STREAM::stop_io(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "stop_io()"); clean_child(false); } /** * If found, replaces the string '%f' with 'filename'. This is * the file used by the forked child for input/output. */ void AUDIO_IO_FORKED_STREAM::set_fork_file_name(const string& filename) { object_rep = filename; /* do not yet replace %f yet as it would make it more difficult to tokenize the exec string */ } /** * If found, replaces the string '%F' with a path name to a * temporary named pipe. This pipe will be used for communicating * with the forked child instead of standard input and output pipes. */ void AUDIO_IO_FORKED_STREAM::set_fork_pipe_name(void) { if (command_rep.find("%F") != string::npos) { use_named_pipe_rep = true; init_temp_directory(); if (tempfile_dir_rep.is_valid() == true) { tmpfile_repp = tempfile_dir_rep.create_filename("fork-pipe", ".raw"); ::mkfifo(tmpfile_repp.c_str(), 0755); command_rep.replace(command_rep.find("%F"), 2, tmpfile_repp); tmp_file_created_rep = true; } else tmp_file_created_rep = false; } else use_named_pipe_rep = false; } void AUDIO_IO_FORKED_STREAM::init_temp_directory(void) { string tmpdir ("ecasound-"); char* tmp_p = getenv("USER"); if (tmp_p != NULL) { tmpdir += string(tmp_p); tempfile_dir_rep.reserve_directory(tmpdir); } if (tempfile_dir_rep.is_valid() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Unable to create temporary directory \"" + tmpdir + "\"."); } } /** * If found, replaces the string '%c' with value of parameter * 'channels'. */ void AUDIO_IO_FORKED_STREAM::set_fork_channels(int channels) { if (command_rep.find("%c") != string::npos) { command_rep.replace(command_rep.find("%c"), 2, kvu_numtostr(channels)); } } /** * If found, replaces the string '%s' with value of parameter * 'sample_rate', and '%S' with 'sample_rate/1000' (kHz). */ void AUDIO_IO_FORKED_STREAM::set_fork_sample_rate(long int sample_rate) { if (command_rep.find("%s") != string::npos) { command_rep.replace(command_rep.find("%s"), 2, kvu_numtostr(sample_rate)); } if (command_rep.find("%S") != string::npos) { command_rep.replace(command_rep.find("%S"), 2, kvu_numtostr(sample_rate/1000.0f)); } } /** * If found, replaces the string '%b' with value of parameter * 'bits'. */ void AUDIO_IO_FORKED_STREAM::set_fork_bits(int bits) { if (command_rep.find("%b") != string::npos) { command_rep.replace(command_rep.find("%b"), 2, kvu_numtostr(bits)); } } void AUDIO_IO_FORKED_STREAM::fork_child_for_read(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Fork child-for-read: '" + fork_command() + "'"); init_state_before_fork(); if (use_named_pipe_rep == true) { if (tmp_file_created_rep == true) { fork_child_for_fifo_read(); } else { last_fork_rep = false; } } else { int fpipes[2]; if (pipe(fpipes) == 0) { sigkill_sent_rep = false; pid_of_child_rep = fork(); if (pid_of_child_rep == 0) { // --- // child // --- sigset_t newset; sigemptyset(&newset); sigaddset(&newset, SIGTERM); sigaddset(&newset, SIGPIPE); #if defined(HAVE_PTHREAD_SIGMASK) pthread_sigmask(SIG_UNBLOCK, &newset, NULL); #elif defined(HAVE_SIGPROCMASK) sigprocmask(SIG_UNBLOCK, &newset, NULL); #endif ::close(1); dup2(fpipes[1], 1); ::close(fpipes[0]); ::close(fpipes[1]); freopen("/dev/null", "w", stderr); int res = afs_run_exec(command_rep, object_rep); ::close(1); exit(res); cerr << "You shouldn't see this!\n"; } else if (pid_of_child_rep > 0) { // --- // parent // --- pid_of_parent_rep = ::getpid(); ::close(fpipes[1]); fd_rep = fpipes[0]; afs_fd_set_cloexec(fd_rep); if (wait_for_child() == true) last_fork_rep = true; else last_fork_rep = false; } } } } /** * Initializes state that needs to be reset/refresh * between every new fork of a child object. */ void AUDIO_IO_FORKED_STREAM::init_state_before_fork(void) { last_fork_rep = false; fd_rep = 0; if (do_supports_seeking() != true) do_set_position_in_samples(0); } void AUDIO_IO_FORKED_STREAM::fork_child_for_fifo_read(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Fork child-for-fifo-read: '" + fork_command() + "'"); init_state_before_fork(); sigkill_sent_rep = false; pid_of_child_rep = fork(); if (pid_of_child_rep == 0) { // --- // child // --- sigset_t newset; sigemptyset(&newset); sigaddset(&newset, SIGTERM); sigaddset(&newset, SIGPIPE); #if defined(HAVE_PTHREAD_SIGMASK) pthread_sigmask(SIG_UNBLOCK, &newset, NULL); #elif defined(HAVE_SIGPROCMASK) sigprocmask(SIG_UNBLOCK, &newset, NULL); #endif freopen("/dev/null", "w", stderr); int res = afs_run_exec(command_rep, object_rep); if (res < 0) { /** * If execvp failed, make sure that the other end of * the pipe doesn't block forever. */ cerr << "execvp() failed!\n"; int fd = open(tmpfile_repp.c_str(), O_WRONLY); close(fd); } exit(res); cerr << "You shouldn't see this!\n"; } else if (pid_of_child_rep > 0) { // --- // parent // --- pid_of_parent_rep = ::getpid(); fd_rep = 0; if (wait_for_child() == true) fd_rep = ::open(tmpfile_repp.c_str(), O_RDONLY); if (fd_rep > 0) { last_fork_rep = true; afs_fd_set_cloexec(fd_rep); } } } void AUDIO_IO_FORKED_STREAM::fork_child_for_write(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Fork child-for-write: '" + fork_command() + "'"); init_state_before_fork(); int fpipes[2]; if (pipe(fpipes) == 0) { sigkill_sent_rep = false; pid_of_child_rep = fork(); if (pid_of_child_rep == 0) { // --- // child // --- sigset_t newset; sigaddset(&newset, SIGTERM); sigaddset(&newset, SIGPIPE); #if defined(HAVE_PTHREAD_SIGMASK) pthread_sigmask(SIG_UNBLOCK, &newset, NULL); #elif defined(HAVE_SIGPROCMASK) sigprocmask(SIG_UNBLOCK, &newset, NULL); #endif ::close(0); ::dup2(fpipes[0],0); ::close(fpipes[0]); ::close(fpipes[1]); freopen("/dev/null", "w", stderr); exit(afs_run_exec(command_rep, object_rep)); cerr << "You shouln't see this!\n"; } else if (pid_of_child_rep > 0) { // --- // parent // --- pid_of_parent_rep = ::getpid(); ::close(fpipes[0]); fd_rep = fpipes[1]; /* make sure in case the parent forks again, the fd_rep * is closed -> otherwise the mechanism to signal end-of-stream * gets broken */ afs_fd_set_cloexec(fd_rep); if (wait_for_child() == true) last_fork_rep = true; else last_fork_rep = false; } } } /** * Cleans (waits for) the forked child process. Note! This * function should be called from the same thread as * fork_child_for_read/write() was called. * * In case the function is called from a different thread, * it attemts to terminate the child anyways, but the child's * state is not known exactly when function returns. * * @param force if true, client is terminated with SIGKILL, * which guarantees that it terminates (but * possibly without going through normal * exit procedure); should be avoided especially * for output objects as this may result in * data loss */ void AUDIO_IO_FORKED_STREAM::clean_child(bool force) { if (fd_rep > 0) { /* close the pipe between this process and the forked child * process, should terminate the forked application -> see * waitpid() below */ ECA_LOG_MSG(ECA_LOGGER::system_objects, "closing pipe handle for: " + object_rep); ::close(fd_rep); fd_rep = -1; } if (pid_of_child_rep > 0 && force == true) { if (sigkill_sent_rep != true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Sending SIGKILL to child process related to: " + object_rep); kill(pid_of_child_rep, SIGKILL); sigkill_sent_rep = true; } else { /* SIGKILL already sent once for this process, don't send it again */ pid_of_child_rep = -1; } } if (pid_of_child_rep > 0 && pid_of_parent_rep == getpid()) { /* wait until child process has exited * note: this only works reliable when our pid is * the same as used for starting the child */ int flags = 0; int status = 0; ECA_LOG_MSG(ECA_LOGGER::system_objects, "waitpid() for: " + object_rep); int res = waitpid(pid_of_child_rep, &status, flags); if (res == pid_of_child_rep) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Child process exit ok: " + object_rep); pid_of_child_rep = 0; } else { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Problems in terminating child process:" + std::string(strerror(errno))); } } if (pid_of_child_rep > 0) { /* unable to use wait(), terminating with a signal */ ECA_LOG_MSG(ECA_LOGGER::system_objects, "Child not responding, sending SIGTERM: " + object_rep); kill(pid_of_child_rep, SIGTERM); pid_of_child_rep = 0; } if (tmp_file_created_rep == true) { ::remove(tmpfile_repp.c_str()); tmp_file_created_rep = false; } } /** * Checks whether child is still active. Returns false * if child has exited, otherwise true. */ bool AUDIO_IO_FORKED_STREAM::wait_for_child(void) const { if (pid_of_child_rep <= 0) return false; else if (pid_of_parent_rep == getpid() && pid_of_child_rep > 0) { int pid = waitpid(pid_of_child_rep, 0, WNOHANG); if (pid == pid_of_child_rep) { return false; } /* no change in state, so still active */ return true; } else /* note: we don't really know so assume that yes */ return true; } ecasound-2.9.1/libecasound/jack-connections.cpp0000644000076400007640000000636711440422070016507 00000000000000// ------------------------------------------------------------------------ // jack-connections.cpp: Utility class to manage JACK port connections // Copyright (C) 2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "eca-logger.h" #include "jack-connections.h" using std::string; JACK_CONNECTIONS::JACK_CONNECTIONS(void) { } JACK_CONNECTIONS::~JACK_CONNECTIONS(void) { } static jack_client_t *priv_prepare(void) { int pid = getpid(); std::string clntname = "libecasound-ctrl-" + kvu_numtostr(pid); jack_client_t *client = jack_client_open(clntname.c_str(), JackNullOption, NULL); return client; } static void priv_cleanup(jack_client_t *client) { jack_client_close(client); } bool JACK_CONNECTIONS::connect(const char* src, const char* dest) { int result = -1; jack_client_t *client = priv_prepare(); if (client != 0) { result = jack_connect(client, src, dest); ECA_LOG_MSG(ECA_LOGGER::user_objects, std::string("Connected JACK ports ") + src + " and " + dest + " with result of " + kvu_numtostr(result)); priv_cleanup(client); } return result == 0; } bool JACK_CONNECTIONS::disconnect(const char* src, const char* dest) { int result = -1; jack_client_t *client = priv_prepare(); if (client != 0) { result = jack_disconnect(client, src, dest); ECA_LOG_MSG(ECA_LOGGER::user_objects, std::string("Connected JACK ports ") + src + " and " + dest + " with result of " + kvu_numtostr(result)); priv_cleanup(client); } return result == 0; } bool JACK_CONNECTIONS::list_connections(std::string* output) { jack_client_t *client = priv_prepare(); if (client != 0) { const char **next, **ports = jack_get_ports(client, NULL, NULL, 0); if (ports) { *output += "\n"; for (next = ports; *next; next++) { jack_port_t *port; *output += string(*next); port = jack_port_by_name(client, *next); const char **nextconn, **conns = jack_port_get_all_connections(client, port); if (conns) { for(nextconn = conns; *nextconn; nextconn++) { *output += string("\n\t") + string(*nextconn) + string("\n"); } free(conns); } else { *output += "\n"; } } free(ports); } priv_cleanup(client); } return client != 0; } ecasound-2.9.1/libecasound/eca-chainsetup-parser_test.h0000644000076400007640000000757511166145417020164 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup-parser_test.h: Unit test for ECA_CHAINSETUP_PARSER // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include "eca-chainsetup.h" #include "kvu_numtostr.h" #include "eca-logger.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_CHAINSETUP. * * FIXME: implementation not ready */ class ECA_CHAINSETUP_PARSER_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("ECA_CHAINSETUP_PARSER_TEST"); } virtual void do_run(void); public: virtual ~ECA_CHAINSETUP_PARSER_TEST(void) { } private: void do_run_format_options(void); }; void ECA_CHAINSETUP_PARSER_TEST::do_run(void) { do_run_format_options(); } void ECA_CHAINSETUP_PARSER_TEST::do_run_format_options(void) { ECA_CHAINSETUP csetup; ECA_CHAINSETUP_PARSER p(&csetup); p.interpret_option("-f:foo,bar"); if (p.interpret_result() != false) { ECA_TEST_FAILURE("invalid sample_format accepted"); } ECA_AUDIO_FORMAT afmt (4, 96000, ECA_AUDIO_FORMAT::sfmt_f64_be, false); csetup.set_default_audio_format(afmt); if (csetup.default_audio_format().sample_format() != ECA_AUDIO_FORMAT::sfmt_f64_be) ECA_TEST_FAILURE("failed to set initial audio fmt (1)"); if (csetup.default_audio_format().channels() != 4 || csetup.default_audio_format().samples_per_second() != 96000 || csetup.default_audio_format().sample_format() != ECA_AUDIO_FORMAT::sfmt_f64_be || csetup.default_audio_format().interleaved_channels() != false) ECA_TEST_FAILURE("failed to set initial audio fmt"); /* note: Setting one audio format component should not affect other * audio format components. The following section has * multiple test cases related to this. */ p.interpret_option("-f:s32_be"); if (csetup.default_audio_format().sample_format() != ECA_AUDIO_FORMAT::sfmt_s32_be) ECA_TEST_FAILURE("unable to set sample format"); if (csetup.default_audio_format().channels() != 4) ECA_TEST_FAILURE("setting sample format affected channels"); ECA_LOG_MSG(ECA_LOGGER::info, afmt.format_string()); ECA_LOG_MSG(ECA_LOGGER::info, csetup.default_audio_format().format_string()); p.interpret_option("-f:,6,"); if (csetup.default_audio_format().channels() != 6) ECA_TEST_FAILURE("unable to channels"); if (csetup.default_audio_format().sample_format() != ECA_AUDIO_FORMAT::sfmt_s32_be) ECA_TEST_FAILURE("setting channels affected sample format"); p.interpret_option("-f:,6,"); if (csetup.default_audio_format().channels() != 6) ECA_TEST_FAILURE("unable to channels"); /* note: Test setting all parameters */ p.interpret_option("-f:u8,1,22050,i"); if (csetup.default_audio_format().channels() != 1 || csetup.default_audio_format().samples_per_second() != 22050 || csetup.default_audio_format().sample_format() != ECA_AUDIO_FORMAT::sfmt_u8 || csetup.default_audio_format().interleaved_channels() != true) ECA_TEST_FAILURE("failed to set all audio fmt components"); } ecasound-2.9.1/libecasound/eca-logger-wellformed.h0000644000076400007640000000144110664032032017055 00000000000000#ifndef INCLUDE_ECA_LOGGER_WELLFORMED_H #define INCLUDE_ECA_LOGGER_WELLFORMED_H #include #include #include "eca-logger-interface.h" /** * Logging implementation that outputs * messages in a well-formed format. The * exact syntax is defined in TBD. * * @author Kai Vehmanen */ class ECA_LOGGER_WELLFORMED : public ECA_LOGGER_INTERFACE { public: ECA_LOGGER_WELLFORMED(void); virtual ~ECA_LOGGER_WELLFORMED(void); virtual void do_msg(ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message); virtual void do_flush(void); virtual void do_log_level_changed(void); static std::string create_wellformed_message(ECA_LOGGER::Msg_level_t level, const std::string& message); }; #endif /* INCLUDE_ECA_LOGGER_WELLFORMED_H */ ecasound-2.9.1/libecasound/resource-file.h0000644000076400007640000000320310664032032015454 00000000000000#ifndef INCLUDED_RESOURCE_FILE_H #define INCLUDED_RESOURCE_FILE_H #include #include #include /** * Generic resource file class */ class RESOURCE_FILE { std::string resfile_rep; mutable std::map resmap_rep; std::vector lines_rep; bool modified_rep; public: /** * Returns a vector of registered presets */ std::vector keywords(void) const; /** * Returns current resource file name. */ const std::string& resource_file(void) const { return resfile_rep; } /** * Set resource file name. */ void resource_file(const std::string& v) { resfile_rep = v; } /** * Returns value of resource 'tag'. */ std::string resource(const std::string& tag) const; /** * Set resource 'tag' value to 'value'. If value wasn't * previously defined, it's added. */ void resource(const std::string& tag, const std::string& value); /** * Returns true if resource 'tag' is 'true', otherwise false */ bool boolean_resource(const std::string& tag) const; /** * Whether resource 'tag' is specified in the resource file */ bool has(const std::string& tag) const; /** * Has any resource value been added, removed or modified? */ bool is_modified(void) const { return modified_rep; } /** * Load/restore resources from file */ void load(void); /** * Save/store resources to file saving */ void save(void); /** * Constructor. Resource values are read, if * filename argument is given. */ RESOURCE_FILE(const std::string& resource_file = ""); virtual ~RESOURCE_FILE(void); }; #endif ecasound-2.9.1/libecasound/eca-audio-position.h0000644000076400007640000000705311032773265016422 00000000000000#ifndef INCLUDED_ECA_AUDIO_POSITION_H #define INCLUDED_ECA_AUDIO_POSITION_H #include "sample-specs.h" #include "eca-samplerate-aware.h" /** * Position cursor for a finite length audio stream */ class ECA_AUDIO_POSITION : public ECA_SAMPLERATE_AWARE { public: /** @name Constructors and destructors */ /*@{*/ ECA_AUDIO_POSITION(void); virtual ~ECA_AUDIO_POSITION(void); /*@}*/ /** @name Public functions for getting length information */ /*@{*/ SAMPLE_SPECS::sample_pos_t length_in_samples(void) const; int length_in_seconds(void) const; double length_in_seconds_exact(void) const; bool length_set(void) const { return(length_set_rep); } /*@}*/ protected: /** @name Protected functions for setting length */ /*@{*/ void set_length_in_samples(SAMPLE_SPECS::sample_pos_t pos); void set_length_in_seconds(int pos_in_seconds); void set_length_in_seconds(double pos_in_seconds); /** * If current position is beyond the current total * length, sets length according to the current position. * * ensure: * position_in_samples() == length_in_samples() */ void extend_position(void) { length_in_samples_rep = (position_in_samples_rep > length_in_samples_rep) ? position_in_samples_rep : length_in_samples_rep; } /*@}*/ public: /** @name Public functions for getting position information */ /*@{*/ SAMPLE_SPECS::sample_pos_t position_in_samples(void) const; int position_in_seconds(void) const; double position_in_seconds_exact(void) const; /*@}*/ protected: /** @name Protected functions for setting position (without action) */ /*@{*/ void set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos); void set_position_in_seconds(int pos_in_seconds); void set_position_in_seconds(double pos_in_seconds); void change_position_in_samples(SAMPLE_SPECS::sample_pos_t pos); void change_position_in_seconds(double pos_in_seconds); /*@}*/ public: /** @name Public functions for setting position (with action) */ /*@{*/ void seek_position_in_samples(SAMPLE_SPECS::sample_pos_t pos_in_samples); void seek_position_in_samples_advance(SAMPLE_SPECS::sample_pos_t pos_in_samples); void seek_position_in_seconds(double pos_in_seconds); void seek_first(void); void seek_last(void); public: virtual bool supports_seeking(void) const = 0; virtual bool supports_seeking_sample_accurate(void) const = 0; protected: /** * Seeks to the current position. * * If the seek is succesful, seek_position() should return * position given as argument 'pos'. * * If the seek is unsuccesful (seeking not supported at all, * or not with sample accuracy), the current actual position * in samples should be returned. * * @param pos new position in samples * @return pos on success, actual current position otherwise */ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos) = 0; /*@}*/ public: /** @name Public utility functions */ /*@{*/ /** * True if current position is beyond the end position or * smaller than zero. */ inline bool out_position(void) const { return((( position_in_samples_rep < 0) && (position_in_samples_rep > length_in_samples_rep)) ? true : false); } /*@}*/ public: /** @name Functions reimplemented from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value); /*@}*/ private: SAMPLE_SPECS::sample_pos_t position_in_samples_rep; SAMPLE_SPECS::sample_pos_t length_in_samples_rep; bool length_set_rep; }; #endif ecasound-2.9.1/libecasound/eca-audio-format.cpp0000644000076400007640000001762511141053131016367 00000000000000// ------------------------------------------------------------------------ // eca-audio-format.cpp: Class for representing audio format parameters // Copyright (C) 1999-2002,2004 Kai Vehmanen // // Attributes: // eca-style-version: 2 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "eca-audio-format.h" #include "eca-error.h" ECA_AUDIO_FORMAT::ECA_AUDIO_FORMAT(int channels, long int srate, ECA_AUDIO_FORMAT::Sample_format format, bool ileaved) { set_channels(channels); set_samples_per_second(srate); set_sample_format(format); toggle_interleaved_channels(ileaved); } ECA_AUDIO_FORMAT::ECA_AUDIO_FORMAT(void) { set_channels(0); set_samples_per_second(-1); set_sample_format(sfmt_none); toggle_interleaved_channels(true); } ECA_AUDIO_FORMAT::~ECA_AUDIO_FORMAT(void) { } ECA_AUDIO_FORMAT ECA_AUDIO_FORMAT::audio_format(void) const { return ECA_AUDIO_FORMAT(channels(), samples_per_second(), sample_format(), interleaved_channels()); } ECA_AUDIO_FORMAT::Sample_format ECA_AUDIO_FORMAT::sample_format(void) const { Sample_format format (sfmt_none); try { format = string_to_sample_format(format_string()); } catch(...) {} return format; } /** * Sets audio format to that of 'f'. */ void ECA_AUDIO_FORMAT::set_audio_format(const ECA_AUDIO_FORMAT& f) { set_channels(f.channels()); set_sample_format(f.sample_format()); set_samples_per_second(f.samples_per_second()); toggle_interleaved_channels(f.interleaved_channels()); } void ECA_AUDIO_FORMAT::set_sample_format(ECA_AUDIO_FORMAT::Sample_format sfmt) throw(ECA_ERROR&) { switch(sfmt) { case sfmt_none: sc_rep = sc_unsigned; update_sample_endianess(se_native); align_rep = 0; break; case sfmt_u8: sc_rep = sc_unsigned; update_sample_endianess(se_native); align_rep = 1; break; case sfmt_s8: sc_rep = sc_signed; update_sample_endianess(se_native); align_rep = 1; break; case sfmt_s16: sc_rep = sc_signed; update_sample_endianess(se_native); align_rep = 2; break; case sfmt_s16_le: sc_rep = sc_signed; update_sample_endianess(se_little); align_rep = 2; break; case sfmt_s16_be: sc_rep = sc_signed; update_sample_endianess(se_big); align_rep = 2; break; case sfmt_s24: sc_rep = sc_signed; update_sample_endianess(se_native); align_rep = 3; break; case sfmt_s24_le: sc_rep = sc_signed; update_sample_endianess(se_little); align_rep = 3; break; case sfmt_s24_be: sc_rep = sc_signed; update_sample_endianess(se_big); align_rep = 3; break; case sfmt_s32: sc_rep = sc_signed; update_sample_endianess(se_native); align_rep = 4; break; case sfmt_s32_le: sc_rep = sc_signed; update_sample_endianess(se_little); align_rep = 4; break; case sfmt_f32: sc_rep = sc_float; update_sample_endianess(se_native); align_rep = 4; break; case sfmt_s32_be: sc_rep = sc_signed; update_sample_endianess(se_big); align_rep = 4; break; case sfmt_f32_le: sc_rep = sc_float; update_sample_endianess(se_little); align_rep = 4; break; case sfmt_f32_be: sc_rep = sc_float; update_sample_endianess(se_big); align_rep = 4; break; case sfmt_f64: sc_rep = sc_float; update_sample_endianess(se_native); align_rep = 8; break; case sfmt_f64_le: sc_rep = sc_float; update_sample_endianess(se_little); align_rep = 8; break; case sfmt_f64_be: sc_rep = sc_float; update_sample_endianess(se_big); align_rep = 8; break; default: { throw(ECA_ERROR("ECA_AUDIO_FORMAT","Audio format not supported!")); } } DBC_ENSURE(se_rep == se_big || se_rep == se_little); } int ECA_AUDIO_FORMAT::bits(void) const { return align_rep * 8; } void ECA_AUDIO_FORMAT::set_channels(int v) { channels_rep = v; } void ECA_AUDIO_FORMAT::toggle_interleaved_channels(bool v) { ileaved_rep = v; } ECA_AUDIO_FORMAT::Sample_format ECA_AUDIO_FORMAT::string_to_sample_format(const std::string& str) const throw(ECA_ERROR&) { Sample_format sfmt = sfmt_none; if (str == "u8") sfmt = sfmt_u8; else if (str == "s16") sfmt = sfmt_s16; else if (str == "s16_le") sfmt = sfmt_s16_le; else if (str == "s16_be") sfmt = sfmt_s16_be; else if (str == "s24") sfmt = sfmt_s24; else if (str == "s24_le") sfmt = sfmt_s24_le; else if (str == "s24_be") sfmt = sfmt_s24_be; else if (str == "s32") sfmt = sfmt_s32; else if (str == "s32_le") sfmt = sfmt_s32_le; else if (str == "s32_be") sfmt = sfmt_s32_be; else if (str == "f32") sfmt = sfmt_f32; else if (str == "f32_le") sfmt = sfmt_f32_le; else if (str == "f32_be") sfmt = sfmt_f32_be; else if (str == "f64") sfmt = sfmt_f64; else if (str == "f64_le") sfmt = sfmt_f64_le; else if (str == "f64_be") sfmt = sfmt_f64_be; else if (str == "8") sfmt = sfmt_u8; else if (str == "16") sfmt = sfmt_s16; else if (str == "24") sfmt = sfmt_s24; else if (str == "32") sfmt = sfmt_s32; else { if (str != "none") throw(ECA_ERROR("ECA_AUDIO_FORMAT", "Unknown sample format \"" + str + "\".")); } return sfmt; } void ECA_AUDIO_FORMAT::set_sample_format_string(const std::string& f_str) throw(ECA_ERROR&) { /* note, may raise an exception */ set_sample_format(string_to_sample_format(f_str)); } /** * Internal helper function that sets sample endianess * and if needed, expands native to either little or big * byteorder. * * @see set_sample_endianess */ void ECA_AUDIO_FORMAT::update_sample_endianess(ECA_AUDIO_FORMAT::Sample_endianess v) { if (v == se_native) { #ifdef WORDS_BIGENDIAN se_rep = se_big; #else se_rep = se_little; #endif } else { se_rep = v; } } void ECA_AUDIO_FORMAT::set_sample_endianess(ECA_AUDIO_FORMAT::Sample_endianess v) { update_sample_endianess(v); /* make sure classes that reimplement set_sample_format * see the change in sample endianess */ set_sample_format_string(format_string()); DBC_ENSURE(se_rep == se_big || se_rep == se_little); } void ECA_AUDIO_FORMAT::set_sample_coding(ECA_AUDIO_FORMAT::Sample_coding v) { sc_rep = v; /* make sure classes that reimplement set_sample_format * see the change in sample coding */ set_sample_format_string(format_string()); } string ECA_AUDIO_FORMAT::format_string(void) const { std::string format; if (align_rep > 0) { /* coding */ switch(sc_rep) { case sc_unsigned: format += "u"; break; case sc_signed: format += "s"; break; case sc_float: format += "f"; break; } /* bits */ format += kvu_numtostr(bits()); DBC_CHECK(se_rep == se_big || se_rep == se_little); /* endianess */ if (align_rep > 1) { if (se_rep == se_little) { format += "_le"; } else { format += "_be"; } } } else { /* align_rep == 0 -> sfmt is yet unspecified */ format = "none"; } return format; } ecasound-2.9.1/libecasound/resource-file.cpp0000644000076400007640000001121710664032032016013 00000000000000// ------------------------------------------------------------------------ // resource-file.cpp: Generic resource file class // Copyright (C) 1999-2004,2007 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include "resource-file.h" #include "eca-logger.h" RESOURCE_FILE::RESOURCE_FILE(const std::string& resource_file) : resfile_rep(resource_file) { if (resfile_rep.size() > 0) load(); } RESOURCE_FILE::~RESOURCE_FILE(void) { } void RESOURCE_FILE::load(void) { ECA_LOG_MSG(ECA_LOGGER::functions, "Loading file " + resfile_rep + "."); lines_rep.resize(0); std::ifstream fin (resfile_rep.c_str()); if (fin) { std::string line; std::string first, second; while(getline(fin,line)) { if (line.size() > 0 && line[0] == '#') { lines_rep.push_back(line); continue; } std::string::size_type n = line.find_first_of("="); if (n == std::string::npos) n = line.find_first_of(" "); if (n == std::string::npos) { continue; } first = std::string(line, 0, n); second = std::string(line, n + 1, std::string::npos); /* step: combine multi-line values ending with '\' into * a single value for 'first' */ first = kvu_remove_surrounding_spaces(first); second = kvu_remove_surrounding_spaces(second); std::string::iterator p = second.end(); --p; while (second.begin() != second.end() && *p == '\\') { second.erase(p); lines_rep.push_back(line); if (getline(fin, line)) { line = kvu_remove_surrounding_spaces(line); second += line; p = second.end(); --p; } else break; } // std::cerr << "found key-value pair: " + // first + " = \"" + second + "\"." << std::endl; resmap_rep[first] = second; lines_rep.push_back(line); } } fin.close(); modified_rep = false; } void RESOURCE_FILE::save(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Saving file " + resfile_rep + "."); std::ofstream fout (resfile_rep.c_str(), std::ios::out | std::ios::trunc); if (fout) { std::vector::const_iterator p = lines_rep.begin(); while(p != lines_rep.end()) { if (p->size() > 0) { // cerr << "Writing line: " << *p << "." << endl; fout << *p << "\n"; } ++p; } } fout.close(); modified_rep = false; } std::vector RESOURCE_FILE::keywords(void) const { std::vector keys; std::map::const_iterator p; p = resmap_rep.begin(); while(p != resmap_rep.end()) { // cerr << "Adding keyword: " << p->first << "." << endl; keys.push_back(p->first); ++p; } return keys; } bool RESOURCE_FILE::boolean_resource(const std::string& tag) const { if (resource(tag) == "true") return true; return false; } bool RESOURCE_FILE::has(const std::string& tag) const { if (resmap_rep.find(tag) == resmap_rep.end()) return false; return true; } std::string RESOURCE_FILE::resource(const std::string& tag) const { if (has(tag) != true) return ""; // cerr << "Returning resource: " << resmap_rep[tag] << "." << endl; return resmap_rep[tag]; } void RESOURCE_FILE::resource(const std::string& tag, const std::string& value) { resmap_rep[tag] = value; bool found = false; std::vector::iterator p; p = lines_rep.begin(); while(p != lines_rep.end()) { std::string line = *p; if (line.size() > 0 && line[0] != '#') { std::string::size_type n = line.find_first_of("="); if (n == std::string::npos) n = line.find_first_of(" "); if (n != std::string::npos) { std::string first = kvu_remove_surrounding_spaces(std::string(line, 0, n)); if (first == tag) { *p = first + " = " + value; found = true; } } } ++p; } if (found != true) { lines_rep.push_back(tag + " = " + value); } modified_rep = true; } ecasound-2.9.1/libecasound/audioio-typeselect.h0000644000076400007640000000321110765534060016531 00000000000000#ifndef INCLUDED_AUDIOIO_TYPESELECT_H #define INCLUDED_AUDIOIO_TYPESELECT_H #include #include #include #include "audioio-proxy.h" /** * A proxy class for overriding default keyword * and filename associations in ecasound's object * maps. * * Related design patterns: * - Proxy (GoF207) * * @author Kai Vehmanen */ class AUDIO_IO_TYPESELECT : public AUDIO_IO_PROXY { public: /** @name Public functions */ /*@{*/ AUDIO_IO_TYPESELECT (void); virtual ~AUDIO_IO_TYPESELECT(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return(string("Typeselect => ") + child()->name()); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual std::string parameter_names(void) const; virtual bool variable_params(void) const { return true; } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_IO_TYPESELECT* clone(void) const; virtual AUDIO_IO_TYPESELECT* new_expr(void) const { return(new AUDIO_IO_TYPESELECT()); } /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); /*@}*/ private: std::string type_rep; mutable std::vector params_rep; bool init_rep; AUDIO_IO_TYPESELECT& operator=(const AUDIO_IO_TYPESELECT& x) { return *this; } AUDIO_IO_TYPESELECT (const AUDIO_IO_TYPESELECT& x) { } }; #endif ecasound-2.9.1/libecasound/eca-logger-default.cpp0000644000076400007640000000372511261610622016704 00000000000000// ------------------------------------------------------------------------ // eca-logger-default.cpp: Default logging subsystem implementation. // Copyright (C) 2002-2004,2008 Kai Vehmanen // // Attributes: // eca-style-version: 2 // // 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 /* find() */ #include #include "eca-logger-default.h" ECA_LOGGER_DEFAULT::ECA_LOGGER_DEFAULT(std::ostream& output) : output_rep(output) { } void ECA_LOGGER_DEFAULT::do_msg(ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message) { if (is_log_level_set(level) == true) { if (level == ECA_LOGGER::subsystems) { output_rep << "[* "; } else if (module_name.size() > 0 && is_log_level_set(ECA_LOGGER::module_names) == true && level != ECA_LOGGER::eiam_return_values) { output_rep << "(" << ECA_LOGGER_INTERFACE::filter_module_name(module_name) << ") "; } output_rep << log_message; if (level == ECA_LOGGER::subsystems) { output_rep << " *]"; } output_rep << std::endl; } } void ECA_LOGGER_DEFAULT::do_flush(void) { } void ECA_LOGGER_DEFAULT::do_log_level_changed(void) { } ECA_LOGGER_DEFAULT::~ECA_LOGGER_DEFAULT(void) { } ecasound-2.9.1/libecasound/eca-static-object-maps.cpp0000644000076400007640000005556011740524567017516 00000000000000// ------------------------------------------------------------------------ // eca-static-object-maps.h: Static object map instances // Copyright (C) 2000-2004,2006,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "eca-version.h" #include "eca-chainop.h" #include "audiofx.h" #include "audiofx_misc.h" #include "audiofx_amplitude.h" #include "audiofx_analysis.h" #include "audiofx_envelope_modulation.h" #include "audiofx_filter.h" #include "audiofx_rcfilter.h" #include "audiofx_reverb.h" #include "audiofx_mixing.h" #include "audiofx_timebased.h" #include "audiogate.h" #include "audiofx_lv2.h" #include "audiofx_lv2_world.h" #include "audiofx_ladspa.h" #include "generic-controller.h" #include "ctrl-source.h" #include "midi-cc.h" #include "osc-gen.h" #include "osc-gen-file.h" #include "osc-sine.h" #include "linear-envelope.h" #include "two-stage-linear-envelope.h" #include "stamp-ctrl.h" #include "generic-linear-envelope.h" #include "audioio-plugin.h" #include "audioio-cdr.h" #include "audioio-wave.h" #ifdef ECA_COMPILE_OSS #include "audioio-oss.h" #endif #include "audioio-ewf.h" #include "audioio-mp3.h" #include "audioio-ogg.h" #include "audioio-mikmod.h" #include "audioio-timidity.h" #include "audioio-flac.h" #include "audioio-aac.h" #include "audioio-raw.h" #include "audioio-null.h" #include "audioio-rtnull.h" #include "audioio-typeselect.h" #include "audioio-resample.h" #include "audioio-reverse.h" #include "audioio-tone.h" #include "audioio-acseq.h" #ifndef ECA_ENABLE_AUDIOIO_PLUGINS #ifdef ECA_COMPILE_AUDIOFILE #include "plugins/audioio_af.h" #endif #ifdef ECA_COMPILE_SNDFILE #include "plugins/audioio_sndfile.h" #endif #ifdef ECA_COMPILE_ALSA #include "plugins/audioio_alsa.h" #include "plugins/audioio_alsa_named.h" #endif #ifdef ECA_COMPILE_ARTS #include "plugins/audioio_arts.h" #endif #ifdef ECA_COMPILE_JACK #include "plugins/audioio_jack.h" #endif #endif /* ECA_ENABLE_AUDIOIO_PLUGINS */ #include "midiio-raw.h" #ifdef ECA_COMPILE_ALSA #include "midiio-aseq.h" #endif #include "eca-object-map.h" #include "eca-preset-map.h" #include "eca-static-object-maps.h" #include "eca-resources.h" #include "eca-logger.h" #include "eca-error.h" using std::cerr; using std::endl; using std::find; using std::string; using std::list; using std::vector; /** * Declarations for static private helper functions */ static vector eca_create_ladspa_plugins(const string& fname); static void eca_import_lv2_plugins(ECA_OBJECT_MAP* objmap); static void eca_import_ladspa_plugins(ECA_OBJECT_MAP* objmap, bool reg_with_id); #ifdef ECA_ENABLE_AUDIOIO_PLUGINS static void eca_import_internal_audioio_plugin(ECA_OBJECT_MAP* objmap, const string& filename); #endif /** * Definitions of static member functions */ void ECA_STATIC_OBJECT_MAPS::register_audio_io_rt_objects(ECA_OBJECT_MAP* objmap) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_audio_io_rt_objects()"); AUDIO_IO* device = 0; #ifdef ECA_COMPILE_OSS device = new OSSDEVICE(); objmap->register_object("/dev/dsp", "/dev/dsp[0-9]*", device); objmap->register_object("/dev/sound/dsp", "/dev/sound/dsp[0-9]*", device); #endif device = new REALTIME_NULL(); objmap->register_object("rtnull", "^rtnull$", device); #ifdef ECA_ENABLE_AUDIOIO_PLUGINS eca_import_internal_audioio_plugin(objmap, "libaudioio_alsa.so"); eca_import_internal_audioio_plugin(objmap, "libaudioio_alsa_named.so"); eca_import_internal_audioio_plugin(objmap, "libaudioio_arts.so"); eca_import_internal_audioio_plugin(objmap, "libaudioio_jack.so"); #else /* ECA_ENABLE_AUDIOIO_PLUGINS */ #ifdef ECA_COMPILE_ALSA device = new AUDIO_IO_ALSA_PCM(); objmap->register_object("alsahw_09", "(^alsahw_09$)|(^alsaplugin_09$)", device); device = new AUDIO_IO_ALSA_PCM_NAMED(); objmap->register_object("alsa_09", "^alsa_09$", device); #endif #ifdef ECA_COMPILE_ARTS device = new ARTS_INTERFACE(); objmap->register_object("arts", "^arts$", device); #endif #ifdef ECA_COMPILE_JACK device = new AUDIO_IO_JACK(); objmap->register_object("jack", "(^jack$)|(^jack_multi$)|(^jack_alsa$)|(^jack_auto$)|(^jack_generic$)", device); #endif #endif /* ECA_ENABLE_AUDIOIO_PLUGINS */ const ECA_OBJECT* aobj = 0; aobj = objmap->object("alsahw_09"); if (aobj != 0) { objmap->register_object("alsahw", "^alsahw$", const_cast(aobj)); objmap->register_object("alsaplugin", "^alsaplugin$", const_cast(aobj)); } aobj = objmap->object("alsa_09"); if (aobj != 0) { objmap->register_object("alsa", "^alsa$", const_cast(aobj)); } } void ECA_STATIC_OBJECT_MAPS::register_audio_io_nonrt_objects(ECA_OBJECT_MAP* objmap) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_audio_io_nonrt_objects()"); bool native_flac = false; objmap->register_object("wav", "wav$", new WAVEFILE()); objmap->register_object("ewf", "ewf$", new EWFFILE()); objmap->register_object("cdr", "cdr$", new CDRFILE()); AUDIO_IO* raw = new RAWFILE(); objmap->register_object("raw", "raw$", raw); AUDIO_IO* mp3 = new MP3FILE(); objmap->register_object("mp3", "mp3$", mp3); objmap->register_object("mp2", "mp2$", mp3); AUDIO_IO* ogg = new OGG_VORBIS_INTERFACE(); objmap->register_object("ogg", "ogg$", ogg); AUDIO_IO* mikmod = new MIKMOD_INTERFACE(); objmap->register_object("mikmod", "(^mikmod$)|(xm$)|(669$)|(amf$)|(dsm$)|(far$)|(gdm$)|(imf$)|" "(it$)|(m15$)|(ed$)|(mod$)|(mtm$)|(s3m$)|" "(stm$)|(stx$)|(ult$)|(uni$)", mikmod); AUDIO_IO* timidity = new TIMIDITY_INTERFACE(); objmap->register_object("mid", "(mid$)|(midi$)", timidity); AUDIO_IO* forkedaac = new AAC_FORKED_INTERFACE(); objmap->register_object("aac", "aac$", forkedaac); objmap->register_object("mp4", "mp4$", forkedaac); objmap->register_object("m4a", "m4a$", forkedaac); #ifdef ECA_ENABLE_AUDIOIO_PLUGINS eca_import_internal_audioio_plugin(objmap, "libaudioio_af.so"); eca_import_internal_audioio_plugin(objmap, "libaudioio_sndfile.so"); #else /* !ECA_ENABLE_AUDIOIO_PLUGINS */ /* ---------------------------------------------------------*/ /* register file types to plugins handling audio file types */ #if defined(ECA_COMPILE_SNDFILE) || defined(ECA_COMPILE_AUDIOFILE) string common_types ("(aif*$)|(au$)|(snd$)"); #endif #ifdef ECA_COMPILE_SNDFILE SNDFILE_INTERFACE* sndfile = new SNDFILE_INTERFACE(); /* 1. register types supported by libsndfile */ string sf_types ("(^sndfile$)"); list el = sndfile->supported_extensions(); list::const_iterator i = el.begin(); string sf_all_types; while(i != el.end()) { sf_all_types += *i + ","; ++i; } ECA_LOG_MSG(ECA_LOGGER::user_objects, "All libsndfile supported extensions: " + sf_all_types); if (find(el.begin(), el.end(), "flac") != el.end()) { sf_types += "|(flac$)"; native_flac = true; } if (find(el.begin(), el.end(), "avr") != el.end()) sf_types += "|(avr$)"; if (find(el.begin(), el.end(), "caf") != el.end()) sf_types += "|(caf$)"; if (find(el.begin(), el.end(), "htk") != el.end()) sf_types += "|(htk$)"; if (find(el.begin(), el.end(), "iff") != el.end()) sf_types += "|(iff$)"; if (find(el.begin(), el.end(), "mat") != el.end()) sf_types += "|(mat$)"; if (find(el.begin(), el.end(), "paf") != el.end()) sf_types += "|(paf$)"; if (find(el.begin(), el.end(), "pvf") != el.end()) sf_types += "|(pvf$)"; if (find(el.begin(), el.end(), "nist") != el.end()) sf_types += "|(nist$)"; if (find(el.begin(), el.end(), "sf") != el.end()) sf_types += "|(sf$)"; if (find(el.begin(), el.end(), "sd2") != el.end()) sf_types += "|(sd2$)"; if (find(el.begin(), el.end(), "sds") != el.end()) sf_types += "|(sds$)"; if (find(el.begin(), el.end(), "voc") != el.end()) sf_types += "|(voc$)"; if (find(el.begin(), el.end(), "w64") != el.end()) sf_types += "|(w64$)"; if (find(el.begin(), el.end(), "xi") != el.end()) sf_types += "|(xi$)"; /* add formats supported by both libaudiofile and libsndfile */ sf_types += string("|") + common_types; common_types.clear(); objmap->register_object("sndfile", sf_types.c_str(), dynamic_cast(sndfile)); #endif #ifdef ECA_COMPILE_AUDIOFILE /* 2. register types for libaudiofile */ string af_types ("(^audiofile$)"); /* note, if sndfile not available, common_types are registered * to libaudiofile */ if (common_types.size() > 0) af_types += string("|") + common_types; AUDIO_IO* af = new AUDIOFILE_INTERFACE(); objmap->register_object("audiofile", af_types.c_str(), af); #endif /* ---------------------------------------------------------*/ #endif /* ECA_ENABLE_AUDIOIO_PLUGINS */ objmap->register_object("-", "^-$", raw); objmap->register_object("stdin", "^stdin$", raw); objmap->register_object("stdout", "^stdout$", raw); objmap->register_object("null", "^null$", new NULLFILE()); objmap->register_object("typeselect", "^typeselect$", new AUDIO_IO_TYPESELECT()); objmap->register_object("resample", "^resample$", new AUDIO_IO_RESAMPLE()); objmap->register_object("resample-hq", "^resample-hq$", new AUDIO_IO_RESAMPLE()); objmap->register_object("resample-lq", "^resample-lq$", new AUDIO_IO_RESAMPLE()); objmap->register_object("reverse", "^reverse$", new AUDIO_IO_REVERSE()); objmap->register_object("tone", "^tone$", new AUDIO_IO_TONE()); objmap->register_object("audioloop", "^(audioloop|select|playat)$", new AUDIO_CLIP_SEQUENCER()); if (native_flac != true) { AUDIO_IO* forkedflac = new FLAC_FORKED_INTERFACE(); objmap->register_object("flac", "flac$", forkedflac); } } void ECA_STATIC_OBJECT_MAPS::register_chain_operator_objects(ECA_OBJECT_MAP* objmap) { #ifndef ECA_DISABLE_EFFECTS ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_chain_operator_objects()"); objmap->register_object("eS", "^eS$", new EFFECT_AUDIO_STAMP()); objmap->register_object("ea", "^ea$", new EFFECT_AMPLIFY()); objmap->register_object("eadb", "^eadb$", new EFFECT_AMPLIFY_DB()); objmap->register_object("eac", "^eac$", new EFFECT_AMPLIFY_CHANNEL()); objmap->register_object("eal", "^eal$", new EFFECT_LIMITER()); objmap->register_object("eaw", "^eaw$", new EFFECT_AMPLIFY_CLIPCOUNT()); objmap->register_object("ec", "^ec$", new EFFECT_COMPRESS()); objmap->register_object("eca", "^eca$", new ADVANCED_COMPRESSOR()); objmap->register_object("eemb", "^eemb$", new EFFECT_PULSE_GATE_BPM()); objmap->register_object("eemp", "^eemp$", new EFFECT_PULSE_GATE()); objmap->register_object("eemt", "^eemt$", new EFFECT_TREMOLO()); objmap->register_object("ef1", "^ef1$", new EFFECT_RESONANT_BANDPASS()); objmap->register_object("ef3", "^ef3$", new EFFECT_RESONANT_LOWPASS()); objmap->register_object("ef4", "^ef4$", new EFFECT_RC_LOWPASS_FILTER()); objmap->register_object("efa", "^efa$", new EFFECT_ALLPASS_FILTER()); objmap->register_object("efb", "^efb$", new EFFECT_BANDPASS()); objmap->register_object("efc", "^efc$", new EFFECT_COMB_FILTER()); objmap->register_object("efh", "^efh$", new EFFECT_HIGHPASS()); objmap->register_object("efi", "^efi$", new EFFECT_INVERSE_COMB_FILTER()); objmap->register_object("efl", "^efl$", new EFFECT_LOWPASS()); objmap->register_object("efr", "^efr$", new EFFECT_BANDREJECT()); objmap->register_object("efs", "^efs$", new EFFECT_RESONATOR()); objmap->register_object("ei", "^ei$", new EFFECT_PITCH_SHIFT()); objmap->register_object("enm", "^enm$", new EFFECT_NOISEGATE()); objmap->register_object("epp", "^epp$", new EFFECT_NORMAL_PAN()); objmap->register_object("chorder", "^chorder$", new EFFECT_CHANNEL_ORDER()); EFFECT_CHANNEL_COPY *op_cp = new EFFECT_CHANNEL_COPY(); objmap->register_object("chcopy", "^chcopy$", op_cp); objmap->register_object("erc", "^erc$", op_cp); objmap->register_object("chmove", "^chmove$", new EFFECT_CHANNEL_MOVE()); objmap->register_object("chmute", "^chmute$", new EFFECT_CHANNEL_MUTE()); EFFECT_MIX_TO_CHANNEL *op_mix = new EFFECT_MIX_TO_CHANNEL(); objmap->register_object("erm", "^erm$", op_mix); objmap->register_object("chmix", "^chmix$", op_mix); objmap->register_object("etc", "^etc$", new EFFECT_CHORUS()); objmap->register_object("etd", "^etd$", new EFFECT_DELAY()); objmap->register_object("ete", "^ete$", new ADVANCED_REVERB()); objmap->register_object("etf", "^etf$", new EFFECT_FAKE_STEREO()); objmap->register_object("etl", "^etl$", new EFFECT_FLANGER()); objmap->register_object("etm", "^etm$", new EFFECT_MULTITAP_DELAY()); objmap->register_object("etp", "^etp$", new EFFECT_PHASER()); objmap->register_object("etr", "^etr$", new EFFECT_REVERB()); objmap->register_object("ev", "^ev$", new EFFECT_VOLUME_BUCKETS()); objmap->register_object("evp", "^evp$", new EFFECT_VOLUME_PEAK()); objmap->register_object("ezf", "^ezf$", new EFFECT_DCFIND()); objmap->register_object("ezx", "^ezx$", new EFFECT_DCFIX()); objmap->register_object("gc", "^gc$", new TIME_CROP_GATE()); objmap->register_object("ge", "^ge$", new THRESHOLD_GATE()); objmap->register_object("gm", "^gm$", new MANUAL_GATE()); #endif } void ECA_STATIC_OBJECT_MAPS::register_lv2_plugin_objects(ECA_OBJECT_MAP* objmap) { #ifndef ECA_DISABLE_EFFECTS ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_lv2_plugin_objects()"); eca_import_lv2_plugins(objmap); #endif } void ECA_STATIC_OBJECT_MAPS::register_ladspa_plugin_objects(ECA_OBJECT_MAP* objmap) { #ifndef ECA_DISABLE_EFFECTS ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_ladspa_plugin_objects()"); eca_import_ladspa_plugins(objmap, false); #endif } void ECA_STATIC_OBJECT_MAPS::register_ladspa_plugin_id_objects(ECA_OBJECT_MAP* objmap) { #ifndef ECA_DISABLE_EFFECTS ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_ladspa_plugin_id_objects()"); eca_import_ladspa_plugins(objmap, true); #endif } void ECA_STATIC_OBJECT_MAPS::register_preset_objects(ECA_PRESET_MAP* objmap) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_preset_objects()"); /* @see ECA_PRESET_MAP */ } void ECA_STATIC_OBJECT_MAPS::register_controller_objects(ECA_OBJECT_MAP* objmap) { #ifndef ECA_DISABLE_EFFECTS ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_controller_objects()"); objmap->register_object("kf", "^kf$", new GENERIC_CONTROLLER(new GENERIC_OSCILLATOR_FILE())); objmap->register_object("kog", "^kog$", new GENERIC_CONTROLLER(new GENERIC_OSCILLATOR())); objmap->register_object("kl", "^kl$", new GENERIC_CONTROLLER(new LINEAR_ENVELOPE())); objmap->register_object("kl2", "^kl2$", new GENERIC_CONTROLLER(new TWO_STAGE_LINEAR_ENVELOPE())); objmap->register_object("klg", "^klg$", new GENERIC_CONTROLLER(new GENERIC_LINEAR_ENVELOPE())); objmap->register_object("km", "^km$", new GENERIC_CONTROLLER(new MIDI_CONTROLLER())); objmap->register_object("kos", "^kos$", new GENERIC_CONTROLLER(new SINE_OSCILLATOR())); objmap->register_object("ksv", "^ksv$", new GENERIC_CONTROLLER(new VOLUME_ANALYZE_CONTROLLER())); #endif } void ECA_STATIC_OBJECT_MAPS::register_midi_device_objects(ECA_OBJECT_MAP* objmap) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_midi_device_objects()"); objmap->register_object("rawmidi", "^rawmidi$", new MIDI_IO_RAW()); #ifdef ECA_COMPILE_ALSA objmap->register_object("alsaseq", "^alsaseq$", new MIDI_IO_ASEQ()); #endif } /** * Definitions for static private helper functions */ #ifdef ECA_ENABLE_AUDIOIO_PLUGINS /** * Load ecasound's internal plugins. Not used since 2.2.0. */ static void eca_import_internal_audioio_plugin(ECA_OBJECT_MAP* objmap, const string& filename) { ECA_RESOURCES ecarc; string libdir = ecarc.resource("internal-plugin-directory"); struct stat fbuf; if (stat(libdir.c_str(), &fbuf) < 0) { ECA_LOG_MSG(ECA_LOGGER::info, "Internal-plugin directory not found. Check your ~/.ecasoundrc!"); return; } string file = libdir + string("/") + filename; audio_io_descriptor desc_func = 0; audio_io_interface_version plugin_version = 0; audio_io_keyword plugin_keyword = 0; audio_io_keyword_regex plugin_keyword_regex = 0; void *plugin_handle = dlopen(file.c_str(), RTLD_NOW | RTLD_GLOBAL); /* RTLD_LAZY */ if (plugin_handle != 0) { plugin_version = (audio_io_interface_version)dlsym(plugin_handle, "audio_io_interface_version"); if (plugin_version != 0) { int version = plugin_version(); if (version < ecasound_library_version_current - ecasound_library_version_age || version > ecasound_library_version_current) { ECA_LOG_MSG(ECA_LOGGER::info, "Opening internal plugin file \"" + file + "\" failed. Plugin version " + kvu_numtostr(version) + " doesn't match libecasound version " + kvu_numtostr(ecasound_library_version_current) + "." + kvu_numtostr(ecasound_library_version_revision) + "." + kvu_numtostr(ecasound_library_version_age) + "."); } else { desc_func = (audio_io_descriptor)dlsym(plugin_handle, "audio_io_descriptor"); plugin_keyword = (audio_io_keyword)dlsym(plugin_handle, "audio_io_keyword"); plugin_keyword_regex = (audio_io_keyword_regex)dlsym(plugin_handle, "audio_io_keyword_regex"); if (desc_func != 0) { AUDIO_IO* aobj = desc_func(); if (plugin_keyword != 0 && plugin_keyword_regex != 0) { objmap->register_object(plugin_keyword(), plugin_keyword_regex(), aobj); // std::cerr << "Registering audio io type: " << aobj->name() << "\nType keyword " << plugin_keyword() << ", regex " << plugin_keyword_regex() << "." << std::endl; } } } } else { std::cerr << "(eca-static-object-maps) dlsym() failed; " << file; std::cerr << ": \"" << dlerror() << "\"." << std::endl; } } else { ECA_LOG_MSG(ECA_LOGGER::user_objects, "dlopen() failed; " + file + + ": \"" + string(dlerror()) + "\"."); } if (plugin_handle == 0 || plugin_version == 0 || plugin_keyword == 0 || plugin_keyword_regex == 0 || desc_func == 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Opening internal plugin file \"" + file + "\" failed."); } } #endif static void eca_import_ladspa_plugins(ECA_OBJECT_MAP* objmap, bool reg_with_id) { DIR *dp; vector dir_names; char* env = std::getenv("LADSPA_PATH"); if (env != 0) { dir_names = kvu_string_to_vector(string(env), ':'); } /* add directories mentioned in 'ladspa-plugin-directory' * to the directory search list and remove duplicates */ ECA_RESOURCES ecarc; string add_file = ecarc.resource("ladspa-plugin-directory"); vector more_dir_names = kvu_string_to_vector(add_file, ':'); vector::const_iterator di = more_dir_names.begin(); while(di != more_dir_names.end()) { if (find(dir_names.begin(), dir_names.end(), *di) == dir_names.end()) { dir_names.push_back(*di); } ++di; } /* go through all directories in the list and * try to open all encountered files as LADSPA plugins */ struct stat statbuf; vector::const_iterator p = dir_names.begin(); while (p != dir_names.end()) { dp = opendir(p->c_str()); if (dp != 0) { struct dirent *entry = readdir(dp); for(; entry != 0; entry = readdir(dp)) { string full_path_str = string(*p + "/" + entry->d_name); int err = lstat(full_path_str.c_str(), &statbuf); if (err) { ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Invalid LADSPA plugin file \"") + entry->d_name + "\" (" + strerror(errno) + ")."); continue; } if (S_ISDIR(statbuf.st_mode)) { ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Skipping directory \"") + entry->d_name + "\" while loading LADSPA plugins."); continue; } if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) { ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Skipping device \"") + entry->d_name + "\" while loading LADSPA plugins."); continue; } if (S_ISFIFO(statbuf.st_mode) || S_ISSOCK(statbuf.st_mode)) { ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Skipping pipe/socket \"") + entry->d_name + "\" while loading LADSPA plugins."); continue; } vector ladspa_plugins; try { if (entry->d_name[0] != '.') ladspa_plugins = eca_create_ladspa_plugins(full_path_str.c_str()); } catch(ECA_ERROR& e) { } for(unsigned int n = 0; n < ladspa_plugins.size(); n++) { if (reg_with_id == true) { objmap->register_object(kvu_numtostr(ladspa_plugins[n]->unique_number()), "^" + kvu_numtostr(ladspa_plugins[n]->unique_number()) + "$", ladspa_plugins[n]); } else { objmap->register_object(ladspa_plugins[n]->unique(), "^" + kvu_string_regex_meta_escape(ladspa_plugins[n]->unique()) + "$", ladspa_plugins[n]); } } } } ++p; } } static vector eca_create_ladspa_plugins(const string& fname) { vector plugins; #ifndef ECA_DISABLE_EFFECTS void *plugin_handle = dlopen(fname.c_str(), RTLD_NOW); if (plugin_handle != 0) { LADSPA_Descriptor_Function desc_func; desc_func = (LADSPA_Descriptor_Function)dlsym(plugin_handle, "ladspa_descriptor"); if (desc_func != 0) { const LADSPA_Descriptor *plugin_desc = 0; for (int i = 0;; i++) { plugin_desc = desc_func(i); if (plugin_desc == 0) break; try { plugins.push_back(new EFFECT_LADSPA(plugin_desc)); } catch (ECA_ERROR&) { } plugin_desc = 0; } } else { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Unable find plugin LADSPA-descriptor."); } } else { ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Unable to open plugin file \"") + fname + "\"."); } #endif return plugins; } static void eca_import_lv2_plugins(ECA_OBJECT_MAP* objmap) { #if !defined(ECA_DISABLE_EFFECTS) && defined(ECA_USE_LIBLILV) LilvWorld* world=ECA_LV2_WORLD::World(); lilv_world_load_all(world); const LilvPlugins* plugins=lilv_world_get_all_plugins(world); LILV_FOREACH(plugins,i,plugins) { const LilvPlugin* p=lilv_plugins_get(plugins,i); try { EFFECT_LV2* eff=new EFFECT_LV2(p); objmap->register_object(eff->unique(), "^" + kvu_string_regex_meta_escape(eff->unique()) + "$", eff); } catch (ECA_ERROR&) { } } #endif } ecasound-2.9.1/libecasound/midi-parser.h0000644000076400007640000000072610664032032015133 00000000000000#ifndef INCLUDED_MIDI_PARSER_H #define INCLUDED_MIDI_PARSER_H /** * Collection of static functions and small stateful * machines for parsing MIDI messages. */ class MIDI_PARSER { public: static bool is_voice_category_status_byte(unsigned char byte); static bool is_system_common_category_status_byte(unsigned char byte); static bool is_realtime_category_status_byte(unsigned char byte); static bool is_status_byte(unsigned char byte); }; #endif ecasound-2.9.1/libecasound/eca-static-object-maps.h0000644000076400007640000000250411740524567017151 00000000000000#ifndef INCLUDED_ECA_STATIC_OBJECT_MAPS_H #define INCLUDED_ECA_STATIC_OBJECT_MAPS_H class ECA_OBJECT_FACTORY; class ECA_OBJECT_MAP; class ECA_PRESET_MAP; /** * A private classed used by ECA_OBJECT_FACTORY * to access object maps. * * @author Kai Vehmanen */ class ECA_STATIC_OBJECT_MAPS { public: friend class ECA_OBJECT_FACTORY; private: static void register_audio_io_rt_objects(ECA_OBJECT_MAP* objmap); static void register_audio_io_nonrt_objects(ECA_OBJECT_MAP* objmap); static void register_chain_operator_objects(ECA_OBJECT_MAP* objmap); static void register_lv2_plugin_objects(ECA_OBJECT_MAP* objmap); static void register_ladspa_plugin_objects(ECA_OBJECT_MAP* objmap); static void register_ladspa_plugin_id_objects(ECA_OBJECT_MAP* objmap); static void register_preset_objects(ECA_PRESET_MAP* objmap); static void register_controller_objects(ECA_OBJECT_MAP* objmap); static void register_midi_device_objects(ECA_OBJECT_MAP* objmap); /** * @name Constructors and destructors * * To prevent accidental use, located in private scope and * without a valid definition. */ /*@{*/ ECA_STATIC_OBJECT_MAPS(void); ECA_STATIC_OBJECT_MAPS(const ECA_STATIC_OBJECT_MAPS&); ECA_STATIC_OBJECT_MAPS& operator=(const ECA_STATIC_OBJECT_MAPS&); ~ECA_STATIC_OBJECT_MAPS(void); /*@}*/ }; #endif ecasound-2.9.1/libecasound/audiofx_envelope_modulation.h0000644000076400007640000000644610664032032020513 00000000000000#ifndef INCLUDED_AUDIOFX_ENVELOPE_MODULATION_H #define INCLUDED_AUDIOFX_ENVELOPE_MODULATION_H #include #include "samplebuffer_iterators.h" #include "audiofx.h" /** * Virtual base for envelope modulation effects. * @author Rob Coker */ class EFFECT_ENV_MOD : public EFFECT_BASE { public: virtual ~EFFECT_ENV_MOD(void); }; /** * Pulse shaped gate * @author Rob Coker */ class EFFECT_PULSE_GATE: public EFFECT_ENV_MOD { SAMPLE_ITERATOR_INTERLEAVED i; parameter_t freq_rep; parameter_t on_time_rep; long int period_rep; long int on_from_rep; long int current_rep; public: virtual std::string name(void) const { return("Pulse Gate"); } virtual std::string parameter_names(void) const { return("freq-Hz,on-time-%"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_PULSE_GATE (parameter_t freq_Hz = 1.0, parameter_t onTime_percent = 50.0); virtual ~EFFECT_PULSE_GATE(void); EFFECT_PULSE_GATE* clone(void) const { return new EFFECT_PULSE_GATE(*this); } EFFECT_PULSE_GATE* new_expr(void) const { return new EFFECT_PULSE_GATE(); } /** @name Protected virtual functions to notify about changes * (Reimplemented from ECA_SAMPLERATE_AWARE) */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ }; /** * Wrapper class for pulse shaped gate providing * a beats-per-minute (bpm) based parameters. * * @author Kai Vehmanen */ class EFFECT_PULSE_GATE_BPM : public EFFECT_ENV_MOD { EFFECT_PULSE_GATE pulsegate_rep; public: virtual std::string name(void) const { return("Pulse gate BPM"); } virtual std::string parameter_names(void) const { return("bpm,on-time-msec"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_PULSE_GATE_BPM (parameter_t bpm = 120.0, parameter_t ontime_percent = 5.0); virtual ~EFFECT_PULSE_GATE_BPM(void); EFFECT_PULSE_GATE_BPM* clone(void) const { return new EFFECT_PULSE_GATE_BPM(*this); } EFFECT_PULSE_GATE_BPM* new_expr(void) const { return new EFFECT_PULSE_GATE_BPM(); } /** @name Protected virtual functions to notify about changes * (Reimplemented from ECA_SAMPLERATE_AWARE) */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ }; /** * Tremolo * @author Rob Coker */ class EFFECT_TREMOLO: public EFFECT_ENV_MOD { SAMPLE_ITERATOR_INTERLEAVED i; parameter_t freq; parameter_t depth; parameter_t currentTime; parameter_t incrTime; public: virtual std::string name(void) const { return("Tremolo"); } virtual std::string parameter_names(void) const { return("bpm,depth-%"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_TREMOLO (parameter_t freq_bpm = 60.0, parameter_t depth_percent = 100.0); virtual ~EFFECT_TREMOLO(void); EFFECT_TREMOLO* clone(void) const { return new EFFECT_TREMOLO(*this); } EFFECT_TREMOLO* new_expr(void) const { return new EFFECT_TREMOLO(); } }; #endif ecasound-2.9.1/libecasound/ctrl-source.h0000644000076400007640000000207011034750333015156 00000000000000#ifndef INCLUDE_CTRL_SOURCE_H #define INCLUDE_CTRL_SOURCE_H #include "eca-audio-position.h" #include "eca-operator.h" /** * Interface class for implementing control data * source objects. */ class CONTROLLER_SOURCE : public OPERATOR { public: typedef SAMPLE_SPECS::sample_t parameter_t; /** * Initializes the controller source. * * This function is called at least once before * the first call to value(). */ virtual void init(void) = 0; /** * Returns the current value for the given * position. */ virtual parameter_t value(double pos_secs) = 0; /** * Sets an initial value for the controller. * * Controllers that are driven by external sources, can use the * initial value if there is an initial gap in control data. The * standard value range ofs [0,1] should be used. * * Should be set before the first call to value(). */ virtual void set_initial_value(parameter_t arg) = 0; virtual CONTROLLER_SOURCE* clone(void) const = 0; virtual CONTROLLER_SOURCE* new_expr(void) const = 0; }; #endif ecasound-2.9.1/libecasound/eca-fileio-mmap.h0000644000076400007640000000324510664032032015643 00000000000000#ifndef INCLUDED_FILEIO_MMAP_H #define INCLUDED_FILEIO_MMAP_H #include #include "eca-fileio.h" #ifndef MAP_FAILED #define MAP_FAILED ((__ptr_t) -1) #endif #if !defined _CADDR_T && !defined __USE_BSD #define _CADDR_T typedef char* caddr_t; #endif /** * File-io and buffering using mmap for data transfers. */ class ECA_FILE_IO_MMAP : public ECA_FILE_IO { public: ECA_FILE_IO_MMAP(void); virtual ~ECA_FILE_IO_MMAP(void); // -- // Open/close routines // --- virtual void open_file(const std::string& fname, const std::string& fmode); virtual void open_stdin(void) { } virtual void open_stdout(void) { } virtual void open_stderr(void) { } virtual void close_file(void); // -- // Normal file operations // --- virtual void read_to_buffer(void* obuf, off_t bytes); virtual void write_from_buffer(void* obuf, off_t bytes); virtual void set_file_position(off_t newpos) { set_file_position(newpos,true); } virtual void set_file_position(off_t newpos, bool seek); virtual void set_file_position_advance(off_t fw); virtual void set_file_position_end(void); virtual off_t get_file_position(void) const; virtual off_t get_file_length(void) const; // -- // Status // --- virtual bool is_file_ready(void) const; virtual bool is_file_error(void) const; virtual bool is_file_ended(void) const; virtual off_t file_bytes_processed(void) const; virtual const std::string& file_mode(void) const { return(mode_rep); } private: int fd_rep; caddr_t buffer_repp; off_t bytes_rep; off_t fposition_rep; off_t flength_rep; bool file_ready_rep; bool file_ended_rep; std::string mode_rep; std::string fname_rep; }; #endif ecasound-2.9.1/libecasound/audioio-raw.h0000644000076400007640000000255611033001310015124 00000000000000#ifndef INCLUDE_AUDIOIO_RAW_H #define INCLUDE_AUDIOIO_RAW_H #include #include #include "eca-fileio.h" #include "eca-fileio-mmap.h" #include "eca-fileio-stream.h" /** * Class for handling raw/headerless audio files * * - multiple channels are interleaved, left channel first * * @author Kai Vehmanen */ class RAWFILE : public AUDIO_IO_BUFFERED { public: RAWFILE (const std::string& name = ""); virtual ~RAWFILE(void); virtual RAWFILE* clone(void) const; virtual RAWFILE* new_expr(void) const { return new RAWFILE(); } virtual std::string name(void) const { return("Raw audio file"); } virtual std::string parameter_names(void) const { return("label,toggle_mmap"); } virtual void open(void) throw (AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const; virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; private: ECA_FILE_IO* fio_repp; std::string mmaptoggle_rep; RAWFILE(const RAWFILE& x) { } RAWFILE& operator=(const RAWFILE& x) { return *this; } void set_length_in_bytes(void); }; #endif ecasound-2.9.1/libecasound/audioio-rtnull.cpp0000644000076400007640000001466511163001560016225 00000000000000// ------------------------------------------------------------------------ // audioio-rtnull.cpp: Null audio object with realtime behaviour // Copyright (C) 1999,2002,2005 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include /* gettimeofday() */ #include #include #include "audioio-device.h" #include "audioio-rtnull.h" #include "eca-error.h" #include "eca-logger.h" using std::cerr; using std::endl; /** * Definitions from glibc's sys/time.h (LGPL 2.1) */ #ifndef timerclear #define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #endif #ifndef timeradd #define timeradd(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ if ((result)->tv_usec >= 1000000) \ { \ ++(result)->tv_sec; \ (result)->tv_usec -= 1000000; \ } \ } while (0) #endif #ifndef timercmp #define timercmp(a, b, CMP) \ (((a)->tv_sec == (b)->tv_sec) ? \ ((a)->tv_usec CMP (b)->tv_usec) : \ ((a)->tv_sec CMP (b)->tv_sec)) #endif #ifndef timersub #define timersub(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) #endif /** * Function definitions */ REALTIME_NULL::REALTIME_NULL(const std::string& name) { xruns_rep = 0; } REALTIME_NULL::~REALTIME_NULL(void) { if (is_open() == true && is_running()) stop(); if (is_open() == true) { close(); } if (xruns_rep != 0) { cerr << "(audioio-rtnull) WARNING! There were " << xruns_rep << " xruns while "; if (io_mode() != io_read) { cerr << "writing.\n"; } else { cerr << "reading.\n"; } } } void REALTIME_NULL::open(void) throw (AUDIO_IO::SETUP_ERROR &) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "open"); double t = static_cast(buffersize()) / samples_per_second(); buffer_length_rep.tv_sec = static_cast(floor(t)); buffer_length_rep.tv_usec = static_cast((t - buffer_length_rep.tv_sec) * 1000000.0); total_buffers_rep = 3; if (max_buffers() == true) { total_buffers_rep = 8; } total_buffer_length_rep.tv_sec = total_buffers_rep * buffer_length_rep.tv_sec; total_buffer_length_rep.tv_usec = total_buffers_rep * buffer_length_rep.tv_usec; AUDIO_IO_DEVICE::open(); } void REALTIME_NULL::close(void) { AUDIO_IO_DEVICE::close(); } void REALTIME_NULL::prepare(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "prepare"); timerclear(&data_processed_rep); AUDIO_IO_DEVICE::prepare(); } void REALTIME_NULL::start(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "start"); gettimeofday(&start_time_rep, NULL); AUDIO_IO_DEVICE::start(); } void REALTIME_NULL::stop(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "stop"); AUDIO_IO_DEVICE::stop(); } /** * Calculates 'time_since_start_rep'. */ void REALTIME_NULL::calculate_device_position(void) { struct timeval now; gettimeofday(&now, NULL); timersub(&now, &start_time_rep, &time_since_start_rep); } /** * Calculates 'avail_data_rep'. */ void REALTIME_NULL::calculate_available_data(void) const { if (io_mode() == io_read) { /* capture: device is always ahead */ timersub(&time_since_start_rep, &data_processed_rep, &avail_data_rep); } else { /* playback: device is always behind */ struct timeval diff; timersub(&data_processed_rep, &time_since_start_rep, &diff); timersub(&total_buffer_length_rep, &diff, &avail_data_rep); } if (timercmp(&avail_data_rep, &total_buffer_length_rep, >)) { ++xruns_rep; // cerr << "(audioio-rtnull) xrun occured!" << endl; } } void REALTIME_NULL::block_until_data_available(void) { calculate_device_position(); calculate_available_data(); while (timercmp(&avail_data_rep, &buffer_length_rep, <)) { struct timeval delay; timersub(&buffer_length_rep, &avail_data_rep, &delay); // cerr << "(audioio-rtnull) sleeping for: " << ndelay.tv_sec << " sec, " << ndelay.tv_nsec << " nanoseconds.\n"; kvu_sleep(delay.tv_sec, delay.tv_usec * 1000); calculate_device_position(); calculate_available_data(); } } long int REALTIME_NULL::read_samples(void* target_buffer, long int samples) { DBC_CHECK(is_running() == true); for(int n = 0; n < samples * frame_size(); n++) ((char*)target_buffer)[n] = 0; block_until_data_available(); /* read one buffer of audio */ timeradd(&data_processed_rep, &buffer_length_rep, &data_processed_rep); return buffersize(); } void REALTIME_NULL::write_samples(void* target_buffer, long int samples) { if (is_running() != true) { /* prefill phase */ /* write one buffer of audio */ timeradd(&data_processed_rep, &buffer_length_rep, &data_processed_rep); } else { /* block until write space available */ block_until_data_available(); /* write one buffer of audio */ timeradd(&data_processed_rep, &buffer_length_rep, &data_processed_rep); } } long int REALTIME_NULL::prefill_space(void) const { if (io_mode() != io_read) return total_buffers_rep * buffersize(); return 0; } long int REALTIME_NULL::delay(void) const { long int delay = 0; if (is_running() == true) { calculate_available_data(); double time = avail_data_rep.tv_sec * 1000000.0 + avail_data_rep.tv_usec; delay = static_cast (time * samples_per_second() / 1000000.0); } DBC_CHECK(delay >= 0); return delay; } ecasound-2.9.1/libecasound/eca-iamode-parser.h0000644000076400007640000000320611065031241016166 00000000000000#ifndef INCLUDED_ECA_IAMODE_PARSER_H #define INCLUDED_ECA_IAMODE_PARSER_H #include #include #include #include #include "eca-error.h" #include "eca-iamode-parser_impl.h" /** * Class that handles registering and querying interactive mode commands. * @author Kai Vehmanen */ class ECA_IAMODE_PARSER : protected ECA_IAMODE_PARSER_COMMANDS { public: static const std::map& registered_commands(void); static std::vector registered_commands_list(void); bool action_requires_params(int id); bool action_requires_connected(int id); bool action_requires_selected_not_connected(int id); bool action_requires_selected(int id); bool action_requires_selected_audio_input(int id); bool action_requires_selected_audio_output(int id); ECA_IAMODE_PARSER(void); virtual ~ECA_IAMODE_PARSER(void); protected: static int command_to_action_id(const std::string& cmdstring); private: static void register_commands_misc(void); static void register_commands_cs(void); static void register_commands_c(void); static void register_commands_aio(void); static void register_commands_ai(void); static void register_commands_ao(void); static void register_commands_cop(void); static void register_commands_copp(void); static void register_commands_ctrl(void); static void register_commands_ctrlp(void); static void register_commands_dump(void); static void register_commands_external(void); private: static std::map* cmd_map_repp; static pthread_mutex_t lock_rep; }; void show_controller_help(void); void show_controller_help_more(void); #endif ecasound-2.9.1/libecasound/audiofx_compressor.h0000644000076400007640000000570010664032032016627 00000000000000#ifndef INCLUDED_AUDIOFX_COMPRESSOR_H #define INCLUDED_AUDIOFX_COMPRESSOR_H #include #include "audiofx_amplitude.h" /** * C++ version of John Dyson's advanced compressor design. * @author Kai Vehmanen */ class ADVANCED_COMPRESSOR : public EFFECT_AMPLITUDE { SAMPLE_ITERATOR_INTERLEAVED iter; public: static const int NFILT = 12; static const int NEFILT = 17; public: ADVANCED_COMPRESSOR (void) : rlevelsqn(ADVANCED_COMPRESSOR::NFILT), rlevelsqe(ADVANCED_COMPRESSOR::NEFILT) { init_values(); // map_parameters(); } virtual ~ADVANCED_COMPRESSOR (void); virtual std::string name(void) const { return("Advanced compressor"); } virtual std::string parameter_names(void) const { return("peak-limit-%,release-time-sec,fast-crate,overall-crate"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual int output_channels(int i_channels) const { return(2); } ADVANCED_COMPRESSOR* clone(void) const { return new ADVANCED_COMPRESSOR(*this); } ADVANCED_COMPRESSOR* new_expr(void) const { return new ADVANCED_COMPRESSOR(); } ADVANCED_COMPRESSOR (double peak_limit, double release_time, double cfrate, double crate); private: double rlevelsq0, rlevelsq1; double rlevelsq0filter, rlevelsq1filter; std::vector rlevelsqn; // [NFILT]; double rlevelsqefilter; std::vector rlevelsqe; // [NEFILT]; double rlevelsq0ffilter; int ndelay; /* delay for rlevelsq0ffilter delay */ int ndelayptr; /* ptr for the input */ std::vector rightdelay; std::vector leftdelay; /* Simple gain running average */ double rgain; double rgainfilter; double lastrgain; /* Max fast agc gain, slow agc gain */ double maxfastgain, maxslowgain; /* Fast gain compression ratio */ /* Note that .5 is 2:1, 1.0 is infinity (hard) */ double fastgaincompressionratio; double compressionratio; /* Max level, target level, floor level */ double maxlevel, targetlevel, floorlevel; /* Gainriding gain */ double rmastergain0filter; double rmastergain0; /* Peak limit gain */ double rpeakgain0, rpeakgain1, rpeakgainfilter; int peaklimitdelay, rpeaklimitdelay; /* Running total gain */ double totalgain; /* Idle gain */ double npeakgain; /* Compress enabled */ int compress; double level, levelsq0, levelsq1, levelsqe; double gain, qgain, tgain; double newright, newleft; double efilt; double fastgain, slowgain, tslowgain; double leveldelta; double right, left, rightd, leftd; int delayed; double nrgain, nlgain, ngain, ngsq; double sqrtrpeakgain; int i; int skipmode; double extra_maxlevel; int parm; double maxgain, mingain; int ch; double fratio; double ratio; double releasetime; double peakpercent; double tnrgain; void init_values(void); double hardlimit(double value, double knee, double limit); }; #endif ecasound-2.9.1/libecasound/audioio-resample.cpp0000644000076400007640000003166011352471254016522 00000000000000// ------------------------------------------------------------------------ // audioio-resample.cpp: A proxy class that resamples the child // object's data. // Copyright (C) 2002-2004,2008,2009,2010 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 /* atoi() */ #include /* ceil(), floor() */ #include #include #include #include #include "audioio-resample.h" #include "eca-logger.h" #include "eca-object-factory.h" #include "samplebuffer.h" // #define RESAMPLE_VERBOSE_DEBUG 1 /** * Constructor. */ AUDIO_IO_RESAMPLE::AUDIO_IO_RESAMPLE (void) : psfactor_rep(1.0f), sbuf_rep(buffersize(), 0) { init_rep = false; quality_rep = 50; } /** * Destructor. */ AUDIO_IO_RESAMPLE::~AUDIO_IO_RESAMPLE (void) { } AUDIO_IO_RESAMPLE* AUDIO_IO_RESAMPLE::clone(void) const { AUDIO_IO_RESAMPLE* target = new AUDIO_IO_RESAMPLE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIO_IO_RESAMPLE::recalculate_psfactor(void) { DBC_REQUIRE(child_srate_conf_rep > 0); DBC_REQUIRE(io_mode() == AUDIO_IO::io_read); psfactor_rep = static_cast(samples_per_second()) / child_srate_conf_rep; child()->set_buffersize(static_cast(std::floor(buffersize() * (1.0f / psfactor_rep)))); ECA_LOG_MSG(ECA_LOGGER::user_objects, "recalc; psfactor=" + kvu_numtostr(psfactor_rep)); } void AUDIO_IO_RESAMPLE::open(void) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "open " + child_params_as_string(1 + AUDIO_IO_RESAMPLE::child_parameter_offset, ¶ms_rep) + "."); if (init_rep != true) { AUDIO_IO* tmp = 0; const string& objname = child_params_as_string(1 + AUDIO_IO_RESAMPLE::child_parameter_offset, ¶ms_rep); if (objname.size() > 0) tmp = ECA_OBJECT_FACTORY::create_audio_object(objname); /* FIXME: add check for real-time devices, resample does _not_ * work with them (rt API not proxied properly) */ if (tmp == 0) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-RESAMPLE: unable to open child object '" + objname + "'")); set_child(tmp); int numparams = child()->number_of_params(); for(int n = 0; n < numparams; n++) { child()->set_parameter(n + 1, get_parameter(n + 1 + AUDIO_IO_RESAMPLE::child_parameter_offset)); if (child()->variable_params()) numparams = child()->number_of_params(); } init_rep = true; /* must be set after dyn. parameters */ } if (child_srate_conf_rep == 0) { /* query the sampling rate from child object */ child()->set_io_mode(io_mode()); child()->set_audio_format(audio_format()); child()->open(); child_srate_conf_rep = child()->samples_per_second(); child()->close(); } if (io_mode() != AUDIO_IO::io_read) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-RESAMPLE: 'io_write' and 'io_readwrite' modes are not supported.")); recalculate_psfactor(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "pre-open(); psfactor=" + kvu_numtostr(psfactor_rep) + ", child_srate=" + kvu_numtostr(child_srate_conf_rep) + ", srate=" + kvu_numtostr(samples_per_second()) + ", bsize=" + kvu_numtostr(buffersize()) + ", c-bsize=" + kvu_numtostr(child()->buffersize()) + ", child=" + child()->label() + "."); /* note, we don't use pre_child_open() as * we want to set srate differently */ child()->set_io_mode(io_mode()); child()->set_audio_format(audio_format()); child()->set_samples_per_second(child_srate_conf_rep); child()->open(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "post-open(); child=" + child()->label() + "."); /* same for the post processing */ SAMPLE_SPECS::sample_rate_t orig_srate = samples_per_second(); if (child()->locked_audio_format() == true) { set_channels(child()->channels()); set_sample_format(child()->sample_format()); set_samples_per_second(orig_srate); toggle_interleaved_channels(child()->interleaved_channels()); } sbuf_rep.length_in_samples(buffersize()); sbuf_rep.number_of_channels(channels()); sbuf_rep.resample_init_memory(child_srate_conf_rep, samples_per_second()); sbuf_rep.resample_set_quality(quality_rep); set_label("resample:" + child()->label()); set_length_in_samples(static_cast(std::ceil(child()->length_in_samples() * psfactor_rep))); //set_length_in_seconds(child()->length_in_seconds_exact()); AUDIO_IO_PROXY::open(); } void AUDIO_IO_RESAMPLE::close(void) { if (child()->is_open() == true) child()->close(); init_rep = false; AUDIO_IO_PROXY::close(); } void AUDIO_IO_RESAMPLE::set_buffersize(long int samples) { if (samples != buffersize()) { long old_bsize = buffersize(); AUDIO_IO_PROXY::set_buffersize(samples); child()->set_buffersize(static_cast(std::floor(samples * (1.0f / psfactor_rep)))); ECA_LOG_MSG(ECA_LOGGER::user_objects, "setting bsize from " + kvu_numtostr(old_bsize) + " to " + kvu_numtostr(child()->buffersize())); } } long int AUDIO_IO_RESAMPLE::buffersize(void) const { return AUDIO_IO_PROXY::buffersize(); } string AUDIO_IO_RESAMPLE::parameter_names(void) const { return string("resample,srate,") + child()->parameter_names(); } void AUDIO_IO_RESAMPLE::set_parameter(int param, string value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, AUDIO_IO::parameter_set_to_string(param, value)); /* total of n+1 params, where n is number of childobj params */ if (param > static_cast(params_rep.size())) params_rep.resize(param); if (param > 0) { params_rep[param - 1] = value; if (param == 1) { if (value == "resample-hq") { quality_rep = 100; ECA_LOG_MSG(ECA_LOGGER::user_objects, "using high-quality resampler"); } else if (value == "resample-lq") { quality_rep = 5; ECA_LOG_MSG(ECA_LOGGER::user_objects, "using low-quality resampler"); } else { quality_rep = 50; ECA_LOG_MSG(ECA_LOGGER::user_objects, "using default resampler"); } } else if (param == 2) { if (value == "auto") { if (init_rep != true) child_srate_conf_rep = 0; ECA_LOG_MSG(ECA_LOGGER::user_objects, "resampling with automatic detection of child srate"); } else { child_srate_conf_rep = std::atoi(value.c_str()); ECA_LOG_MSG(ECA_LOGGER::user_objects, "resampling w/ child srate of " + kvu_numtostr(child_srate_conf_rep)); } } } sbuf_rep.resample_set_quality(quality_rep); if (param > AUDIO_IO_RESAMPLE::child_parameter_offset && init_rep == true) { child()->set_parameter(param - AUDIO_IO_RESAMPLE::child_parameter_offset, value); } } string AUDIO_IO_RESAMPLE::get_parameter(int param) const { if (param > 0 && param < static_cast(params_rep.size()) + 1) { if (param > AUDIO_IO_RESAMPLE::child_parameter_offset && init_rep == true) { params_rep[param - 1] = child()->get_parameter(param - AUDIO_IO_RESAMPLE::child_parameter_offset); } return params_rep[param - 1]; } return ""; } SAMPLE_SPECS::sample_pos_t AUDIO_IO_RESAMPLE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { SAMPLE_SPECS::sample_pos_t pub_pos, child_pos = static_cast(std::floor(pos * (1.0f / psfactor_rep))); child()->seek_position_in_samples(child_pos); child_pos = child()->position_in_samples(); pub_pos = static_cast(std::floor(child_pos * (psfactor_rep))); return pub_pos; } void AUDIO_IO_RESAMPLE::set_audio_format(const ECA_AUDIO_FORMAT& f_str) { AUDIO_IO::set_audio_format(f_str); child()->set_audio_format(f_str); /* set_audio_format() also sets the sample rate so we need to reset the value back to the correct one */ child()->set_samples_per_second(child_srate_conf_rep); } void AUDIO_IO_RESAMPLE::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { /* the child srate is set in open */ if (child()->is_open() == true) recalculate_psfactor(); AUDIO_IO::set_samples_per_second(v); } void AUDIO_IO_RESAMPLE::read_buffer(SAMPLE_BUFFER* dst_sbuf) { long int dst_left = buffersize(); SAMPLE_BUFFER::buf_size_t dst_write_pos = 0; dst_sbuf->number_of_channels(channels()); dst_sbuf->length_in_samples(dst_left); #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "--- (%ld samples)\n", dst_left); #endif /* step: copy any leftover resampled audio from * last iteration */ if (dst_left > 0 && leftoverbuf_rep.length_in_samples() > 0) { DBC_CHECK(leftoverbuf_rep.length_in_samples() <= dst_left); #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "leftover copy_range 0..%ld -> %ld..%ld, copied %ld, dst_left=%ld\n", leftoverbuf_rep.length_in_samples() - 1, dst_write_pos, dst_write_pos + leftoverbuf_rep.length_in_samples() - 1, leftoverbuf_rep.length_in_samples(), dst_left); #endif dst_sbuf->copy_range(leftoverbuf_rep, 0, leftoverbuf_rep.length_in_samples(), dst_write_pos); dst_sbuf->event_tags_add(leftoverbuf_rep); dst_left -= leftoverbuf_rep.length_in_samples(); dst_write_pos += leftoverbuf_rep.length_in_samples();; #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "copied %ld leftover samples, %ld remain, dst_write_pos=%ld\n", leftoverbuf_rep.length_in_samples(), dst_left, dst_write_pos); #endif leftoverbuf_rep.length_in_samples(0); } DBC_CHECK(leftoverbuf_rep.length_in_samples() == 0); /* note: loop until we have buffersize() worth of samples, * or until we encounter end-of-stream */ for(int i = 0; dst_left > 0; i++) { long int src_to_copy = dst_left; /* step: read sample buffer, src-rate */ child()->read_buffer(&sbuf_rep); #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "%d: asked for %ld samples, got %ld\n", i, child()->buffersize(), sbuf_rep.length_in_samples()); #endif /* step: resample dst-rate */ sbuf_rep.resample(child_srate_conf_rep, samples_per_second()); #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "after resample, %ld samples\n", sbuf_rep.length_in_samples()); #endif /* step: if we didn't get enough samples, adjust src_to_copy */ if (sbuf_rep.length_in_samples() < src_to_copy) src_to_copy = sbuf_rep.length_in_samples(); /* step: copy src_to_copy resampled samples */ #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "copy_range 0..%ld -> %ld..%ld, copied %ld, dst_left=%ld\n", src_to_copy - 1, dst_write_pos, dst_write_pos + src_to_copy - 1, src_to_copy, dst_left); #endif dst_sbuf->copy_range(sbuf_rep, 0, src_to_copy, dst_write_pos); dst_sbuf->event_tags_add(sbuf_rep); dst_write_pos += src_to_copy; dst_left -= src_to_copy; if (dst_left > 0 && sbuf_rep.event_tag_test(SAMPLE_BUFFER::tag_end_of_stream)) { dst_sbuf->event_tag_set(SAMPLE_BUFFER::tag_end_of_stream); dst_sbuf->length_in_samples(dst_sbuf->length_in_samples() - dst_left); break; } /* step: if there are any new leftovers, store them for * the next iteration */ if (sbuf_rep.length_in_samples() > src_to_copy) { DBC_CHECK(dst_left <= 0); SAMPLE_BUFFER::buf_size_t leftover = sbuf_rep.length_in_samples() - src_to_copy; leftoverbuf_rep.length_in_samples(leftover); leftoverbuf_rep.number_of_channels(channels()); #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "copy_range leftovers %ld..%ld -> %ld..%ld, copied %ld, dst_left=%ld\n", src_to_copy, sbuf_rep.length_in_samples() - 1, 0, leftover - 1, leftover, dst_left); #endif leftoverbuf_rep.copy_range(sbuf_rep, src_to_copy, sbuf_rep.length_in_samples(), 0); leftoverbuf_rep.event_tags_set(sbuf_rep); } } change_position_in_samples(dst_sbuf->length_in_samples()); #ifdef RESAMPLE_VERBOSE_DEBUG std::fprintf(stderr, "exit with %ld samples\n", dst_sbuf->length_in_samples()); #endif DBC_ENSURE(dst_sbuf->length_in_samples() <= buffersize()); DBC_ENSURE(dst_sbuf->number_of_channels() == channels()); } void AUDIO_IO_RESAMPLE::write_buffer(SAMPLE_BUFFER* sbuf) { /* FIXME: not implemented */ DBC_NEVER_REACHED(); change_position_in_samples(sbuf->length_in_samples()); } ecasound-2.9.1/libecasound/audioio-buffered.cpp0000644000076400007640000000774211161544004016470 00000000000000// ------------------------------------------------------------------------ // audioio-buffered.cpp: A lower level interface for audio I/O objects // Copyright (C) 1999-2002,2008,2009 Kai Vehmanen // // 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 /* ceil() */ #include #include "eca-logger.h" #include "samplebuffer.h" #include "audioio-buffered.h" AUDIO_IO_BUFFERED::AUDIO_IO_BUFFERED(void) : buffersize_rep(0), iobuf_uchar_repp(0), iobuf_size_rep(0) { } AUDIO_IO_BUFFERED::~AUDIO_IO_BUFFERED(void) { if (iobuf_uchar_repp != 0) { delete[] iobuf_uchar_repp; iobuf_uchar_repp = 0; iobuf_size_rep = 0; } } void AUDIO_IO_BUFFERED::reserve_buffer_space(long int bytes) { if (bytes > static_cast(iobuf_size_rep)) { if (iobuf_uchar_repp != 0) { delete[] iobuf_uchar_repp; iobuf_uchar_repp = 0; } // remember to include // std::cerr << "Reserving " << bytes << " bytes (" << label() << ").\n"; iobuf_uchar_repp = new unsigned char [bytes]; iobuf_size_rep = bytes; } } void AUDIO_IO_BUFFERED::set_buffersize(long int samples) { if (buffersize_rep != samples || static_cast(iobuf_size_rep) < buffersize_rep * frame_size()) { buffersize_rep = samples; reserve_buffer_space(buffersize_rep * frame_size()); } } void AUDIO_IO_BUFFERED::read_buffer(SAMPLE_BUFFER* sbuf) { // -------- DBC_REQUIRE(iobuf_uchar_repp != 0); DBC_REQUIRE(static_cast(iobuf_size_rep) >= buffersize_rep * frame_size()); // -------- if (interleaved_channels() == true) { sbuf->import_interleaved(iobuf_uchar_repp, read_samples(iobuf_uchar_repp, buffersize_rep), sample_format(), channels()); } else { sbuf->import_noninterleaved(iobuf_uchar_repp, read_samples(iobuf_uchar_repp, buffersize_rep), sample_format(), channels()); } if (sbuf->length_in_samples() < buffersize_rep) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "end-of-stream tag detected for '" + description() + "'"); sbuf->event_tag_set(SAMPLE_BUFFER::tag_end_of_stream); } change_position_in_samples(sbuf->length_in_samples()); // -------- DBC_ENSURE(sbuf->number_of_channels() == channels()); // -------- } void AUDIO_IO_BUFFERED::write_buffer(SAMPLE_BUFFER* sbuf) { // -------- DBC_REQUIRE(iobuf_uchar_repp != 0); DBC_REQUIRE(static_cast(iobuf_size_rep) >= buffersize_rep * frame_size()); // -------- set_buffersize(sbuf->length_in_samples()); if (interleaved_channels() == true) { sbuf->export_interleaved(iobuf_uchar_repp, sample_format(), channels()); } else { sbuf->export_noninterleaved(iobuf_uchar_repp, sample_format(), channels()); } write_samples(iobuf_uchar_repp, sbuf->length_in_samples()); change_position_in_samples(sbuf->length_in_samples()); extend_position(); } void AUDIO_IO_BUFFERED::set_channels(SAMPLE_SPECS::channel_t v) { AUDIO_IO::set_channels(v); /* adjust allocated buffers if audio format has changed */ set_buffersize(buffersize_rep); } void AUDIO_IO_BUFFERED::set_sample_format(Sample_format v) throw(ECA_ERROR&) { AUDIO_IO::set_sample_format(v); /* adjust allocated buffers if audio format has changed */ set_buffersize(buffersize_rep); } ecasound-2.9.1/libecasound/samplebuffer.h0000644000076400007640000001453611166105206015400 00000000000000#ifndef INCLUDED_SAMPLEBUFFER_H #define INCLUDED_SAMPLEBUFFER_H #include #include "eca-audio-format.h" #include "sample-specs.h" class SAMPLE_BUFFER_FUNCTIONS; class SAMPLE_BUFFER_impl; /** * A dynamic container for storing blocks of * audio data. * * Static attributes are: * - samples of type 'sample_t' (usually 32bit float) * * Dynamic attributes are: * - number of channels * - length in samples * - event tags * * Provided services: * - copying from/to other samplebuffer objects * - basic audio operations * - importing and exporting data from/to\n * raw buffers of audio data * - changing channel count and length * - reserving space before-hand * - realtime-safety and pointer locking * - access to event tags */ class SAMPLE_BUFFER { friend class SAMPLE_BUFFER_FUNCTIONS; friend class SAMPLE_ITERATOR; friend class SAMPLE_ITERATOR_CHANNEL; friend class SAMPLE_ITERATOR_CHANNELS; friend class SAMPLE_ITERATOR_INTERLEAVED; public: /** @name Public type definitions */ /*@{*/ typedef SAMPLE_SPECS::channel_t channel_size_t; typedef long int buf_size_t; typedef SAMPLE_SPECS::sample_t sample_t; enum Tag_name { /* buffer contains last samples of a stream */ tag_end_of_stream = 1, /* buffer contains samples from multiple inputs */ tag_mixed_content = (1 << 1), /* internal: placeholder */ tag_last = (1 << 30), /* internal: matches all tags */ tag_all = 0xffffffff }; /*@}*/ public: /** @name Constructors/destructors */ /*@{*/ SAMPLE_BUFFER (buf_size_t buffersize = 0, channel_size_t channels = 0); ~SAMPLE_BUFFER(void); /*@}*/ public: /** @name Copying from/to other samplebuffer objects */ /*@{*/ void add_matching_channels(const SAMPLE_BUFFER& x); void add_matching_channels_ref(const SAMPLE_BUFFER& x); void add_with_weight(const SAMPLE_BUFFER& x, int weight); void copy_matching_channels(const SAMPLE_BUFFER& x); void copy_all_content(const SAMPLE_BUFFER& x); void copy_range(const SAMPLE_BUFFER& x, buf_size_t start_pos, buf_size_t end_pos, buf_size_t to_pos); /*@}*/ /** @name Basic audio operations */ /*@{*/ void divide_by(sample_t dvalue); void divide_by_ref(sample_t dvalue); void multiply_by(sample_t factor); void multiply_by(sample_t factor, int channel); void multiply_by_ref(sample_t factor); void multiply_by_ref(sample_t factor, int channel); void limit_values(void); void limit_values_ref(void); void make_empty(void); bool is_empty(void) const { return buffersize_rep == 0; } void make_silent(void); void make_silent(int channel); void make_silent_ref(int channel); void make_silent_range(buf_size_t start_pos, buf_size_t end_pos); void make_silent_range_ref(buf_size_t start_pos, buf_size_t end_pos); void resample(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate); void resample_set_quality(int quality); int resample_get_quality(void) const; /*@}*/ /** * @name Importing and exporting data from/to raw buffers of audio data */ /*@{*/ void import_interleaved(unsigned char* source, buf_size_t samples, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch); void import_noninterleaved(unsigned char* source, buf_size_t samples, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch); void export_interleaved(unsigned char* target, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch); void export_noninterleaved(unsigned char* target, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t ch); /*@}*/ public: /** @name Changing channel count, length and sample-rate. */ /*@{*/ void number_of_channels(channel_size_t num); inline channel_size_t number_of_channels(void) const { return(channel_count_rep); } void length_in_samples(buf_size_t len); inline buf_size_t length_in_samples(void) const { return(buffersize_rep); } /*@}*/ /** @name Reserving space before-hand */ /*@{*/ void resample_init_memory(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate); void reserve_channels(channel_size_t num); void reserve_length_in_samples(buf_size_t len); /*@}*/ /** @name Realtime-safety and pointer locking */ /*@{*/ void set_rt_lock(bool state); void get_pointer_reflock(void); void release_pointer_reflock(void); /*@}*/ /** @name Event tags - for relaying additional info about the buffer */ /*@{*/ void event_tags_add(const SAMPLE_BUFFER& sbuf); void event_tags_set(const SAMPLE_BUFFER& sbuf); void event_tags_clear(Tag_name tagmask = tag_all); void event_tag_set(Tag_name tag, bool val = true); bool event_tag_test(Tag_name tag); /*@}*/ private: void resample_extfilter(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate); void resample_secret_rabbit_code(SAMPLE_SPECS::sample_rate_t from_srate, SAMPLE_SPECS::sample_rate_t to_srate); void resample_simplefilter(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate); void resample_nofilter(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate); void resample_with_memory(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate); static void import_helper(const unsigned char *ibuffer, buf_size_t* iptr, sample_t* obuffer, buf_size_t optr, ECA_AUDIO_FORMAT::Sample_format fmt); static void export_helper(unsigned char* obuffer, buf_size_t* optr, sample_t value, ECA_AUDIO_FORMAT::Sample_format fmt); public: /** @name Data representation */ /** * WARNING! Although 'buffer' is a public member, you should only * use it directly for a very, very good reason. All normal * input/output should be done via the SAMPLEBUFFER_ITERATORS * class. Representation of 'buffer' may change at any time, * and this will break all code using direct-access. * * If you do use direct access, then you must also * use the get_pointer_reflock() and release_pointer_reflock() * calls so that reference counting is possible. */ std::vector buffer; /*@}*/ private: /** @name Private data */ /*@{*/ channel_size_t channel_count_rep; buf_size_t buffersize_rep; buf_size_t reserved_samples_rep; /*@}*/ SAMPLE_BUFFER_impl* impl_repp; private: SAMPLE_BUFFER& operator= (const SAMPLE_BUFFER& t); SAMPLE_BUFFER (const SAMPLE_BUFFER& x); }; #endif ecasound-2.9.1/libecasound/eca-chainop.h0000644000076400007640000000452411755700042015073 00000000000000#ifndef INCLUDED_CHAINOP_H #define INCLUDED_CHAINOP_H #include #include #include "eca-operator.h" #include "eca-audio-format.h" #include "sample-specs.h" class SAMPLE_BUFFER; /** * Virtual base class for chain operators. * @author Kai Vehmanen */ class CHAIN_OPERATOR : public OPERATOR { public: /** * Virtual destructor. */ virtual ~CHAIN_OPERATOR (void) { } /** * Prepares chain operator for processing. * * This function is called at least once before * the first call to process(). * * Whenever attributes of the sample buffer pointed * by 'sbuf' are changed, chain operator should * be reinitialized with a new call to init(). * * Init should also reset any state, including any audio * buffers, from previous process() cycles. * * @param sbuf pointer to a sample buffer object * * @see release */ virtual void init(SAMPLE_BUFFER* sbuf) = 0; /** * Releases the buffer that was used to initialize * the chain operator. * * This function is called after the last call * to process(). * * After release(), chain operator is not * allowed to access the sample buffer given * to init(). * * @see init() */ virtual void release(void) { } /** * Processes sample data in the buffer passed * to init(). */ virtual void process(void) = 0; /** * Returns a string describing chain operator's * current status. * * @param single_sample pointer to a single sample */ virtual std::string status(void) const { return(""); } /** * Returns the maximum length of the sample buffer after * a call to process(), if the buffer's original * length was 'i_samples'. * * This function should be reimplemented by chain * operator types that add or remove samples * from the input data stream. * * @see process() */ virtual long int max_output_samples(long int i_samples) const { return(i_samples); } /** * Returns number of channels of the sample buffer * after a call to process(), if the buffer originally * had 'i_channels' channels. * * This function should be reimplemented by chain * operator types that change the channel count * during processing. * * @see process() */ virtual int output_channels(int i_channels) const { return(i_channels); } }; #endif ecasound-2.9.1/libecasound/audioio-proxy.cpp0000644000076400007640000001104711607655300016067 00000000000000// ------------------------------------------------------------------------ // audioio-proxy.cpp: Generic interface for objects that act as // proxies for other objects of type AUDIO_IO. // Copyright (C) 2002,2005,2008,2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include "samplebuffer.h" #include "audioio-null.h" #include "audioio-proxy.h" AUDIO_IO_PROXY::AUDIO_IO_PROXY(void) : buffersize_rep(0), child_initialized_rep(false) { child_repp = new NULLFILE("uninitialized proxy child"); } AUDIO_IO_PROXY::~AUDIO_IO_PROXY(void) { delete child_repp; // either null or the actual child object } /** * Sets a new proxy target object. The old * target (if any) is deleted. */ void AUDIO_IO_PROXY::set_child(AUDIO_IO* v) { if (child_repp != 0) delete child_repp; child_repp = v; child_initialized_rep = true; } /** * Releases the current child without deleting Itx. */ void AUDIO_IO_PROXY::release_child_no_delete(void) { child_repp = new NULLFILE("uninitialized proxy child"); child_initialized_rep = false; } /** * Prepares child object for opening. * * Sets the audio objects parameters, which have an effect * at open time, to those of the parent object. */ void AUDIO_IO_PROXY::pre_child_open(void) { child()->set_buffersize(buffersize()); child()->set_io_mode(io_mode()); child()->set_audio_format(audio_format()); child()->set_samples_per_second(samples_per_second()); } /** * Checks if any audio parameters were changed * during child's open(), fetches any changes and * sets the object length. */ void AUDIO_IO_PROXY::post_child_open(void) { if (child()->locked_audio_format() == true) { set_audio_format(child()->audio_format()); } set_length_in_samples(child()->length_in_samples()); } void AUDIO_IO_PROXY::set_buffersize(long int samples) { buffersize_rep = samples; child_repp->set_buffersize(samples); } void AUDIO_IO_PROXY::set_channels(SAMPLE_SPECS::channel_t v) { AUDIO_IO::set_channels(v); child_repp->set_channels(v); } void AUDIO_IO_PROXY::set_sample_format(Sample_format v) throw(ECA_ERROR&) { AUDIO_IO::set_sample_format(v); child_repp->set_sample_format(v); } void AUDIO_IO_PROXY::set_audio_format(const ECA_AUDIO_FORMAT& f_str) { AUDIO_IO::set_audio_format(f_str); child_repp->set_audio_format(f_str); } void AUDIO_IO_PROXY::toggle_interleaved_channels(bool v) { AUDIO_IO::toggle_interleaved_channels(v); child_repp->toggle_interleaved_channels(v); } void AUDIO_IO_PROXY::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { AUDIO_IO::set_samples_per_second(v); child_repp->set_samples_per_second(v); } std::string AUDIO_IO_PROXY::parameter_names(void) const { return child_repp->parameter_names(); } void AUDIO_IO_PROXY::set_parameter(int param, std::string value) { AUDIO_IO::set_parameter(param, value); child_repp->set_parameter(param, value); } std::string AUDIO_IO_PROXY::get_parameter(int param) const { return child_repp->get_parameter(param); } void AUDIO_IO_PROXY::start_io(void) { AUDIO_IO_BARRIER *barrier = dynamic_cast(child_repp); if (barrier) barrier->start_io(); } void AUDIO_IO_PROXY::stop_io(void) { AUDIO_IO_BARRIER *barrier = dynamic_cast(child_repp); if (barrier) barrier->stop_io(); } std::string AUDIO_IO_PROXY::child_params_as_string(int first, std::vector* params) { int last = params->size(); string res; for (int n = first; n <= last; n++) { std::string v = get_parameter(n); /* note: as we are passing a filename plus optional params, we * need to escape any commans in the filename */ if (v.find(",") != string::npos) v = "\"" + v + "\""; res += v; if (n != last) res += ","; } return res; } ecasound-2.9.1/libecasound/midi-parser.cpp0000644000076400007640000000357610664032032015474 00000000000000// ------------------------------------------------------------------------ // midi-parser.cpp: Collection of static functions and small stateful // machines for parsing MIDI messages. // Copyright (C) 2001 Kai Vehmanen // // 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 "midi-parser.h" /** * Whether 'byte' belong to Voice Category status messages * (ie. 0x80 to 0xef)? */ bool MIDI_PARSER::is_voice_category_status_byte(unsigned char byte) { if (byte >= 0x80 && byte < 0xf0) return(true); return(false); } /** * Whether 'byte' belong to System Common Category status messages * (ie. 0xf0 to 0xf7)? */ bool MIDI_PARSER::is_system_common_category_status_byte(unsigned char byte) { if (byte >= 0xf0 && byte < 0xf8) return(true); return(false); } /** * Whether 'byte' belongs to Realtime Category status messages * (ie. 0xf8 to 0xff)? */ bool MIDI_PARSER::is_realtime_category_status_byte(unsigned char byte) { if (byte > 0xf7) return(true); return(false); } /** * Whether 'byte' is a status byte (0x80 to 0xff)? */ bool MIDI_PARSER::is_status_byte(unsigned char byte) { if (byte & 0x80) return(true); return(false); } ecasound-2.9.1/libecasound/samplebuffer_impl.h0000644000076400007640000000126511161457254016424 00000000000000#ifndef INCLUDED_SAMPLEBUFFER_IMPL_H #define INCLUDED_SAMPLEBUFFER_IMPL_H #include #include "samplebuffer.h" #ifdef HAVE_CONFIG_H #include #endif #ifdef ECA_COMPILE_SAMPLERATE #include #endif class SAMPLE_BUFFER_impl { public: friend class SAMPLE_BUFFER; private: /** @name Misc member variables */ /*@{*/ bool rt_lock_rep; int lockref_rep; int quality_rep; int event_tags_rep; SAMPLE_BUFFER::sample_t* old_buffer_repp; // for resampling std::vector resample_memory_rep; #ifdef ECA_COMPILE_SAMPLERATE int src_state_channels_rep; std::vector src_state_rep; #endif /*@}*/ }; #endif ecasound-2.9.1/libecasound/eca-chain.cpp0000644000076400007640000006100712260762753015077 00000000000000// ------------------------------------------------------------------------ // eca-chain.cpp: Class representing an abstract audio signal chain. // Copyright (C) 1999-2009 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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, see . // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include "samplebuffer.h" #include "generic-controller.h" #include "eca-chainop.h" #include "audioio.h" #include "file-preset.h" #include "global-preset.h" #include "audiofx_ladspa.h" #include "eca-object-factory.h" #include "eca-object-map.h" #include "eca-preset-map.h" #include "eca-chain.h" #include "eca-chainop.h" #include "eca-error.h" #include "eca-logger.h" /* Debug controller source values */ // #define DEBUG_CONTROLLERS #ifdef DEBUG_CONTROLLERS #define DEBUG_CTRL_STATEMENT(x) x #else #define DEBUG_CTRL_STATEMENT(x) ((void)0) #endif CHAIN::CHAIN (void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "constructor: CHAIN"); muted_rep = false; bypass_rep = false; initialized_rep = false; input_id_rep = output_id_rep = -1; /* FIXME: remove these and only store the index */ selected_controller_repp = 0; selected_dynobj_repp = 0; selected_chainop_number_rep = 0; selected_controller_number_rep = 0; selected_chainop_parameter_rep = 0; selected_controller_parameter_rep = 0; } CHAIN::~CHAIN (void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "CHAIN destructor!"); if (is_initialized()) release(); for(std::vector::iterator p = chainops_rep.begin(); p != chainops_rep.end(); p++) { string tmp = (*p).cop->status(); if (tmp.size() > 0) { ECA_LOG_MSG(ECA_LOGGER::info, tmp); } delete (*p).cop; } for(std::vector::iterator p = gcontrollers_rep.begin(); p != gcontrollers_rep.end(); p++) { delete *p; } } /** * Whether chain is in a valid state (= ready for processing)? */ bool CHAIN::is_valid(void) const { if (input_id_rep == -1 || output_id_rep == -1) { return false; } return true; } /** * Connects input to chain */ void CHAIN::connect_input(int input) { input_id_rep = input; } /** * Connects output to chain */ void CHAIN::connect_output(int output) { output_id_rep = output; } /** * Disconnects input */ void CHAIN::disconnect_input(void) { input_id_rep = -1; initialized_rep = false; } /** * Disconnects output */ void CHAIN::disconnect_output(void) { output_id_rep = -1; initialized_rep = false; } /** * Disconnects the sample buffer */ void CHAIN::disconnect_buffer(void) { audioslot_repp = 0; initialized_rep = false; release(); } /** * Notifies chain that an input has been removed. */ void CHAIN::input_removed(int input) { // adjust input_id_rep in case position in input // array has changed if (input_id_rep > input) --input_id_rep; else if (input_id_rep == input) disconnect_input(); } /** * Notifies chain that an output has been removed. */ void CHAIN::output_removed(int output) { // adjust output_id_rep in case position in output // array has changed if (output_id_rep > output) --output_id_rep; else if (output_id_rep == output) disconnect_output(); } /** * Adds the chain operator to the end of the chain * * require: * chainop != 0 * * ensure: * selected_chain_operator() == number_of_chain_operators() * is_initialized() != true */ void CHAIN::add_chain_operator(CHAIN_OPERATOR* chainop) { // -------- DBC_REQUIRE(chainop != 0); // -------- ECA_SAMPLERATE_AWARE* srateobj = dynamic_cast(chainop); if (srateobj != 0) { srateobj->set_samples_per_second(samples_per_second()); } CHAIN::COP_CONTAINER container; container.cop = chainop; container.bypassed = false; chainops_rep.push_back(container); selected_chainop_number_rep = chainops_rep.size(); initialized_rep = false; // -------- DBC_ENSURE(selected_chain_operator() == number_of_chain_operators()); DBC_ENSURE(is_initialized() != true); // -------- } /** * Removes the selected chain operator * * @param op_index operator index (1...N), or -1 to use the selected op * * ensure: * is_initialized() != true */ void CHAIN::remove_chain_operator(int op_index) { if (op_index < 0) op_index = selected_chainop_number_rep; CHAIN_OPERATOR *to_remove = 0; if (op_index > 0 && op_index <= static_cast(chainops_rep.size())) to_remove = chainops_rep[op_index - 1].cop; if (to_remove != 0) { for(std::vector::iterator p = chainops_rep.begin(); p != chainops_rep.end(); p++) { if ((*p).cop == to_remove) { for(std::vector::iterator q = gcontrollers_rep.begin(); q != gcontrollers_rep.end();) { if ((*p).cop == (*q)->target_pointer()) { /* step: if the deleted controller is selected, unselect it */ if (selected_controller_repp == *q) selected_controller_repp = 0; /* step: remove the related controller */ delete *q; gcontrollers_rep.erase(q); /* step: in case there are multiple controllers per chainop */ q = gcontrollers_rep.begin(); } else ++q; } /* step: delete and remove from the list */ delete (*p).cop; chainops_rep.erase(p); /* step: invalidate selection if the selected cop * was affected */ if (op_index >= selected_chainop_number_rep) { selected_chainop_number_rep = -1; break; } } } initialized_rep = false; } // -------- DBC_ENSURE(is_initialized() != true || to_remove == 0); // -------- } /** * Returns the name of selected chain operator. * * require: * selected_chain_operator() != 0 */ string CHAIN::chain_operator_name(void) const { assert(selected_chainop_number_rep > 0); assert(selected_chainop_number_rep <= static_cast(chainops_rep.size())); return chainops_rep[selected_chainop_number_rep - 1].cop->name(); } /** * Returns the name of selected chain operator parameter. * * require: * selected_chain_operator() != 0 * selected_chain_operator_parameter() != 0 */ string CHAIN::chain_operator_parameter_name(void) const { assert(selected_chainop_number_rep > 0); assert(selected_chainop_number_rep <= static_cast(chainops_rep.size())); return chainops_rep[selected_chainop_number_rep - 1].cop->get_parameter_name(selected_chain_operator_parameter()); } /** * Returns the name of selected controller parameter. * * require: * selected_controller() != 0 * selected_controller_parameter() != 0 */ string CHAIN::controller_parameter_name(void) const { // -------- DBC_REQUIRE(selected_controller() > 0); DBC_REQUIRE(selected_controller_parameter() > 0); // -------- return selected_controller_repp->get_parameter_name(selected_controller_parameter()); } /** * Returns the total number of parameters for the * selected chain operator. * * require: * selected_chain_operator() != 0 */ int CHAIN::number_of_chain_operator_parameters(void) const { assert(selected_chainop_number_rep > 0); assert(selected_chainop_number_rep <= static_cast(chainops_rep.size())); return chainops_rep[selected_chainop_number_rep - 1].cop->number_of_params(); } /** * Returns the total number of parameters for the * chain operator 'index' ([1...N]). * * require: * index < number_of_chain_operators() */ int CHAIN::number_of_chain_operator_parameters(int index) const { DBC_REQUIRE(index > 0); DBC_REQUIRE(index <= number_of_chain_operators()); if (index > 0 && index <= number_of_chain_operators()) return chainops_rep[index - 1].cop->number_of_params(); return -1; } /** * Returns the total number of parameters for the selected controller. * * require: * selected_controller() != 0 */ int CHAIN::number_of_controller_parameters(void) const { // -------- DBC_REQUIRE(selected_controller() > 0); // -------- return selected_controller_repp->number_of_params(); } /** * Returns the name of selected controller. * * require: * selected_controller() != 0 */ string CHAIN::controller_name(void) const { // -------- DBC_REQUIRE(selected_controller() > 0); // -------- return selected_controller_repp->name(); } /** * Sets the parameter value (selected chain operator) * * @param op_index operator index (1...N), or -1 to use the selected op * @param param_index param index (1...N), or -1 to use the selected param * @param value new value */ void CHAIN::set_parameter(int op_index, int param_index, CHAIN_OPERATOR::parameter_t value) { CHAIN_OPERATOR *cop = 0; if (op_index < 0) { if (selected_chainop_number_rep > 0 && selected_chainop_number_rep <= static_cast(chainops_rep.size())) cop = chainops_rep[selected_chainop_number_rep - 1].cop; } else if (op_index > 0 && op_index <= static_cast(chainops_rep.size())) cop = chainops_rep[op_index - 1].cop; if (param_index < 0) param_index = selected_chainop_parameter_rep; if (cop) cop->set_parameter(param_index, value); } /** * Returns true if op_index is valid. */ bool CHAIN::is_valid_op_index(int op_index) const { if (op_index > 0 && op_index <= static_cast(chainops_rep.size())) return true; return false; } /** * Sets bypass state (selected chain operator) * * @param op_index operator index (1...N), or -1 to use the selected op * @param bypassed 1=bypass, 0=nobypass, -1=toggle (change state) */ void CHAIN::bypass_operator(int op_index, int bypassed) { if (is_valid_op_index(op_index)) { if (bypassed < 0) { // just toggle the current value chainops_rep[op_index - 1].bypassed = !(chainops_rep[op_index - 1].bypassed); } else { chainops_rep[op_index - 1].bypassed = (bypassed > 0 ? true : false); } } } /** * Sets muting state for the chain * * @param bypassed 1=mute, 0=unmute, -1=toggle (change state) */ void CHAIN::set_mute(int state) { if (state < 0) muted_rep = !muted_rep; else if (state > 0) muted_rep = true; else muted_rep = false; } /** * Sets muting state for the chain * * @param state 1=bypass, 0=nobypass, -1=toggle (change state) */ void CHAIN::set_bypass(int state) { if (state < 0) bypass_rep = !bypass_rep; else if (state > 0) bypass_rep = true; else bypass_rep = false; } bool CHAIN::is_operator_bypassed(int op_index) const { if (is_valid_op_index(op_index)) { return chainops_rep[op_index - 1].bypassed; } return false; } /** * Gets the parameter value (selected chain operator) * * @param index parameter number * * require: * selected_chain_operator_parameter() > 0 && * selected_chain_operator() != 0 */ CHAIN_OPERATOR::parameter_t CHAIN::get_parameter(void) const { DBC_CHECK(selected_chainop_number_rep > 0); DBC_CHECK(selected_chainop_number_rep <= static_cast(chainops_rep.size())); if (selected_chainop_number_rep > 0 && selected_chainop_number_rep <= static_cast(chainops_rep.size())) { return chainops_rep[selected_chainop_number_rep - 1].cop->get_parameter(selected_chainop_parameter_rep); } return 0.0f; } /** * Adds a generic controller and assign it to selected dynamic object * * require: * gcontroller != 0 * selected_dynobj != 0 */ void CHAIN::add_controller(GENERIC_CONTROLLER* gcontroller) { // -------- DBC_REQUIRE(gcontroller != 0); DBC_REQUIRE(selected_dynobj_repp != 0); // -------- #ifndef ECA_DISABLE_EFFECTS gcontroller->assign_target(selected_dynobj_repp); ECA_LOG_MSG(ECA_LOGGER::user_objects, gcontroller->status()); #endif gcontrollers_rep.push_back(gcontroller); selected_controller_repp = gcontroller; selected_controller_number_rep = gcontrollers_rep.size(); } const CHAIN_OPERATOR* CHAIN::get_selected_chain_operator(void) const { if (selected_chainop_number_rep > 0 && selected_chainop_number_rep <= static_cast(chainops_rep.size())) return chainops_rep[selected_chainop_number_rep - 1].cop; return 0; } /** * Removes the selected controller * * require: * selected_controller() <= number_of_controllers(); * selected_controller() > 0 */ void CHAIN::remove_controller(void) { // -------- DBC_REQUIRE(selected_controller() > 0); DBC_REQUIRE(selected_controller() <= number_of_controllers()); // -------- int n = 0; for(std::vector::iterator q = gcontrollers_rep.begin(); q != gcontrollers_rep.end(); q++) { if ((n + 1) == selected_controller()) { delete *q; gcontrollers_rep.erase(q); select_controller(-1); break; } ++n; } } /** * Clears chain (removes all chain operators and controllers) */ void CHAIN::clear(void) { for(std::vector::iterator p = chainops_rep.begin(); p != chainops_rep.end(); p++) { delete (*p).cop; (*p).cop = 0; } chainops_rep.resize(0); for(std::vector::iterator p = gcontrollers_rep.begin(); p != gcontrollers_rep.end(); p++) { delete *p; *p = 0; } gcontrollers_rep.resize(0); initialized_rep = false; } /** * Selects a chain operator. If no chain operators * are found with 'index', with index 'index'. * * @param index 1...N * * ensure: * index == selected_chain_operator() || * selected_chain_operator() == 0 */ void CHAIN::select_chain_operator(int index) { if (index > 0 && index <= static_cast(chainops_rep.size())) { selected_chainop_number_rep = index; selected_chain_operator_as_target(); } } /** * Selects a chain operator parameter. Index of zero clears out * current selection. * * require: * index > 0 * selected_chain_operator() != 0 || index == 0 * index <= selected_chain_operator()->number_of_params() * * ensure: * index == selected_chain_operator_parameter() */ void CHAIN::select_chain_operator_parameter(int index) { DBC_REQUIRE(index > 0); selected_chainop_parameter_rep = index; } /** * Selects a controller. Index of zero clears out * current selection. * * @param index 1...N, or negative to clear selection * * ensure: * index == selected_controller() || * selected_controller() == 0 */ void CHAIN::select_controller(int index) { DBC_REQUIRE(index != 0); selected_controller_repp = 0; selected_controller_number_rep = 0; for(int gcontroller_sizet = 0; gcontroller_sizet != static_cast(gcontrollers_rep.size()); gcontroller_sizet++) { if (gcontroller_sizet + 1 == index) { selected_controller_repp = gcontrollers_rep[gcontroller_sizet]; selected_controller_number_rep = index; } } } /** * Selects a controller parameter. Index of zero clears out * current selection. * * require: * index > 0 * selected_controller() != 0 || index == 0 * index <= selected_controller()->number_of_params() * * ensure: * index == selected_controller_parameter() */ void CHAIN::select_controller_parameter(int index) { selected_controller_parameter_rep = index; } /** * Gets the value of the currently selected controller parameter. * * require: * selected_controller() != 0 * selected_controller_parameter() != 0 */ CHAIN_OPERATOR::parameter_t CHAIN::get_controller_parameter(void) const { // -------- DBC_REQUIRE(selected_controller_parameter() > 0); DBC_REQUIRE(selected_controller() != 0); // -------- return selected_controller_repp->get_parameter(selected_controller_parameter_rep); } /** * Sets the value of the currently selected controller parameter. * * @param ctrl_index operator index (1...N), or -1 to use the selected ctrl * @param param_index param index (1...N), or -1 to use the selected param * @param value new value */ void CHAIN::set_controller_parameter(int ctrl_index, int param_index, CHAIN_OPERATOR::parameter_t value) { GENERIC_CONTROLLER *ctrl = 0; if (ctrl_index < 0) { if (selected_controller_number_rep > 0 && selected_controller_number_rep <= static_cast(gcontrollers_rep.size())) ctrl = gcontrollers_rep[selected_controller_number_rep - 1]; } else if (ctrl_index > 0 && ctrl_index <= static_cast(gcontrollers_rep.size())) ctrl = gcontrollers_rep[ctrl_index - 1]; if (param_index < 0) param_index = selected_controller_parameter_rep; DBC_CHECK(param_index > 0); if (ctrl) ctrl->set_parameter(param_index, value); } /** * Use current selected chain operator as * target for parameters control. * * require: * selected_chain_operator() != 0 * * ensure: * selected_target() == selected_chain_operator() */ void CHAIN::selected_chain_operator_as_target(void) { assert(selected_chainop_number_rep > 0); assert(selected_chainop_number_rep <= static_cast(chainops_rep.size())); selected_dynobj_repp = chainops_rep[selected_chainop_number_rep - 1].cop; // -------- DBC_ENSURE(selected_dynobj_repp == chainops_rep[selected_chainop_number_rep - 1].cop); // -------- } /** * Use current selected controller as * target for parameter control. * * require: * selected_controller() != 0 * * ensure: * selected_target() == selected_controller() */ void CHAIN::selected_controller_as_target(void) { // -------- DBC_REQUIRE(selected_controller_repp != 0); // -------- selected_dynobj_repp = selected_controller_repp; // -------- DBC_ENSURE(selected_dynobj_repp == selected_controller_repp); // -------- } /** * Prepares chain for processing. All further processing * will be done using the buffer pointer by 'sbuf'. * If all parameters are zero, previously specified * parameters are used (state re-initialization). * * require: * input_id != 0 || in_channels != 0 * output_id != 0 || out_channels != 0 * audioslot_repp != 0 || sbuf != 0 * * ensure: * is_initialized() == true */ void CHAIN::init(SAMPLE_BUFFER* sbuf, int in_channels, int out_channels) { // -------- DBC_REQUIRE(in_channels != 0 || in_channels_rep != 0); DBC_REQUIRE(out_channels != 0 || out_channels_rep != 0); DBC_REQUIRE(sbuf != 0 || audioslot_repp != 0); // -------- DBC_CHECK(samples_per_second() > 0); if (sbuf != 0) audioslot_repp = sbuf; if (in_channels != 0) in_channels_rep = in_channels; if (out_channels != 0) out_channels_rep = out_channels; int channels_next = in_channels_rep; for(size_t p = 0; p != chainops_rep.size(); p++) { /* note: buffer must have room to store both input and * output channels (processing in-place) */ int out_ch = chainops_rep[p].cop->output_channels(channels_next); if (out_ch > channels_next) channels_next = out_ch; audioslot_repp->number_of_channels(channels_next); chainops_rep[p].cop->init(audioslot_repp); /* note: for the next plugin, only 'out_ch' channels contain * valid audio */ channels_next = out_ch; } for(size_t p = 0; p != gcontrollers_rep.size(); p++) { gcontrollers_rep[p]->init(); } refresh_parameters(); initialized_rep = true; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Initialized chain " + name() + " with " + kvu_numtostr(chainops_rep.size()) + " chainops and " + kvu_numtostr(gcontrollers_rep.size()) + " gcontrollers. Sbuf points to " + kvu_numtostr(reinterpret_cast(audioslot_repp)) + "."); // -------- DBC_ENSURE(is_initialized() == true); // -------- } /** * Releases all buffers assigned to chain operators. */ void CHAIN::release(void) { for(size_t p = 0; p != chainops_rep.size(); p++) { chainops_rep[p].cop->release(); } initialized_rep = false; // --------- DBC_ENSURE(is_initialized() != true); // --------- } /** * Processes chain data with all chain operators. * * require: * is_initialized() == true */ void CHAIN::process(void) { // -------- DBC_REQUIRE(is_initialized() == true); // -------- /* step: update operator parameters */ controller_update(); /* step: run processing components */ if (muted_rep != true) { /* note: if muted, don't bother running the chainops */ if (bypass_rep != true) { /* note: processing enabled (no bypass) */ for(int p = 0; p != static_cast(chainops_rep.size()); p++) { if (chainops_rep[p].bypassed == true) continue; /* note: increase channel count if chainop needs the space */ int out_ch = chainops_rep[p].cop->output_channels(audioslot_repp->number_of_channels()); if (out_ch > audioslot_repp->number_of_channels()) audioslot_repp->number_of_channels(out_ch); chainops_rep[p].cop->process(); } } } else { audioslot_repp->make_silent(); } /* step: update chain position */ change_position_in_samples(audioslot_repp->length_in_samples()); } /** * Calculates/fetches new values for all controllers. */ void CHAIN::controller_update(void) { for(size_t n = 0; n < gcontrollers_rep.size(); n++) { DEBUG_CTRL_STATEMENT(GENERIC_CONTROLLER* ptr = gcontrollers_rep[n]); gcontrollers_rep[n]->value(position_in_seconds_exact()); DEBUG_CTRL_STATEMENT(std::cerr << "trace: " << ptr->name()); DEBUG_CTRL_STATEMENT(std::cerr << "; value " << ptr->source_pointer()->value() << "." << std::endl); } } /** * Re-initializes all effect parameters. */ void CHAIN::refresh_parameters(void) { for(int chainop_sizet = 0; chainop_sizet != static_cast(chainops_rep.size()); chainop_sizet++) { for(int n = 0; n < chainops_rep[chainop_sizet].cop->number_of_params(); n++) { chainops_rep[chainop_sizet].cop->set_parameter(n + 1, chainops_rep[chainop_sizet].cop->get_parameter(n + 1)); } } } /** * Converts chain to a formatted string. */ string CHAIN::to_string(void) const { MESSAGE_ITEM t; FILE_PRESET* fpreset; GLOBAL_PRESET* gpreset; int q = 0; while (q < static_cast(chainops_rep.size())) { #ifndef ECA_DISABLE_EFFECTS fpreset = 0; fpreset = dynamic_cast(chainops_rep[q].cop); if (fpreset != 0) { t << "-pf:" << fpreset->filename(); if (fpreset->number_of_params() > 0) t << ","; t << ECA_OBJECT_FACTORY::operator_parameters_to_eos(fpreset); t << " "; } else { gpreset = 0; gpreset = dynamic_cast(chainops_rep[q].cop); if (gpreset != 0) { t << "-pn:" << gpreset->name(); if (gpreset->number_of_params() > 0) t << ","; t << ECA_OBJECT_FACTORY::operator_parameters_to_eos(gpreset); t << " "; } else { t << ECA_OBJECT_FACTORY::chain_operator_to_eos(chainops_rep[q].cop) << " "; } } /* check if the chainop is controlled by a gcontroller */ std::vector::size_type p = 0; while (p < gcontrollers_rep.size()) { if (chainops_rep[q].cop == gcontrollers_rep[p]->target_pointer()) { t << " " << ECA_OBJECT_FACTORY::controller_to_eos(gcontrollers_rep[p]); t << " "; /* check if the gcontroller is controlled by another gcontroller */ std::vector::size_type r = 0; while (r < gcontrollers_rep.size()) { if (p != r && gcontrollers_rep[p] == gcontrollers_rep[r]->target_pointer()) { t << " -kx " << ECA_OBJECT_FACTORY::controller_to_eos(gcontrollers_rep[r]); } ++r; } } ++p; } #endif ++q; } return t.to_string(); } /** * Reimplemented from ECA_SAMPLERATE_AWARE */ void CHAIN::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { for(size_t p = 0; p != chainops_rep.size(); p++) { CHAIN_OPERATOR* temp = chainops_rep[p].cop; ECA_SAMPLERATE_AWARE* srateobj = dynamic_cast(temp); if (srateobj != 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "sample rate change, chain '" + name() + "' object '" + temp->name() + "' rate " + kvu_numtostr(v) + "."); srateobj->set_samples_per_second(v); } } ECA_SAMPLERATE_AWARE::set_samples_per_second(v); } /** * Reimplemented from ECA_AUDIO_POSITION. */ SAMPLE_SPECS::sample_pos_t CHAIN::seek_position(SAMPLE_SPECS::sample_pos_t pos) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "seek position, to pos " + kvu_numtostr(pos) + "."); return pos; } ecasound-2.9.1/libecasound/eca-chainsetup-position.h0000644000076400007640000000361211032763261017454 00000000000000#ifndef INCLUDED_ECA_CONTROL_POSITION_H #define INCLUDED_ECA_CONTROL_POSITION_H #include "sample-specs.h" #include "eca-audio-position.h" /** * Virtual class implementing position and * length related chainsetup features. */ class ECA_CHAINSETUP_POSITION : public ECA_AUDIO_POSITION { public: /** @name Init and cleaup */ /*@{*/ ECA_CHAINSETUP_POSITION(void); virtual ~ECA_CHAINSETUP_POSITION(void); /*@}*/ /** @name Public getter/setter functions for max length information. * Note that this length information is different from * that defined in ECA_AUDIO_POSITION. Max length can be * set by the users of this class, and can be either shorter * or longer than the actual length. */ /*@{*/ void set_max_length_in_samples(SAMPLE_SPECS::sample_pos_t pos); void set_max_length_in_seconds(double pos_in_seconds); inline bool is_over_max_length(void) const { return((position_in_samples() > max_length_in_samples() && max_length_set() == true) ? true : false); } SAMPLE_SPECS::sample_pos_t max_length_in_samples(void) const; double max_length_in_seconds_exact(void) const; bool max_length_set(void) const { return(max_length_set_rep); } /*@}*/ /** @name Functions reimplemented from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value); /*@}*/ /** @name Functions implemented from ECA_AUDIO_POSITION */ /*@{*/ virtual bool supports_seeking(void) const { return true; } virtual bool supports_seeking_sample_accurate(void) const { return true; } /*@}*/ protected: /** @name Protected functions for controlling looping */ /*@{*/ void toggle_looping(bool v) { looping_rep = v; } bool looping_enabled(void) const { return(looping_rep); } /*@}*/ private: bool looping_rep, max_length_set_rep; SAMPLE_SPECS::sample_pos_t max_length_in_samples_rep; }; #endif ecasound-2.9.1/libecasound/audioio-mp3.cpp0000644000076400007640000004540711161425433015411 00000000000000// ------------------------------------------------------------------------ // audioio-mp3.cpp: Interface for mp3 decoders and encoders that support // input/output using standard streams. Defaults to // mpg123 and lame. // Copyright (C) 1999-2006,2008,2009 Kai Vehmanen // Note! Routines for parsing mp3 header information were taken from XMMS // 1.2.5's mpg123 plugin. Improvements to parsing logic were // contributed by Julian Dobson. // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // References: // http://www.mp3-tech.org/programmer/frame_header.html // http://www.mpg123.de/ // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include /* atol() */ #include #include /* stat() */ #include /* stat() */ #include #include #include #include #include "audioio-mp3.h" #include "audioio-mp3_impl.h" #include "samplebuffer.h" #include "audioio.h" #include "eca-logger.h" const char *default_input_cmd = "mpg123 --stereo -b 0 -q -s -k %o %f"; const char *default_output_cmd = "lame -b %B -s %S -r --big-endian -S - %f"; const long int default_output_bitrate = 128000; std::string MP3FILE::conf_input_cmd = std::string(default_input_cmd); std::string MP3FILE::conf_output_cmd = std::string(default_output_cmd); long int MP3FILE::conf_default_output_bitrate = default_output_bitrate; void MP3FILE::set_input_cmd(const std::string& value) { MP3FILE::conf_input_cmd = value; } void MP3FILE::set_output_cmd(const std::string& value) { MP3FILE::conf_output_cmd = value; } /*************************************************************** * Routines for parsing mp3 header information. Taken from XMMS * 1.2.5's mpg123 plugin. **************************************************************/ #define MAXFRAMESIZE 1792 #define MPG_MD_STEREO 0 #define MPG_MD_JOINT_STEREO 1 #define MPG_MD_DUAL_CHANNEL 2 #define MPG_MD_MONO 3 int tabsel_123[2][3][16] = { { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}}, { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}} }; long mpg123_freqs[9] = {44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000}; struct frame { int stereo; int jsbound; int single; int II_sblimit; int down_sample_sblimit; int lsf; int mpeg25; int down_sample; int header_change; int lay; int error_protection; int bitrate_index; int sampling_frequency; int padding; int extension; int mode; int mode_ext; int copyright; int original; int emphasis; int framesize; /* computed framesize */ }; static bool mpg123_head_check(unsigned long head) { /* ref: http://www.mp3-tech.org/programmer/frame_header.html */ /* frame sync must be 0xffe (11bits) */ if ((head & 0xffe00000) != 0xffe00000) return false; /* layer must be non-null (2bits) */ if (!((head >> 17) & 3)) return false; /* invalid bitrate index: all-ones (4bit) */ if (((head >> 12) & 0xf) == 0xf) return false; /* invalid bitrate index: null (4bit) */ if (!((head >> 12) & 0xf)) return false; /* invalid srate index: all-ones (2bit) */ if (((head >> 10) & 0x3) == 0x3) return false; #if 0 /* invalid: mpeg2/2.5, layer I, protection bit off */ if (((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1) return false; /* - mpeg version 1, CRC protection bit */ if ((head & 0xffff0000) == 0xfffe0000) return false; #endif return true; } static double mpg123_compute_bpf(struct frame *fr) { double bpf; switch (fr->lay) { case 1: bpf = tabsel_123[fr->lsf][0][fr->bitrate_index]; bpf *= 12000.0 * 4.0; bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf); break; case 2: case 3: bpf = tabsel_123[fr->lsf][fr->lay - 1][fr->bitrate_index]; bpf *= 144000; bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf); break; default: bpf = 1.0; } return bpf; } static double mpg123_compute_tpf(struct frame *fr) { static int bs[4] = {0, 384, 1152, 1152}; double tpf; tpf = (double) bs[fr->lay]; tpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf); return tpf; } /* * the code a header and write the information * into the frame structure */ static bool mpg123_decode_header(struct frame *fr, unsigned long newhead) { if (newhead & (1 << 20)) { fr->lsf = (newhead & (1 << 19)) ? 0x0 : 0x1; fr->mpeg25 = 0; } else { fr->lsf = 1; fr->mpeg25 = 1; } fr->lay = 4 - ((newhead >> 17) & 3); if (fr->mpeg25) { fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3); } else fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->lsf * 3); fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1; if (fr->mpeg25) /* allow Bitrate change for 2.5 ... */ fr->bitrate_index = ((newhead >> 12) & 0xf); fr->bitrate_index = ((newhead >> 12) & 0xf); fr->padding = ((newhead >> 9) & 0x1); fr->extension = ((newhead >> 8) & 0x1); fr->mode = ((newhead >> 6) & 0x3); fr->mode_ext = ((newhead >> 4) & 0x3); fr->copyright = ((newhead >> 3) & 0x1); fr->original = ((newhead >> 2) & 0x1); fr->emphasis = newhead & 0x3; fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; if (!fr->bitrate_index) { ECA_LOG_MSG(ECA_LOGGER::errors, "Invalid bitrate!"); return false; } int ssize = 0; switch (fr->lay) { case 1: // fr->do_layer = mpg123_do_layer1; // mpg123_init_layer2(); fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; fr->framesize /= mpg123_freqs[fr->sampling_frequency]; fr->framesize = ((fr->framesize + fr->padding) << 2) - 4; break; case 2: // fr->do_layer = mpg123_do_layer2; // mpg123_init_layer2(); fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; fr->framesize /= mpg123_freqs[fr->sampling_frequency]; fr->framesize += fr->padding - 4; break; case 3: // fr->do_layer = mpg123_do_layer3; if (fr->lsf) ssize = (fr->stereo == 1) ? 9 : 17; else ssize = (fr->stereo == 1) ? 17 : 32; if (fr->error_protection) ssize += 2; fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; fr->framesize /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf); fr->framesize = fr->framesize + fr->padding - 4; break; default: return false; } if(fr->framesize > MAXFRAMESIZE) { ECA_LOG_MSG(ECA_LOGGER::errors, "Invalid framesize!"); return false; } return true; } /* not used anymore, kaiv 2005/03 */ #if 0 static uint32_t convert_to_header(uint8_t * buf) { return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]; } #endif static bool mpg123_detect_by_content(const char* filename, struct frame* frp) { FILE *file; uint8_t tmp[4]; /* room for the 32bit head */ uint32_t head = 0; bool data_left = true; bool header_found = false; size_t offset = 0; if((file = std::fopen(filename, "rb")) == NULL) { ECA_LOG_MSG(ECA_LOGGER::errors, string("Unable to open file ") + filename + "."); data_left = false; } /* search for headers in the first 262kB of data */ while(data_left == true && offset < (1<<18)) { /* octet-by-octet search */ if (std::fread(tmp, 1, 1, file) != 1) { ECA_LOG_MSG(ECA_LOGGER::errors, "End of mp3 file, no valid header data found."); data_left = false; break; } head <<= 8; head |= tmp[0]; offset += 1; if (offset > 3) { /* verify the header and if ok, fetch mp3 parameters and store them to 'frp' */ if (mpg123_head_check(head) && mpg123_decode_header(frp, head)) { if (header_found == true) { /* two headers found, stop searching */ data_left = false; } else { /* after the first header is found, skip to the next valid frame to verify that the first frame is not dummy frame (id3 or something similar) */ if (std::fseek(file, frp->framesize, SEEK_CUR) != 0) { data_left = false; } header_found = true; } ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found mp3 header at offset " + kvu_numtostr(static_cast(offset - 4))); } } } return header_found; } /*************************************************************** * MP3FILE specific parts. **************************************************************/ MP3FILE::MP3FILE(const std::string& name) : finished_rep(false), triggered_rep(false) { set_label(name); filedes_rep = -1; filehandle_rep = 0; mono_input_rep = false; pcm_rep = 1; bitrate_rep = MP3FILE::conf_default_output_bitrate; } MP3FILE::~MP3FILE(void) { /* see notes in stop_io() */ clean_child(io_mode() == io_read ? true : false); if (is_open() == true) { close(); } } void MP3FILE::open(void) throw(AUDIO_IO::SETUP_ERROR &) { if (io_mode() == io_read) { /* decoder supports: fixed channel count and sample format, sample rate set by parsing mp3 header */ get_mp3_params(label()); } else { /* encoder supports: srate configurable, fixed channel count and sample format */ set_channels(2); set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le); /* note: 'lame' command-line syntax, and default related to them, * have changed slightly in lame 3.98, so we need this hack * to support both old and new versions. In the past, * Ecasound wrote little-endian samples and used lame * option "-x". Newer lame versions (3.97) introduced * "--litle-endian" and "--big-endian", but these were * buggy still in 3.97 (fixed in 3.98). And with 3.98, * additional options (e.g. "-r") need to be passed, or * otherwise lame will exit with an error. * * In addition to above problems, we also need to remember * people updating to a newer Ecasound, but who do not update * their custom 'lame' launch commands in * ~/.ecasound/ecasoundrc (ecasound must continue to output * little-endian samples by default). */ if (MP3FILE::conf_output_cmd.find("lame ") != std::string::npos && MP3FILE::conf_output_cmd.find(" --big-endian ") != std::string::npos) { set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_be); } } triggered_rep = false; AUDIO_IO::open(); } void MP3FILE::close(void) { if (pid_of_child() > 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + "."); /* note: mp3 input/output can handle SIGTERM */ clean_child(true); triggered_rep = false; } AUDIO_IO::close(); } void MP3FILE::process_mono_fix(char* target_buffer, long int bytes) { for(long int n = 0; n < bytes;) { target_buffer[n + 2] = target_buffer[n]; target_buffer[n + 3] = target_buffer[n + 1]; n += 4; } } long int MP3FILE::read_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_input_process(); } bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, filehandle_rep); if (bytes_rep < samples * frame_size() || bytes_rep == 0) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::errors, "Can't start process \"" + MP3FILE::conf_input_cmd + "\". Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; } else finished_rep = false; last_position_rep += (bytes_rep / frame_size()); return bytes_rep / frame_size(); } void MP3FILE::write_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { triggered_rep = true; fork_output_process(); } if (wait_for_child() != true) { finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Attempt to write after child process has terminated."); } else { bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples); if (bytes_rep < frame_size() * samples) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::errors, "Can't start process \"" + MP3FILE::conf_output_cmd + "\". Please check your ~/.ecasound/ecasoundrc."); else ECA_LOG_MSG(ECA_LOGGER::errors, "Error in writing to child process (to write " + kvu_numtostr(frame_size() * samples) + ", result " + kvu_numtostr(bytes_rep) + ")."); finished_rep = true; } else finished_rep = false; } } SAMPLE_SPECS::sample_pos_t MP3FILE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { finished_rep = false; if (triggered_rep == true && last_position_rep != pos) { if (is_open() == true) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + "."); clean_child(true); triggered_rep = false; } } return pos; } void MP3FILE::set_parameter(int param, std::string value) { switch (param) { case 1: set_label(value); break; case 2: long int numvalue = atol(value.c_str()); if (numvalue > 0) bitrate_rep = numvalue; else bitrate_rep = MP3FILE::conf_default_output_bitrate; break; } } std::string MP3FILE::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return kvu_numtostr(bitrate_rep); } return ""; } void MP3FILE::get_mp3_params(const std::string& fname) throw(AUDIO_IO::SETUP_ERROR&) { std::string urlprefix; struct frame fr; if (mpg123_detect_by_content(fname.c_str(), &fr) != true) { /* not a file, next search for an URL */ size_t offset = fname.find_first_of("://"); if (offset == std::string::npos) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-MP3: Can't open " + label() + " for reading.")); } else { urlprefix = std::string(fname, 0, offset); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found url; protocol '" + urlprefix + "'."); } } else { /* file size */ struct stat buf; ::stat(fname.c_str(), &buf); double fsize = (double)buf.st_size; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total file size (bytes): " + kvu_numtostr(fsize)); /* bitrate */ double bitrate = tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index] * 1000; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Bitrate (bits/s): " + kvu_numtostr(bitrate)); /* sample freq */ double sfreq = mpg123_freqs[fr.sampling_frequency]; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Sampling frequncy (Hz): " + kvu_numtostr(sfreq)); set_samples_per_second(static_cast(sfreq)); /* channels */ // notice! mpg123 always outputs 16bit samples, stereo mono_input_rep = (fr.mode == MPG_MD_MONO) ? true : false; /* temporal length */ long int numframes = static_cast((fsize / mpg123_compute_bpf(&fr))); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total length (frames): " + kvu_numtostr(numframes)); double tpf = mpg123_compute_tpf(&fr); set_length_in_seconds(tpf * numframes); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total length (seconds): " + kvu_numtostr(length_in_seconds())); /* set pcm per frame value */ static int bs[4] = {0, 384, 1152, 1152}; pcm_rep = bs[fr.lay]; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Pcm per mp3 frames: " + kvu_numtostr(pcm_rep)); } /* sample format (this comes from mpg123) */ set_channels(2); set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le); } void MP3FILE::start_io(void) { if (triggered_rep != true) { if (io_mode() == io_read) fork_input_process(); else fork_output_process(); triggered_rep = true; } } void MP3FILE::stop_io(void) { if (triggered_rep == true) { /* note: it's safe to send a SIGTERM if the client is * an input and we know its PID (otherwise * cleanup will still work but will take more time, which * is nasty if we are in a middle of a seek */ if (io_mode() == io_read) clean_child(true); else clean_child(false); triggered_rep = false; } } void MP3FILE::fork_input_process(void) { std::string cmd = MP3FILE::conf_input_cmd; if (cmd.find("%o") != std::string::npos) { cmd.replace(cmd.find("%o"), 2, kvu_numtostr((long)(position_in_samples() / pcm_rep))); } last_position_rep = position_in_samples(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "" + cmd); set_fork_command(cmd); set_fork_file_name(label()); set_fork_bits(bits()); set_fork_channels(channels()); set_fork_sample_rate(samples_per_second()); /* for old mpg123 */ fork_child_for_read(); if (child_fork_succeeded() == true) { /* NOTE: the file description will be closed by * AUDIO_IO_FORKED_STREAM::clean_child() */ filedes_rep = file_descriptor(); filehandle_rep = fdopen(filedes_rep, "r"); /* not part of */ if (filehandle_rep == 0) { finished_rep = true; triggered_rep = false; } } } void MP3FILE::fork_output_process(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Starting to encode " + label() + " with lame."); last_position_rep = position_in_samples(); std::string cmd = MP3FILE::conf_output_cmd; if (cmd.find("%B") != std::string::npos) { cmd.replace(cmd.find("%B"), 2, kvu_numtostr((long int)(bitrate_rep / 1000))); } set_fork_command(cmd); set_fork_file_name(label()); set_fork_bits(bits()); set_fork_channels(channels()); set_fork_sample_rate(samples_per_second()); fork_child_for_write(); if (child_fork_succeeded() == true) { filedes_rep = file_descriptor(); } } ecasound-2.9.1/libecasound/audiofx_reverb.h0000644000076400007640000000266710664032032015731 00000000000000#ifndef INCLUDED_AUDIOFX_REVERB_H #define INCLUDED_AUDIOFX_REVERB_H #include #include "audiofx_timebased.h" /** * Reverb effect * * May 2000, Stefan Fendt (C++ version by Kai Vehmanen) */ class ADVANCED_REVERB : public EFFECT_TIME_BASED { private: SAMPLE_ITERATOR_CHANNELS i_channels; parameter_t roomsize_rep; parameter_t feedback_rep; parameter_t wet_rep; class CHANNEL_DATA { public: std::vector buffer; std::vector dpos; std::vector mul; long int bufferpos_rep; SAMPLE_SPECS::sample_t oldvalue, lpvalue; CHANNEL_DATA(void) : buffer(65536, 0.0), dpos(200), mul(200), bufferpos_rep(0) { } }; std::vector cdata; public: virtual std::string name(void) const { return("Advanced reverb"); } virtual std::string parameter_names(void) const { return("Room-size,feedback-%,wet-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual parameter_t get_parameter(int param) const; virtual void set_parameter(int param, parameter_t value); virtual void init(SAMPLE_BUFFER* insample); virtual void process(void); ADVANCED_REVERB* clone(void) const { return new ADVANCED_REVERB(*this); } ADVANCED_REVERB* new_expr(void) const { return new ADVANCED_REVERB(); } ADVANCED_REVERB (parameter_t roomsize = 10.0, parameter_t feedback_percent = 50.0, parameter_t wet_percent = 50.0); }; #endif ecasound-2.9.1/libecasound/audiofx_filter.h0000644000076400007640000002742610664032032015731 00000000000000#ifndef INCLUDED_AUDIOFX_FILTER_H #define INCLUDED_AUDIOFX_FILTER_H #include #include #include #include "audiofx.h" #include "samplebuffer_iterators.h" /** * Virtual base for filter effects. * @author Kai Vehmanen */ class EFFECT_FILTER : public EFFECT_BASE { public: virtual ~EFFECT_FILTER(void); }; /** * Base class for butterworth filter effects. * * Based on SPKit Butterworth algorithms. * (for more info, see http://www.music.helsinki.fi/research/spkit) */ class EFFECT_BW_FILTER : public EFFECT_FILTER { private: SAMPLE_SPECS::sample_t outputSample; SAMPLE_ITERATOR_CHANNELS i; std::vector > sin; std::vector > sout; void init_values(void); protected: std::vector a; std::vector b; public: void process_notused(SAMPLE_BUFFER* sbuf); virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual EFFECT_BW_FILTER* clone(void) const = 0; // EFFECT_BW_FILTER(void) : sin(2), sout(2), a(3), b(2) { EFFECT_BW_FILTER(void) : a(3), b(2) { init_values(); } }; /** * Bandpass filter * * Based on SPKit Butterworth algorithms * (for more info, see http://www.music.helsinki.fi/research/spkit) */ class EFFECT_BANDPASS: public EFFECT_BW_FILTER { private: parameter_t center; parameter_t width; parameter_t C; parameter_t D; public: virtual std::string name(void) const { return("Bandpass filter"); } virtual std::string parameter_names(void) const { return("center-freq,width"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; EFFECT_BANDPASS* clone(void) const { return new EFFECT_BANDPASS(*this); } EFFECT_BANDPASS* new_expr(void) const { return new EFFECT_BANDPASS(); } EFFECT_BANDPASS (parameter_t centerf = 1000.0, parameter_t width = 1000.0); }; /** * Bandreject filter * * Based on SPKit Butterworth algorithms * (for more info, see http://www.music.helsinki.fi/research/spkit) */ class EFFECT_BANDREJECT: public EFFECT_BW_FILTER { private: parameter_t center; parameter_t width; parameter_t C; parameter_t D; public: virtual std::string name(void) const { return("Bandreject filter"); } virtual std::string parameter_names(void) const { return("center-freq,width"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; EFFECT_BANDREJECT* clone(void) const { return new EFFECT_BANDREJECT(*this); } EFFECT_BANDREJECT* new_expr(void) const { return new EFFECT_BANDREJECT(); } EFFECT_BANDREJECT (parameter_t centerf = 1000.0, parameter_t width = 1000.0); }; /** * Highpass filter * * Based on SPKit Butterworth algorithms * (for more info, see http://www.music.helsinki.fi/research/spkit) */ class EFFECT_HIGHPASS : public EFFECT_BW_FILTER { private: parameter_t cutOffFreq; parameter_t C; public: virtual std::string name(void) const { return("Highpass filter"); } virtual std::string parameter_names(void) const { return("cutoff-freq"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; EFFECT_HIGHPASS* clone(void) const { return new EFFECT_HIGHPASS(*this); } EFFECT_HIGHPASS* new_expr(void) const { return new EFFECT_HIGHPASS(); } EFFECT_HIGHPASS (parameter_t cutoff = 1000.0); }; /** * Allpass filter */ class EFFECT_ALLPASS_FILTER : public EFFECT_FILTER { std::vector > inbuf, outbuf; SAMPLE_ITERATOR_CHANNELS i; parameter_t feedback_gain; parameter_t D; public: virtual std::string name(void) const { return("Allpass filter"); } virtual std::string parameter_names(void) const { return("delay-samples,feedback-%"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_ALLPASS_FILTER* clone(void) const { return new EFFECT_ALLPASS_FILTER(*this); } EFFECT_ALLPASS_FILTER* new_expr(void) const { return new EFFECT_ALLPASS_FILTER(); } EFFECT_ALLPASS_FILTER (void); }; /** * Comb filter * * The basic theory behind this can be found from Ken Steiglitz's book * "A digital signal processing primer", page 103. */ class EFFECT_COMB_FILTER : public EFFECT_FILTER { std::vector > buffer; std::vector temp; SAMPLE_ITERATOR_CHANNELS i; parameter_t C; parameter_t D; public: virtual std::string name(void) const { return("Comb filter"); } virtual std::string parameter_names(void) const { return("delay-samples,radius"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_COMB_FILTER* clone(void) const { return new EFFECT_COMB_FILTER(*this); } EFFECT_COMB_FILTER* new_expr(void) const { return new EFFECT_COMB_FILTER(); } EFFECT_COMB_FILTER (int delay_in_samples = 1, parameter_t constant = 1.0); }; /** * Inverse comb filter * * The basic theory behind this can be found from Ken Steiglitz's book * "A digital signal processing primer", page 77. */ class EFFECT_INVERSE_COMB_FILTER : public EFFECT_FILTER { std::vector laskuri; std::vector > buffer; std::vector temp; SAMPLE_ITERATOR_CHANNELS i; parameter_t C; parameter_t D; public: virtual std::string name(void) const { return("Inverse comb filter"); } virtual std::string parameter_names(void) const { return("delay-samples,radius"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_INVERSE_COMB_FILTER* clone(void) const { return new EFFECT_INVERSE_COMB_FILTER(*this); } EFFECT_INVERSE_COMB_FILTER* new_expr(void) const { return new EFFECT_INVERSE_COMB_FILTER(); } EFFECT_INVERSE_COMB_FILTER (int delay_in_samples = 10, parameter_t constant = 1.0); }; /** * Lowpass filter * * Based on SPKit Butterworth algorithms * (for more info, see http://www.music.helsinki.fi/research/spkit) */ class EFFECT_LOWPASS: public EFFECT_BW_FILTER { private: parameter_t cutOffFreq; parameter_t C; public: virtual std::string name(void) const { return("Lowpass filter"); } virtual std::string parameter_names(void) const { return("cutoff-freq"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; void set_cutoff(parameter_t value, long int srate); EFFECT_LOWPASS* clone(void) const { return new EFFECT_LOWPASS(*this); } EFFECT_LOWPASS* new_expr(void) const { return new EFFECT_LOWPASS(); } EFFECT_LOWPASS (parameter_t cutoff = 1000.0); }; /** * A simple lowpass filter * * Algorithm: 1nd order filter. * From Fugue source code: * * output[N] = input[N] * A + input[N-1] * B * * A = 2.0 * pi * center * B = exp(-A / frequency) */ class EFFECT_LOWPASS_SIMPLE : public EFFECT_FILTER { private: parameter_t cutOffFreq; parameter_t A, B; std::vector outhist, tempin, temphist; SAMPLE_ITERATOR_CHANNELS i; public: virtual std::string name(void) const { return("Simple lowpass filter"); } virtual std::string parameter_names(void) const { return("cutoff-freq"); } virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; EFFECT_LOWPASS_SIMPLE* clone(void) const { return new EFFECT_LOWPASS_SIMPLE(*this); } EFFECT_LOWPASS_SIMPLE* new_expr(void) const { return new EFFECT_LOWPASS_SIMPLE(); } EFFECT_LOWPASS_SIMPLE (parameter_t cutoff = 1000.0); }; /** * Resonant bandpass filter */ class EFFECT_RESONANT_BANDPASS : public EFFECT_FILTER { private: std::vector outhist1, outhist2; parameter_t center; parameter_t width; parameter_t a, b, c, R; parameter_t pole_angle; SAMPLE_ITERATOR_CHANNELS i; public: virtual std::string name(void) const { return("Resonant bandpass filter"); } virtual std::string parameter_names(void) const { return("center-freq,width"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_RESONANT_BANDPASS* clone(void) const { return new EFFECT_RESONANT_BANDPASS(*this); } EFFECT_RESONANT_BANDPASS* new_expr(void) const { return new EFFECT_RESONANT_BANDPASS(); } EFFECT_RESONANT_BANDPASS (parameter_t centerf = 1000.0, parameter_t width = 1000.0); }; /** * Resonant lowpass filter * * Algorithm is based on a sample filter-routine (iir_filter) posted to comp.dsp. */ class EFFECT_RESONANT_LOWPASS : public EFFECT_FILTER { SAMPLE_ITERATOR_CHANNELS i; std::vector outhist0, outhist1, outhist2, outhist3; std::vector newhist0, newhist1; class TRIPLE_COEFS { public: parameter_t a0, a1, a2; // numerator coefficients parameter_t b0, b1, b2; // denominator coefficients }; class FILTER_COEFS { public: parameter_t A, B, C, D; // filter coefficients }; std::vector ProtoCoef; // Filter prototype coefficients, // for each filter section std::vector Coef; parameter_t cutoff, Q, gain, gain_orig; parameter_t pi; parameter_t laskuri; parameter_t ad, bd, wp; // for szxform() void szxform(int section); void refresh_values(void); public: virtual std::string name(void) const { return("Resonant lowpass filter"); } virtual std::string parameter_names(void) const { return("cutoff-freq,resonance,gain"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_RESONANT_LOWPASS* clone(void) const { return new EFFECT_RESONANT_LOWPASS(*this); } EFFECT_RESONANT_LOWPASS* new_expr(void) const { return new EFFECT_RESONANT_LOWPASS(); } EFFECT_RESONANT_LOWPASS (parameter_t cutoff = 1000.0, parameter_t resonance = 1.0, parameter_t gain = 1.0); }; /** * Resonating bandpass filter * * Based on a second order all-pole (IIR) band-pass filter from SPKit * (for more info, see: http://www.music.helsinki.fi/research/spkit) */ class EFFECT_RESONATOR : public EFFECT_FILTER { private: SAMPLE_ITERATOR_CHANNELS i; parameter_t center; parameter_t width; std::vector cona; std::vector conb; std::vector saout0, saout1; public: virtual std::string name(void) const { return("Resonator filter"); } virtual std::string parameter_names(void) const { return("center-freq,width"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_RESONATOR* clone(void) const { return new EFFECT_RESONATOR(*this); } EFFECT_RESONATOR* new_expr(void) const { return new EFFECT_RESONATOR(); } EFFECT_RESONATOR (parameter_t center = 1000.0, parameter_t width = 1000.0); }; #endif ecasound-2.9.1/libecasound/audioio-flac.cpp0000644000076400007640000002025311137153215015606 00000000000000// ------------------------------------------------------------------------ // audioio-flac.cpp: Interface to FLAC decoders and encoders using UNIX // pipe i/o. // Copyright (C) 2004-2006,2008,2009 Kai Vehmanen // // 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 #include /* atol() */ #include /* stat() */ #include /* stat() */ #include #include #include "audioio-flac.h" #include "eca-logger.h" /** * References: * http://flac.sourceforge.net/ * http://flac.sourceforge.net/format.html */ string FLAC_FORKED_INTERFACE::default_input_cmd = "flac -d -c %f"; string FLAC_FORKED_INTERFACE::default_output_cmd = "flac -o %f -f --force-raw-format --channels=%c --bps=%b --sample-rate=%s --sign=%I --endian=%E -"; void FLAC_FORKED_INTERFACE::set_input_cmd(const std::string& value) { FLAC_FORKED_INTERFACE::default_input_cmd = value; } void FLAC_FORKED_INTERFACE::set_output_cmd(const std::string& value) { FLAC_FORKED_INTERFACE::default_output_cmd = value; } FLAC_FORKED_INTERFACE::FLAC_FORKED_INTERFACE(const std::string& name) : triggered_rep(false), finished_rep(false) { set_label(name); } FLAC_FORKED_INTERFACE::~FLAC_FORKED_INTERFACE(void) { clean_child(true); if (is_open() == true) { close(); } } void FLAC_FORKED_INTERFACE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { std::string urlprefix; triggered_rep = false; finished_rep = false; /** * FIXME: we have no idea about the audio format of the * stream we get from ogg123... maybe we should force decoder * to generate RIFF wave to a named pipe and parse the header...? */ /* flac tools do not support packed 24bit samples, use * 32bit format instead */ if (bits() == 24) { enum Sample_endianess t = sample_endianess(); set_sample_format(ECA_AUDIO_FORMAT::sfmt_s32); set_sample_endianess(t); } if (io_mode() == io_read) { struct stat buf; int ret = ::stat(label().c_str(), &buf); if (ret != 0) { size_t offset = label().find_first_of("://"); if (offset == std::string::npos) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-FLAC: Can't open file " + label() + ".")); } else { urlprefix = std::string(label(), 0, offset); ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-flac) Found url; protocol '" + urlprefix + "'."); } } /* decoder supports: nothing configurable nor fixed * * FIXME: we have no idea about the audio format of the * stream we get from the decoder... ybe we should force the decoder * to generate RIFF wave to a named pipe and parse the header...? * * - possibly copy FLAC__metadata_get_streaminfo() from flac * package... might be messy due to dependencies * - see http://flac.sourceforge.net/format.html */ } else { /* encoder supports: coding, channel-count, srate and endianess configurable */ } AUDIO_IO::open(); } void FLAC_FORKED_INTERFACE::close(void) { if (pid_of_child() > 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + "."); /* note: flac output must not be sent a SIGTERM upon close(), or otherwise the generated header is invalid */ clean_child(); triggered_rep = false; } AUDIO_IO::close(); } long int FLAC_FORKED_INTERFACE::read_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_input_process(); } if (f1_rep != 0) { bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, f1_rep); } else { bytes_rep = 0; } if (bytes_rep < samples * frame_size() || bytes_rep == 0) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::info, "(audioio-flac) Can't start process \"" + FLAC_FORKED_INTERFACE::default_input_cmd + "\". Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; } else finished_rep = false; return(bytes_rep / frame_size()); } void FLAC_FORKED_INTERFACE::write_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_output_process(); } if (wait_for_child() != true) { finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Attempt to write after child process has terminated."); } else { if (filedes_rep > 0) { bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples); } else { bytes_rep = 0; } if (bytes_rep < frame_size() * samples) { finished_rep = true; triggered_rep = false; ECA_LOG_MSG(ECA_LOGGER::errors, "Error in writing to child process (to write " + kvu_numtostr(frame_size() * samples) + ", result " + kvu_numtostr(bytes_rep) + ")."); } else finished_rep = false; } } void FLAC_FORKED_INTERFACE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; } } string FLAC_FORKED_INTERFACE::get_parameter(int param) const { switch (param) { case 1: return(label()); } return(""); } void FLAC_FORKED_INTERFACE::fork_input_process(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, FLAC_FORKED_INTERFACE::default_input_cmd); set_fork_command(FLAC_FORKED_INTERFACE::default_input_cmd); set_fork_file_name(label()); fork_child_for_read(); if (child_fork_succeeded() == true) { /* NOTE: the file description will be closed by * AUDIO_IO_FORKED_STREAM::clean_child() */ filedes_rep = file_descriptor(); f1_rep = fdopen(filedes_rep, "r"); /* not part of */ if (f1_rep == 0) { finished_rep = true; triggered_rep = false; } } else f1_rep = 0; } void FLAC_FORKED_INTERFACE::fork_output_process(void) { string command = FLAC_FORKED_INTERFACE::default_output_cmd; // replace with 'little/big' byteorder if (command.find("%E") != string::npos) { string byteorder ("big"); if (sample_endianess() == ECA_AUDIO_FORMAT::se_little) byteorder = "little"; command.replace(command.find("%E"), 2, byteorder); } // replace with 'signed/unsigned' if (command.find("%I") != string::npos) { string sign ("signed"); if (sample_coding() == ECA_AUDIO_FORMAT::sc_unsigned) sign = "unsigned"; command.replace(command.find("%I"), 2, sign); } set_fork_command(command); set_fork_file_name(label()); int bitcount = bits(); if (bitcount == 32) { /* flac uses 24-in-32bit format, but you have to give * number of used bits for --bps=xxx */ bitcount = 24; } set_fork_bits(bitcount); set_fork_channels(channels()); set_fork_sample_rate(samples_per_second()); fork_child_for_write(); if (child_fork_succeeded() == true) { filedes_rep = file_descriptor(); } else { filedes_rep = 0; } } void FLAC_FORKED_INTERFACE::start_io(void) { if (triggered_rep != true) { if (io_mode() == io_read) fork_input_process(); else fork_output_process(); triggered_rep = true; } } void FLAC_FORKED_INTERFACE::stop_io(void) { if (triggered_rep == true) { if (io_mode() == io_read) clean_child(true); else clean_child(false); triggered_rep = false; } } ecasound-2.9.1/libecasound/stamp-ctrl.cpp0000644000076400007640000000420211034535055015336 00000000000000// ------------------------------------------------------------------------ // stamp-ctrl.cpp: Controller sources that analyze audio stamps // and produce control data. // Copyright (C) 2000,2001,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // This program is fre 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 "samplebuffer_functions.h" #include "stamp-ctrl.h" VOLUME_ANALYZE_CONTROLLER::VOLUME_ANALYZE_CONTROLLER(void) { } CONTROLLER_SOURCE::parameter_t VOLUME_ANALYZE_CONTROLLER::value(double pos) { parameter_t v = 0.0f; fetch_stamp(&sbuf_rep); if (rms_mode_rep != 0) v = SAMPLE_BUFFER_FUNCTIONS::RMS_volume(sbuf_rep); else v = SAMPLE_BUFFER_FUNCTIONS::average_amplitude(sbuf_rep); if (!(v > 0.0f)) v = 0.0f; // cerr << "(volume-analyze-ctrl) Fetches a sbuf with value " << v << endl; return v; } void VOLUME_ANALYZE_CONTROLLER::init(void) { } void VOLUME_ANALYZE_CONTROLLER::set_parameter(int param, CONTROLLER_SOURCE::parameter_t value) { switch (param) { case 1: set_id(static_cast(value)); break; case 2: rms_mode_rep = static_cast(value); break; } } CONTROLLER_SOURCE::parameter_t VOLUME_ANALYZE_CONTROLLER::get_parameter(int param) const { switch (param) { case 1: return static_cast(id()); case 2: return static_cast(rms_mode_rep); } return 0.0f; } ecasound-2.9.1/libecasound/audioio-oss_impl.h0000644000076400007640000000021510664032032016164 00000000000000#ifndef _AUDIOIO_OSS_IMPL_H #define _AUDIOIO_OSS_IMPL_H #define DEFAULT_FRAGMENT_SIZE 0 #define DEFAULT_FRAGMENT_COUNT 0 #endif ecasound-2.9.1/libecasound/global-preset.h0000644000076400007640000000101010664032032015442 00000000000000#ifndef INCLUDED_GLOBAL_PRESET_H #define INCLUDED_GLOBAL_PRESET_H #include "preset.h" /** * Effect preset that is read from a global * preset database. * * @author Kai Vehmanen */ class GLOBAL_PRESET : public PRESET { private: std::string preset_name_rep; public: virtual GLOBAL_PRESET* clone(void) const; virtual GLOBAL_PRESET* new_expr(void) const { return(new GLOBAL_PRESET(preset_name_rep)); } virtual ~GLOBAL_PRESET (void) { } GLOBAL_PRESET(const std::string& preset_name = ""); }; #endif ecasound-2.9.1/libecasound/stamp-ctrl.h0000644000076400007640000000231011034531771015002 00000000000000#ifndef INCLUDE_STAMP_CTRL_H #define INCLUDE_STAMP_CTRL_H #include #include "ctrl-source.h" #include "audio-stamp.h" #include "samplebuffer.h" /** * Controller sources that analyze audio stamps * and produce control data. * @author Kai Vehmanen */ class AUDIO_STAMP_CONTROLLER : public CONTROLLER_SOURCE, public AUDIO_STAMP_CLIENT { public: }; /** * Controller that analyzes stamp volume level, and creates * control data based on the results. */ class VOLUME_ANALYZE_CONTROLLER : public AUDIO_STAMP_CONTROLLER { public: virtual std::string name(void) const { return("Volume analyze controller"); } virtual void init(void); virtual parameter_t value(double pos_secs); virtual void set_initial_value(parameter_t arg) {} virtual std::string parameter_names(void) const { return("stamp-id,rms-toggle"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; VOLUME_ANALYZE_CONTROLLER(void); VOLUME_ANALYZE_CONTROLLER* clone(void) const { return 0; } VOLUME_ANALYZE_CONTROLLER* new_expr(void) const { return new VOLUME_ANALYZE_CONTROLLER(); } private: int rms_mode_rep; SAMPLE_BUFFER sbuf_rep; }; #endif ecasound-2.9.1/libecasound/eca-chainsetup_impl.h0000644000076400007640000000137310664032032016630 00000000000000#ifndef INCLUDED_ECA_CHAINSETUP_IMPL_H #define INCLUDED_ECA_CHAINSETUP_IMPL_H #include "eca-chainsetup-bufparams.h" #include "audio-stamp.h" #include "midi-server.h" #include "audioio-db-client.h" class ECA_CHAINSETUP_impl { public: friend class ECA_CHAINSETUP; private: /** @name Aggregate objects */ /*@{*/ ECA_AUDIO_FORMAT default_audio_format_rep; AUDIO_STAMP_SERVER stamp_server_rep; AUDIO_IO_DB_SERVER pserver_rep; MIDI_SERVER midi_server_rep; ECA_CHAINSETUP_BUFPARAMS bmode_active_rep; ECA_CHAINSETUP_BUFPARAMS bmode_override_rep; ECA_CHAINSETUP_BUFPARAMS bmode_nonrt_rep; ECA_CHAINSETUP_BUFPARAMS bmode_rt_rep; ECA_CHAINSETUP_BUFPARAMS bmode_rtlowlatency_rep; /*@}*/ }; #endif /* INCLUDED_ECA_CHAINSETUP_IMPL_H */ ecasound-2.9.1/libecasound/audiofx_lv2.h0000644000076400007640000000367211740524567015163 00000000000000#ifndef INCLUDED_AUDIOFX_LV2_H #define INCLUDED_AUDIOFX_LV2_H #include #include #include "audiofx.h" #if ECA_USE_LIBLILV #include class SAMPLE_BUFFER; /** * Wrapper class for LV2 plugins * @author Jeremy Salwen */ class EFFECT_LV2 : public EFFECT_BASE { public: EFFECT_LV2 (Lilv::Plugin plugin_d) throw(ECA_ERROR&); virtual ~EFFECT_LV2(void); EFFECT_LV2* clone(void) const; EFFECT_LV2* new_expr(void) const { return new EFFECT_LV2(plugin_desc); } virtual std::string name(void) const { return(name_rep); } virtual std::string description(void) const; virtual std::string parameter_names(void) const { return(param_names_rep); } /** * This identifier can be used as a unique, case-sensitive * identifier for the plugin type within the plugin file. * Labels must not contain white-space characters. */ std::string unique(void) const { return(unique_rep); } virtual int output_channels(int i_channels) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); private: EFFECT_LV2(const EFFECT_LV2& x):plugin_desc(x.plugin_desc) { } EFFECT_LV2& operator=(const EFFECT_LV2& x) { return *this; } private: SAMPLE_BUFFER* buffer_repp; Lilv::Plugin plugin_desc; std::vector plugins_rep; unsigned long port_count_rep; int in_audio_ports; int out_audio_ports; std::string name_rep, maker_rep, unique_rep, param_names_rep; std::vector params; std::vector param_descs_rep; void init_ports(void) throw(ECA_ERROR&); void parse_parameter_hint_information(const Lilv::Plugin plugin, Lilv::Port p, struct PARAM_DESCRIPTION *pd); }; #endif /* ECA_USE_LIBLILV */ #endif ecasound-2.9.1/libecasound/audioio-tone.cpp0000644000076400007640000001664011260602227015652 00000000000000// ------------------------------------------------------------------------ // audioio-tone.cpp: Tone generator // // Adaptation to Ecasound: // Copyright (C) 2007-2009 Kai Vehmanen (adaptation to Ecasound) // // Sources for sine generation (cmt-src-1.15/src/sine.cpp): // // Computer Music Toolkit - a library of LADSPA plugins. Copyright (C) // 2000-2002 Richard W.E. Furse. The author may be contacted at // richard@muse.demon.co.uk. // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include /* C++'s standard does not define M_PI */ #include #include #include #include "eca-object-factory.h" #include "samplebuffer.h" #include "audioio-tone.h" #include "eca-error.h" #include "eca-logger.h" /** * FIXME notes (last update 2008-03-06) * * - define the syntax: is this 'tone', 'sinetone', * 'tone=sine', ..., or? * - add support for multichannel testing (different * frequnecies for different channels?) */ using std::cout; using std::endl; using std::atof; using std::string; /* Sine table size is given by (1 << SINE_TABLE_BITS). */ #define SINE_TABLE_BITS 14 #define SINE_TABLE_SHIFT (8 * sizeof(unsigned long) - SINE_TABLE_BITS) SAMPLE_SPECS::sample_t *g_pfSineTable = NULL; SAMPLE_SPECS::sample_t g_fPhaseStepBase = 0; static void initialise_sine_wavetable(void) { if (g_pfSineTable == NULL) { unsigned long lTableSize = (1 << SINE_TABLE_BITS); double dShift = (double(M_PI) * 2) / lTableSize; g_pfSineTable = new SAMPLE_SPECS::sample_t[lTableSize]; if (g_pfSineTable != NULL) for (unsigned long lIndex = 0; lIndex < lTableSize; lIndex++) g_pfSineTable[lIndex] = SAMPLE_SPECS::sample_t(sin(dShift * lIndex)); } if (g_fPhaseStepBase == 0) { g_fPhaseStepBase = (SAMPLE_SPECS::sample_t)pow(2, sizeof(unsigned long) * 8); } } AUDIO_IO_TONE::AUDIO_IO_TONE (const std::string& name) : m_lPhaseStep(0), m_fCachedFrequency(0), m_fLimitFrequency(0), m_fPhaseStepScalar(0) { set_label(name); initialise_sine_wavetable(); } AUDIO_IO_TONE::~AUDIO_IO_TONE(void) { } AUDIO_IO_TONE* AUDIO_IO_TONE::clone(void) const { AUDIO_IO_TONE* target = new AUDIO_IO_TONE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } target->set_position_in_samples(position_in_samples()); if (ECA_AUDIO_POSITION::length_set()) target->ECA_AUDIO_POSITION::set_length_in_samples(ECA_AUDIO_POSITION::length_in_samples()); target->buffersize_rep = buffersize_rep; target->finished_rep = finished_rep; target->m_lPhase = m_lPhase; target->m_lPhaseStep = m_lPhaseStep; DBC_CHECK(target->m_fCachedFrequency == m_fCachedFrequency); target->m_fLimitFrequency = m_fLimitFrequency; target->m_fPhaseStepScalar = m_fPhaseStepScalar; return target; } void AUDIO_IO_TONE::open(void) throw(AUDIO_IO::SETUP_ERROR &) { DBC_CHECK(samples_per_second() != 0); if (io_mode() != AUDIO_IO::io_read) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIO_IO_TONE: Writing to tone generator not allowed!")); finished_rep = false; m_fLimitFrequency = SAMPLE_SPECS::sample_t(samples_per_second() * 0.5); m_fPhaseStepScalar = SAMPLE_SPECS::sample_t(g_fPhaseStepBase / samples_per_second()); /* recalculate m_fLimitFrequency and mfPhaseStepScalar */ if (m_fCachedFrequency) setPhaseStepFromFrequency(m_fCachedFrequency, true); AUDIO_IO::open(); } void AUDIO_IO_TONE::close(void) { AUDIO_IO::close(); } bool AUDIO_IO_TONE::finite_length_stream(void) const { return ECA_AUDIO_POSITION::length_set(); } void AUDIO_IO_TONE::read_buffer(SAMPLE_BUFFER* sbuf) { /* write to sbuf->buffer[ch], similarly as the LADSPA * chainops */ sbuf->number_of_channels(channels()); /* set the length according to our buffersize */ if ((ECA_AUDIO_POSITION::length_set() == true) && ((position_in_samples() + buffersize()) >= ECA_AUDIO_POSITION::length_in_samples())) { /* over requested duration, adjust buffersize */ SAMPLE_BUFFER::buf_size_t partialbuflen = ECA_AUDIO_POSITION::length_in_samples() - position_in_samples(); if (partialbuflen < 0) partialbuflen = 0; DBC_CHECK(partialbuflen <= buffersize()); sbuf->length_in_samples(partialbuflen); sbuf->event_tag_set(SAMPLE_BUFFER::tag_end_of_stream); finished_rep = true; } else sbuf->length_in_samples(buffersize()); i.init(sbuf); i.begin(); while(!i.end()) { for(int n = 0; n < channels(); n++) { if (i.end()) break; *(i.current(n)) = g_pfSineTable[m_lPhase >> SINE_TABLE_SHIFT]; } m_lPhase += m_lPhaseStep; i.next(); } change_position_in_samples(sbuf->length_in_samples()); DBC_ENSURE(sbuf->number_of_channels() == channels()); } void AUDIO_IO_TONE::write_buffer(SAMPLE_BUFFER* sbuf) { /* NOP */ DBC_CHECK(false); } SAMPLE_SPECS::sample_pos_t AUDIO_IO_TONE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { /* note: phase must be correct after arbitrary seeks */ m_lPhase = m_lPhaseStep * pos; if (ECA_AUDIO_POSITION::length_set() == true && pos < ECA_AUDIO_POSITION::length_in_samples()) finished_rep = false; return pos; } void AUDIO_IO_TONE::setPhaseStepFromFrequency(const SAMPLE_SPECS::sample_t fFrequency, bool force) { if (fFrequency != m_fCachedFrequency || force == true) { if (fFrequency >= 0 && fFrequency < m_fLimitFrequency) m_lPhaseStep = (unsigned long)(m_fPhaseStepScalar * fFrequency); else m_lPhaseStep = 0; m_fCachedFrequency = fFrequency; } } void AUDIO_IO_TONE::set_parameter(int param, string value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, AUDIO_IO::parameter_set_to_string(param, value)); switch (param) { case 1: { AUDIO_IO::set_parameter (param, value); break; } case 2: { /* type; only "sine" supported */ break; } case 3: { setPhaseStepFromFrequency (atof(value.c_str()), false); break; } case 4: { double duration = atof(value.c_str()); if (duration > 0.0f) ECA_AUDIO_POSITION::set_length_in_seconds(duration); break; } } } string AUDIO_IO_TONE::get_parameter(int param) const { switch (param) { case 1: return AUDIO_IO::get_parameter(param); case 2: return "sine"; case 3: return kvu_numtostr(m_fCachedFrequency); case 4: { if (ECA_AUDIO_POSITION::length_set() == true) return kvu_numtostr(ECA_AUDIO_POSITION::length_in_seconds_exact()); else return kvu_numtostr(-1.0f); } default: break; } return std::string(); } ecasound-2.9.1/libecasound/audioio-mp3.h0000644000076400007640000000556711161425433015061 00000000000000#ifndef INCLUDED_AUDIOIO_MP3_H #define INCLUDED_AUDIOIO_MP3_H #include #include #include "audioio-buffered.h" #include "audioio-forked-stream.h" #include "sample-specs.h" /** * Interface for mp3 decoders and encoders that support * input/output using standard streams. Defaults to * mpg123 and lame. * @author Kai Vehmanen */ class MP3FILE : public AUDIO_IO_BUFFERED, public AUDIO_IO_FORKED_STREAM { private: static std::string conf_input_cmd; static std::string conf_output_cmd; static long int conf_default_output_bitrate; public: static void set_input_cmd(const std::string& value); static void set_output_cmd(const std::string& value); public: MP3FILE (const std::string& name = ""); virtual ~MP3FILE(void); virtual MP3FILE* clone(void) const { return new MP3FILE(*this); } virtual MP3FILE* new_expr(void) const { return new MP3FILE(*this); } virtual std::string name(void) const { return("Mp3 stream"); } virtual std::string description(void) const { return("Interface for mp3 decoders and encoders that support input/output using standard streams."); } virtual std::string parameter_names(void) const { return("label,bitrate"); } virtual bool locked_audio_format(void) const { return(true); } virtual int supported_io_modes(void) const { return(io_read | io_write); } virtual bool supports_seeking(void) const { return io_mode() == io_read; } virtual bool supports_seeking_sample_accurate(void) const { return false; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const { return finished_rep; } virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; virtual void start_io(void); virtual void stop_io(void); protected: /* functions called by AUDIO_IO_FORKED_STREAM that require * the use of AUDIO_IO methods */ virtual bool do_supports_seeking(void) const { return supports_seeking(); } virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { set_position_in_samples(pos); } private: bool finished_rep; bool triggered_rep; int pid_of_child_rep; long pcm_rep; long int bytes_rep; long int bitrate_rep; SAMPLE_SPECS::sample_pos_t last_position_rep; int filedes_rep; FILE* filehandle_rep; bool mono_input_rep; void process_mono_fix(char* target_buffer, long int bytes_rep); void get_mp3_params(const std::string& fname) throw(AUDIO_IO::SETUP_ERROR&); // MP3FILE(const MP3FILE& x) { } MP3FILE& operator=(const MP3FILE& x) { return *this; } void fork_input_process(void); void fork_output_process(void); }; #endif ecasound-2.9.1/libecasound/audio-stamp.cpp0000644000076400007640000000465711161515355015513 00000000000000// ------------------------------------------------------------------------ // audio-stamp.cpp: Classes for handling audio stamps and their clients // Copyright (C) 2000 Kai Vehmanen // // 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 "audio-stamp.h" AUDIO_STAMP::AUDIO_STAMP(void) : id_rep(0), id_set_rep(false) { } int AUDIO_STAMP::id(void) const { return(id_rep); } void AUDIO_STAMP::set_id(int n) { id_rep = n; id_set_rep = true; } void AUDIO_STAMP::store(const SAMPLE_BUFFER* x) { buffer_rep.copy_all_content(*x); } void AUDIO_STAMP::fetch_stamp(SAMPLE_BUFFER* x) { x->copy_all_content(buffer_rep); } void AUDIO_STAMP_SERVER::register_stamp(AUDIO_STAMP* stamp) { stamp_map_rep[stamp->id()] = stamp; } void AUDIO_STAMP_SERVER::fetch_stamp(int id, SAMPLE_BUFFER* x) { if (stamp_map_rep.find(id) == stamp_map_rep.end()) { x->make_silent(); // std::cerr << "(as-server) Making silent!" << std::endl; } else { AUDIO_STAMP* p = stamp_map_rep[id]; p->fetch_stamp(x); // cerr << "(as-server) fetch stamp from id " << p->id() << "." << endl; } } AUDIO_STAMP_CLIENT::AUDIO_STAMP_CLIENT(void) : id_rep(0), id_set_rep(false), server_repp(0) { } int AUDIO_STAMP_CLIENT::id(void) const { return(id_rep); } void AUDIO_STAMP_CLIENT::set_id(int n) { id_rep = n; id_set_rep = true; } void AUDIO_STAMP_CLIENT::fetch_stamp(SAMPLE_BUFFER* x) { if (server_repp != 0) { server_repp->fetch_stamp(id(), x); // cerr << "(as-client) fetch stamp id " << id() << "." << endl; } else { // cerr << "(as-client) Making silent!" << endl; x->make_silent(); } } void AUDIO_STAMP_CLIENT::register_server(AUDIO_STAMP_SERVER* server) { server_repp = server; } ecasound-2.9.1/libecasound/eca-session.cpp0000644000076400007640000004044611170072260015466 00000000000000// ------------------------------------------------------------------------ // eca-session.cpp: Ecasound runtime setup and parameters. // Copyright (C) 1999-2004,2007 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // This program is fre 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 #include #include #include #include #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "eca-resources.h" #include "eca-version.h" #include "eca-chain.h" #include "audiofx.h" #include "audioio.h" #include "audioio-mp3.h" #include "audioio-mikmod.h" #include "audioio-timidity.h" #include "audioio-ogg.h" #include "audioio-flac.h" #include "audioio-aac.h" #include "osc-gen-file.h" #include "eca-error.h" #include "eca-logger.h" #include "eca-logger.h" #include "eca-session.h" #include "eca-chainsetup.h" using std::string; using std::vector; ECA_SESSION::ECA_SESSION(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Session created (empty)"); connected_chainsetup_repp = 0; selected_chainsetup_repp = 0; cs_defaults_set_rep = false; } ECA_SESSION::~ECA_SESSION(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects,"ECA_SESSION destructor-in"); for(std::vector::iterator q = chainsetups_rep.begin(); q != chainsetups_rep.end(); q++) { delete *q; } ECA_LOG_MSG(ECA_LOGGER::system_objects,"ECA_SESSION destructor-out"); } ECA_SESSION::ECA_SESSION(COMMAND_LINE& cline) throw(ECA_ERROR&) { int errors = 0; connected_chainsetup_repp = 0; selected_chainsetup_repp = 0; cs_defaults_set_rep = false; cline.combine(); std::vector options,csoptions; create_chainsetup_options(cline, &options); preprocess_options(&options); errors += interpret_general_options(options,&csoptions); /* NOTE: must be printed after general options are parsed * in case user has specified -q (quiet operation) */ ECA_LOG_MSG(ECA_LOGGER::system_objects, "Session created"); if (errors > 0) { throw(ECA_ERROR("ECA-SESSION", "Errors parsing session-level options. Unable to create session.")); } set_cs_param_defaults(); if (chainsetups_rep.size() == 0) { /* Try to create a valid chainsetup from the options given * on the command-line. */ ECA_CHAINSETUP* comline_setup = new ECA_CHAINSETUP(csoptions); if (comline_setup->interpret_result() != true) { string temp = comline_setup->interpret_result_verbose(); delete comline_setup; // std::cerr << "EXCEPTION DETECTED:'" << temp << "'. Core dump follows if you've compiled with gcc-3.3...\n"; throw(ECA_ERROR("ECA-SESSION", temp)); } else { add_chainsetup(comline_setup); /* ownership object transfered */ if (selected_chainsetup_repp == 0) { /* adding the chainsetup failed */ delete comline_setup; } else if (selected_chainsetup_repp->is_valid() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "NOTE: Unable to create a valid chainsetup from the command-line arguments."); } } } } /** * Sets defaults values for various chainsetup parameters * using ECA_RESOURCES class services. */ void ECA_SESSION::set_cs_param_defaults(void) { if (cs_defaults_set_rep != true) { // --- // Interpret resources ECA_RESOURCES ecaresources; string v; /* note: defaults specified in ecasoundrc(5) */ v = ecaresources.resource("ext-cmd-mp3-input"); if (v.size() > 0) MP3FILE::set_input_cmd(v); v = ecaresources.resource("ext-cmd-mp3-output"); if (v.size() > 0) MP3FILE::set_output_cmd(v); v = ecaresources.resource("ext-cmd-mikmod"); if (v.size() > 0) MIKMOD_INTERFACE::set_mikmod_cmd(v); v = ecaresources.resource("ext-cmd-timidity"); if (v.size() > 0) TIMIDITY_INTERFACE::set_timidity_cmd(v); v = ecaresources.resource("ext-cmd-ogg-input"); if (v.size() > 0) OGG_VORBIS_INTERFACE::set_input_cmd(v); v = ecaresources.resource("ext-cmd-ogg-output"); if (v.size() > 0) OGG_VORBIS_INTERFACE::set_output_cmd(v); v = ecaresources.resource("ext-cmd-flac-input"); if (v.size() > 0) FLAC_FORKED_INTERFACE::set_input_cmd(v); v = ecaresources.resource("ext-cmd-flac-output"); if (v.size() > 0) FLAC_FORKED_INTERFACE::set_output_cmd(v); v = ecaresources.resource("ext-cmd-aac-input"); if (v.size() > 0) AAC_FORKED_INTERFACE::set_input_cmd(v); v = ecaresources.resource("ext-cmd-aac-output"); if (v.size() > 0) AAC_FORKED_INTERFACE::set_output_cmd(v); cs_defaults_set_rep = true; } } /** * Add a new chainsetup * * require: * name.empty() != true * * ensure: * selected_chainsetup->name() == name || * chainsetup_names().size() has not changed */ void ECA_SESSION::add_chainsetup(const std::string& name) { // -------- DBC_REQUIRE(name != ""); // -------- set_cs_param_defaults(); ECA_CHAINSETUP* newsetup = new ECA_CHAINSETUP; newsetup->set_name(name); add_chainsetup(newsetup); if (selected_chainsetup_repp == 0) { /* adding the chainsetup failed */ delete newsetup; } // -------- DBC_ENSURE((selected_chainsetup_repp != 0 && selected_chainsetup_repp->name() == name) || selected_chainsetup_repp == 0); // -------- } /** * Add a new chainsetup. Ownership of the object given as argument * is passed along the call. If a chainsetup with the same name already * exists, the call will fail and the chainsetup given as argument * is deleted. * * require: * comline_setup != 0 * * ensure: * (selected_chainsetup_repp == comline_setup && * static_cast(chainsetups_rep.size()) == old_size + 1) || * (selected_chainsetup_repp == 0 && * static_cast(chainsetups_rep.size()) == old_size) */ void ECA_SESSION::add_chainsetup(ECA_CHAINSETUP* comline_setup) { // -------- DBC_REQUIRE(comline_setup != 0); DBC_DECLARE(int old_size = chainsetups_rep.size()); // -------- selected_chainsetup_repp = comline_setup; set_cs_param_defaults(); std::vector::const_iterator p = chainsetups_rep.begin(); while(p != chainsetups_rep.end()) { if ((*p)->name() == comline_setup->name()) { ECA_LOG_MSG(ECA_LOGGER::info, "Unable to add chainsetup, chainsetup with the same name already exists."); selected_chainsetup_repp = 0; break; } ++p; } if (selected_chainsetup_repp != 0) { chainsetups_rep.push_back(selected_chainsetup_repp); } // -------- DBC_ENSURE((selected_chainsetup_repp == comline_setup && static_cast(chainsetups_rep.size()) == old_size + 1) || (selected_chainsetup_repp == 0 && static_cast(chainsetups_rep.size()) == old_size)); // -------- } /** * Removes selected chainsetup * * require: * connected_chainsetup != selected_chainsetup * * ensure: * selected_chainsetup == 0 */ void ECA_SESSION::remove_chainsetup(void) { // -------- // require: DBC_REQUIRE(connected_chainsetup_repp != selected_chainsetup_repp); // -------- std::vector::iterator p = chainsetups_rep.begin(); while(p != chainsetups_rep.end()) { if (*p == selected_chainsetup_repp) { selected_chainsetup_repp = 0; delete *p; chainsetups_rep.erase(p); break; } ++p; } // -------- DBC_ENSURE(selected_chainsetup_repp == 0); // -------- } void ECA_SESSION::select_chainsetup(const std::string& name) { // -------- // require: DBC_REQUIRE(name.empty() != true); // -------- selected_chainsetup_repp = 0; std::vector::const_iterator p = chainsetups_rep.begin(); while(p != chainsetups_rep.end()) { if ((*p)->name() == name) { // ECA_LOG_MSG(ECA_LOGGER::system_objects, "Chainsetup \"" + name + "\" selected."); selected_chainsetup_repp = *p; break; } ++p; } // -------- DBC_ENSURE(selected_chainsetup_repp == 0 || selected_chainsetup_repp->name() == name); // -------- } void ECA_SESSION::save_chainsetup(void) throw(ECA_ERROR&) { // -------- // require: DBC_REQUIRE(selected_chainsetup_repp != 0); // -------- selected_chainsetup_repp->save(); } void ECA_SESSION::save_chainsetup(const std::string& filename) throw(ECA_ERROR&) { // -------- // require: DBC_REQUIRE(selected_chainsetup_repp != 0 && filename.empty() != true); // -------- selected_chainsetup_repp->save_to_file(filename); } /** * Load a chainsetup from file (ecs). If operation fails, * selected_chainsetup_repp == 0, ie. no chainsetup * selected. * * @post (selected_chainsetup_repp != 0 && * selected_chainsetup_repp->filename() == filename || * selected_chainsetup_repp == 0) */ void ECA_SESSION::load_chainsetup(const std::string& filename) { // -------- DBC_REQUIRE(filename.empty() != true); // -------- set_cs_param_defaults(); ECA_CHAINSETUP* new_setup = new ECA_CHAINSETUP(filename); if (new_setup->interpret_result() != true) { string temp = new_setup->interpret_result_verbose(); delete new_setup; selected_chainsetup_repp = 0; ECA_LOG_MSG(ECA_LOGGER::info, "Error loading chainsetup: " + temp); } else { add_chainsetup(new_setup); if (selected_chainsetup_repp == 0) { /* adding the chainsetup failed */ delete new_setup; } } // -------- DBC_ENSURE((selected_chainsetup_repp != 0 && selected_chainsetup_repp->filename() == filename) || selected_chainsetup_repp == 0); // -------- } void ECA_SESSION::connect_chainsetup(void) throw(ECA_ERROR&) { // -------- DBC_REQUIRE(selected_chainsetup_repp != 0); DBC_REQUIRE(selected_chainsetup_repp->is_valid()); // -------- ECA_LOG_MSG(ECA_LOGGER::user_objects, "Connecting chainsetup"); if (selected_chainsetup_repp == connected_chainsetup_repp) return; if (connected_chainsetup_repp != 0) { disconnect_chainsetup(); } /** * enable() throws an exception if it wasn't possibly * to open/activate all input and output objects */ selected_chainsetup_repp->enable(); connected_chainsetup_repp = selected_chainsetup_repp; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Chainsetup connected"); // -------- // ensure: DBC_ENSURE(selected_chainsetup_repp == connected_chainsetup_repp); // -------- } void ECA_SESSION::disconnect_chainsetup(void) { // -------- DBC_REQUIRE(connected_chainsetup_repp != 0); // -------- connected_chainsetup_repp->disable(); connected_chainsetup_repp = 0; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Chainsetup disconnected"); // -------- DBC_ENSURE(connected_chainsetup_repp == 0); // -------- } std::vector ECA_SESSION::chainsetup_names(void) const { std::vector result; std::vector::const_iterator p = chainsetups_rep.begin(); while(p != chainsetups_rep.end()) { result.push_back((*p)->name()); ++p; } return result; } void ECA_SESSION::create_chainsetup_options(COMMAND_LINE& cline, std::vector* options) { cline.begin(); cline.next(); // skip the program name while(cline.end() == false) { options->push_back(cline.current()); cline.next(); } } /** * Tests whether the given argument is a session-level option. */ bool ECA_SESSION::is_session_option(const std::string& arg) const { if (arg.size() < 2 || arg[0] != '-') return false; switch(arg[1]) { case 'R': case 'd': case 'q': return true; case 's': if (arg.size() > 2 && arg[2] == ':') return true; } return false; } /** * Preprocesses a set of options. * * Notes! See also ECA_CHAINSETUP_PARSER::preprocess_options() * * ensure: * all options valid for further processing (all options * must start with a '-' sign) */ void ECA_SESSION::preprocess_options(std::vector* opts) { std::vector::iterator p = opts->begin(); while(p != opts->end()) { if (p->size() > 0 && (*p)[0] != '-') { /* hack1: options ending with .ecs as "-s:file.ecs" */ string::size_type pos = p->find(".ecs"); if (pos + 4 == p->size()) { ECA_LOG_MSG(ECA_LOGGER::info, "NOTE: Interpreting option " + *p + " as -s:" + *p + "."); *p = "-s:" + *p; } } ++p; } } /** * Interprets all session specific options from 'inopts'. * All unprocessed options are copied to 'outopts'. * * @return number of parsing errors */ int ECA_SESSION::interpret_general_options(const std::vector& inopts, std::vector* outopts) { int errors = 0; std::vector::const_iterator p = inopts.begin(); while(p != inopts.end()) { if (p->size() > 0 && (*p)[0] == '-') errors += interpret_general_option(*p); ++p; } p = inopts.begin(); while(p != inopts.end()) { if (p->size() > 0 && (*p)[0] == '-') errors += interpret_chainsetup_option(*p); if (is_session_option(*p) != true) outopts->push_back(*p); ++p; } return errors; } /** * Parses session option 'argu'. * * See also is_session_parameter() * * @return number of parsing errors */ int ECA_SESSION::interpret_general_option (const std::string& argu) { if (argu.size() < 2) return 0; if (argu[0] != '-') return 0; switch(argu[1]) { case 'd': { if (argu.size() > 2 && argu[2] == ':') { /* argu == "-d:XXX" */ ECA_LOGGER::instance().set_log_level_bitmask(atoi(kvu_get_argument_number(1, argu).c_str())); } else { /* argu == "-dXXX" */ ECA_LOGGER::instance().set_log_level_bitmask(0); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::errors, 1); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::info, 1); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::subsystems, 1); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::module_names, 1); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::user_objects, 1); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::eiam_return_values, 1); if (argu.size() > 2 && argu[2] == 'd') { /* argu == "-dd" */ ECA_LOGGER::instance().set_log_level(ECA_LOGGER::system_objects, 1); if (argu.size() > 3 && argu[3] == 'd') { /* argu == "-ddd" */ ECA_LOGGER::instance().set_log_level(ECA_LOGGER::functions, 1); ECA_LOGGER::instance().set_log_level(ECA_LOGGER::continuous, 1); } } } MESSAGE_ITEM mtempd; mtempd << "Set debug level to: " << ECA_LOGGER::instance().get_log_level_bitmask(); ECA_LOG_MSG(ECA_LOGGER::info, mtempd.to_string()); break; } case 'R': { string tname = kvu_get_argument_number(1, argu); /* note: options are normalized, so ':' is always present * if there are any argument to an option */ if (argu.size() > 2 && argu[2] == ':') { ECA_RESOURCES::rc_override_file = tname; cs_defaults_set_rep = false; ECA_LOG_MSG(ECA_LOGGER::info, "Using resource file \"" + tname + "\". Disabling use of global/user resource files."); } } break; case 'q': ECA_LOGGER::instance().disable(); break; default: { } } return 0; } /** * Parses session chainsetup option 'argu'. * * @return number of parsing errors */ int ECA_SESSION::interpret_chainsetup_option (const std::string& argu) { int errors = 0; if (argu.size() == 0) return errors; string tname = kvu_get_argument_number(1, argu); if (argu.size() < 2) return errors; switch(argu[1]) { case 's': { if (argu.size() > 2 && argu[2] == ':') { load_chainsetup(tname); if (selected_chainsetup_repp == 0 || selected_chainsetup_repp->is_valid_for_connection(true) != true) { ECA_LOG_MSG(ECA_LOGGER::info, "Chainsetup loaded from \"" + tname + "\" is not valid!"); ++errors; } } break; } default: { } } return errors; } ecasound-2.9.1/libecasound/eca-control.cpp0000644000076400007640000014506511762446716015510 00000000000000// ------------------------------------------------------------------------ // eca-control.cpp: Class for controlling the whole ecasound library // Copyright (C) 1999-2005,2008,2009,2012 Kai Vehmanen // Copyright (C) 2005 Stuart Allie // Copyright (C) 2009 Adam Linson // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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, see . // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_LOCALE_H #include #endif #include /* string_to_vector(), string_to_int_vector() */ #include #include #include #include #include "audioio.h" #include "eca-chain.h" #include "eca-chainop.h" #include "eca-chainsetup.h" #include "eca-control.h" #include "eca-control-main.h" #include "eca-engine.h" #include "eca-object-factory.h" #include "eca-object-map.h" #include "eca-preset-map.h" #include "eca-session.h" #include "generic-controller.h" #include "eca-chainop.h" #include "audiofx_ladspa.h" #include "audiofx_lv2.h" #include "preset.h" #include "sample-specs.h" #include "jack-connections.h" #include "eca-version.h" #include "eca-error.h" #include "eca-logger.h" #include "eca-logger-wellformed.h" /** * Import namespaces */ using std::string; using std::list; using std::vector; using std::cerr; using std::endl; using namespace ECA; /** * Declarations for private static functions */ static string eca_aio_register_sub(ECA_OBJECT_MAP& objmap); /** * Definitions for member functions */ ECA_CONTROL::ECA_CONTROL (ECA_SESSION* psession) : ctrl_dump_rep(this), wellformed_mode_rep(false) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "ECA_CONTROL constructor"); session_repp = psession; selected_chainsetup_repp = psession->selected_chainsetup_repp; engine_repp = 0; engine_pid_rep = -1; engine_exited_rep.set(0); float_to_string_precision_rep = 3; joining_rep = false; DBC_CHECK(is_engine_created() != true); selected_audio_object_repp = 0; selected_audio_input_repp = 0; selected_audio_output_repp = 0; } ECA_CONTROL::~ECA_CONTROL(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "ECA_CONTROL destructor"); close_engine(); } void ECA_CONTROL::fill_command_retval(struct eci_return_value *retval) const { if (retval == 0) return; *retval = last_retval_rep; } void ECA_CONTROL::command(const string& cmd_and_args, struct eci_return_value *retval) { clear_last_values(); clear_action_arguments(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "processing cmd and arg: " + cmd_and_args); vector tokens = kvu_string_to_tokens_quoted(cmd_and_args); vector::iterator cmd = tokens.begin(); if (cmd != tokens.end()) { const std::map& cmdmap = ECA_IAMODE_PARSER::registered_commands(); if (cmdmap.find(*cmd) == cmdmap.end()) { // --- // *p is not recognized as a iamode command // --- if (cmd->size() > 0 && (*cmd)[0] == '-') { // std::cerr << "Note! Direct use of EOS-options (-prefix:arg1,...,argN)" << " as iactive-mode commands is considered deprecated. " << "\tUse the notation 'cs-option -prefix:a,b,x' instead." << std::endl; if (*cmd == "-i") ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: syntax variant '-i file.ext' not supported, please use 'ai-add file.ext' instead."); else if (*cmd == "-o") ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: syntax variant '-o file.ext' not supported, please use 'ai-add file.ext' instead."); else { ECA_LOG_MSG(ECA_LOGGER::user_objects, "passiong to cs-option: " + cmd_and_args); chainsetup_option(cmd_and_args); } } else { set_last_error("Unknown command!"); } } else { int action_id = ECA_IAMODE_PARSER::command_to_action_id(*cmd); if (action_id == ec_help) { show_controller_help(); } else { vector::iterator args = cmd + 1; if (args != tokens.end()) { set_action_argument(vector (args, tokens.end())); } action(action_id); } } } fill_command_retval(retval); } void ECA_CONTROL::set_action_argument(const string& s) { action_args_rep.resize(0); action_args_rep.push_back(s); action_arg_f_set_rep = false; } void ECA_CONTROL::set_action_argument(const std::vector& s) { action_args_rep = s; action_arg_f_set_rep = false; } void ECA_CONTROL::set_action_argument(double v) { action_arg_f_rep = v; action_arg_f_set_rep = true; } void ECA_CONTROL::clear_action_arguments(void) { // use resize() instead of clear(); clear() was a late // addition to C++ standard and not supported by all // compilers (for example egcs-2.91.66) action_args_rep.resize(0); action_arg_f_rep = 0.0f; action_arg_f_set_rep = false; } double ECA_CONTROL::first_action_argument_as_float(void) const { if (action_arg_f_set_rep == true) return action_arg_f_rep; if (action_args_rep.size() == 0) return 0.0f; return atof(action_args_rep[0].c_str()); } string ECA_CONTROL::first_action_argument_as_string(void) const { if (action_args_rep.size() == 0) return std::string(); return action_args_rep[0]; } const vector& ECA_CONTROL::action_arguments_as_vector(void) const { return action_args_rep; } int ECA_CONTROL::first_action_argument_as_int(void) const { if (action_args_rep.size() == 0) return 0; return atoi(action_args_rep[0].c_str()); } long int ECA_CONTROL::first_action_argument_as_long_int(void) const { if (action_args_rep.size() == 0) return 0; return atol(action_args_rep[0].c_str()); } SAMPLE_SPECS::sample_pos_t ECA_CONTROL::first_action_argument_as_samples(void) const { if (action_args_rep.size() == 0) return 0; #ifdef HAVE_ATOLL return atoll(action_args_rep[0].c_str()); #else return atol(action_args_rep[0].c_str()); #endif } void ECA_CONTROL::command_float_arg(const string& cmd, double arg, struct eci_return_value *retval) { clear_action_arguments(); set_action_argument(arg); int action_id = ec_unknown; action_id = ECA_IAMODE_PARSER::command_to_action_id(cmd); action(action_id); fill_command_retval(retval); } /** * Interprets an EOS (ecasound optiont syntax) token (prefixed with '-'). */ void ECA_CONTROL::chainsetup_option(const string& cmd) { string prefix = kvu_get_argument_prefix(cmd); if (prefix == "el" || prefix == "pn") { // --- LADSPA plugins and presets if (selected_chains().size() == 1) add_chain_operator(cmd); else set_last_error("When adding chain operators, only one chain can be selected."); } else if (ECA_OBJECT_FACTORY::chain_operator_map().object(prefix) != 0) { if (selected_chains().size() == 1) add_chain_operator(cmd); else set_last_error("When adding chain operators, only one chain can be selected."); } else if (ECA_OBJECT_FACTORY::controller_map().object(prefix) != 0) { if (selected_chains().size() == 1) add_controller(cmd); else set_last_error("When adding controllers, only one chain can be selected."); } else { set_action_argument(cmd); action(ec_cs_option); } } /** * Checks action preconditions. * * @return Sets status of private data members 'action_ok', * 'action_restart', and 'action_reconnect'. */ void ECA_CONTROL::check_action_preconditions(int action_id) { action_ok = true; action_reconnect = false; action_restart = false; /* case 1: action requiring arguments, but not arguments available */ if (action_arg_f_set_rep == false && first_action_argument_as_string().size() == 0 && action_requires_params(action_id)) { set_last_error("Can't perform requested action; argument omitted."); action_ok = false; } /* case 2: action requires an audio input, but no input available */ else if (is_selected() == true && get_audio_input() == 0 && action_requires_selected_audio_input(action_id)) { set_last_error("Can't perform requested action; no audio input selected."); action_ok = false; } /* case 3: action requires an audio output, but no output available */ else if (is_selected() == true && get_audio_output() == 0 && action_requires_selected_audio_output(action_id)) { set_last_error("Can't perform requested action; no audio output selected."); action_ok = false; } /* case 4: action requires a select chainsetup, but none selected */ else if (is_selected() == false && action_requires_selected(action_id)) { if (!is_connected()) { set_last_error("Can't perform requested action; no chainsetup selected."); action_ok = false; } else { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: No chainsetup selected. Connected chainsetup will be selected."); select_chainsetup(connected_chainsetup()); } } /* case 5: action requires a connected chainsetup, but none connected */ else if (is_connected() == false && action_requires_connected(action_id)) { if (!is_selected()) { set_last_error("Can't perform requested action; no chainsetup connected."); action_ok = false; } else { if (is_valid() == true) { ECA_LOG_MSG(ECA_LOGGER::info, "NOTE: No chainsetup connected. Trying to connect currently selected chainsetup \"" + selected_chainsetup_repp->name() + "\""); connect_chainsetup(0); } if (is_connected() != true) { /* connect_chainsetup() sets last_error() so we just add to it */ set_last_error(last_error() + " Selected chainsetup cannot be connected. Can't perform requested action. "); action_ok = false; } } } /* case 6: action can't be performed on a connected setup, * but selected chainsetup is also connected */ else if (selected_chainsetup() == connected_chainsetup() && action_requires_selected_not_connected(action_id)) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: This operation requires that chainsetup is disconnected. Temporarily disconnecting..."); if (is_running()) action_restart = true; disconnect_chainsetup(); action_reconnect = true; } } void ECA_CONTROL::action(int action_id, const vector& args) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: ECA_CONTROL::action() method is obsolete.\n"); clear_action_arguments(); set_action_argument(kvu_vector_to_string(args, " ")); action(action_id); } bool ECA_CONTROL::action_helper_check_cop_op_args(int copid, int coppid) { DBC_REQUIRE(is_selected() == true); const vector& selchains = selected_chainsetup_repp->selected_chains(); bool res = false; if (selchains.size() == 0) { set_last_error("No chain selected, unable to identify chainop"); } else if (selchains.size() > 1) { set_last_error("More than one chain selected, unable to identify chainop"); } else { const CHAIN* selch = selected_chainsetup_repp->get_chain_with_name(selchains[0]); if (copid < 1 || copid > selch->number_of_chain_operators()) { set_last_error("Invalid chainop-id, unable to identify chainop"); } else if (coppid < 1) { set_last_error("Invalid copp-id, indexing starts from 1."); } else { res = true; } } return res; } void ECA_CONTROL::action(int action_id) { clear_last_values(); check_action_preconditions(action_id); if (action_ok != true) return; switch(action_id) { case ec_unknown: { set_last_error("Unknown command!"); break; } // --- // General // --- case ec_exit: { quit(); break; } case ec_start: { if (is_running() != true) { int result = start(); if (result < 0) { set_last_error("Error, unable to start processing"); } } // ECA_LOG_MSG(ECA_LOGGER::info, "Can't perform requested action; no chainsetup connected."); break; } case ec_stop: { if (is_engine_created()) stop(); break; } case ec_stop_sync: { if (is_engine_created()) stop_on_condition(); break; } case ec_run: { int result = run(); if (result < 0) { set_last_error("Errors during processing"); } break; } case ec_debug: { int level = first_action_argument_as_int(); ECA_LOGGER::instance().set_log_level_bitmask(level); set_last_string("Debug level set to " + kvu_numtostr(level) + "."); break; } case ec_resource_file: { session_repp->interpret_general_option(string("-R:") + first_action_argument_as_string()); break; } // --- // Chainsetups // --- case ec_cs_add: { add_chainsetup(first_action_argument_as_string()); break; } case ec_cs_remove: { remove_chainsetup(); break; } case ec_cs_list: { set_last_string_list(chainsetup_names()); break; } case ec_cs_select: { select_chainsetup(first_action_argument_as_string()); break; } case ec_cs_selected: { set_last_string(selected_chainsetup()); break; } case ec_cs_index_select: { if (first_action_argument_as_string().size() > 0) { select_chainsetup_by_index(first_action_argument_as_int()); } break; } case ec_cs_edit: { edit_chainsetup(); break; } case ec_cs_load: { load_chainsetup(first_action_argument_as_string()); break; } case ec_cs_save: { save_chainsetup(""); break; } case ec_cs_save_as: { save_chainsetup(first_action_argument_as_string()); break; } case ec_cs_is_valid: { if (is_valid() == true) set_last_integer(1); else set_last_integer(0); break; } case ec_cs_connect: { if (is_valid() != false) { connect_chainsetup(0); } else { set_last_error("Can't connect; chainsetup not valid!"); } break; } case ec_cs_connected: { set_last_string(connected_chainsetup()); break; } case ec_cs_disconnect: { disconnect_chainsetup(); break; } case ec_cs_set_param: { set_chainsetup_parameter(first_action_argument_as_string()); break; } case ec_cs_set_audio_format: { set_chainsetup_sample_format(first_action_argument_as_string()); break; } case ec_cs_status: { set_last_string(chainsetup_status()); break; } case ec_cs_rewind: { change_chainsetup_position(-first_action_argument_as_float()); break; } case ec_cs_forward: { change_chainsetup_position(first_action_argument_as_float()); break; } case ec_cs_set_position: { set_chainsetup_position(first_action_argument_as_float()); break; } case ec_cs_set_position_samples: { set_chainsetup_position_samples(first_action_argument_as_samples()); break; } case ec_cs_get_position: { set_last_float(position_in_seconds_exact()); break; } case ec_cs_get_position_samples: { set_last_long_integer(selected_chainsetup_repp->position_in_samples()); break; } case ec_cs_get_length: { set_last_float(length_in_seconds_exact()); break; } case ec_cs_get_length_samples: { set_last_long_integer(length_in_samples()); break; } case ec_cs_set_length: { set_chainsetup_processing_length_in_seconds(first_action_argument_as_float()); break; } case ec_cs_set_length_samples: { set_chainsetup_processing_length_in_samples(first_action_argument_as_samples()); break; } case ec_cs_toggle_loop: { toggle_chainsetup_looping(); break; } case ec_cs_option: { selected_chainsetup_repp->interpret_options(action_arguments_as_vector()); if (selected_chainsetup_repp->interpret_result() != true) { set_last_error(selected_chainsetup_repp->interpret_result_verbose()); } break; } // --- // Chains // --- case ec_c_add: { add_chains(kvu_string_to_vector(first_action_argument_as_string(), ',')); break; } case ec_c_remove: { remove_chains(); break; } case ec_c_list: { set_last_string_list(chain_names()); break; } case ec_c_select: { select_chains(kvu_string_to_vector(first_action_argument_as_string(), ',')); break; } case ec_c_selected: { set_last_string_list(selected_chains()); break; } case ec_c_index_select: { select_chains_by_index(kvu_string_to_int_vector(first_action_argument_as_string(), ',')); break; } case ec_c_deselect: { deselect_chains(kvu_string_to_vector(first_action_argument_as_string(), ',')); break; } case ec_c_select_add: { select_chains(kvu_string_to_vector(first_action_argument_as_string() + "," + kvu_vector_to_string(selected_chains(), ","), ',')); break; } case ec_c_select_all: { select_all_chains(); break; } case ec_c_clear: { clear_chains(); break; } case ec_c_rename: { if (selected_chains().size() != 1) { set_last_error("When renaming chains, only one chain canbe selected."); } else { rename_chain(first_action_argument_as_string()); } break; } case ec_c_muting: { set_chain_muting(first_action_argument_as_string()); break; } case ec_c_bypass: { set_chain_bypass(first_action_argument_as_string()); break; } case ec_c_status: { set_last_string(chain_status()); break; } case ec_c_is_bypassed: { set_last_integer(chain_is_bypassed()); break; } case ec_c_is_muted: { set_last_integer(chain_is_muted()); break; } // --- // Actions common to audio inputs and outputs // --- case ec_aio_status: case ec_ai_status: case ec_ao_status: { set_last_string(aio_status()); break; } case ec_aio_register: { aio_register(); break; } // --- // Audio input objects // --- case ec_ai_add: { add_audio_input(first_action_argument_as_string()); break; } case ec_ai_describe: { set_last_string(ECA_OBJECT_FACTORY::audio_object_to_eos(selected_audio_input_repp, "i")); break; } case ec_ai_remove: { remove_audio_input(); break; } case ec_ai_list: { set_last_string_list(audio_input_names()); break; } case ec_ai_select: { select_audio_input(first_action_argument_as_string()); break; } case ec_ai_selected: { set_last_string(get_audio_input()->label()); break; } case ec_ai_index_select: { if (first_action_argument_as_string().size() > 0) { select_audio_input_by_index(first_action_argument_as_int()); } break; } case ec_ai_attach: { attach_audio_input(); break; } case ec_ai_forward: { audio_input_as_selected(); forward_audio_object(first_action_argument_as_float()); break; } case ec_ai_rewind: { audio_input_as_selected(); rewind_audio_object(first_action_argument_as_float()); break; } case ec_ai_set_position: { audio_input_as_selected(); set_audio_object_position(first_action_argument_as_float()); break; } case ec_ai_set_position_samples: { audio_input_as_selected(); set_audio_object_position_samples(first_action_argument_as_long_int()); break; } case ec_ai_get_position: { set_last_float(get_audio_input()->position().seconds()); break; } case ec_ai_get_position_samples: { set_last_long_integer(get_audio_input()->position().samples()); break; } case ec_ai_get_length: { set_last_float(get_audio_input()->length().seconds()); break; } case ec_ai_get_length_samples: { set_last_long_integer(get_audio_input()->length().samples()); break; } case ec_ai_get_format: { set_last_string(get_audio_input()->format_string() + "," + kvu_numtostr(get_audio_input()->channels()) + "," + kvu_numtostr(get_audio_input()->samples_per_second())); break; } case ec_ai_wave_edit: { audio_input_as_selected(); wave_edit_audio_object(); break; } // --- // Audio output objects // --- case ec_ao_add: { if (first_action_argument_as_string().size() == 0) add_default_output(); else add_audio_output(first_action_argument_as_string()); break; } case ec_ao_add_default: { add_default_output(); break; } case ec_ao_describe: { set_last_string(ECA_OBJECT_FACTORY::audio_object_to_eos(selected_audio_output_repp, "o")); break; } case ec_ao_remove: { remove_audio_output(); break; } case ec_ao_list: { set_last_string_list(audio_output_names()); break; } case ec_ao_select: { select_audio_output(first_action_argument_as_string()); break; } case ec_ao_selected: { set_last_string(get_audio_output()->label()); break; } case ec_ao_index_select: { select_audio_output_by_index(first_action_argument_as_int()); break; } case ec_ao_attach: { attach_audio_output(); break; } case ec_ao_forward: { audio_output_as_selected(); forward_audio_object(first_action_argument_as_float()); break; } case ec_ao_rewind: { audio_output_as_selected(); rewind_audio_object(first_action_argument_as_float()); break; } case ec_ao_set_position: { audio_output_as_selected(); set_audio_object_position(first_action_argument_as_float()); break; } case ec_ao_set_position_samples: { audio_output_as_selected(); set_audio_object_position_samples(first_action_argument_as_long_int()); break; } case ec_ao_get_position: { set_last_float(get_audio_output()->position().seconds()); break; } case ec_ao_get_position_samples: { set_last_long_integer(get_audio_output()->position().samples()); break; } case ec_ao_get_length: { set_last_float(get_audio_output()->length().seconds()); break; } case ec_ao_get_length_samples: { set_last_long_integer(get_audio_output()->length().samples()); break; } case ec_ao_get_format: { set_last_string(get_audio_output()->format_string() + "," + kvu_numtostr(get_audio_output()->channels()) + "," + kvu_numtostr(get_audio_output()->samples_per_second())); break; } case ec_ao_wave_edit: { audio_output_as_selected(); wave_edit_audio_object(); break; } // --- // Chain operators // --- case ec_cop_add: { add_chain_operator(first_action_argument_as_string()); break; } case ec_cop_bypass: { bypass_chain_operator(first_action_argument_as_string()); break; } case ec_cop_describe: { const CHAIN_OPERATOR *t = get_chain_operator(); set_last_string(t == 0 ? "" : ECA_OBJECT_FACTORY::chain_operator_to_eos(t)); break; } case ec_cop_remove: { remove_chain_operator(); break; } case ec_cop_list: { set_last_string_list(chain_operator_names()); break; } case ec_cop_is_bypassed: { set_last_integer(chain_operator_is_bypassed()); break; } case ec_cop_select: { select_chain_operator(first_action_argument_as_int()); break; } case ec_cop_selected: { set_last_integer(selected_chain_operator()); break; } case ec_cop_set: { vector a = kvu_string_to_vector(first_action_argument_as_string(), ','); if (a.size() < 3) { set_last_error("Not enough parameters!"); break; } int id1 = atoi(a[0].c_str()); int id2 = atoi(a[1].c_str()); CHAIN_OPERATOR::parameter_t v = atof(a[2].c_str()); bool valid = action_helper_check_cop_op_args(id1, id2); if (valid == true) { select_chain_operator(id1); select_chain_operator_parameter(id2); set_chain_operator_parameter(v); } // note: helper func sets the error string if needed break; } case ec_cop_get: { vector a = kvu_string_to_vector(first_action_argument_as_string(), ','); if (a.size() < 2) { set_last_error("Not enough parameters!"); break; } int id1 = atoi(a[0].c_str()); int id2 = atoi(a[1].c_str()); bool valid = action_helper_check_cop_op_args(id1, id2); if (valid == true) { select_chain_operator(id1); select_chain_operator_parameter(id2); set_last_float(get_chain_operator_parameter()); } // note: helper func sets the error string if needed break; } case ec_cop_status: { set_last_string(chain_operator_status()); break; } // --- // Chain operator parameters // --- case ec_copp_list: { set_last_string_list(chain_operator_parameter_names()); break; } case ec_copp_select: { select_chain_operator_parameter(first_action_argument_as_int()); break; } case ec_copp_selected: { set_last_integer(selected_chain_operator_parameter()); break; } case ec_copp_set: { set_chain_operator_parameter(first_action_argument_as_float()); break; } case ec_copp_get: { set_last_float(get_chain_operator_parameter()); break; } // --- // Controllers // --- case ec_ctrl_add: { add_controller(first_action_argument_as_string()); break; } case ec_ctrl_describe: { const GENERIC_CONTROLLER *t = get_controller(); set_last_string(t == 0 ? "" : ECA_OBJECT_FACTORY::controller_to_eos(t)); break; } case ec_ctrl_remove: { remove_controller(); break; } case ec_ctrl_list: { set_last_string_list(controller_names()); break; } case ec_ctrl_select: { select_controller(first_action_argument_as_int()); break; } case ec_ctrl_selected: { set_last_integer(selected_controller()); break; } case ec_ctrl_status: { set_last_string(controller_status()); break; } case ec_ctrl_get_target: { set_last_integer(selected_controller_target()); break; } // --- // Controller parameters // --- case ec_ctrlp_list: { set_last_string_list(controller_parameter_names()); break; } case ec_ctrlp_select: { select_controller_parameter(first_action_argument_as_int()); break; } case ec_ctrlp_selected: { set_last_integer(selected_controller_parameter()); break; } case ec_ctrlp_get: { set_last_float(get_controller_parameter()); break; } case ec_ctrlp_set: { set_controller_parameter(first_action_argument_as_float()); break; } case ec_cop_register: { cop_register(); break; } case ec_preset_register: { preset_register(); break; } case ec_ladspa_register: { ladspa_register(); break; } case ec_lv2_register: { lv2_register(); break; } case ec_ctrl_register: { ctrl_register(); break; } case ec_map_cop_list: { cop_descriptions(); break; } case ec_map_preset_list: { preset_descriptions(); break; } case ec_map_ladspa_list: { ladspa_descriptions(false); break; } case ec_map_ladspa_id_list: { ladspa_descriptions(true); break; } case ec_map_lv2_list: { lv2_descriptions(); break; } case ec_map_ctrl_list: { ctrl_descriptions(); break; } // --- // Engine commands // --- case ec_engine_launch: { if (is_engine_ready_for_commands() != true) engine_start(); else set_last_error("Engine already running, use 'engine-halt' first."); break; } case ec_engine_halt: { if (is_engine_ready_for_commands() == true) close_engine(); else set_last_error("Engine not running, use 'engine-launch' first."); break; } case ec_engine_status: { set_last_string(engine_status()); break; } // --- // Internal commands // --- case ec_int_cmd_list: { set_last_string_list(registered_commands_list()); break; } case ec_int_log_history: { set_last_string(ECA_LOGGER::instance().log_history()); break; } case ec_int_output_mode_wellformed: { ECA_LOGGER::attach_logger(new ECA_LOGGER_WELLFORMED()); wellformed_mode_rep = true; break; } case ec_int_set_float_to_string_precision: { set_float_to_string_precision(first_action_argument_as_int()); break; } case ec_int_set_log_history_length: { ECA_LOGGER::instance().set_log_history_length(first_action_argument_as_int()); break; } case ec_int_version_string: { set_last_string(ecasound_library_version); break; } case ec_int_version_lib_current: { set_last_integer(ecasound_library_version_current); break; } case ec_int_version_lib_revision: { set_last_integer(ecasound_library_version_revision); break; } case ec_int_version_lib_age: { set_last_integer(ecasound_library_version_age); break; } // --- // Dump commands // --- case ec_dump_target: { ctrl_dump_rep.set_dump_target(first_action_argument_as_string()); break; } case ec_dump_status: { ctrl_dump_rep.dump_status(); break; } case ec_dump_position: { ctrl_dump_rep.dump_position(); break; } case ec_dump_length: { ctrl_dump_rep.dump_length(); break; } case ec_dump_cs_status: { ctrl_dump_rep.dump_chainsetup_status(); break; } case ec_dump_c_selected: { ctrl_dump_rep.dump_selected_chain(); break; } case ec_dump_ai_selected: { ctrl_dump_rep.dump_selected_audio_input(); break; } case ec_dump_ai_position: { ctrl_dump_rep.dump_audio_input_position(); break; } case ec_dump_ai_length: { ctrl_dump_rep.dump_audio_input_length(); break; } case ec_dump_ai_open_state: { ctrl_dump_rep.dump_audio_input_open_state(); break; } case ec_dump_ao_selected: { ctrl_dump_rep.dump_selected_audio_output(); break; } case ec_dump_ao_position: { ctrl_dump_rep.dump_audio_output_position(); break; } case ec_dump_ao_length: { ctrl_dump_rep.dump_audio_output_length(); break; } case ec_dump_ao_open_state: { ctrl_dump_rep.dump_audio_output_open_state(); break; } case ec_dump_cop_value: { vector temp = kvu_string_to_vector(first_action_argument_as_string(), ','); if (temp.size() > 1) { ctrl_dump_rep.dump_chain_operator_value(atoi(temp[0].c_str()), atoi(temp[1].c_str())); } break; } // --- // Commands with external dependencies // --- #if ECA_COMPILE_JACK case ec_jack_connect: { const vector& params = action_arguments_as_vector(); if (params.size() >= 2) JACK_CONNECTIONS::connect(params[0].c_str(), params[1].c_str()); break; } case ec_jack_disconnect: { const vector& params = action_arguments_as_vector(); if (params.size() >= 2) JACK_CONNECTIONS::disconnect(params[0].c_str(), params[1].c_str()); break; } case ec_jack_list_connections: { string foo; if (JACK_CONNECTIONS::list_connections(&foo) == true) set_last_string(foo); else set_last_error("Unable to a list of JACK connections."); break; } #endif } // <-- switch-case if (action_reconnect == true) { if (is_selected() == false || is_valid() == false) { set_last_error("Can't reconnect chainsetup."); } else { connect_chainsetup(0); if (selected_chainsetup() != connected_chainsetup()) { set_last_error("Can't reconnect chainsetup."); } else { if (action_restart == true) { DBC_CHECK(is_running() != true); start(); } } } } } /** * Executes chainsetup edit on connect chainsetup. * * @pre is_connected() */ bool ECA_CONTROL::execute_edit_on_connected(const chainsetup_edit_t& edit) { DBC_REQUIRE(is_connected() == true); bool retval = false; if (is_engine_ready_for_commands() == true) { ECA_ENGINE::complex_command_t engine_cmd; engine_cmd.type = ECA_ENGINE::ep_exec_edit; engine_cmd.cs = edit; engine_repp->command(engine_cmd); retval = true; } else { /* note: engine not yet running, execute edit directly */ retval = session_repp->connected_chainsetup_repp->execute_edit(edit); } return retval; } /** * Executes chainsetup edit on selected chainsetup. * * @param edit object specifying the edit action * @param index if non-negative, override the chainsetup selection */ bool ECA_CONTROL::execute_edit_on_selected(const chainsetup_edit_t& edit, int index) { bool retval = false; ECA_CHAINSETUP *csetup = 0; if (index < 0) { csetup = selected_chainsetup_repp; } else { if (index >= 0 && index < static_cast(session_repp->chainsetups_rep.size())) { csetup = session_repp->chainsetups_rep[index]; } } /* note: make sure that if the selected chainsetup is * in use by the engine, the edit is performed * by the engine thread! */ if (csetup != 0) { if (csetup->is_enabled() == true && is_engine_ready_for_commands() == true) { execute_edit_on_connected(edit); } else { csetup->execute_edit(edit); } } return retval; } void ECA_CONTROL::print_last_value(struct eci_return_value *retval) const { std::string result; if (retval->type == eci_return_value::retval_error) { result += "ERROR: "; } result += ECA_CONTROL_MAIN::return_value_to_string(retval); if (wellformed_mode_rep != true) { if (result.size() > 0) ECA_LOG_MSG(ECA_LOGGER::eiam_return_values, result); } else { /* in wellformed-output-mode we always create return output */ ECA_LOG_MSG(ECA_LOGGER::eiam_return_values, std::string(return_value_type_to_string(retval)) + " " + result); } } string ECA_CONTROL::chainsetup_details_to_string(const ECA_CHAINSETUP* cs) const { string result; vector::const_iterator chain_citer; result += "\n -> Objects..: " + kvu_numtostr(cs->inputs.size()); result += " inputs, " + kvu_numtostr(cs->outputs.size()); result += " outputs, " + kvu_numtostr(cs->chains.size()); result += " chains"; // FIXME: add explanations on why the chainsetup cannot be // connected result += "\n -> State....: "; if (cs->is_locked()) { result += "connected to engine (engine status: "; result += engine_status() + ")"; } else if (cs->is_enabled() && is_engine_created() == true) { result += "connected (engine status: "; result += engine_status() + ")"; } else if (cs->is_enabled()) result += "connected (engine not yet running)"; else if (cs->is_valid()) result += "valid (can be connected)"; else result += "not valid (cannot be connected)"; result += "\n -> Position.: "; result += kvu_numtostr(cs->position_in_seconds_exact(), 3); result += " / "; if (cs->length_set()) result += kvu_numtostr(cs->length_in_seconds_exact(), 3); else result += "inf"; result += "\n -> Options..: "; result += cs->options_to_string(); for(chain_citer = cs->chains.begin(); chain_citer != cs->chains.end();) { result += "\n -> Chain \"" + (*chain_citer)->name() + "\": "; int idx = (*chain_citer)->connected_input(); if (idx >= 0) result += ECA_OBJECT_FACTORY::audio_object_to_eos(cs->inputs[idx], "i"); result += " "; result += (*chain_citer)->to_string(); idx = (*chain_citer)->connected_output(); if (idx >= 0) result += ECA_OBJECT_FACTORY::audio_object_to_eos(cs->outputs[idx], "o"); ++chain_citer; } return result; } string ECA_CONTROL::chainsetup_status(void) const { vector::const_iterator cs_citer = session_repp->chainsetups_rep.begin(); int index = 0; string result ("### Chainsetup status ###\n"); while(cs_citer != session_repp->chainsetups_rep.end()) { result += "Chainsetup (" + kvu_numtostr(++index) + ") \""; result += (*cs_citer)->name() + "\" "; if (*cs_citer == selected_chainsetup_repp) result += "[selected] "; if (*cs_citer == session_repp->connected_chainsetup_repp) result += "[connected] "; if ((*cs_citer == selected_chainsetup_repp) || (*cs_citer == session_repp->connected_chainsetup_repp)) result += chainsetup_details_to_string((*cs_citer)); else result += ": "; ++cs_citer; if (cs_citer != session_repp->chainsetups_rep.end()) result += "\n"; } return result; } string ECA_CONTROL::chain_status(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- MESSAGE_ITEM mitem; vector::const_iterator chain_citer; const vector& schains = selected_chainsetup_repp->selected_chains(); mitem << "### Chain status (chainsetup '" << selected_chainsetup() << "') ###\n"; for(chain_citer = selected_chainsetup_repp->chains.begin(); chain_citer != selected_chainsetup_repp->chains.end();) { mitem << "Chain \"" << (*chain_citer)->name() << "\" "; if ((*chain_citer)->is_muted()) mitem << "[muted] "; if ((*chain_citer)->is_bypassed()) mitem << "[bypassed] "; if (find(schains.begin(), schains.end(), (*chain_citer)->name()) != schains.end()) mitem << "[selected] "; for(int n = 0; n < (*chain_citer)->number_of_chain_operators(); n++) { mitem << "\"" << (*chain_citer)->get_chain_operator(n)->name() << "\""; if (n == (*chain_citer)->number_of_chain_operators()) mitem << " -> "; } ++chain_citer; if (chain_citer != selected_chainsetup_repp->chains.end()) mitem << "\n"; } return mitem.to_string(); } string ECA_CONTROL::chain_operator_status(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- MESSAGE_ITEM msg; string st_info_string; vector::const_iterator chain_citer = selected_chainsetup_repp->chains.begin(); msg << "### Chain operator status (chainsetup '" << selected_chainsetup() << "') ###\n"; while(chain_citer != selected_chainsetup_repp->chains.end()) { msg << "Chain \"" << (*chain_citer)->name() << "\":\n"; for(int p = 0; p < (*chain_citer)->number_of_chain_operators(); p++) { const CHAIN_OPERATOR* cop = (*chain_citer)->get_chain_operator(p); msg << "\t"; msg << p + 1 << ". "; msg << cop->name(); if ((*chain_citer)->is_operator_bypassed(p + 1)) msg << " (BYPASSED)"; for(int n = 0; n < cop->number_of_params(); n++) { if (n == 0) msg << ": "; msg << "[" << n + 1 << "] "; msg << cop->get_parameter_name(n + 1); msg << " "; msg << float_to_string(cop->get_parameter(n + 1)); if (n + 1 < cop->number_of_params()) msg << ", "; } st_info_string = cop->status(); if (st_info_string.empty() == false) { msg << "\n\tStatus info:\n" << st_info_string; } if (p + 1 < (*chain_citer)->number_of_chain_operators()) msg << "\n"; } ++chain_citer; if (chain_citer != selected_chainsetup_repp->chains.end()) msg << "\n"; } return msg.to_string(); } string ECA_CONTROL::controller_status(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- MESSAGE_ITEM mitem; string st_info_string; vector::const_iterator chain_citer; mitem << "### Controller status (chainsetup '" << selected_chainsetup() << "') ###\n"; for(chain_citer = selected_chainsetup_repp->chains.begin(); chain_citer != selected_chainsetup_repp->chains.end();) { mitem << "Chain \"" << (*chain_citer)->name() << "\":\n"; for(int p = 0; p < (*chain_citer)->number_of_controllers(); p++) { const GENERIC_CONTROLLER* gtrl = (*chain_citer)->get_controller(p); mitem << "\t" << p + 1 << ". " << gtrl->name() << ": "; for(int n = 0; n < gtrl->number_of_params(); n++) { mitem << "\n\t\t[" << n + 1 << "] "; mitem << gtrl->get_parameter_name(n + 1); mitem << " "; mitem << float_to_string(gtrl->get_parameter(n + 1)); if (n + 1 < gtrl->number_of_params()) mitem << ", "; } st_info_string = gtrl->status(); if (st_info_string.empty() == false) { mitem << "\n\t -- Status info: " << st_info_string; } if (p + 1 < (*chain_citer)->number_of_controllers()) mitem << "\n"; } ++chain_citer; if (chain_citer != selected_chainsetup_repp->chains.end()) mitem << "\n"; } return mitem.to_string(); } string ECA_CONTROL::aio_status(void) const { // -------- DBC_REQUIRE(is_selected() == true); // -------- string st_info_string; vector::size_type adev_sizet = 0; vector::const_iterator adev_citer = selected_chainsetup_repp->inputs.begin(); st_info_string += "### Audio input/output status (chainsetup '" + selected_chainsetup() + "') ###\n"; while(adev_citer != selected_chainsetup_repp->inputs.end()) { st_info_string += "Input (" + kvu_numtostr(adev_sizet + 1) + "): \""; for(int n = 0; n < (*adev_citer)->number_of_params(); n++) { st_info_string += (*adev_citer)->get_parameter(n + 1); if (n + 1 < (*adev_citer)->number_of_params()) st_info_string += ","; } st_info_string += "\" - [" + (*adev_citer)->name() + "]"; if ((*adev_citer) == selected_audio_input_repp) st_info_string += " [selected]"; st_info_string += "\n -> connected to chains \""; vector temp = selected_chainsetup_repp->get_attached_chains_to_input((selected_chainsetup_repp->inputs)[adev_sizet]); vector::const_iterator p = temp.begin(); while (p != temp.end()) { st_info_string += *p; ++p; if (p != temp.end()) st_info_string += ","; } st_info_string += "\": " + (*adev_citer)->status() + "\n"; ++adev_sizet; ++adev_citer; } adev_sizet = 0; adev_citer = selected_chainsetup_repp->outputs.begin(); while(adev_citer != selected_chainsetup_repp->outputs.end()) { st_info_string += "Output (" + kvu_numtostr(adev_sizet + 1) + "): \""; for(int n = 0; n < (*adev_citer)->number_of_params(); n++) { st_info_string += (*adev_citer)->get_parameter(n + 1); if (n + 1 < (*adev_citer)->number_of_params()) st_info_string += ","; } st_info_string += "\" - [" + (*adev_citer)->name() + "]"; if ((*adev_citer) == selected_audio_output_repp) st_info_string += " [selected]"; st_info_string += "\n -> connected to chains \""; vector temp = selected_chainsetup_repp->get_attached_chains_to_output((selected_chainsetup_repp->outputs)[adev_sizet]); vector::const_iterator p = temp.begin(); while (p != temp.end()) { st_info_string += *p; ++p; if (p != temp.end()) st_info_string += ","; } st_info_string += "\": "; st_info_string += (*adev_citer)->status(); ++adev_sizet; ++adev_citer; if (adev_sizet < selected_chainsetup_repp->outputs.size()) st_info_string += "\n"; } return st_info_string; } void ECA_CONTROL::aio_register(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Registered audio object types:\n"); string result (eca_aio_register_sub(ECA_OBJECT_FACTORY::audio_io_nonrt_map())); result += "\n"; result += eca_aio_register_sub(ECA_OBJECT_FACTORY::audio_io_rt_map()); set_last_string(result); } static string eca_aio_register_sub(ECA_OBJECT_MAP& objmap) { string result; const list& objlist = objmap.registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { string temp; const AUDIO_IO* q = dynamic_cast(objmap.object_expr(*p)); DBC_CHECK(q != 0); if (q != 0) { int params = q->number_of_params(); if (params > 0) { temp += ": "; for(int n = 0; n < params; n++) { temp += q->get_parameter_name(n + 1); if (n + 1 < params) temp += ","; } } result += kvu_numtostr(count) + ". " + q->name() + ", regex: " + objmap.keyword_to_expr(*p) + ", params" + temp; result += "\n"; ++count; } // else std::cerr << "Failed obj: " << *p << "." << std::endl; ++p; } return result; } void ECA_CONTROL::cop_register(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Registered chain operators:\n"); string result; const list& objlist = ECA_OBJECT_FACTORY::chain_operator_map().registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { string temp; const CHAIN_OPERATOR* q = dynamic_cast(ECA_OBJECT_FACTORY::chain_operator_map().object(*p)); if (q != 0) { int params = q->number_of_params(); for(int n = 0; n < params; n++) { if (n == 0) temp += ":"; temp += q->get_parameter_name(n + 1); if (n + 1 < params) temp += ","; } result += kvu_numtostr(count) + ". " + q->name() + ", -" + *p + temp; result += "\n"; ++count; } ++p; } set_last_string(result); } void ECA_CONTROL::preset_register(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Registered effect presets:\n"); string result; #ifndef ECA_DISABLE_EFFECTS const list& objlist = ECA_OBJECT_FACTORY::preset_map().registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { string temp; const PRESET* q = dynamic_cast(ECA_OBJECT_FACTORY::preset_map().object(*p)); if (q != 0) { int params = q->number_of_params(); for(int n = 0; n < params; n++) { if (n == 0) temp += ":"; temp += q->get_parameter_name(n + 1); if (n + 1 < params) temp += ","; } result += kvu_numtostr(count) + ". " + q->name() + ", -pn:" + *p + temp; result += "\n"; ++count; } ++p; } #endif set_last_string(result); } void ECA_CONTROL::ladspa_register(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Registered LADSPA plugins:\n"); string result; #ifndef ECA_DISABLE_EFFECTS const list& objlist = ECA_OBJECT_FACTORY::ladspa_plugin_map().registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { const EFFECT_LADSPA* q = dynamic_cast(ECA_OBJECT_FACTORY::ladspa_plugin_map().object(*p)); if (q != 0) { string temp = "\n\t-el:" + q->unique() + ","; int params = q->number_of_params(); for(int n = 0; n < params; n++) { temp += "'" + q->get_parameter_name(n + 1) + "'"; if (n + 1 < params) temp += ","; } result += kvu_numtostr(count) + ". " + q->name() + "" + temp; result += "\n"; ++count; } ++p; } #endif set_last_string(result); } void ECA_CONTROL::lv2_register(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Registered LV2 plugins:\n"); string result; #if !defined(ECA_DISABLE_EFFECTS) && defined(ECA_USE_LIBLILV) const list& objlist = ECA_OBJECT_FACTORY::lv2_plugin_map().registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { const EFFECT_LV2* q = dynamic_cast(ECA_OBJECT_FACTORY::lv2_plugin_map().object(*p)); if (q != 0) { string temp = "\n\t-elv2:" + q->unique() + ","; int params = q->number_of_params(); for(int n = 0; n < params; n++) { temp += "'" + q->get_parameter_name(n + 1) + "'"; if (n + 1 < params) temp += ","; } result += kvu_numtostr(count) + ". " + q->name() + "" + temp; result += "\n"; ++count; } ++p; } #endif set_last_string(result); } void ECA_CONTROL::ctrl_register(void) { ECA_LOG_MSG(ECA_LOGGER::info, "Registered controllers:\n"); string result; const list& objlist = ECA_OBJECT_FACTORY::controller_map().registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { string temp; const GENERIC_CONTROLLER* q = dynamic_cast(ECA_OBJECT_FACTORY::controller_map().object(*p)); if (q != 0) { int params = q->number_of_params(); for(int n = 0; n < params; n++) { if (n == 0) temp += ":"; temp += q->get_parameter_name(n + 1); if (n + 1 < params) temp += ","; } result += kvu_numtostr(count) + ". " + q->name() + ", -" + *p + temp; result += "\n"; ++count; } ++p; } set_last_string(result); } /** * Print description of all chain operators and * their parameters. */ void ECA_CONTROL::operator_descriptions_helper(const ECA_OBJECT_MAP& arg, string* result) { /* switch to "C" locale to avoid strange floating point * presentations that could break the output format * (for example "a,b" insteof of "a.b" */ #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) string old_locale (setlocale(LC_ALL, "C")); #endif const list& objlist = arg.registered_objects(); list::const_iterator p = objlist.begin(); int count = 1; while(p != objlist.end()) { string temp; const OPERATOR* q = dynamic_cast(arg.object(*p)); if (q != 0) { /* FIXME: prefer backslash escaped over '_' to handle commas */ /* 1. keyword */ *result += kvu_string_search_and_replace(*p, ',', '_'); /* 2. name */ *result += "," + kvu_string_search_and_replace(q->name(), ',', '_'); /* 3. description */ *result += "," + kvu_string_search_and_replace(q->description(), ',', '_'); int params = q->number_of_params(); /* 4. number of params */ *result += "," + kvu_numtostr(params); /* 5. description of params (for all params) */ for(int n = 0; n < params; n++) { struct OPERATOR::PARAM_DESCRIPTION pd; q->parameter_description(n + 1, &pd); /* 5.1 name of param */ *result += "," + kvu_string_search_and_replace(q->get_parameter_name(n + 1), ',', '_'); /* 5.2 description */ *result += "," + kvu_string_search_and_replace(pd.description, ',', '_'); /* 5.3 default value */ *result += "," + float_to_string(pd.default_value); /* 5.4 is bounded above (1=yes, 0=no) */ *result += ",above=" + kvu_numtostr(static_cast(pd.bounded_above)); /* 5.5 upper bound */ *result += ",upper=" + float_to_string(pd.upper_bound); /* 5.6 is bounded below (1=yes, 0=no) */ *result += ",below=" + kvu_numtostr(static_cast(pd.bounded_below)); /* 5.7 lower bound */ *result += ",lower=" + float_to_string(pd.lower_bound); /* 5.8. is toggled (1=yes, 0=no) */ *result += "," + kvu_numtostr(static_cast(pd.toggled)); /* 5.9. is integer value (1=yes, 0=no) */ *result += "," + kvu_numtostr(static_cast(pd.integer)); /* 5.10. is logarithmis value (1=yes, 0=no) */ *result += "," + kvu_numtostr(static_cast(pd.logarithmic)); /* 5.11. is output value (1=yes, 0=no) */ *result += ",output=" + kvu_numtostr(static_cast(pd.output)); } *result += "\n"; ++count; } ++p; } /* see above */ #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) setlocale(LC_ALL, old_locale.c_str()); #endif } /** * Print the description of all chain operators and * their parameters. */ void ECA_CONTROL::cop_descriptions(void) { string result; operator_descriptions_helper(ECA_OBJECT_FACTORY::chain_operator_map(), &result); set_last_string(result); } /** * Prints the description of all effect presets and * their parameters. */ void ECA_CONTROL::preset_descriptions(void) { string result; operator_descriptions_helper(ECA_OBJECT_FACTORY::preset_map(), &result); set_last_string(result); } /** * Prints the description of all LADSPA plugins and * their parameters. */ void ECA_CONTROL::ladspa_descriptions(bool use_id) { string result; if (use_id) { operator_descriptions_helper(ECA_OBJECT_FACTORY::ladspa_plugin_id_map(), &result); } else { operator_descriptions_helper(ECA_OBJECT_FACTORY::ladspa_plugin_map(), &result); } set_last_string(result); } /** * Prints the description of all LV2 plugins and * their parameters. */ void ECA_CONTROL::lv2_descriptions() { string result; operator_descriptions_helper(ECA_OBJECT_FACTORY::lv2_plugin_map(), &result); set_last_string(result); } /** * Print the description of all controllers and * their parameters. */ void ECA_CONTROL::ctrl_descriptions(void) { string result; operator_descriptions_helper(ECA_OBJECT_FACTORY::controller_map(), &result); set_last_string(result); } ecasound-2.9.1/libecasound/eca-chainsetup-parser.h0000644000076400007640000000531311541135170017101 00000000000000#ifndef INCLUDED_ECA_CHAINSETUP_PARSER_H #define INCLUDED_ECA_CHAINSETUP_PARSER_H #include #include class ECA_CHAINSETUP; class AUDIO_IO; /** * Functionality for parsing chainsetup * option syntax. * * Notes: Code was originally part of the * ECA_CHAINSETUP class. * * @author Kai Vehmanen */ class ECA_CHAINSETUP_PARSER { public: ECA_CHAINSETUP_PARSER(ECA_CHAINSETUP* csetup); // -- // functions for std::string->state conversions /** * Returns the result of last call to interpret_option(), interpret_global_option() * or interpret_object_option(). * * @result true if options interpreted successfully, otherwise false */ bool interpret_result(void) const { return(interpret_result_rep); } const std::string& interpret_result_verbose(void) const { return(interpret_result_verbose_rep); } void interpret_option(const std::string& arg); void interpret_global_option(const std::string& arg); void interpret_object_option(const std::string& arg); void interpret_options(const std::vector& opts); void reset_interpret_status(void); void preprocess_options(std::vector& opts) const; // -- // functions for state->string conversions std::string inputs_to_string(void) const; std::string outputs_to_string(void) const; std::string chains_to_string(void) const; std::string midi_to_string(void) const; std::string general_options_to_string(void) const; private: // -- // functions for std::string->state conversions void interpret_entry(void); void interpret_exit(const std::string& arg); void interpret_set_result(bool result, const std::string& verbose) { interpret_result_rep = result; interpret_result_verbose_rep = verbose; } void interpret_general_option (const std::string& arg); void interpret_processing_control (const std::string& arg); void interpret_audio_format (const std::string& arg); void interpret_chains (const std::string& arg); void interpret_chain_operator (const std::string& arg); void interpret_controller (const std::string& arg); void interpret_effect_preset (const std::string& arg); void interpret_audioio_device (const std::string& argu); void interpret_audioio_manager (const std::string& argu); void interpret_midi_device (const std::string& arg); bool interpret_match_found(void) const { return(istatus_rep); } // -- // data members ECA_CHAINSETUP* csetup_repp; std::vector* last_audio_add_vector_repp; AUDIO_IO* last_audio_object_repp; bool istatus_rep; /* whether we have found an option match? */ bool interpret_result_rep; /* whether we found an option match with correct format? */ std::string interpret_result_verbose_rep; }; #endif ecasound-2.9.1/libecasound/eca-test-repository.cpp0000644000076400007640000001032111544701326017173 00000000000000// ------------------------------------------------------------------------ // eca-test-repository.cpp: A testing subsystem implemented as a // singleton class. // Copyright (C) 2002,2003,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 "kvu_locks.h" #include "kvu_numtostr.h" #include "eca-logger.h" #include "eca-test-repository.h" using namespace std; ECA_TEST_REPOSITORY* ECA_TEST_REPOSITORY::interface_impl_repp = 0; pthread_mutex_t ECA_TEST_REPOSITORY::lock_rep = PTHREAD_MUTEX_INITIALIZER; ECA_TEST_REPOSITORY& ECA_TEST_REPOSITORY::instance(void) { // // Note! Below we use the Double-Checked Locking Pattern // to protect against concurrent access if (interface_impl_repp == 0) { KVU_GUARD_LOCK guard(&ECA_TEST_REPOSITORY::lock_rep); if (interface_impl_repp == 0) { interface_impl_repp = new ECA_TEST_REPOSITORY(); } } return(*interface_impl_repp); } /** * List of unit tests defined in libecasound. */ #include "audiofx_amplitude_test.h" #include "eca-audio-time_test.h" #include "eca-control_test.h" #include "eca-session_test.h" #include "eca-object-factory_test.h" #include "eca-sample-conversion_test.h" #include "eca-chainsetup_test.h" #include "eca-chainsetup-parser_test.h" #include "generic-linear-envelope_test.h" #include "samplebuffer_test.h" /** * Class constructor. * * Registers known tests in libecasound to * the repository. */ ECA_TEST_REPOSITORY::ECA_TEST_REPOSITORY(void) { test_cases_rep.push_back(new EFFECT_AMPLIFY_TEST()); test_cases_rep.push_back(new EFFECT_AMPLIFY_CHANNEL_TEST()); test_cases_rep.push_back(new ECA_AUDIO_TIME_TEST()); test_cases_rep.push_back(new ECA_SESSION_TEST()); test_cases_rep.push_back(new ECA_CONTROL_TEST()); test_cases_rep.push_back(new ECA_OBJECT_FACTORY_TEST()); test_cases_rep.push_back(new ECA_SAMPLE_CONVERSION_TEST()); test_cases_rep.push_back(new ECA_CHAINSETUP_TEST()); test_cases_rep.push_back(new ECA_CHAINSETUP_PARSER_TEST()); test_cases_rep.push_back(new GENERIC_LINEAR_ENVELOPE_TEST()); test_cases_rep.push_back(new SAMPLE_BUFFER_TEST()); } /** * Class destructor. */ ECA_TEST_REPOSITORY::~ECA_TEST_REPOSITORY(void) { } void ECA_TEST_REPOSITORY::do_run_worker(ECA_TEST_CASE* testcase) { ECA_LOG_MSG(ECA_LOGGER::info, "Running test case '" + testcase->name() + "'."); testcase->run(); if (testcase->success() != true) { string errormsg = (string("Test case ") + testcase->name() + string(" FAILED.")); ECA_LOG_MSG(ECA_LOGGER::user_objects, errormsg); ECA_TEST_FAILURE(errormsg); const list& failures = testcase->failures(); list::const_iterator q = failures.begin(); int m = 1; while(q != failures.end()) { ECA_TEST_FAILURE(testcase->name() + ":" + kvu_numtostr(m++) + ". " + *q); ++q; } } else { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Test case '" + testcase->name() + "' passed."); } } void ECA_TEST_REPOSITORY::do_run(const std::string& name) { list::const_iterator p = test_cases_rep.begin(); while(p != test_cases_rep.end()) { if ((*p)->name() == name) { do_run_worker(*p); return; } ++p; } ECA_TEST_FAILURE("Test case with name '" + name + "' not found."); } void ECA_TEST_REPOSITORY::do_run(void) { list::const_iterator p = test_cases_rep.begin(); while(p != test_cases_rep.end()) { do_run_worker(*p); ++p; } } ecasound-2.9.1/libecasound/audioio-null.cpp0000644000076400007640000000221610664032032015647 00000000000000// ------------------------------------------------------------------------ // audioio-null.cpp: Object that consumes and produces null audio data. // Copyright (C) 2005 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include "audioio-null.h" NULLFILE::NULLFILE(const std::string& name) { set_label(name); } NULLFILE::~NULLFILE(void) { } ecasound-2.9.1/libecasound/eca-object-factory.cpp0000644000076400007640000006374311760510671016733 00000000000000// ------------------------------------------------------------------------ // eca-object-factory.cpp: Abstract factory for creating libecasound // objects. // Copyright (C) 2000-2005,2007,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include /* ANSI-C++: find() */ #include #include #include #include #include #include #include #ifdef ECA_COMPILE_JACK #include #endif #include #include "kvu_locks.h" #include #include #include "audioio.h" #include "audioio-loop.h" #include "midiio.h" #include "audiofx_ladspa.h" #include "audiofx_lv2.h" #include "generic-controller.h" #include "eca-static-object-maps.h" #include "eca-object-map.h" #include "eca-preset-map.h" #include "eca-object-factory.h" #include "eca-resources.h" #include "eca-logger.h" /** * Import std namespace. */ using std::list; using std::map; using std::string; /** * Initialize static member variables. */ ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::audio_io_rt_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::audio_io_nonrt_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::chain_operator_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::lv2_plugin_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::ladspa_plugin_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::ladspa_plugin_id_map_repp = 0; ECA_PRESET_MAP* ECA_OBJECT_FACTORY::preset_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::controller_map_repp = 0; ECA_OBJECT_MAP* ECA_OBJECT_FACTORY::midi_device_map_repp = 0; pthread_mutex_t ECA_OBJECT_FACTORY::lock_rep = PTHREAD_MUTEX_INITIALIZER; /** * Definitions for static member functions. */ /** * Returns an object map containing all registered * realtime audio i/o object types. * * All stored objects are derived from AUDIO_IO_DEVICE. */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::audio_io_rt_map(void) { // // Note! Below we use the Double-Checked Locking Pattern // to protect against concurrent access if (audio_io_rt_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (audio_io_rt_map_repp == 0) { audio_io_rt_map_repp = new ECA_OBJECT_MAP(); ECA_STATIC_OBJECT_MAPS::register_audio_io_rt_objects(audio_io_rt_map_repp); } } return *audio_io_rt_map_repp; } /** * Returns an object map containing all registered * non-realtime audio i/o object types. * * All stored objects are derived from AUDIO_IO. */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::audio_io_nonrt_map(void) { if (audio_io_nonrt_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (audio_io_nonrt_map_repp == 0) { audio_io_nonrt_map_repp = new ECA_OBJECT_MAP(); ECA_STATIC_OBJECT_MAPS::register_audio_io_nonrt_objects(audio_io_nonrt_map_repp); } } return *audio_io_nonrt_map_repp; } /** * Returns an object map containing all registered * chain operator object types. * * All stored objects are derived from CHAIN_OPERATOR. */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::chain_operator_map(void) { if (chain_operator_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (chain_operator_map_repp == 0) { chain_operator_map_repp = new ECA_OBJECT_MAP(); ECA_STATIC_OBJECT_MAPS::register_chain_operator_objects(chain_operator_map_repp); } } return *chain_operator_map_repp; } /** * Returns an object map containing all registered * LV2 plugin types. * * All stored objects are derived from EFFECT_LV2. * * @see ladspa_plugin_id_map() */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::lv2_plugin_map(void) { if (lv2_plugin_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (lv2_plugin_map_repp == 0) { lv2_plugin_map_repp = new ECA_OBJECT_MAP(); DBC_CHECK(lv2_plugin_map_repp != 0); /* note: matching LADSPA unique names must be case sensitive */ lv2_plugin_map_repp->toggle_case_sensitive_expressions(true); ECA_STATIC_OBJECT_MAPS::register_lv2_plugin_objects(lv2_plugin_map_repp); } } return *lv2_plugin_map_repp; } /** * Returns an object map containing all registered * LADSPA plugin types. * * * All stored objects are derived from EFFECT_LADSPA. * * @see ladspa_plugin_id_map() */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::ladspa_plugin_map(void) { if (ladspa_plugin_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (ladspa_plugin_map_repp == 0) { ladspa_plugin_map_repp = new ECA_OBJECT_MAP(); DBC_CHECK(ladspa_plugin_map_repp != 0); /* note: matching LADSPA unique names must be case sensitive */ ladspa_plugin_map_repp->toggle_case_sensitive_expressions(true); ECA_STATIC_OBJECT_MAPS::register_ladspa_plugin_objects(ladspa_plugin_map_repp); } } return *ladspa_plugin_map_repp; } /** * Returns an object map containing all registered * LADSPA plugin types. Plugins are identified using * their unique LADSPA id number. * * All stored objects are derived from EFFECT_LADSPA. * * @see ladspa_plugin_map() */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::ladspa_plugin_id_map(void) { if (ladspa_plugin_id_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (ladspa_plugin_id_map_repp == 0) { ladspa_plugin_id_map_repp = new ECA_OBJECT_MAP(); ECA_STATIC_OBJECT_MAPS::register_ladspa_plugin_id_objects(ladspa_plugin_id_map_repp); } } return *ladspa_plugin_id_map_repp; } /** * Returns an object map containing all registered * chain operator preset object types. * * All stored objects are derived from PRESET. */ ECA_PRESET_MAP& ECA_OBJECT_FACTORY::preset_map(void) { if (preset_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (preset_map_repp == 0) { preset_map_repp = new ECA_PRESET_MAP(); ECA_STATIC_OBJECT_MAPS::register_preset_objects(preset_map_repp); } } return *preset_map_repp; } /** * Returns an object map containing all registered * controller object types. * * All stored objects are derived from GENERIC_CONTROLLER. */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::controller_map(void) { if (controller_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (controller_map_repp == 0) { controller_map_repp = new ECA_OBJECT_MAP(); ECA_STATIC_OBJECT_MAPS::register_controller_objects(controller_map_repp); } } return *controller_map_repp; } /** * Returns an object map containing all registered * MIDI-device types. * * * All stored objects are derived from MIDI_IO. */ ECA_OBJECT_MAP& ECA_OBJECT_FACTORY::midi_device_map(void) { if (midi_device_map_repp == 0) { KVU_GUARD_LOCK guard(&ECA_OBJECT_FACTORY::lock_rep); if (midi_device_map_repp == 0) { midi_device_map_repp = new ECA_OBJECT_MAP(); ECA_STATIC_OBJECT_MAPS::register_midi_device_objects(midi_device_map_repp); } } return *midi_device_map_repp; } /** * Create a new audio object based on the formatted argument string. * * @param arg a formatted string describing an audio object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre arg.empty() != true */ AUDIO_IO* ECA_OBJECT_FACTORY::create_audio_object(const string& arg) { // -- DBC_REQUIRE(arg.empty() != true); // -- int args_given = kvu_get_number_of_arguments(arg); string fname = kvu_get_argument_number(1, arg); const AUDIO_IO* main_file = 0; main_file = dynamic_cast(ECA_OBJECT_FACTORY::audio_io_rt_map().object_expr(fname)); if (main_file == 0) { main_file = dynamic_cast(ECA_OBJECT_FACTORY::audio_io_nonrt_map().object_expr(fname)); } AUDIO_IO* new_file = 0; if (main_file != 0) { new_file = main_file->new_expr(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Object \"" + arg + "\" created, type \"" + new_file->name() + "\". Has " + kvu_numtostr(new_file->number_of_params()) + " parameter(s) (variable: " + (new_file->variable_params() == true ? string("yes).") : string("no)."))); /* if more params are given and the object supports * variable number of args, pass them all to the object */ int params = new_file->number_of_params(); if (new_file->variable_params() && args_given > params) params = args_given; for(int n = 0; n < params; n++) { new_file->set_parameter(n + 1, kvu_get_argument_number(n + 1, arg)); } } return new_file; } /** * Create a new MIDI-device object based on the formatted argument string. * * @param arg a formatted string describing a MIDI-device object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * require: * arg.empty() != true */ MIDI_IO* ECA_OBJECT_FACTORY::create_midi_device(const string& arg) { // -------- DBC_REQUIRE(arg.empty() != true); // -------- string fname = kvu_get_argument_number(1, arg); const MIDI_IO* device = 0; device = dynamic_cast(ECA_OBJECT_FACTORY::midi_device_map().object_expr(fname)); MIDI_IO* new_device = 0; if (device != 0) { new_device = device->new_expr(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Object \"" + arg + "\" created, type \"" + new_device->name() + "\". Has " + kvu_numtostr(new_device->number_of_params()) + " parameter(s)."); for(int n = 0; n < new_device->number_of_params(); n++) { new_device->set_parameter(n + 1, kvu_get_argument_number(n + 1, arg)); } } return new_device; } /** * Create a new loop input object. * * @param arg a formatted string describing an loop object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre argu.empty() != true */ AUDIO_IO* ECA_OBJECT_FACTORY::create_loop_input(const string& argu, map* loop_map) { // -------- DBC_REQUIRE(argu.empty() != true); // -------- LOOP_DEVICE* p = 0; string tname = kvu_get_argument_number(1, argu); if (tname == "loop") { string id = kvu_get_argument_number(2, argu); p = new LOOP_DEVICE(id); if (loop_map->find(id) == loop_map->end()) { (*loop_map)[id] = p; } else p = (*loop_map)[id]; p->register_input(); } return p; } /** * Create a new loop output object. * * @param arg a formatted string describing an loop object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre argu.empty() != true */ AUDIO_IO* ECA_OBJECT_FACTORY::create_loop_output(const string& argu, map* loop_map) { // -------- DBC_REQUIRE(argu.empty() != true); // -------- LOOP_DEVICE* p = 0; string tname = kvu_get_argument_number(1, argu); if (tname == "loop") { string id = kvu_get_argument_number(2, argu); p = new LOOP_DEVICE(id); if (loop_map->find(id) == loop_map->end()) { (*loop_map)[id] = p; } else p = (*loop_map)[id]; p->register_output(); } return p; } /** * Creates a new LADSPA plugin. * * @param arg a formatted string describing an LADSPA object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre argu.size() > 0 * @pre argu[0] == '-' */ CHAIN_OPERATOR* ECA_OBJECT_FACTORY::create_ladspa_plugin (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); // -------- MESSAGE_ITEM otemp; otemp.setprecision(3); const CHAIN_OPERATOR* cop = 0; string prefix = kvu_get_argument_prefix(argu); if (prefix == "el" || prefix == "eli") { string unique = kvu_get_argument_number(1, argu); if (prefix == "el") cop = dynamic_cast(ECA_OBJECT_FACTORY::ladspa_plugin_map().object(unique)); else cop = dynamic_cast(ECA_OBJECT_FACTORY::ladspa_plugin_id_map().object(unique)); CHAIN_OPERATOR* new_cop = 0; if (cop != 0) { new_cop = dynamic_cast(cop->new_expr()); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Creating LADSPA-plugin \"" + new_cop->name() + "\""); otemp << "Setting parameters: "; for(int n = 0; n < new_cop->number_of_params(); n++) { new_cop->set_parameter(n + 1, atof(kvu_get_argument_number(n + 2, argu).c_str())); otemp << new_cop->get_parameter_name(n + 1) << " = "; otemp << new_cop->get_parameter(n + 1); if (n + 1 < new_cop->number_of_params()) otemp << ", "; } ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } else { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Unable to find LADSPA plugin \"" + unique + "\""); } return new_cop; } return 0; } /** * Creates a new LV2 plugin. * * @param arg a formatted string describing an LV2 object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre argu.size() > 0 * @pre argu[0] == '-' */ CHAIN_OPERATOR* ECA_OBJECT_FACTORY::create_lv2_plugin (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); // -------- MESSAGE_ITEM otemp; otemp.setprecision(3); const CHAIN_OPERATOR* cop = 0; string prefix = kvu_get_argument_prefix(argu); if (prefix == "elv2") { string unique = kvu_get_argument_number(1, argu); cop = dynamic_cast(ECA_OBJECT_FACTORY::lv2_plugin_map().object(unique)); CHAIN_OPERATOR* new_cop = 0; if (cop != 0) { new_cop = dynamic_cast(cop->new_expr()); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Creating LV2-plugin \"" + new_cop->name() + "\""); otemp << "Setting parameters: "; for(int n = 0; n < new_cop->number_of_params(); n++) { new_cop->set_parameter(n + 1, atof(kvu_get_argument_number(n + 2, argu).c_str())); otemp << new_cop->get_parameter_name(n + 1) << " = "; otemp << new_cop->get_parameter(n + 1); if (n + 1 < new_cop->number_of_params()) otemp << ", "; } ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } else { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: Unable to find LV2 plugin \"" + unique + "\""); } return new_cop; } return 0; } /** * VST not currently actively supported due to licensing * issues. */ #if 0 /** * Creates a new VST1.0/2.0 plugin. * * Notes: VST support is currently not used * because of licensing problems * (distribution of VST-headers is not * allowed). */ CHAIN_OPERATOR* ECA_OBJECT_FACTORY::create_vst_plugin (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); // -------- MESSAGE_ITEM otemp; otemp.setprecision(3); const CHAIN_OPERATOR* cop = 0; string prefix = kvu_get_argument_prefix(argu); cop = dynamic_cast(ECA_STATIC_OBJECT_MAPS::vst_plugin_map().object(prefix)); CHAIN_OPERATOR* new_cop = 0; if (cop != 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Creating VST-plugin \"" + new_cop->name() + "\""); otemp << "Setting parameters: "; for(int n = 0; n < new_cop->number_of_params(); n++) { new_cop->set_parameter(n + 1, atof(kvu_get_argument_number(n + 1, argu).c_str())); otemp << new_cop->get_parameter_name(n + 1) << " = "; otemp << new_cop->get_parameter(n + 1); if (n + 1 < new_cop->number_of_params()) otemp << ", "; } ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } return new_cop; } #endif /* VST ifdef 0 */ /** * Creates a new chain operator object. * * @param arg a formatted string describing an chain operator object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre argu.size() > 0 * @pre argu[0] == '-' */ CHAIN_OPERATOR* ECA_OBJECT_FACTORY::create_chain_operator (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); // -------- string prefix = kvu_get_argument_prefix(argu); int args_given = kvu_get_number_of_arguments(argu); MESSAGE_ITEM otemp; otemp.setprecision(3); const CHAIN_OPERATOR* cop = dynamic_cast(ECA_OBJECT_FACTORY::chain_operator_map().object(prefix)); CHAIN_OPERATOR* new_cop = 0; if (cop != 0) { new_cop = dynamic_cast(cop->new_expr()); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Creating chain operator \"" + new_cop->name() + "\""); // otemp << "(eca-chainsetup) Adding effect " << new_cop->name(); otemp << "Setting parameters: "; int params = new_cop->number_of_params(); if (new_cop->variable_params() && args_given > params) params = args_given; for(int n = 0; n < params; n++) { new_cop->set_parameter(n + 1, atof(kvu_get_argument_number(n + 1, argu).c_str())); otemp << new_cop->get_parameter_name(n + 1) << " = "; otemp << new_cop->get_parameter(n +1); if (n + 1 < new_cop->number_of_params()) otemp << ", "; } ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); return new_cop; } return 0; } /** * Creates a new generic controller object. * * @param arg a formatted string describing an generic controller object, see ecasound * manuals for detailed info * @return the created object or 0 if an invalid format string was given * as the argument * * @pre argu.size() > 0 * @pre argu[0] == '-' */ GENERIC_CONTROLLER* ECA_OBJECT_FACTORY::create_controller (const string& argu) { // -------- DBC_REQUIRE(argu.size() > 0); DBC_REQUIRE(argu[0] == '-'); // -------- if (argu.size() > 0 && argu[0] != '-') return 0; string prefix = kvu_get_argument_prefix(argu); const GENERIC_CONTROLLER* gcontroller = dynamic_cast(ECA_OBJECT_FACTORY::controller_map().object(prefix)); GENERIC_CONTROLLER* new_gcontroller = 0; if (gcontroller != 0) { new_gcontroller = gcontroller->new_expr(); if (new_gcontroller != 0) { const CONTROLLER_SOURCE* csource = gcontroller->source_pointer(); CONTROLLER_SOURCE* new_csource = 0; if (csource != 0) { new_csource = csource->new_expr(); } new_gcontroller->assign_source(new_csource); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Creating controller source \"" + new_gcontroller->name() + "\""); MESSAGE_ITEM otemp; otemp.setprecision(3); otemp << "Setting parameters: "; int numparams = new_gcontroller->number_of_params(); for(int n = 0; n < numparams; n++) { new_gcontroller->set_parameter(n + 1, atof(kvu_get_argument_number(n + 1, argu).c_str())); otemp << new_gcontroller->get_parameter_name(n + 1) << " = "; otemp << new_gcontroller->get_parameter(n +1); if (new_gcontroller->variable_params()) numparams = new_gcontroller->number_of_params(); // in case 'n_o_p()' varies if (n + 1 < numparams) otemp << ", "; } ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); return new_gcontroller; } } return 0; } /** * Returns a EOS-compatible string describing the default * output device. This device is determined based on * ecasoundrc settings, available resources, * compile-time options, etc. */ std::string ECA_OBJECT_FACTORY::probe_default_output_device(void) { ECA_RESOURCES ecaresources; const char *output_autodetect = "autodetect"; string default_output = output_autodetect; bool output_selected = true; if (ecaresources.has("default-output") == true) default_output = ecaresources.resource("default-output"); if (default_output == output_autodetect) { output_selected = false; #ifdef ECA_COMPILE_JACK /* phase 1: check for JACK */ int pid = getpid(); string cname = "ecasound-autodetect-" + kvu_numtostr(pid); jack_client_t *client = jack_client_open(cname.c_str(), JackNoStartServer, NULL); if (client != 0) { jack_client_close(client); default_output = "jack_alsa"; output_selected = true; } #endif /* phase 2: check for ALSA support */ if (output_selected != true) { const ECA_OBJECT *obj = ECA_OBJECT_FACTORY::audio_io_rt_map().object("alsa"); if (obj != 0) { default_output = "alsa,default"; output_selected = true; } } /* phase 3: check for OSS support */ if (output_selected != true) { const ECA_OBJECT *obj = ECA_OBJECT_FACTORY::audio_io_rt_map().object("/dev/dsp"); if (obj != 0) { default_output = "/dev/dsp"; output_selected = true; } } /* phase 4: fallback to rtnull */ if (output_selected != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: No default output available. Using 'rtnull' as a fallback."); default_output = "rtnull"; } } return default_output; } /** * Makes an Ecasound Option Syntax (EOS) compatible string * describing the current state of chain operator 'gctrl'. */ string ECA_OBJECT_FACTORY::chain_operator_to_eos(const CHAIN_OPERATOR* chainop) { MESSAGE_ITEM t; // >-- // special handling for LADSPA-plugins #ifndef ECA_DISABLE_EFFECTS const EFFECT_LADSPA* ladspa = dynamic_cast(chainop); const CHAIN_OPERATOR *lv2_cop = 0; string lv2_arg; #ifdef ECA_USE_LIBLILV const EFFECT_LV2* lv2 = dynamic_cast(chainop); if (lv2 != 0) { lv2_cop = static_cast(lv2); lv2_arg = lv2->unique(); } #endif if (lv2_cop != 0) { t << "-elv2:" << lv2_arg; if (chainop->number_of_params() > 0) t << ","; } else if (ladspa != 0) { t << "-eli:" << ladspa->unique_number(); if (chainop->number_of_params() > 0) t << ","; } else { ECA_OBJECT_MAP& copmap = ECA_OBJECT_FACTORY::chain_operator_map(); ECA_PRESET_MAP& presetmap = ECA_OBJECT_FACTORY::preset_map(); string idstring = copmap.object_identifier(chainop); if (idstring.size() == 0) { idstring = presetmap.object_identifier(chainop); } if (idstring.size() == 0) { ECA_LOG_MSG(ECA_LOGGER::errors, "Unable to save chain operator \"" + chainop->name() + "\"."); return t.to_string(); } t << "-" << idstring; if (chainop->number_of_params() > 0) t << ":"; } #endif // --< t << ECA_OBJECT_FACTORY::operator_parameters_to_eos(chainop); return t.to_string(); } /** * Makes an Ecasound Option Syntax (EOS) compatible string * describing the current state of controller object 'gctrl'. */ string ECA_OBJECT_FACTORY::controller_to_eos(const GENERIC_CONTROLLER* gctrl) { MESSAGE_ITEM t; ECA_OBJECT_MAP& ctrlmap = ECA_OBJECT_FACTORY::controller_map(); string idstring = ctrlmap.object_identifier(gctrl); if (idstring.size() == 0) { ECA_LOG_MSG(ECA_LOGGER::errors, "Unable to save controller \"" + gctrl->name() + "\"."); return t.to_string(); } t << "-" << idstring << ":" << ECA_OBJECT_FACTORY::operator_parameters_to_eos(gctrl); return t.to_string(); } /** * Makes an Ecasound Option Syntax (EOS) compatible, * comma-separated list of parameter values for * chain operator 'chainop'. */ string ECA_OBJECT_FACTORY::operator_parameters_to_eos(const OPERATOR* chainop) { MESSAGE_ITEM t; for(int n = 0; n < chainop->number_of_params(); n++) { /* FIXME: escape commas */ t << chainop->get_parameter(n + 1); if (n + 1 < chainop->number_of_params()) t << ","; } return t.to_string(); } /** * Return a string compliant with Ecasound Option Syntax (EOS) * describing the object 'aiod'. * * @pre direction == "i" || direction == "o" */ string ECA_OBJECT_FACTORY::audio_object_to_eos(const AUDIO_IO* aiod, const std::string& direction) { MESSAGE_ITEM t; t << "-" << direction << ":"; for(int n = 0; n < aiod->number_of_params(); n++) { /* step: if parameter has commas, or whitespace, quote the whole parameter */ std::string param = aiod->get_parameter(n + 1); if (find(param.begin(), param.end(), ',') != param.end() || find(param.begin(), param.end(), ' ') != param.end() || find(param.begin(), param.end(), '\t') != param.end()) { param = std::string("\"") + param + std::string("\""); } /* step: add processed parameter to the EOS string */ t << param; if (n + 1 < aiod->number_of_params()) t << ","; } return t.to_string(); } /** * Return a string compliant with Ecasound Option Syntax (EOS) * describing the audio format 'aformat'. */ string ECA_OBJECT_FACTORY::audio_format_to_eos(const ECA_AUDIO_FORMAT* aformat) { MESSAGE_ITEM t; t << "-f:" << aformat->format_string() << "," << aformat->channels() << "," << aformat->samples_per_second(); return t.to_string(); } /** * Return a string compliant with Ecasound Option Syntax (EOS) * describing the audio format of object 'aiod'. */ string ECA_OBJECT_FACTORY::audio_object_format_to_eos(const AUDIO_IO* aio) { return ECA_OBJECT_FACTORY::audio_format_to_eos(dynamic_cast(aio)); #if 0 MESSAGE_ITEM t; t << "-f:" << aiod->format_string() << "," << aiod->channels() << "," << aiod->samples_per_second(); return t.to_string(); #endif } ecasound-2.9.1/libecasound/generic-linear-envelope_test.h0000644000076400007640000000640611544705771020475 00000000000000// ------------------------------------------------------------------------ // generic-linear-envelope_tests.h: Unit test // Copyright (C) 2011 Kai Vehmanen // // 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 #include #include "generic-linear-envelope.h" #include "eca-logger.h" #include "eca-test-case.h" using namespace std; /** * Unit test for GENERIC_LINEAR_ENVELOPE class. */ class GENERIC_LINEAR_ENVELOPE_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("GENERIC_LINEAR_ENVELOPE"); } virtual void do_run(void); public: virtual ~GENERIC_LINEAR_ENVELOPE_TEST(void) { } private: bool roughly_same(float a, float b); }; bool GENERIC_LINEAR_ENVELOPE_TEST::roughly_same(float a, float b) { const int significant_bits = 24; const double diff_threshold = 1.0 / ((1 << significant_bits) - 1); double diff = std::fabs(a - b); if (diff > diff_threshold) return false; return true; } void GENERIC_LINEAR_ENVELOPE_TEST::do_run(void) { GENERIC_LINEAR_ENVELOPE f; bool verbose = false; if (getenv("V") != NULL) verbose = true; f.set_parameter(1, 4); f.set_parameter(2, 40.0);// point1 f.set_parameter(3, 0.1); f.set_parameter(4, 100); // point2 f.set_parameter(5, 0.5); f.set_parameter(6, 200); // point3 f.set_parameter(7, 1); f.set_parameter(8, 500); // point4 f.set_parameter(9, 0.9); f.set_parameter(10, 0); // invalid param f.set_parameter(11, 0); // invalid param f.init(); if (roughly_same(f.value(-10.0), 0.1) != true) ECA_TEST_FAILURE("at pos -10.0s (invalid)"); if (roughly_same(f.value(0.0), 0.1) != true) ECA_TEST_FAILURE("at pos 0.0s (start)"); if (roughly_same(f.value(10.0), 0.1) != true) ECA_TEST_FAILURE("at pos 10.0s"); if (roughly_same(f.value(40.0), 0.1) != true) ECA_TEST_FAILURE("at pos 40.0s"); if (f.value(250) <= 0.9 || f.value(250) >= 1.0) ECA_TEST_FAILURE("at pos 250.0s"); if (f.value(251) <= 0.9 || f.value(251) >= 1.0) ECA_TEST_FAILURE("at pos 251.0s"); if (f.value(60) <= 0.1 || f.value(60) >= 0.5) ECA_TEST_FAILURE("at pos 60.0s"); if (f.value(250) <= 0.9 || f.value(250) >= 1.0) ECA_TEST_FAILURE("at pos 250.0s"); if (f.value(60) <= 0.1 || f.value(60) >= 0.5) ECA_TEST_FAILURE("at pos 60.0s"); if (roughly_same(f.value(10.0), 0.1) != true) ECA_TEST_FAILURE("retest pos 10.0s"); if (f.value(60) <= 0.1 || f.value(60) >= 0.5) ECA_TEST_FAILURE("retest pos 60.0s"); if (roughly_same(f.value(2000.0), 0.9) != true) ECA_TEST_FAILURE("at pos 2000.0s (end)"); } ecasound-2.9.1/libecasound/audioio-wave.cpp0000644000076400007640000004415011740514653015654 00000000000000// ------------------------------------------------------------------------ // audioio-wave.cpp: RIFF WAVE audio file input/output. // Copyright (C) 1999-2003,2005,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // References: // - http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include /* off_t */ #endif #include #include #include #include "sample-specs.h" /* for system endianess */ #include "samplebuffer.h" #include "audioio-wave.h" #include "eca-fileio-mmap.h" #include "eca-fileio-stream.h" #include "eca-logger.h" /** * Private macro definitions */ #ifndef UINT32_MAX #define UINT32_MAX 4294967295U #endif #ifdef WORDS_BIGENDIAN static const bool is_system_littleendian = false; #else static const bool is_system_littleendian = true; #endif /** * Private function declarations */ static uint16_t little_endian_uint16(uint16_t arg); static uint32_t little_endian_uint32(uint32_t arg); /** * Private function definitions */ static uint16_t little_endian_uint16(uint16_t arg) { if (is_system_littleendian != true) { return ((arg >> 8) & 0x00ff) | ((arg << 8) & 0xff00); } return arg; } static uint32_t little_endian_uint32(uint32_t arg) { if (is_system_littleendian != true) { return ((arg >> 24) & 0x000000ff) | ((arg >> 8) & 0x0000ff00) | ((arg << 8) & 0x00ff0000) | ((arg << 24) & 0xff000000); } return arg; } /** * Public definitions */ /** * Print extra debug information about RIFF header * contents to stdout when opening files. */ // #define DEBUG_WAVE_HEADER WAVEFILE::WAVEFILE (const std::string& name) { set_label(name); fio_repp = 0; mmaptoggle_rep = "0"; } WAVEFILE::~WAVEFILE(void) { if (is_open() == true) { close(); } } WAVEFILE* WAVEFILE::clone(void) const { WAVEFILE* target = new WAVEFILE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void WAVEFILE::format_query(void) throw(AUDIO_IO::SETUP_ERROR&) { // -------- DBC_REQUIRE(is_open() != true); // -------- if (io_mode() == io_write) return; fio_repp = new ECA_FILE_IO_STREAM(); if (fio_repp == 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Critical error when opening file \"" + label() + "\" for reading.")); } fio_repp->open_file(label(), "rb"); if (fio_repp->file_mode() != "") { set_length_in_bytes(); read_riff_fmt(); // also sets format() find_riff_datablock(); fio_repp->close_file(); } delete fio_repp; fio_repp = 0; // ------- DBC_ENSURE(!is_open()); DBC_ENSURE(fio_repp == 0); // ------- } void WAVEFILE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { switch(io_mode()) { case io_read: { if (mmaptoggle_rep == "1") { ECA_LOG_MSG(ECA_LOGGER::user_objects, "using mmap() mode for file access"); fio_repp = new ECA_FILE_IO_MMAP(); } else fio_repp = new ECA_FILE_IO_STREAM(); if (fio_repp == 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Critical error when opening file \"" + label() + "\" for reading.")); } fio_repp->open_file(label(), "rb"); if (fio_repp->is_file_ready() != true) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Couldn't open file \"" + label() + "\" for reading.")); } read_riff_header(); read_riff_fmt(); // also sets format() set_length_in_bytes(); find_riff_datablock(); break; } case io_write: { fio_repp = new ECA_FILE_IO_STREAM(); if (fio_repp == 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Critical error when opening file \"" + label() + "\" for writing.")); } fio_repp->open_file(label(), "w+b"); if (fio_repp->is_file_ready() != true) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Couldn't open file \"" + label() + "\" for writing.")); } write_riff_header(); write_riff_fmt(); write_riff_datablock(); break; } case io_readwrite: { fio_repp = new ECA_FILE_IO_STREAM(); if (fio_repp == 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Critical error when opening file \"" + label() + "\" for read&write.")); } fio_repp->open_file(label(), "r+b"); if (fio_repp->file_mode() != "") { set_length_in_bytes(); read_riff_fmt(); // also sets format() find_riff_datablock(); } else { fio_repp->open_file(label(), "w+b"); if (fio_repp->is_file_ready() != true) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Couldn't open file \"" + label() + "\" for read&write.")); write_riff_header(); write_riff_fmt(); write_riff_datablock(); } if (fio_repp->is_file_ready() != true) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-WAVE: Couldn't open file \"" + label() + "\" for read&write.")); } } } if (little_endian_uint16(riff_format_rep.bits) > 8 && format_string()[0] == 'u') throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-WAVE: unsigned sample format accepted only with 8bit.")); if (little_endian_uint16(riff_format_rep.bits) > 8 && format_string().size() > 4 && format_string()[4] == 'b') { /* force little-endian operation / affects only write-mode */ set_sample_format_string(format_string()[0] + kvu_numtostr(bits()) + "_le"); ECA_LOG_MSG(ECA_LOGGER::user_objects, "forcing little-endian operation (" + format_string() + ")"); DBC_CHECK(format_string().size() > 4 && format_string()[4] != 'b'); } AUDIO_IO::open(); } void WAVEFILE::close(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects,"Closing file " + label()); if (is_open() == true && fio_repp != 0) { update(); fio_repp->close_file(); delete fio_repp; fio_repp = 0; } AUDIO_IO::close(); } void WAVEFILE::update (void) { if (io_mode() != io_read) { update_riff_datablock(); write_riff_header(); set_length_in_bytes(); } } void WAVEFILE::find_riff_datablock (void) throw(AUDIO_IO::SETUP_ERROR&) { if (find_block("data", 0) != true) { throw(ECA_ERROR("AUDIOIO-WAVE", "no RIFF data block found", ECA_ERROR::retry)); } data_start_position_rep = fio_repp->get_file_position(); } void WAVEFILE::read_riff_header (void) throw(AUDIO_IO::SETUP_ERROR&) { // ECA_LOG_MSG(ECA_LOGGER::user_objects, "read_riff_header()"); fio_repp->read_to_buffer(&riff_header_rep, sizeof(riff_header_rep)); // fread(&riff_header_rep,1,sizeof(riff_header_rep),fobject); if ((memcmp("RIFF",riff_header_rep.id,4) == 0 && memcmp("WAVE",riff_header_rep.wname,4) == 0) != true) { throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-WAVE: invalid RIFF-header (read)")); } } void WAVEFILE::write_riff_header (void) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "write_riff_header()"); off_t savetemp = fio_repp->get_file_position(); memcpy(riff_header_rep.id,"RIFF",4); memcpy(riff_header_rep.wname,"WAVE",4); /* hack for 64bit wav files */ #if _FILE_OFFSET_BITS == 64 if (fio_repp->get_file_length() > static_cast(UINT32_MAX)) riff_header_rep.size = little_endian_uint32(UINT32_MAX); else #endif if (fio_repp->get_file_length() > static_cast(sizeof(riff_header_rep))) riff_header_rep.size = little_endian_uint32(fio_repp->get_file_length() - 8); else riff_header_rep.size = little_endian_uint32(0); fio_repp->set_file_position(0); // fseek(fobject,0,SEEK_SET); fio_repp->write_from_buffer(&riff_header_rep, sizeof(riff_header_rep)); // fwrite(&riff_header_rep,1,sizeof(riff_header_rep),fobject); if (memcmp("RIFF",riff_header_rep.id,4) != 0 || memcmp("WAVE",riff_header_rep.wname,4) != 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-WAVE: invalid RIFF-header (write)")); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Wave data size " + kvu_numtostr(little_endian_uint32(riff_header_rep.size))); fio_repp->set_file_position(savetemp); } void WAVEFILE::read_riff_fmt(void) throw(AUDIO_IO::SETUP_ERROR&) { // ECA_LOG_MSG(ECA_LOGGER::user_objects, "read_riff_fmt()"); off_t savetemp = fio_repp->get_file_position(); if (find_block("fmt ", 0) != true) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-WAVE: no riff fmt-block found")); else { fio_repp->read_to_buffer(&riff_format_rep, sizeof(riff_format_rep)); // fread(&riff_format_rep,1,sizeof(riff_format_rep),fobject); #ifdef DEBUG_WAVE_HEADER std::cout << "RF: format = " << little_endian_uint16(riff_format_rep.format) << std::endl; std::cout << "RF: channels = " << little_endian_uint16(riff_format_rep.channels) << std::endl; std::cout << "RF: srate = " << little_endian_uint32(riff_format_rep.srate) << std::endl; std::cout << "RF: byte_second = " << little_endian_uint32(riff_format_rep.byte_second) << std::endl; std::cout << "RF: align = " << little_endian_uint16(riff_format_rep.align) << std::endl; std::cout << "RF: bits = " << little_endian_uint16(riff_format_rep.bits) << std::endl; #endif if (little_endian_uint16(riff_format_rep.format) != 1 && little_endian_uint16(riff_format_rep.format) != 3) { throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-WAVE: Only WAVE_FORMAT_PCM and WAVE_FORMAT_IEEE_FLOAT are supported.")); } set_samples_per_second(little_endian_uint32(riff_format_rep.srate)); set_channels(little_endian_uint16(riff_format_rep.channels)); if (little_endian_uint16(riff_format_rep.bits) == 32) { if (little_endian_uint16(riff_format_rep.format) == 3) set_sample_format(ECA_AUDIO_FORMAT::sfmt_f32_le); else set_sample_format(ECA_AUDIO_FORMAT::sfmt_s32_le); } else if (little_endian_uint16(riff_format_rep.bits) == 24) { if (riff_format_rep.align == little_endian_uint16(channels() * 3)) { /* packet s24 format */ set_sample_format(ECA_AUDIO_FORMAT::sfmt_s24_le); } else if (riff_format_rep.align == little_endian_uint16(channels() * 4)) { /* unpacked s24 format */ set_sample_format(ECA_AUDIO_FORMAT::sfmt_s32_le); } else { throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-WAVE: Invalid 24bit sample format combination.")); } } else if (little_endian_uint16(riff_format_rep.bits) == 16) set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le); else if (little_endian_uint16(riff_format_rep.bits) == 8) set_sample_format(ECA_AUDIO_FORMAT::sfmt_u8); else throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-WAVE: Sample format not supported.")); } DBC_CHECK(little_endian_uint16(riff_format_rep.channels) == channels()); DBC_CHECK(little_endian_uint16(riff_format_rep.bits) == bits()); DBC_CHECK(little_endian_uint32(riff_format_rep.srate) == static_cast(samples_per_second())); DBC_CHECK(little_endian_uint32(riff_format_rep.byte_second) == static_cast(bytes_per_second())); DBC_CHECK(little_endian_uint16(riff_format_rep.align) == frame_size()); fio_repp->set_file_position(savetemp); } void WAVEFILE::write_riff_fmt(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "write_riff_fmt()"); RB fblock; fio_repp->set_file_position_end(); riff_format_rep.channels = little_endian_uint16(channels()); riff_format_rep.bits = little_endian_uint16(bits()); riff_format_rep.srate = little_endian_uint32(samples_per_second()); riff_format_rep.byte_second = little_endian_uint32(bytes_per_second()); riff_format_rep.align = little_endian_uint16(frame_size()); if (sample_coding() == ECA_AUDIO_FORMAT::sc_float) { // WAVE_FORMAT_IEEE_FLOAT 0x0003 (Microsoft IEEE754 range [-1, +1)) riff_format_rep.format = little_endian_uint16(3); } else { // WAVE_FORMAT_PCM (0x0001) Microsoft Pulse Code Modulation (PCM) format riff_format_rep.format = little_endian_uint16(1); } memcpy(fblock.sig, "fmt ", 4); fblock.bsize = little_endian_uint32(16); fio_repp->write_from_buffer(&fblock, sizeof(fblock)); fio_repp->write_from_buffer(&riff_format_rep, sizeof(riff_format_rep)); // ECA_LOG_MSG(ECA_LOGGER::user_objects, "Wrote RIFF format header."); } void WAVEFILE::write_riff_datablock(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "write_riff_datablock()"); RB fblock; // ECA_LOG_MSG(ECA_LOGGER::user_objects, "write_riff_datablock()"); fio_repp->set_file_position_end(); memcpy(fblock.sig,"data",4); fblock.bsize = little_endian_uint32(0); fio_repp->write_from_buffer(&fblock, sizeof(fblock)); data_start_position_rep = fio_repp->get_file_position(); } void WAVEFILE::update_riff_datablock(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "update_riff_datablock()"); RB fblock; memcpy(fblock.sig,"data",4); find_block("data", 0); off_t savetemp = fio_repp->get_file_position(); fio_repp->set_file_position_end(); /* hack for wav files with length over 2^32-1 bytes */ #if _FILE_OFFSET_BITS == 64 if (fio_repp->get_file_position() - savetemp > static_cast(UINT32_MAX)) fblock.bsize = little_endian_uint32(UINT32_MAX); else #endif fblock.bsize = little_endian_uint32(fio_repp->get_file_position() - savetemp); ECA_LOG_MSG(ECA_LOGGER::user_objects, "updating data block header length to " + kvu_numtostr(little_endian_uint32(fblock.bsize))); savetemp = savetemp - sizeof(fblock); if (savetemp > 0) { fio_repp->set_file_position(savetemp); fio_repp->write_from_buffer(&fblock, sizeof(fblock)); } } bool WAVEFILE::next_riff_block(RB *t, off_t *offtmp) { // ECA_LOG_MSG(ECA_LOGGER::user_objects, "next_riff_block()"); fio_repp->read_to_buffer(t, sizeof(RB)); if (fio_repp->file_bytes_processed() != sizeof(RB)) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "invalid RIFF block!"); return false; } if (!fio_repp->is_file_ready()) return false; *offtmp = little_endian_uint32(t->bsize) + fio_repp->get_file_position(); return true; } bool WAVEFILE::find_block(const char* fblock, uint32_t* blksize) { off_t offset; RB block; // ECA_LOG_MSG(ECA_LOGGER::user_objects, "find_block(): " + string(fblock,4)); fio_repp->set_file_position(sizeof(riff_header_rep)); while(next_riff_block(&block,&offset)) { // ECA_LOG_MSG(ECA_LOGGER::user_objects, "found RIFF-block "); if (memcmp(block.sig,fblock,4) == 0) { if (blksize != 0) *blksize = little_endian_uint32(block.bsize); return true; } fio_repp->set_file_position(offset); } return false; } bool WAVEFILE::finished(void) const { if (io_mode() == io_read && (length_set() == true && position_in_samples() >= length_in_samples())) { return true; } if (fio_repp->is_file_error() || !fio_repp->is_file_ready()) return true; return false; } long int WAVEFILE::read_samples(void* target_buffer, long int samples) { // -------- DBC_REQUIRE(samples >= 0); DBC_REQUIRE(target_buffer != 0); // -------- if (length_set() == true && position_in_samples() + samples >= length_in_samples()) samples = length_in_samples() - position_in_samples(); fio_repp->read_to_buffer(target_buffer, frame_size() * samples); return fio_repp->file_bytes_processed() / frame_size(); } void WAVEFILE::write_samples(void* target_buffer, long int samples) { // -------- DBC_REQUIRE(samples >= 0); DBC_REQUIRE(target_buffer != 0); // -------- /* note: When writing in write-update mode (i.e. modifying an * existing file), we do not honor the previous length value * in "data" header chunk. This may lead to overriding some * non-data chunk at the end of the file. */ fio_repp->write_from_buffer(target_buffer, frame_size() * samples); } SAMPLE_SPECS::sample_pos_t WAVEFILE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { if (is_open() == true) { fio_repp->set_file_position(data_start_position_rep + pos * frame_size()); } return pos; } void WAVEFILE::set_length_in_bytes(void) { off_t savetemp = fio_repp->get_file_position(); uint32_t blksize = 0; find_block("data", &blksize); off_t datastart = fio_repp->get_file_position(); fio_repp->set_file_position_end(); off_t datalen = fio_repp->get_file_position() - datastart; /* note: If the audio stream length defined in "data" header * block is zero (not updated), or it's set to maximum * value, set the length according to actual file length. * * This is not strictly according to the RIFF WAVE spec, * but allows to handle RIFF WAVE files with a broken * header, as well as files with size exceeding the 2GiB * limit. */ if (blksize != 0 && blksize != UINT32_MAX) { set_length_in_samples(blksize / frame_size()); } else set_length_in_samples(datalen / frame_size()); ECA_LOG_MSG(ECA_LOGGER::user_objects, "data block length in header " + kvu_numtostr(blksize) + ", file length after data block " + kvu_numtostr(datalen) + ", length set to " + kvu_numtostr(length_in_samples()) + " samples"); fio_repp->set_file_position(savetemp); } void WAVEFILE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: mmaptoggle_rep = value; break; } } string WAVEFILE::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return mmaptoggle_rep; } return ""; } ecasound-2.9.1/libecasound/generic-linear-envelope.cpp0000644000076400007640000001053311544710440017752 00000000000000// ------------------------------------------------------------------------ // generic-linear-envelope.cpp: Generic linear envelope // Copyright (C) 2000-2002,2006,2008,2011 Kai Vehmanen // Copyright (C) 2001 Arto Hamara // // Attributes: // eca-style-version: 3 // // This program is fre 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 #include #include "generic-linear-envelope.h" #include "eca-logger.h" /* Debug controller source values */ // #define DEBUG_CONTROLLERS #ifdef DEBUG_CONTROLLERS #define DEBUG_CTRL_STATEMENT(x) x #else #define DEBUG_CTRL_STATEMENT(x) ((void)0) #endif GENERIC_LINEAR_ENVELOPE::GENERIC_LINEAR_ENVELOPE(void) { pos_rep.resize(1); val_rep.resize(1); curstage = -2; /* processing not yet started */ pos_rep[0] = 0; val_rep[0] = 0; set_param_count(0); } GENERIC_LINEAR_ENVELOPE::~GENERIC_LINEAR_ENVELOPE(void) { } bool GENERIC_LINEAR_ENVELOPE::is_valid_for_stage(double pos, int stage) const { if ((stage >= 0) && (stage < static_cast(pos_rep.size()-1)) && (pos >= pos_rep[stage]) && (pos < pos_rep[stage+1])) return true; return false; } void GENERIC_LINEAR_ENVELOPE::set_stage(double curpos) { /* case: init not called yet */ if (curstage == -2) return; if (curpos < pos_rep[0]) { curstage = -1; return; } int n; for(n = 0; n < static_cast(pos_rep.size() - 1); n++) { if (curpos < pos_rep[n + 1]) { break; } } curstage = n; } CONTROLLER_SOURCE::parameter_t GENERIC_LINEAR_ENVELOPE::value(double curpos) { if (is_valid_for_stage(curpos, curstage)) { curval = (((curpos - pos_rep[curstage]) * val_rep[curstage+1] + (pos_rep[curstage+1] - curpos) * val_rep[curstage]) / (pos_rep[curstage+1] - pos_rep[curstage])); } else { set_stage(curpos); if (is_valid_for_stage(curpos, curstage)) return value(curpos); if (curstage < 0) curval = val_rep[0]; else curval = val_rep.back(); } DEBUG_CTRL_STATEMENT(std::cerr << "generic-linear-envelope: type '" << name() << "', pos " << curpos << ", value " << curval << ", stage " << curstage << "." << std::endl); return curval; } void GENERIC_LINEAR_ENVELOPE::init(void) { curval = 0.0f; curstage = -1; /* processing started */ ECA_LOG_MSG(ECA_LOGGER::info, "Envelope created."); } void GENERIC_LINEAR_ENVELOPE::set_param_count(int params) { param_names_rep = "point_count"; if (params > 0) { for(int n = 0; n < params; ++n) { param_names_rep += ",pos"; param_names_rep += kvu_numtostr(n + 1); param_names_rep += ",val"; param_names_rep += kvu_numtostr(n + 1); } } } std::string GENERIC_LINEAR_ENVELOPE::parameter_names(void) const { return param_names_rep; } void GENERIC_LINEAR_ENVELOPE::set_parameter(int param, parameter_t value) { switch(param) { case 1: set_param_count(static_cast(value)); pos_rep.resize(static_cast(value)); val_rep.resize(static_cast(value)); break; default: int pointnum = param/2 - 1; if (pointnum >= static_cast(pos_rep.size())) break; if (param % 2 == 0) pos_rep[pointnum] = value; else val_rep[pointnum] = value; } } CONTROLLER_SOURCE::parameter_t GENERIC_LINEAR_ENVELOPE::get_parameter(int param) const { switch(param) { case 1: return static_cast(pos_rep.size()); break; default: int pointnum = param/2 - 1; if (pointnum >= static_cast(pos_rep.size())) { return 0.0f; } if (param % 2 == 0) return pos_rep[pointnum]; else return val_rep[pointnum]; } } ecasound-2.9.1/libecasound/audioio-timidity.h0000644000076400007640000000403211141362373016201 00000000000000#ifndef INCLUDED_AUDIOIO_TIMIDITY_H #define INCLUDED_AUDIOIO_TIMIDITY_H #include #include #include "audioio-buffered.h" #include "audioio-forked-stream.h" /** * Interface to MIDI-to-audio converters that support * UNIX pipe i/o. By default, Timidity++ is used. * * @author Kai Vehmanen */ class TIMIDITY_INTERFACE : public AUDIO_IO_BUFFERED, public AUDIO_IO_FORKED_STREAM { private: static std::string default_timidity_cmd; public: static void set_timidity_cmd(const std::string& value); public: TIMIDITY_INTERFACE (const std::string& name = ""); virtual ~TIMIDITY_INTERFACE(void); virtual TIMIDITY_INTERFACE* clone(void) const { return new TIMIDITY_INTERFACE(*this); } virtual TIMIDITY_INTERFACE* new_expr(void) const { return new TIMIDITY_INTERFACE(); } virtual std::string name(void) const { return("MIDI-to-audio stream"); } virtual std::string description(void) const { return("Interface to MIDI-to-audio converters that support UNIX pipe i/o."); } virtual int supported_io_modes(void) const { return(io_read); } virtual bool supports_seeking(void) const { return(false); } virtual void open(void) throw (AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples) { } virtual bool finished(void) const { return(finished_rep); } virtual void start_io(void); virtual void stop_io(void); protected: /* functions called by AUDIO_IO_FORKED_STREAM that require * the use of AUDIO_IO methods */ virtual bool do_supports_seeking(void) const { return supports_seeking(); } virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { set_position_in_samples(pos); } private: bool triggered_rep; bool finished_rep; long int bytes_read_rep; int filedes_rep; FILE* f1_rep; TIMIDITY_INTERFACE& operator=(const TIMIDITY_INTERFACE& x) { return *this; } void fork_timidity(void); void kill_timidity(void); }; #endif ecasound-2.9.1/libecasound/audiofx_rcfilter.h0000644000076400007640000000325710664032032016252 00000000000000#ifndef _AUDIOFX_RC_LOWPASS_FILTER_H #define _AUDIOFX_RC_LOWPASS_FILTER_H #include #include #include "audiofx_filter.h" #include "samplebuffer_iterators.h" /** * Simulation of an 3rd-order 36dB active RC-lowpass * * 5th of February 2000 by Stefan Fendt * * This is a quite realistic simulation of an analouge * RC-lowpass as used in many old synthesisers. You can * increase filter-resonance up to the point were the * filter starts oscillating (without any signal aplied * to it...) and this without digital clipping. Knowing * that this was a design flaw (which had technical * reasons on real RC-filters) this was implemented in * this simulation, too. I do not know any other * filter-simulation which provides this. * * @author Stefan Fendt */ class EFFECT_RC_LOWPASS_FILTER : public EFFECT_FILTER { SAMPLE_ITERATOR_CHANNELS i; SAMPLE_SPECS::sample_t output_temp; std::vector lp1_old, lp2_old, lp3_old, hp1_old, feedback; parameter_t cutoff_rep; parameter_t resonance_rep; public: virtual std::string name(void) const { return("RC-lowpass filter"); } virtual std::string parameter_names(void) const { return("cutoff-freq,resonance"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_RC_LOWPASS_FILTER* clone(void) const { return new EFFECT_RC_LOWPASS_FILTER(*this); } EFFECT_RC_LOWPASS_FILTER* new_expr(void) const { return new EFFECT_RC_LOWPASS_FILTER(); } EFFECT_RC_LOWPASS_FILTER (parameter_t cutoff = 0.25, parameter_t resonance = 1.0); }; #endif ecasound-2.9.1/libecasound/audioio-seqbase.cpp0000644000076400007640000003744212260762753016347 00000000000000// ------------------------------------------------------------------------ // audioio-seqbase.cpp: Base class for audio sequencer objects // Copyright (C) 1999,2002,2005,2008-2010,2013 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include #include #include #include #include "eca-object-factory.h" #include "samplebuffer.h" #include "audioio-seqbase.h" #include "eca-error.h" #include "eca-logger.h" using std::cout; using std::endl; using SAMPLE_SPECS::sample_pos_t; /** * FIXME notes (last update 2008-03-04) * * - Add check for supports_sample_accurate_seek(). This could * be used to warn users if EWF source file cannot provide * accurate enough seeking (which will lead to unexpected * results). * - Remove write-support altogether (changes supported io_modes(), * modify write_buffer(), and remove child_write_started. * - Should extend the object length when looping is enabled. */ /** * Returns the child position in samples for the given * public position. */ sample_pos_t AUDIO_SEQUENCER_BASE::priv_public_to_child_pos(sample_pos_t pubpos) const { if (pubpos <= child_offset_rep.samples()) return child_start_pos_rep.samples(); if (child_looping_rep == true) { DBC_CHECK(child()->finite_length_stream() == true); sample_pos_t one_loop = child_length_rep.samples() - child_start_pos_rep.samples(); sample_pos_t res = pubpos - child_offset_rep.samples(); DBC_CHECK(res > 0); if (one_loop > 0) res = res % one_loop; return res + child_start_pos_rep.samples(); } else { /* not looping */ return pubpos - child_offset_rep.samples() + child_start_pos_rep.samples(); } } AUDIO_SEQUENCER_BASE::AUDIO_SEQUENCER_BASE (void) : child_looping_rep(false), child_length_set_by_client_rep(false), buffersize_rep(-1), child_write_started(false), init_rep(false) { } AUDIO_SEQUENCER_BASE::~AUDIO_SEQUENCER_BASE(void) { } AUDIO_SEQUENCER_BASE* AUDIO_SEQUENCER_BASE::clone(void) const { AUDIO_SEQUENCER_BASE* target = new AUDIO_SEQUENCER_BASE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIO_SEQUENCER_BASE::change_child_name(const string& child_name) throw(AUDIO_IO::SETUP_ERROR &) { AUDIO_IO* tmp = 0; if (child_name.size() > 0) tmp = ECA_OBJECT_FACTORY::create_audio_object(child_name); if (tmp == 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-SEQBASE: Could not create child object.")); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Creating audio sequencer file:" + tmp->label() + "."); set_child(tmp); init_rep = true; } void AUDIO_SEQUENCER_BASE::open(void) throw(AUDIO_IO::SETUP_ERROR &) { if (init_rep != true) change_child_name(child_object_str_rep); pre_child_open(); child()->open(); if (child()->finite_length_stream() != true && child_looping_rep) { child()->close(); throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-SEQBASE: Unable to loop an object with infinite length.")); } if (child()->supports_seeking_sample_accurate() != true && child_start_pos_rep.samples() > 0) { child()->close(); throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-SEQBASE: Unable use sections of an object that does not support seeking.")); } /* step: set srate for audio time variable */ child_offset_rep.set_samples_per_second_keeptime(child()->samples_per_second()); child_start_pos_rep.set_samples_per_second_keeptime(child()->samples_per_second()); child_length_rep.set_samples_per_second_keeptime(child()->samples_per_second()); post_child_open(); /* step: unless overridden by the client, store the length * of child object */ ECA_AUDIO_TIME len_tmp (child()->length_in_samples(), child()->samples_per_second()); if (child_length_set_by_client_rep != true) set_child_length_private(len_tmp); else if (len_tmp.valid() == true && child_length_rep.valid() == true) { if (len_tmp.seconds() < child_length_rep.seconds()) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: object \"" + child()->label() + "\" is too short, reducing segment length to '" + kvu_numtostr(len_tmp.seconds()) + "'sec."); } /* step: set public length of the EWF object; * child length is infinite, we will extend our object * length in read_buffer(), see also * AUDIO_SEQUENCER_BASE::finite_length_stream() */ if (child_looping_rep != true) set_length_in_samples(child_offset_rep.samples() + child_length_rep.samples()); //dump_child_debug("open"); tmp_buffer.number_of_channels(child()->channels()); tmp_buffer.length_in_samples(child()->buffersize()); AUDIO_IO_PROXY::open(); } void AUDIO_SEQUENCER_BASE::close(void) { if (child()->is_open() == true) child()->close(); AUDIO_IO_PROXY::close(); } void AUDIO_SEQUENCER_BASE::read_buffer(SAMPLE_BUFFER* sbuf) { /** * implementation notes: * * position: the current global position (note, this * can exceed child_offset+child_length when * looping is used. * child_offset: global position when child is activated * child_start_position: position inside the child-object where * input is started (data between child * beginning and child_start_pos is not used) * child_length: amount of child data between start and end * positions (end can in middle of stream or * at end-of-file position) * child_looping: when child end is reached, whether to jump * back to start position? * * note! all cases (if-else blocks) end to setting a new * position_in_samples value */ //dump_child_debug("read_buffer"); if (position_in_samples() + buffersize() <= child_offset_rep.samples()) { // --- // case 1: child not active yet // --- /* ensure that channel count matches that of child */ sbuf->number_of_channels(child()->channels()); sbuf->length_in_samples(buffersize()); sbuf->make_silent(); change_position_in_samples(buffersize()); //dump_child_debug("case1-out"); } else if (position_in_samples() < child_offset_rep.samples()) { // --- // case 2: next read will bring in the first child samples // --- DBC_CHECK(position_in_samples() + buffersize() > child_offset_rep.samples()); /* make sure child position is correct at start */ sample_pos_t chipos = priv_public_to_child_pos(position_in_samples()); if (chipos != child()->position_in_samples()) child()->seek_position_in_samples(chipos); sample_pos_t segment = position_in_samples() + buffersize() - child_offset_rep.samples(); if (segment > buffersize()) segment = buffersize(); // dump_child_debug("case2-in"); ECA_LOG_MSG(ECA_LOGGER::user_objects, "child-object \"" + child()->label() + "\" activated."); /* step: read segment of audio and copy it to the correct * location */ long int save_bsize = buffersize(); DBC_CHECK(save_bsize == buffersize()); child()->set_buffersize(segment); child()->read_buffer(&tmp_buffer); /* ensure that channel count matches that of child */ sbuf->number_of_channels(child()->channels()); sbuf->length_in_samples(buffersize()); sbuf->copy_range(tmp_buffer, 0, tmp_buffer.length_in_samples(), buffersize() - segment); child()->set_buffersize(save_bsize); change_position_in_samples(buffersize()); //dump_child_debug("case2-out"); } else { // --- // case 3: child is active // --- sample_pos_t chipos1 = priv_public_to_child_pos(position_in_samples()); sample_pos_t chipos2 = priv_public_to_child_pos(position_in_samples() + buffersize()); if (chipos2 >= (child_length_rep.samples() + child_start_pos_rep.samples()) && child_looping_rep != true && child()->finite_length_stream() == true) { // --- // case 3a: not looping, reaching child file end during the next read // --- /* note: max samples to included (assuming child object does * not reach end-of-stream */ sample_pos_t samples_to_include = (child_length_rep.samples() + child_start_pos_rep.samples()) - chipos1; //dump_child_debug("case3a-in"); child()->set_buffersize(buffersize()); child()->read_buffer(sbuf); /* resize the sbuf if needed: either EOF was encountered * and sbuf is shorter than buffersize() or otherwise we * need to drop some of the samples read so at to not * go beyond set length */ if (sbuf->length_in_samples() > samples_to_include) { sbuf->length_in_samples(samples_to_include); } change_position_in_samples(sbuf->length_in_samples()); //dump_child_debug("case3a-out"); } else if (chipos2 < chipos1 && child_looping_rep == true) { // --- // case 3b: looping, we will run out of data during read // --- //dump_child_debug("case3b-in"); child()->set_buffersize(buffersize()); child()->read_buffer(sbuf); sample_pos_t over_child_eof = chipos2 - child_start_pos_rep.samples(); /* step: copy segment 1 from loop end, and segment 2 from * loop start point */ sample_pos_t chistartpos = priv_public_to_child_pos(position_in_samples() + buffersize() - over_child_eof); DBC_CHECK(chistartpos == child_start_pos_rep.samples()); child()->seek_position_in_samples(chistartpos); if (over_child_eof > 0) { long int save_bsize = buffersize(); DBC_CHECK(save_bsize == buffersize()); child()->set_buffersize(over_child_eof); child()->read_buffer(&tmp_buffer); DBC_CHECK(tmp_buffer.length_in_samples() == over_child_eof); DBC_CHECK((buffersize() - over_child_eof) < buffersize()); sbuf->length_in_samples(buffersize()); sbuf->number_of_channels(channels()); sbuf->copy_range(tmp_buffer, 0, tmp_buffer.length_in_samples(), buffersize() - over_child_eof); child()->set_buffersize(save_bsize); } change_position_in_samples(buffersize()); //dump_child_debug("case3b-out"); } else { // --- // case 3c: normal case, read samples from child // --- child()->set_buffersize(buffersize()); child()->read_buffer(sbuf); /* note: if the 'length' parameter value is longer than * actual child object length, less than buffersize() * samples will be read */ change_position_in_samples(sbuf->length_in_samples()); //dump_child_debug("case3c-out"); } // dump_child_debug("case3-e"); } /* note: as we are looping indefinitely, so our length must * be continuously updated (see child_lengt() implementation) */ if (child_looping_rep == true || (child_length_set_by_client_rep != true && child()->finite_length_stream() != true)) extend_position(); DBC_ENSURE(channels() == child()->channels()); DBC_ENSURE(sbuf->number_of_channels() == channels()); DBC_ENSURE(sbuf->length_in_samples() <= buffersize()); } void AUDIO_SEQUENCER_BASE::dump_child_debug(const char *tag) { sample_pos_t chipos1 = priv_public_to_child_pos(position_in_samples()); cout << "TAG:" << tag << endl; cout << "global position (in samples): " << position_in_samples() << endl; cout << "child-pos: " << child()->position_in_samples() << endl; cout << "child-derived-pos: " << chipos1 << endl; cout << "child-offset: " << child_offset_rep.samples() << endl; cout << "child-startpos: " << child_start_pos_rep.samples() << endl; cout << "child-length: " << child_length_rep.samples() << endl; } void AUDIO_SEQUENCER_BASE::write_buffer(SAMPLE_BUFFER* sbuf) { if (child_write_started != true) { child_write_started = true; child_offset_rep.set_samples(position_in_samples()); MESSAGE_ITEM m; m << "found child_offset_rep " << child_offset_rep.seconds() << "."; ECA_LOG_MSG(ECA_LOGGER::user_objects, m.to_string()); } child()->write_buffer(sbuf); change_position_in_samples(sbuf->length_in_samples()); extend_position(); } SAMPLE_SPECS::sample_pos_t AUDIO_SEQUENCER_BASE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { /* in write mode, seek can be only performed once * the initial write has been performed to the child */ if (is_open() == true && (io_mode() == AUDIO_IO::io_read || (io_mode() != AUDIO_IO::io_read && child_write_started == true))) { sample_pos_t chipos = priv_public_to_child_pos(pos); child()->seek_position_in_samples(chipos); } return pos; } void AUDIO_SEQUENCER_BASE::set_child_object_string(const std::string& v) { child_object_str_rep = v; change_child_name(child_object_str_rep); } void AUDIO_SEQUENCER_BASE::set_child_offset(const ECA_AUDIO_TIME& v) { child_offset_rep = v; } void AUDIO_SEQUENCER_BASE::set_child_start_position(const ECA_AUDIO_TIME& v) { if (is_open() == true && child()->supports_seeking_sample_accurate() != true) { ECA_LOG_MSG(ECA_LOGGER::errors, "ERROR: object \"" + child()->label() + "\" does not support sample accurate seeking, unable to set start position."); return; } child_start_pos_rep = v; } void AUDIO_SEQUENCER_BASE::set_child_length_private(const ECA_AUDIO_TIME& v) { child_length_rep = v; } void AUDIO_SEQUENCER_BASE::set_child_length(const ECA_AUDIO_TIME& v) { set_child_length_private(v); child_length_set_by_client_rep = true; } ECA_AUDIO_TIME AUDIO_SEQUENCER_BASE::child_length(void) const { /* case: infinite child length */ if (child_length_set_by_client_rep != true && child()->finite_length_stream() != true) { ECA_AUDIO_TIME tmp; tmp.mark_as_invalid(); return tmp; } return child_length_rep; } bool AUDIO_SEQUENCER_BASE::finite_length_stream(void) const { if (child_looping_rep == true) return false; return child()->finite_length_stream(); } bool AUDIO_SEQUENCER_BASE::finished(void) const { /** * File is finished if... * 1) the child object is out of data (implies that looping * is disabled), or * 2) file is open in read mode, looping is disabled, child is * a finite length stream and its position has gone beyond * the requested child_length */ if (child()->finished()) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Child object " + child()->label() + " finished."); return true; } if (io_mode() != AUDIO_IO::io_read) { return false; } if (child_looping_rep != true && child()->finite_length_stream() == true && priv_public_to_child_pos(position_in_samples()) >= child_length_rep.samples() + child_start_pos_rep.samples()) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Finite length child object " + child()->label() + " finished. All samples from the requested range have been read."); return true; } return false; } ecasound-2.9.1/libecasound/audioio-db-server_impl.h0000644000076400007640000000164010664032032017254 00000000000000#ifndef INCLUDED_AUDIOIO_DB_SERVER_IMPL_H #define INCLUDED_AUDIOIO_DB_SERVER_IMPL_H #include #include class AUDIO_IO_DB_SERVER_impl { public: friend class AUDIO_IO_DB_SERVER; private: pthread_t io_thread_rep; pthread_cond_t client_cond_rep; pthread_mutex_t client_mutex_rep; pthread_cond_t data_cond_rep; pthread_mutex_t data_mutex_rep; pthread_cond_t full_cond_rep; pthread_mutex_t full_mutex_rep; pthread_cond_t stop_cond_rep; pthread_mutex_t stop_mutex_rep; pthread_cond_t flush_cond_rep; pthread_mutex_t flush_mutex_rep; size_t profile_full_rep; size_t profile_no_processing_rep; size_t profile_not_full_anymore_rep; size_t profile_processing_rep; size_t profile_read_xrun_danger_rep; size_t profile_write_xrun_danger_rep; size_t profile_rounds_total_rep; PROCEDURE_TIMER looptimer_rep; }; #endif /* INCLUDED_AUDIOIO_DB_SERVER_IMPL_H */ ecasound-2.9.1/libecasound/audioio-db-server.cpp0000644000076400007640000004364111562466671016617 00000000000000// ------------------------------------------------------------------------ // audioio-db-server.cpp: Audio i/o engine serving db clients. // Copyright (C) 2000-2005,2009,2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include /* ETIMEDOUT */ #include #include #include #include /* gettimeofday() */ #include #include #include #include "sample-specs.h" #include "samplebuffer.h" #include "eca-logger.h" #include "audioio-db-server.h" #include "audioio-db-server_impl.h" // -- // Select features // #define DB_PROFILING // -- // Macro definitions #ifdef DB_PROFILING #define DB_PROFILING_INC(x) ++(x) #define DB_PROFILING_STATEMENT(x) x #else #define DB_PROFILING_INC(x) (void)0 #define DB_PROFILING_STATEMENT(x) (void)0 #endif // -- // Initialization of static member functions const int AUDIO_IO_DB_SERVER::buffercount_default = 32; const long int AUDIO_IO_DB_SERVER::buffersize_default = 1024; // -- // Initialization of static, global functions static int timed_wait(pthread_mutex_t* mutex, pthread_cond_t* cond, long int usecs); static void timed_wait_print_result(int result, const char* tag, bool verbose); /** * Helper function for starting the slave thread. */ void* start_db_server_io_thread(void *ptr) { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigprocmask(SIG_BLOCK, &sigset, 0); AUDIO_IO_DB_SERVER* pserver = static_cast(ptr); pserver->io_thread(); return 0; } /** * Constructor. */ AUDIO_IO_DB_SERVER::AUDIO_IO_DB_SERVER (void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "constructor"); buffercount_rep = buffercount_default; buffersize_rep = buffersize_default; impl_repp = new AUDIO_IO_DB_SERVER_impl; thread_running_rep = false; pthread_cond_init(&impl_repp->client_cond_rep, NULL); pthread_mutex_init(&impl_repp->client_mutex_rep, NULL); pthread_cond_init(&impl_repp->data_cond_rep, NULL); pthread_mutex_init(&impl_repp->data_mutex_rep, NULL); pthread_cond_init(&impl_repp->full_cond_rep, NULL); pthread_mutex_init(&impl_repp->full_mutex_rep, NULL); pthread_cond_init(&impl_repp->stop_cond_rep, NULL); pthread_mutex_init(&impl_repp->stop_mutex_rep, NULL); pthread_cond_init(&impl_repp->flush_cond_rep, NULL); pthread_mutex_init(&impl_repp->flush_mutex_rep, NULL); running_rep.set(0); full_rep.set(0); stop_request_rep.set(0); exit_request_rep.set(0); exit_ok_rep.set(0); impl_repp->profile_full_rep = 0; impl_repp->profile_no_processing_rep = 0; impl_repp->profile_not_full_anymore_rep = 0; impl_repp->profile_processing_rep = 0; impl_repp->profile_read_xrun_danger_rep = 0; impl_repp->profile_write_xrun_danger_rep = 0; impl_repp->profile_rounds_total_rep = 0; } /** * Destructor. Doesn't delete any client objects. */ AUDIO_IO_DB_SERVER::~AUDIO_IO_DB_SERVER(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "destructor"); stop_request_rep.set(1); exit_request_rep.set(1); exit_ok_rep.set(0); if (thread_running_rep == true) { pthread_join(impl_repp->io_thread_rep, 0); } for(unsigned int p = 0; p < buffers_rep.size(); p++) { delete buffers_rep[p]; } delete impl_repp; DB_PROFILING_STATEMENT(dump_profile_counters()); ECA_LOG_MSG(ECA_LOGGER::system_objects, "destructor-out"); } /** * Starts the db server. * * @pre is_running() != true */ void AUDIO_IO_DB_SERVER::start(void) { // -- DBC_REQUIRE(is_running() != true); // -- ECA_LOG_MSG(ECA_LOGGER::system_objects, "start"); if (thread_running_rep != true) { int ret = pthread_create(&impl_repp->io_thread_rep, 0, start_db_server_io_thread, static_cast(this)); if (ret != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "pthread_create failed, exiting"); exit(1); } thread_running_rep = true; } stop_request_rep.set(0); running_rep.set(1); ECA_LOG_MSG(ECA_LOGGER::system_objects, "starting processing"); } /** * Stops the db server. */ void AUDIO_IO_DB_SERVER::stop(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "stop requested"); stop_request_rep.set(1); } /** * Whether the db server has been started? */ bool AUDIO_IO_DB_SERVER::is_running(void) const { if (running_rep.get() == 0) return false; return true; } /** * Whether the db server buffers are full? */ bool AUDIO_IO_DB_SERVER::is_full(void) const { if (full_rep.get() == 0) return false; return true; } /** * Waits for condition to occur. * * @return 0 on success, * -ETIMEDOUT if timeout occured, * other nonzero value on other errors */ static int timed_wait(pthread_mutex_t* mutex, pthread_cond_t* cond, long int msecs) { struct timeval now; gettimeofday(&now, 0); struct timespec sleepcount; sleepcount.tv_nsec = now.tv_usec * 1000 + (msecs % 1000) * 1000000; sleepcount.tv_sec = now.tv_sec + msecs / 1000; if (sleepcount.tv_nsec > 1000000000) { sleepcount.tv_sec++; sleepcount.tv_nsec -= 1000000000; } int ret = 0; pthread_mutex_lock(mutex); ret = pthread_cond_timedwait(cond, mutex, &sleepcount); pthread_mutex_unlock(mutex); return ret; } /** * Prints debug information based on the result * of timed_wait() call. */ static void timed_wait_print_result(int result, const char* tag, bool verbose) { ECA_LOGGER::Msg_level_t level = ECA_LOGGER::info; if (verbose != true) level = ECA_LOGGER::continuous; if (result != 0) { if (result == -ETIMEDOUT) ECA_LOG_MSG(level, std::string(tag) + " failed; timeout"); else ECA_LOG_MSG(level, std::string(tag) + " failed"); } } /** * Signals the server that one of its client has * processed data from the db buffers. This * function helps server to keep its buffers * full without resorting to polling. * * Called by both db clients and the db server. */ void AUDIO_IO_DB_SERVER::signal_client_activity(void) { pthread_mutex_lock(&impl_repp->client_mutex_rep); pthread_cond_broadcast(&impl_repp->client_cond_rep); pthread_mutex_unlock(&impl_repp->client_mutex_rep); } /** * Function that blocks until some client * activity occurs. * * Only called by db server. * * @see signal_client_activity() * * @pre is_running() != true */ void AUDIO_IO_DB_SERVER::wait_for_client_activity(void) { // -- DBC_REQUIRE(is_running() == true); // -- /* note! we only wait for 100msec in case no clients * clients signal activity but there's still * room for new data */ int res = timed_wait(&impl_repp->client_mutex_rep, &impl_repp->client_cond_rep, 100); timed_wait_print_result(res, "wait_for_client_activity", false); } /** * Function that blocks until the server signals * that all its buffers are full. */ void AUDIO_IO_DB_SERVER::wait_for_full(void) { if (is_running() == true && clients_rep.size() > 0) { /* note! we wait until we get a signal_full() even though * full_rep could already be set */ int res = timed_wait(&impl_repp->full_mutex_rep, &impl_repp->full_cond_rep, 5000); timed_wait_print_result(res, "wait_for_full", true); } else { ECA_LOG_MSG(ECA_LOGGER::system_objects, "wait_for_full failed; not running"); } } /** * Function that blocks until the server signals * that it has stopped. */ void AUDIO_IO_DB_SERVER::wait_for_stop(void) { if (is_running() == true) { int res = timed_wait(&impl_repp->stop_mutex_rep, &impl_repp->stop_cond_rep, 5000); timed_wait_print_result(res, "wait_for_stop", true); } } /** * Function that blocks until the server signals * that it has flushed all buffers (after * exit request). */ void AUDIO_IO_DB_SERVER::wait_for_flush(void) { if (is_running() == true) { if (exit_ok_rep.get() == 0) { signal_client_activity(); int res = timed_wait(&impl_repp->flush_mutex_rep, &impl_repp->flush_cond_rep, 5000); timed_wait_print_result(res, "wait_for_flush", true); } } else { ECA_LOG_MSG(ECA_LOGGER::system_objects, "wait_for_flush failed; not running"); } } /** * Sends a signal notifying that server buffers * are fulls. * * Called by db server. */ void AUDIO_IO_DB_SERVER::signal_full(void) { pthread_mutex_lock(&impl_repp->full_mutex_rep); pthread_cond_broadcast(&impl_repp->full_cond_rep); pthread_mutex_unlock(&impl_repp->full_mutex_rep); } /** * Sends a signal notifying that server has * stopped. * * Called by db server. */ void AUDIO_IO_DB_SERVER::signal_stop(void) { pthread_mutex_lock(&impl_repp->stop_mutex_rep); pthread_cond_broadcast(&impl_repp->stop_cond_rep); pthread_mutex_unlock(&impl_repp->stop_mutex_rep); } /** * Sends a signal notifying that server has * flushed all buffers (after an exit request). * * Called by db server. */ void AUDIO_IO_DB_SERVER::signal_flush(void) { pthread_mutex_lock(&impl_repp->flush_mutex_rep); pthread_cond_broadcast(&impl_repp->flush_cond_rep); pthread_mutex_unlock(&impl_repp->flush_mutex_rep); } /** * Sets new default values for sample buffers. * * @pre is_running() != true */ void AUDIO_IO_DB_SERVER::set_buffer_defaults(int buffers, long int buffersize) { // -- DBC_REQUIRE(is_running() != true); // -- buffercount_rep = buffers; buffersize_rep = buffersize; } /** * Registers a new client object. * * @pre aobject != 0 * @pre is_running() != true */ void AUDIO_IO_DB_SERVER::register_client(AUDIO_IO* aobject) { // -- DBC_REQUIRE(aobject != 0); DBC_REQUIRE(is_running() != true); // -- clients_rep.push_back(aobject); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Registering client " + kvu_numtostr(clients_rep.size() - 1) + ". Buffer count " + kvu_numtostr(buffercount_rep) + "."); buffers_rep.push_back(new AUDIO_IO_DB_BUFFER(buffercount_rep, buffersize_rep, aobject->channels())); client_map_rep[aobject] = clients_rep.size() - 1; } /** * Unregisters the client object given as the argument. No * resources are freed during this call. * */ void AUDIO_IO_DB_SERVER::unregister_client(AUDIO_IO* aobject) { // -- DBC_REQUIRE(is_running() != true); // -- ECA_LOG_MSG(ECA_LOGGER::system_objects, "unregister_client " + aobject->name() + "."); if (client_map_rep.find(aobject) != client_map_rep.end()) { size_t index = client_map_rep[aobject]; if (index >= 0 && index < clients_rep.size()) { clients_rep[index] = 0; delete buffers_rep[index]; buffers_rep[index] = 0; } else ECA_LOG_MSG(ECA_LOGGER::system_objects, "unregister_client failed (1)"); } else ECA_LOG_MSG(ECA_LOGGER::system_objects, "unregister_client failed (2)"); } /** * Gets a pointer to the client buffer belonging to * the audio object given as parameter. If no * buffers are found (client not registered, etc), * null is returned. */ AUDIO_IO_DB_BUFFER* AUDIO_IO_DB_SERVER::get_client_buffer(AUDIO_IO* aobject) { if (client_map_rep.find(aobject) == client_map_rep.end() || clients_rep[client_map_rep[aobject]] == 0) return 0; return buffers_rep[client_map_rep[aobject]]; } /** * Slave thread. */ void AUDIO_IO_DB_SERVER::io_thread(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Hey, in the I/O loop!"); int processed = 0; int passive_rounds = 0; DB_PROFILING_STATEMENT(bool one_time_full = false); /* set idle timeout to ~10% of total buffersize (using 44.1Hz as a reference) */ long int sleeplen = buffersize_rep * buffercount_rep * 1000 / 44100 / 10 * 1000000; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Using idle timeout of " + kvu_numtostr(sleeplen) + " nsecs."); while(true) { if (running_rep.get() == 0) { kvu_sleep(0, sleeplen); if (exit_request_rep.get() == 1) break; continue; } DB_PROFILING_INC(impl_repp->profile_rounds_total_rep); processed = 0; int min_free_space = buffercount_rep; DB_PROFILING_STATEMENT(impl_repp->looptimer_rep.start()); for(unsigned int p = 0; p < clients_rep.size(); p++) { if (clients_rep[p] == 0 || buffers_rep[p]->finished_rep.get()) { continue; } else if (clients_rep[p]->finished() == true) { buffers_rep[p]->finished_rep.set(1); } int free_space = 0; if (buffers_rep[p]->io_mode_rep == AUDIO_IO::io_read) { free_space = buffers_rep[p]->write_space(); if (free_space > 0) { /* room available, so we can read at least one buffer of data */ if (clients_rep[p]->finished() != true) { clients_rep[p]->read_buffer(buffers_rep[p]->sbufs_rep[buffers_rep[p]->writeptr_rep.get()]); if (clients_rep[p]->finished() == true) buffers_rep[p]->finished_rep.set(1); buffers_rep[p]->advance_write_pointer(); ++processed; } #ifdef DB_PROFILING if (buffers_rep[p]->write_space() > 16 && one_time_full == true) { DB_PROFILING_INC(impl_repp->profile_read_xrun_danger_rep); } #endif } } else { free_space = buffers_rep[p]->read_space(); if (free_space > 0) { /* room available, so we can write at least one buffer of data */ if (clients_rep[p]->finished() != true) { clients_rep[p]->write_buffer(buffers_rep[p]->sbufs_rep[buffers_rep[p]->readptr_rep.get()]); if (clients_rep[p]->finished() == true) buffers_rep[p]->finished_rep.set(1); buffers_rep[p]->advance_read_pointer(); ++processed; } #ifdef DB_PROFILING if (buffers_rep[p]->read_space() < 16 && one_time_full == true) { DB_PROFILING_INC(impl_repp->profile_write_xrun_danger_rep); } #endif } } if (free_space < min_free_space) min_free_space = free_space; } DB_PROFILING_STATEMENT(impl_repp->looptimer_rep.stop()); if (stop_request_rep.get() == 1) { stop_request_rep.set(0); running_rep.set(0); full_rep.set(0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "stop complete"); signal_stop(); } else { if (processed == 0) passive_rounds++; else passive_rounds = 0; if (processed == 0) { if (passive_rounds > 1) { /* case 1: nothing processed during the last two rounds ==> signal_full, wait_for_client_activity */ DB_PROFILING_INC(impl_repp->profile_full_rep); full_rep.set(1); DB_PROFILING_STATEMENT(if (one_time_full != true) one_time_full = true); signal_full(); DBC_CHECK(running_rep.get() == 1); } else { /* case 2: nothing processed during the last round ==> wait_for_client_activity */ DB_PROFILING_INC(impl_repp->profile_no_processing_rep); } wait_for_client_activity(); } else { /* case 3: something processed; business as usual */ DB_PROFILING_INC(impl_repp->profile_processing_rep); } /* case X: something processed; room in the buffers ==> data available */ // DB_PROFILING_INC(impl_repp->profile_not_full_anymore_rep); } } flush(); exit_ok_rep.set(1); // std::cerr << "Exiting db server thread." << std::endl; } void AUDIO_IO_DB_SERVER::dump_profile_counters(void) { std::cerr << "(audioio-db-server) *** profile begin ***" << std::endl; std::cerr << "Profile_full_rep: " << impl_repp->profile_full_rep << std::endl; std::cerr << "Profile_no_processing_rep: " << impl_repp->profile_no_processing_rep << std::endl; std::cerr << "Profile_not_full_anymore_rep: " << impl_repp->profile_not_full_anymore_rep << std::endl; std::cerr << "Profile_processing_rep: " << impl_repp->profile_processing_rep << std::endl; std::cerr << "Profile_read_xrun_danger_rep: " << impl_repp->profile_read_xrun_danger_rep << std::endl; std::cerr << "Profile_write_xrun_danger_rep: " << impl_repp->profile_write_xrun_danger_rep << std::endl; std::cerr << "Profile_rounds_total_rep: " << impl_repp->profile_rounds_total_rep << std::endl; std::cerr << "Fastest/slowest/average loop time: "; std::cerr << kvu_numtostr(impl_repp->looptimer_rep.min_duration_seconds() * 1000, 1); std::cerr << "/"; std::cerr << kvu_numtostr(impl_repp->looptimer_rep.max_duration_seconds() * 1000, 1); std::cerr << "/"; std::cerr << kvu_numtostr(impl_repp->looptimer_rep.average_duration_seconds() * 1000, 1); std::cerr << " msec." << std::endl; std::cerr << "(audioio-db-server) *** profile end ***" << std::endl; } /** * Flushes all data in the buffers to disk. */ void AUDIO_IO_DB_SERVER::flush(void) { int not_finished = 1; while(not_finished != 0) { not_finished = 0; for(unsigned int p = 0; p < clients_rep.size(); p++) { if (clients_rep[p] == 0 || buffers_rep[p]->finished_rep.get()) continue; if (buffers_rep[p]->io_mode_rep != AUDIO_IO::io_read) { if (buffers_rep[p]->read_space() > 0) { ++not_finished; ECA_LOG_MSG(ECA_LOGGER::info, "Flushing buffer " + kvu_numtostr(buffers_rep[p]->readptr_rep.get()) + " of client " + kvu_numtostr(p) + " read_space: " + kvu_numtostr(buffers_rep[p]->read_space()) + "."); clients_rep[p]->write_buffer(buffers_rep[p]->sbufs_rep[buffers_rep[p]->readptr_rep.get()]); if (clients_rep[p]->finished() == true) buffers_rep[p]->finished_rep.set(1); buffers_rep[p]->advance_read_pointer(); } } } } for(unsigned int p = 0; p < buffers_rep.size(); p++) { if (buffers_rep[p] != 0) { buffers_rep[p]->reset(); } } signal_flush(); } ecasound-2.9.1/libecasound/osc-sine.cpp0000644000076400007640000000502611744616230015000 00000000000000// ------------------------------------------------------------------------ // osc-sine.cpp: Sine oscillator // Copyright (C) 1999,2001,2008,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // This program is fre 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 #include #include #include "oscillator.h" #include "osc-sine.h" #include "eca-logger.h" CONTROLLER_SOURCE::parameter_t SINE_OSCILLATOR::value(double pos_secs) { parameter_t retval, phase; if (period_len_rep == 0) return 1.0; phase = 2.0 * M_PI * (pos_secs / period_len_rep); retval = sin(phase + phase_offset()); /* note: scale return value to proper [0,1] range */ retval += 1.0; retval /= 2.0; return retval; } SINE_OSCILLATOR::SINE_OSCILLATOR (double freq, double initial_phase) : OSCILLATOR(freq, initial_phase) { set_parameter(1, get_parameter(1)); set_parameter(2, get_parameter(2)); } void SINE_OSCILLATOR::init(void) { MESSAGE_ITEM otemp; otemp << "Sine oscillator created; frequency "; otemp.setprecision(3); otemp << frequency(); otemp << " and initial phase of "; otemp << phase_offset() << "."; ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } void SINE_OSCILLATOR::set_parameter(int param, CONTROLLER_SOURCE::parameter_t v) { switch (param) { case 1: frequency(v); /* note: cache length of one period in seconds */ if (frequency() > 0) period_len_rep = 1.0 / frequency(); else period_len_rep = 0; break; case 2: phase_offset(static_cast(v * M_PI)); break; } } CONTROLLER_SOURCE::parameter_t SINE_OSCILLATOR::get_parameter(int param) const { switch (param) { case 1: return frequency(); case 2: return phase_offset() / M_PI; } return 0.0; } ecasound-2.9.1/libecasound/audiogate.cpp0000644000076400007640000001523311432774076015232 00000000000000// ------------------------------------------------------------------------ // audiogate.cpp: Signal gates. // Copyright (C) 1999-2002,2005-2008,2010 Kai Vehmanen // Copyrtigh (C) 2008 Andrew Lees // // Attributes: // eca-style-version: 3 // // 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 #include "samplebuffer.h" #include "samplebuffer_functions.h" #include "audiogate.h" #include "eca-logger.h" GATE_BASE::~GATE_BASE(void) { } void GATE_BASE::process(void) { analyze(target); if (is_open() == false) { target->length_in_samples(0); } } void GATE_BASE::init(SAMPLE_BUFFER* sbuf) { gate_open = false; target = sbuf; } void TIME_CROP_GATE::analyze(SAMPLE_BUFFER* sbuf) { parameter_t etime = begtime_rep + durtime_rep; parameter_t curtime = static_cast(position_in_samples_rep) / samples_per_second(); if (curtime >= begtime_rep) { /* note: handle the special case where a zero open time * has been requested */ if (begtime_rep == etime) open_gate(); else if (curtime < etime) open_gate(); else close_gate(); } else close_gate(); position_in_samples_rep += sbuf->length_in_samples(); } TIME_CROP_GATE::TIME_CROP_GATE (CHAIN_OPERATOR::parameter_t open_at, CHAIN_OPERATOR::parameter_t duration) { begtime_rep = open_at; durtime_rep = duration; position_in_samples_rep = 0; ECA_LOG_MSG(ECA_LOGGER::info, "Time crop gate created; opens at " + kvu_numtostr(begtime_rep) + " seconds and stays open for " + kvu_numtostr(durtime_rep) + " seconds.\n"); } CHAIN_OPERATOR::parameter_t TIME_CROP_GATE::get_parameter(int param) const { switch (param) { case 1: return begtime_rep; case 2: return durtime_rep; } return 0.0; } void TIME_CROP_GATE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: begtime_rep = value; position_in_samples_rep = 0; break; case 2: durtime_rep = value; break; } } void TIME_CROP_GATE::set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value) { double ratio (new_value); ratio /= samples_per_second(); /* note: as we store position as samples, changes in sampling rate * require recalculation of position */ position_in_samples_rep = static_cast(position_in_samples_rep * ratio); ECA_SAMPLERATE_AWARE::set_samples_per_second(new_value); } THRESHOLD_GATE::THRESHOLD_GATE (CHAIN_OPERATOR::parameter_t threshold_openlevel, CHAIN_OPERATOR::parameter_t threshold_closelevel, bool use_rms) { openlevel_rep = threshold_openlevel / 100.0; closelevel_rep = threshold_closelevel / 100.0; rms_rep = use_rms; reopen_count_param_rep = 0; is_opened_rep = is_closed_rep = false; if (rms_rep) { ECA_LOG_MSG(ECA_LOGGER::info, "Threshold gate created; open threshold " + kvu_numtostr(openlevel_rep * 100) + "%, close threshold " + kvu_numtostr(closelevel_rep * 100) + "%, using RMS volume."); } else { ECA_LOG_MSG(ECA_LOGGER::info, "Threshold gate created; open threshold " + kvu_numtostr(openlevel_rep * 100) + "%, close threshold " + kvu_numtostr(closelevel_rep * 100) + "%, using peak volume."); } } void THRESHOLD_GATE::init(SAMPLE_BUFFER* sbuf) { reopens_left_rep = reopen_count_param_rep; is_opened_rep = false; is_closed_rep = false; GATE_BASE::init(sbuf); } void THRESHOLD_GATE::analyze(SAMPLE_BUFFER* sbuf) { if (rms_rep == true) avolume_rep = SAMPLE_BUFFER_FUNCTIONS::RMS_volume(*sbuf) / SAMPLE_SPECS::max_amplitude; else avolume_rep = SAMPLE_BUFFER_FUNCTIONS::average_amplitude(*sbuf) / SAMPLE_SPECS::max_amplitude; if (is_opened_rep == false) { if (avolume_rep > openlevel_rep) { open_gate(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Threshold gate opened (reopen count = " + kvu_numtostr(reopens_left_rep) + ")"); is_opened_rep = true; is_closed_rep = false; } } else if (is_closed_rep == false) { if (avolume_rep < closelevel_rep) { close_gate(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Threshold gate closed (reopens left = " + kvu_numtostr(reopens_left_rep) + ")"); is_closed_rep = true; if (reopens_left_rep != 0) { is_opened_rep = false; if (reopens_left_rep > 0) --reopens_left_rep; } else { // - Could we stop the engine and exit here, maybe? -AL/2008-Jul // - Not from a chain operator, but the audio object // that writes the stream to a file could in // theory react in a special way to the 0-length // samplebuffers we generate when the gate is closed... -KV/2008-Jul } } } } CHAIN_OPERATOR::parameter_t THRESHOLD_GATE::get_parameter(int param) const { switch (param) { case 1: return openlevel_rep * 100.0; case 2: return closelevel_rep * 100.0; case 3: if (rms_rep) return 1.0; else return 0.0; case 4: return reopen_count_param_rep; } return 0.0; } void THRESHOLD_GATE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: openlevel_rep = value / 100.0; break; case 2: closelevel_rep = value / 100.0; break; case 3: rms_rep = (value != 0); break; case 4: reopen_count_param_rep = static_cast(value); break; } } void MANUAL_GATE::analyze(SAMPLE_BUFFER* sbuf) { if (is_open() == true && open_rep != true) { close_gate(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Manual gate closed"); } else if (is_open() != true && open_rep == true) { open_gate(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Manual gate opened"); } } CHAIN_OPERATOR::parameter_t MANUAL_GATE::get_parameter(int param) const { switch (param) { case 1: return open_rep == true ? 1 : 0; } return 0.0; } void MANUAL_GATE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: if (value > 0) open_rep = true; else open_rep = false; break; } } ecasound-2.9.1/libecasound/audioio-device.cpp0000644000076400007640000000443312260762753016155 00000000000000// ------------------------------------------------------------------------ // audioio-device.cpp: Virtual base class for real-time devices. // Copyright (C) 1999-2001,2010,2013 Kai Vehmanen // // 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 #include #include "audioio-device.h" #include "samplebuffer.h" AUDIO_IO_DEVICE::AUDIO_IO_DEVICE(void) : is_running_rep(false), is_prepared_rep(false), ignore_xruns_rep(true), max_buffers_rep(true) { } AUDIO_IO_DEVICE::~AUDIO_IO_DEVICE(void) { if (is_open() == true) close(); DBC_CHECK(is_running() != true); } bool AUDIO_IO_DEVICE::is_realtime_object(const AUDIO_IO* aobj) { const AUDIO_IO_DEVICE* p = dynamic_cast(aobj); if (p != 0) return(true); return(false); } string AUDIO_IO_DEVICE::status(void) const { MESSAGE_ITEM mitem; mitem << "realtime-device; position "; mitem << position_in_samples() << ", delay "; mitem << delay() << ".\n -> "; if (is_open() == true) mitem << "open, "; else mitem << "closed, "; mitem << format_string() << "/" << channels() << "ch/" << samples_per_second(); mitem << "Hz, buffer " << buffersize() << "."; return(mitem.to_string()); } void AUDIO_IO_DEVICE::write_buffer(SAMPLE_BUFFER* sbuf) { long int payload = sbuf->length_in_samples(); if (payload != buffersize()) { // Always pad write to full buffersize(). SAMPLE_BUFFER // will ensure the added samples are muted. sbuf->length_in_samples(buffersize()); } AUDIO_IO_BUFFERED::write_buffer(sbuf); } ecasound-2.9.1/libecasound/audioio-typeselect.cpp0000644000076400007640000000756211143422610017065 00000000000000// ------------------------------------------------------------------------ // audioio-typeselect.cpp: A proxy class for overriding default keyword // and filename associations. // Copyright (C) 2001,2002,2008,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 "eca-logger.h" #include "eca-object-factory.h" #include "audioio-null.h" #include "audioio-typeselect.h" /** * Constructor. */ AUDIO_IO_TYPESELECT::AUDIO_IO_TYPESELECT (void) { // ECA_LOG_MSG(ECA_LOGGER::user_objects, "constructor " + label() + "."); init_rep = false; } /** * Destructor. */ AUDIO_IO_TYPESELECT::~AUDIO_IO_TYPESELECT (void) { // ECA_LOG_MSG(ECA_LOGGER::user_objects, "destructor " + label() + "."); } AUDIO_IO_TYPESELECT* AUDIO_IO_TYPESELECT::clone(void) const { AUDIO_IO_TYPESELECT* target = new AUDIO_IO_TYPESELECT(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIO_IO_TYPESELECT::open(void) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "open " + label() + "."); if (init_rep != true) { AUDIO_IO* tmp = 0; const string& objname = child_params_as_string(2, ¶ms_rep); tmp = ECA_OBJECT_FACTORY::create_audio_object(objname); if (tmp == 0) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-TYPESELECT: unable to open child object '" + objname + "'")); set_child(tmp); int numparams = child()->number_of_params(); for(int n = 0; n < numparams; n++) { child()->set_parameter(n + 1, get_parameter(n + 3)); if (child()->variable_params()) numparams = child()->number_of_params(); } init_rep = true; /* must be set after dyn. parameters */ } pre_child_open(); child()->open(); post_child_open(); /* if child changed the format during open; * fetch the changes */ if (child()->locked_audio_format() == true) { set_audio_format(child()->audio_format()); } set_label(child()->label()); set_length_in_samples(child()->length_in_samples()); AUDIO_IO_PROXY::open(); } void AUDIO_IO_TYPESELECT::close(void) { if (child()->is_open() == true) child()->close(); AUDIO_IO_PROXY::close(); } string AUDIO_IO_TYPESELECT::parameter_names(void) const { return string("typeselect,format,") + child()->parameter_names(); } void AUDIO_IO_TYPESELECT::set_parameter(int param, string value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "set_parameter " + label() + "."); if (param > static_cast(params_rep.size())) params_rep.resize(param); if (param > 0) { params_rep[param - 1] = value; } if (param > 2 && init_rep == true) { child()->set_parameter(param - 2, value); } } string AUDIO_IO_TYPESELECT::get_parameter(int param) const { ECA_LOG_MSG(ECA_LOGGER::user_objects, "get_parameter " + label() + "."); if (param > 0 && param < static_cast(params_rep.size()) + 1) { if (param > 2 && init_rep == true) { params_rep[param - 1] = child()->get_parameter(param - 2); } return params_rep[param - 1]; } return ""; } ecasound-2.9.1/libecasound/ChangeLog0000644000076400007640000014771411762640642014345 000000000000002012-06-03 Kai Vehmanen * library interface version 24:0:0 frozen (2.9.0 release) 2012-04-14 Kai Vehmanen * modifications to classes, ABI change * library interface version to 24:0:0 2012-04-13 Kai Vehmanen ============================================================= NOTE: as ecasound has full git/VCS history, tracking of added/removed functions will be stopped in this file and in the future it is only recorded when the library API has changed (details will be in git) ============================================================= 2012-04-09 Kai Vehmanen * eca-engine.h (ECA_ENGINE): added is_started() * eca-control-main.h (ECA_CONTROL_MAIN): added is_started() * library interface version to 24:0:1 2011-05-11 Kai Vehmanen * library interface version 23:0:0 frozen (2.8.0 release) 2011-05-04 Kai Vehmanen * eca-engine.h (Engine_command): added 'ep_stop_with_drain' 2011-05-02 Kai Vehmanen * audioio-device.h (stop): add drain parameter * library interface version to 23:0:0 2009-10-17 Kai Vehmanen * library interface version 22:0:0 frozen (2.7.0 release) 2009-10-04 Kai Vehmanen * samplebuffer_functions.h (is_almost_equal): Added parameters. New signature still source-compatible with the old one. 2009-04-18 Kai Vehmanen * eca-control-base.h: File removed, ECA_CONTROL_BASE combined into ECA_CONTROL and defined in eca-control.h. * eca-control-objects.h: File removed, ECA_CONTROL_OBJECTS combined into ECA_CONTROL and defined in eca-control.h. * eca-control-main.h: File added. A new abstract interface class defining a minimal public interface to ECA_CONTROL. * eca-control-mt.h: File added. * eca-control.h: Updated signature for command() and command_float_arg(). * eca-control.h: Moved various members functions, not part of the functionality set defined by ECA_CONTROL_MAIN, to private visibility scope. 2009-04-13 Kai Vehmanen * eca-chainsetup.h: Added get_chain_index(). * eca-control-objects.h: get_connected_chainsetup() added. * eca-chain.h: New signature for set_parameter(). * eca-engine.h: Added new type ECA_ENGINE::complex_command_t and new enum type ECA_ENGINE::ep_exec_edit. Removed enum types ECA_ENGINE::ep_ctrl_* and ECA_ENGINE::ep_cop_*. 2009-04-12 Kai Vehmanen * eca-chain.h: Added member function number_of_chain_operator_parameters(). * eca-osc.h: File added. 2009-04-10 Kai Vehmanen * audiofx_amplitude.h: Added EFFECT_AMPLIFY::process_ref(), EFFECT_AMPLIFY_DB::process_ref(), EFFECT_AMPLIFY_CHANNEL::process_ref() and EFFECT_NORMAL_PAN::process_ref(). * samplebuffer_functions.h: Added fill_with_random_samples(), is_almost_equal(). 2009-04-04 Kai Vehmanen * samplebuffer.h: Added member functions multiply_by() (two overloaded versions). * samplebuffer.h: Added unoptimized member funcs make_silent_range_ref(), add_matching_channels_ref(), multiply_by_ref(), divide_by_ref(), make_silent_ref(), limit_values_ref(). 2009-03-28 Kai Vehmanen * samplebuffer.h: Added overloaded make_silent(int channel). 2009-03-24 Kai Vehmanen * eca-control-base.cpp: Removed is_engine_started() and replaced it with is_engine_created() that has slightly different semantics. * eca-control-base.h: Added is_engine_running(). 2009-03-23 Kai Vehmanen * samplebuffer.h: copy_range() now requires the object channel counts to match. 2009-03-22 Kai Vehmanen * samplebuffer.h: Renamed copy() member function into copy_matching_channels() to more accurately describe the semantics. * samplebuffer.h: Renamed add() into add_matching_channels(). * samplebuffer.h: Added copy_all_content(). * samplebuffer.h: Added event_tag_set(), event_tag_test(), event_tags_set(), event_tags_add() and event_tags_clear() member functions. Added new Tag_name enum type. * library interface version to 22:0:0 2009-03-21 Kai Vehmanen * samplebuffer_iterators.h: Added optional second argument to SAMPLE_ITERATOR_CHANNEL::init() and an overloaded version of SAMPLE_ITERATOR_CHANNEL::begin(). 2009-02-08 Kai Vehmanen * library interface version 21:0:1 frozen (2.6.0 release) 2009-02-02 Kai Vehmanen * eca-object-map.h (toggle_case_sensitive_expressions, case_sensitive_expressions): Member functions added. 2009-01-31 Kai Vehmanen * eca-test-case.h (run): A new overloaded function taking a string argument added. * eca-chainsetup-parser.h (interpret_audio_format): Corrected function signature, may throw an exception. 2008-09-28 Kai Vehmanen * eca-logger.h (ECA_LOG_MSG_NOPREFIX): Added. 2008-09-21 Kai Vehmanen * eca-chainsetup-parser.cpp (interpret_options): Now takes a const vector. * eca-chainsetup.cpp (interpret_options): Now takes a const vector. 2008-08-20 Kai Vehmanen * jack-connection.h (file added): * library interface version to 21:0:1. 2008-08-21 Kai Vehmanen * library interface version 20 frozen (2.5.1 release) 2008-08-20 Kai Vehmanen * eca-control-base.cpp (quit_async added): * library interface version to 20:0:0. 2008-08-16 Kai Vehmanen * library interface version 19 frozen (2.5.0 release) * audioio-loop.h (id): Renamed to tag(). 2008-07-13 Kai Vehmanen * eca-chainsetup.cpp (audio_object_open_info): Renamed from audio_object_info and moved to private scope. * eca-object-factory.cpp (audio_object_format_to_eos): Added. 2008-07-08 Kai Vehmanen * ctrl-source.h: Major refactoring. No longer inherits ECA_AUDIO_POSITION. * generic-controller.h: Now inherits ECA_AUDIO_POSITION. 2008-07-06 Kai Vehmanen * eca-audio-time.h (valid): Added. * eca-audio-time.h (mark_as_invalid): Added. 2008-07-02 Kai Vehmanen * eca-audio-position.h (seek_position): Moved to protected scope. The signature and the call semantics were also changed. All classed inhering from ECA_AUDIO_POSITION need to be updated. * eca-audio-position.h (supports_seeking, supports_seeking_sample_accurate): Added as pure virtual methods. * audioio.h (supports_seeking_sample_accurate): Added as implemented inherited method. 2008-03-11 Kai Vehmanen * dynamic-parameters.h (variable_params): Added. 2008-03-10 Kai Vehmanen * eca-audio-time.h: Modified constructor variants. Added sample_rate as a parameter to most setter functions. * audioio-aac.h, audioio-flac.h, audioio-mikmod.h, audioio-ogg.h, audioio-timidity.h: Inheritance of AUDIO_IO_FORKED_STREAM changed from protected to public. * audioio-forked-stream.h (start_io,stop_io): Added new functions. Most of the other public functions moved to protected status. * audioio-forked-stream.h: Class now inherits AUDIO_IO_BARRIER. * audioio-barrier.h: File added. 2008-03-09 Kai Vehmanen * eca-audio-time.h: Added overloaded constructor that takes a std::string as parameter. * eca-audio-time.h (set_time_string): Added. * library interface version to 19:0:0. * audioio-tone.h: File added. * audioio-seqbase.h: File added. * audioio-acseq.h: File added. * audioio-ewf.h: Rebased implementation on the new AUDIO_SEQUENCER_BASE interface. 2007-08-14 Kai Vehmanen * library interface version 18 frozen (2.4.6 release) 2007-08-13 Kai Vehmanen * eca-resources.h: Added static member 'rc_override_file' of type std::string. 2007-08-12 Kai Vehmanen * samplebuffer.h: Added make_empty() and is_empty() public methods. * eca-chain.h: Added is_finished() and toggle_finished() methods. * library interface version to 18:0:0. 2006-12-07 Kai Vehmanen * library interface version 17 frozen (2.4.5 release) 2006-04-24 Kai Vehmanen * eca-control-base.cpp (start): Added non-void return value to report errors. 2006-04-20 Kai Vehmanen * audioio-forked-stream.h (clean_child): Added force argument. * eca-engine.h (exec): Added non-void return value to report exit status. * eca-control-base.h (run): Added non-void return value to report exit status. 2006-03-31 Kai Vehmanen * eca-chainsetup.h: Added enum 'Audio_dir'. * eca-chainsetup.h (remove_audio_object_impl): Added. * library interface version updated to 17:0:0 * eca-chainsetup.h: Renamed remove_audio_object_helper() to remove_audio_object_proxy(). 2006-01-27 Kai Vehmanen * library interface version 16 frozen (2.4.4 release) 2005-09-01 Kai Vehmanen * midi-server.h (add_controller_trace): Added optional 3rd argument. * ctrl-source.h (set_initial_value): Added. 2005-08-31 Kai Vehmanen * eca-object-factory.h (*_to_eos): Added. * eca-chain.cpp (chain_operator_to_string): Removed. * eca-chain.cpp (controller_to_string): Removed. * eca-chain.cpp (operator_params_to_string): Removed. * eca-chainsetup-parser.cpp (audioio_to_string): Removed. * library interface version updated to 16:0:0 2005-08-21 Kai Vehmanen * library interface version 15 frozen (2.4.3 release) 2005-08-20 Kai Vehmanen * midi-server.h: Added MIDI_SERVER::set_schedrealtime(). 2005-08-19 Pedro Lopez-Cabanillas * midiio-aseq.h: Added. * library interface version updated to 15:0:1 2005-08-07 Kai Vehmanen * eca-control-base.cpp (run): Added optional "batchmode" parameter. 2005-03-12 Kai Vehmanen * library interface version 14 frozen (2.4.0 release) 2004-12-21 Kai Vehmanen * eca-chainsetup.h (Mix_mode_t): Added. * eca-chainsetup.h (set_mix_mode, mix_mode): Added. 2004-12-12 Kai Vehmanen * eca-audio-format.h (format_string): Function signature changed; no longer throws an exception. * sample-specs.h: SAMPLE_SPECS::is_system_littleendian removed as obsolete. * eca-chainsetup.cpp (is_valid_for_connection): Function signature changed, added an argument. 2004-12-11 Kai Vehmanen * eca-logger-interface.cpp (set_backlog_length): Added. * eca-logger-interface.cpp (backlog): Added. * eca-logger.h (level_to_string): Added. * eca-engine-driver.h (exec): Signature changed. * library interface version to 14:0:0 2004-12-09 Kai Vehmanen * sample-ops_impl.h: Added, not part of the public interface. 2004-10-27 Kai Vehmanen * library interface version 13 frozen 2004-10-23 Kai Vehmanen * eca-control-base.h (set_float_to_string_precision): Added to protected API. * eca-control-base.h (float_to_string_precision): Added to public API. * eca-control-base.h (set_float_to_string_precision_rep): Added to protected API. 2004-07-13 Kai Vehmanen * audioio-aac.h: Added. 2004-07-09 Kai Vehmanen * eca-audio-format.h (Sample_endianess, set_sample_endianess, sample_endianess): Added. * eca-audio-format.h (Sample_coding, set_sample_coding, sample_coding): Added. * audioio-forked-stream.h (fork_command): Added. * audioio-flac.h: Added. * library interface version to 13:0:4 2004-05-05 Kai Vehmanen * library interface version 12 frozen 2004-05-04 Kai Vehmanen * eca-object-factory.cpp (probe_default_output_device): Added. 2004-05-02 Kai Vehmanen * eca-chain.h (operator_params_to_string): Added. * library interface version to 12:0:3 2003-08-29 Kai Vehmanen * library interface version 11 frozen 2003-08-26 Kai Vehmanen * eca-chainsetup.h (multitrack_mode_offset): Added. 2003-08-14 Kai Vehmanen * eca-control-base.h (engine_start): Moved to public scope, signature changed. 2003-08-13 Kai Vehmanen * eca-chainsetup.cpp (add_default_midi_device): Added. 2003-05-29 Kai Vehmanen * eca-audio-time.h (set_samples_per_second_keeptime): Added. * library version to 11:0:2 2003-02-15 Kai Vehmanen * library interface version 10 frozen 2003-02-05 Kai Vehmanen * eca-engine.cpp (is_finite_length): Added. 2003-02-03 Kai Vehmanen * eca-engine.h (is_locked_for_editing): Added. * eca-engine.h (ECA_ENGINE::Engine_command): Added enums 'ep_edit_lock' and 'ep_edit_unlock'. 2003-02-02 Kai Vehmanen * eca-engine.h (ECA_ENGINE::Engine_command): Added enum 'ep_prepare'. 2003-01-30 Kai Vehmanen * samplebuffer.cpp (resample_get_quality): added * samplebuffer.cpp (resample_set_quality): added * library version to 10:0:1 2003-01-07 Kai Vehmanen * library interface version 9 frozen 2002-11-18 Kai Vehmanen * eca-chainsetup-position.h: Added a separate public API for maximum chainsetup length. This is to avoid confusion between maximum and actual lengths. 2002-10-30 Kai Vehmanen * eca-control.cpp (last_value_to_string): added * eca-logger-wellformed.cpp (create_wellformed_message): added 2002-10-26 Kai Vehmanen * eca-chainop.h (output_samples): renamed to max_output_samples() * eca-audio-position.h (set_length_in_samples, length_in_samples, set_position_in_samples, position_in_samples): turned into non-virtuals 2002-10-22 Kai Vehmanen * eca-operator.h (parameter_description): turned into const member 2002-10-16 Kai Vehmanen * NOTE: from now on, the library version presents the public API version number, not the ABI version. * removed interface version from library base name * library version changed to 9:0:0 2002-10-04 Kai Vehmanen * eca-control.h (print_last_error): function removed 2002-09-29 Kai Vehmanen * audioio-resample.h: modified to inherit AUDIO_IO_PROXY instead of AUDIO_IO * audioio-reverse.h: modified to inherit AUDIO_IO_PROXY instead of AUDIO_IO * audioio-typeselect.h: modified to inherit AUDIO_IO_PROXY instead of AUDIO_IO * audioio-proxy.h (all): added * various: all AUDIO_IO_PROXY_XXX classes renamed to AUDIO_IO_DB_XXX * various: AUDIO_IO_BUFFERED_PROXY renamed to AUDIO_IO_DB_CLIENT 2002-08-22 Kai Vehmanen * sample-specs.h: sample conversion constants removed 2002-07-18 Kai Vehmanen * eca-sample-conversion.h: new file * eca-sample-conversion_test.h: new file 2002-07-17 Kai Vehmanen * audiofx.h (class EFFECT_BASE): channels() from protected to public scope * audiofx_analysis.cpp (EFFECT_VOLUME_BUCKETS): renamed from EFFECT_ANALYZE (EFFECT_VOLUME_PEAK): new class 2002-06-28 Kai Vehmanen * eca-comhelp.h: file removed 2002-06-24 Kai Vehmanen * eca-engine.h: ECA_ENGINE::set_position_samples() added 2002-06-23 Kai Vehmanen * eca-resources.h: removed ECA_RESOURCES::set_default() * eca-resources.h: ECA_RESOURCES::has_any() added 2002-05-18 Kai Vehmanen * audioio-manager.h (get_object_list): return type changed 2002-05-17 Kai Vehmanen * audioio-manager.h (all): added inheritance of DYNAMIC_OBJECT * eca-chainsetup.h (set_audio_io_manager_option): added 2002-05-16 Kai Vehmanen * audioio-proxy-server.h (set_priority): removed * eca-engine-driver.h (stop,exit): blocking arg dropped 2002-05-13 Kai Vehmanen * ctrl-source.h (init): arg dropped * ctrl-source.h (step_length): removed * generic-controller.h (param_number, low_range_limit, high_range_limit): removed * generic-controller.h (all): changed to derive CONTROLLER_SOURCE instead of OPERATOR * finite-envelope.h (all): file removed 2002-04-29 Kai Vehmanen * eca-object-factory.h (all): turned into a singleton class * eca-object-factory.h (reserve_factory, free_factory): removed * eca-object-factory.h (*_list, *_object): removed * eca-object-factory.h (object_identifier): removed 2002-04-28 Kai Vehmanen * eca-logger.h (all): added * eca-logger-interface.h (all): added * eca-logger-default.h (all): added * eca-debug.h (all): removed, replaced by eca-logger.h 2002-04-25 Kai Vehmanen * library version number added to library name; current name is libecasound8 * eca-chainsetup.h, eca-chainsetup-bufparams.h (sched_priority): renamed to get_sched_priority to avoid namespace conflict with system header sched.h which introduces a macro with the same name 2002-04-25 Kai Vehmanen * eca-version.h: replaced all macros with static const variables 2002-03-13 Kai Vehmanen * eca-chainsetup.h (multitrack_mode): added 2002-03-11 Kai Vehmanen * eca-chainsetup.h (set_mixmode, mixmode): removed * audioio-device.h (supports_prefill): renamed to prefill_space 2002-02-27 Kai Vehmanen * eca-engine.h (various): added * eca-chainsetup.h (add_output): second parameter added * audioio-device.h (supports_prefill, delay): added 2002-02-26 Kai Vehmanen * eca-chainsetup.h (is_in_use, toggle_is_in_use): renamed to is_locked and toggle_locked_state * eca-control-base.h (start_engine,run_engine,close_engine): moved to private scope * eca-control-base.h (toggle_interactive_mode): removed * eca-session (is_interactive, toggle_interactive_mode): removed 2002-02-24 Kai Vehmanen * eca-audio-format (set_audio_format): turned into a virtual function 2002-02-13 Kai Vehmanen * eca-chainop.h (release): added * eca-chain.h (release): added 2002-02-09 Kai Vehmanen * eca-audio-format.h (set_audio_format): renamed to set_audio_format_string to avoid clashed with virtual overloaded function set_audio_format() 2002-02-01 Kai Vehmanen * eca-audio-position.h (length_in_samples): renamed to set_length_in_samples * eca-audio-position.h (position_in_samples): renamed to set_position_in_samples * eca-audio-position.h (position_in_seconds): renamed to set_position_in_seconds * eca-audio-position.h (position_in_samples_advance): renamed to change_position_in_samples * eca-chainsetup-position.h (): changed to inherit ECA_AUDIO_POSITION * eca-chain.h (): changed to inherit ECA_AUDIO_POSITION * finite-envelope.h (): changed to inherit ECA_AUDIO_POSITION * eca-control-objects.h (rewind_chains): removed * eca-control-objects.h (forward_chains): removed * eca-control-objects.h (set_position_chains): removed * eca-control-objects.h (change_position_chains): removed 2002-01-31 Kai Vehmanen * samplebuffer.h (constructor): srate param removed * samplebuffer.h (resample_to,resample_from): replaced with resample() * samplebuffer.h (export_*,import_): srate param removed * samplebuffer.h (sample_rate): function removed * samplebuffer.h (length_in_seconds): function removed * eca-audio-time.h (): all samplerate information moved to ECA_SAMPLERATE_AWARE * eca-audio-time.h (bytes_per_second): return changed to 'long int' * audiofx.h (): added inheritance of ECA_SAMPLERATE_AWARE * eca-audio-format.h (channels_changed): removed * eca-audio-format.h (sample_format_changed): removed * eca-audio-format.h (samples_per_second_changed): removed * eca-audio-format.h (interleaved_channels_changed): removed * eca-audio-format.h (set_channels): turned into virtual * eca-audio-format.h (set_sample_format): turned into virtual * eca-audio-format.h (toggle_interleaved_channels): turned into virtual * audioio.h (buffersize): modifying version renamed to set_buffersize; second parameter dropped * audioio.h (io_mode,label): modifying versions renamed to set_io_mode and set_label * audioio.h (toggle_open_state): removed * audioio.h (open, closed): added a default implementation * audioio-device.h (is_running, is_prepared): turned into non-virtual * sample-specs.h (channel_count_default, sample_rate_default): removed * eca-chain.h (): added inheritance of ECA_SAMPLERATE_AWARE * eca-audio-position.h (): added direct inheritance of ECA_SAMPLERATE_AWARE * audioio.h (): added inheritance of both ECA_AUDIO_POSITION and ECA_AUDIO_FORMAT 2002-01-28 Kai Vehmanen * audioio-proxy-server.h (wait_for_data): added * audioio-reverse.h (all): added 2002-01-24 Kai Vehmanen * eca-audio-format.h (channels_changed): added * eca-audio-format.h (sample_format_changed): added * eca-audio-format.h (samples_per_second_changed): added * eca-audio-format.h (interleaved_channels_changed): added * eca-audio-position.h (extend_position): moved from public to protected scope 2001-12-22 Kai Vehmanen * samplebuffer.h (copy_from_buffer): renamed to export_interleaved() * samplebuffer.h (copy_from_buffer_vector): renamed to export_noninterleaved() * samplebuffer.h (copy_to_buffer): renamed to import_interleaved() * samplebuffer.h (copy_to_buffer_vector): renamed to import_noninterleaved() * samplebuffer.h (reserve_length_in_samples,reserve_channels): added * samplebuffer.h (assign-operator,copy-constructor): moved to private access scope * samplebuffer.h (set_rt_lock): added * samplebuffer.h (get_pointer_reflock,release_pointer_reflock): added 2001-12-19 Kai Vehmanen * audioio-types.h (all): removed - replaced by audioio-buffered.h and audioio-device.h * audioio-manager.h (all): added * audioio.h (create_object_manager): added 2001-12-08 Kai Vehmanen * samplebuffer.h (resample_init_memory): added 2001-12-06 Kai Vehmanen * eca-resources.h (all): dropped inheritance of RESOURCE_FILE * audioio-mp3.h (default_mp3_output_default_bitrate): added 2001-11-29 Kai Vehmanen * eca-fileio.h, eca-fileio-mmap.h, eca-fileio-stream.h (all): added support for 64bit files; long ints changed to fpos_t in all public interfaces * eca-fileio-stream.h (open_stderr): added * sample-specs.h (sample_type): renamed to sample_t * sample-specs.h (sample_pos_t,sample_rate_t,channel_t): added * dynamic-parameters.h (parameter_type): renamed to parameter_t 2001-11-19 Kai Vehmanen * resource-file.h (is_modified): added 2001-10-30 Kai Vehmanen * samplebuffer.h (all): class de-templatized 2001-10-28 Kai Vehmanen * eca-static-object-maps.h (all): all global functions and variables encapsulated into the ECA_STATIC_OBJECT_MAPS class; from now on, all access to object maps only throuh ECA_OBJECT_FACTORY * eca-object-map.h (registered_objects): return type changed * eca-object-map.h (object_regex): added * eca-operator.h (new_expr,clone): changed to const; affect all subclasses * audioio-plugin.h (audio_io_keyword, audio_io_keyword_regex): added * eca-object-factory.h (object_identifier): added * eca-object-factory.h (reserve_factory, free_factory): added * eca-object-map.h (keyword_to_expr, expr_to_keyword): added * eca-object-factory (register_chain_operator,register_controller): added 2001-10-17 Kai Vehmanen * eca-chainsetup.h (is_in_use): added 2001-10-13 Kai Vehmanen * eca-chainsetup.h (options_to_string): added * eca-control.h (print_general_status): removed 2001-10-11 Kai Vehmanen * audioio-types.h (AUDIO_IO_DEVICE::is_realtime_object): added * eca-engine.h (is_realtime_object): removed 2001-10-11 Kai Vehmanen * eca-chainsetup-bufparams.h (number_of_set): added * eca-chainsetup.h (has_nonrealtime_objects): added 2001-10-10 Kai Vehmanen * midiio.h (file_descriptor): renamed to poll_descriptor * audioio.h (poll_descriptor): added * eca-debug (detach_debug_object): added 2001-10-06 Kai Vehmanen * eca-main.h (all): renamed to eca-engine.h * eca-engine.h (ECA_PROCESSOR): renamed to ECA_ENGINE * eca-engine.h (status,finished): added * eca-control-objects.h (set_default_audio_format_to_selected): divided into _to_selected_input() and to_selected_output() * eca-chainsetup.h (is_slave_output): renamed to is_realtime_target_output * eca-session.h (session): added * eca-control-base.h (set_buffersize): moved to eca-control-objects.h and renamed to set_chainsetup_buffersize() * eca-control-base.h (toggle_raise_priority,toggle_multitrack_mode): removed 2001-10-05 Kai Vehmanen * eca-chainsetup.h (ok_audio_object): added 2001-10-04 Kai Vehmanen * eca-chainsetup.h (set_buffering_mode, buffering_mode): added * eca-session.h (raised_priority, toggle_raised_priority): moved to eca-chainsetup.h * eca-chainsetup.h (sched_priority, set_sched_priority): added * eca-chainsetup-bufparams.h (all): added * eca-chain.h (connect_input,connected_input,connect_output, connected_output): return type changed * eca-session.h (number_of_attached_chains_to_*): removed * eca-session.h (get_attached_chains_to_*): removed * eca-chain.h (get_chain_operator, get_controller): added * eca-chain.h (get_selected_chain_operator, get_selected_controller): added * eca-control-objects.h (get_*): return type changed to const pointers * eca-control-objects.h (set_audio_object_position_samples): added * eca-chainsetup-position.h (seek_position): added * eca-chainsetup.h (seek_position): added * eca-chainsetup.h (change_position_exact, set_position_exactseek_position): removed * eca-control-objects.h (set_default_audio_format_to_selected,default_audio_format,chainsetup_buffersize): added 2001-10-03 Kai Vehmanen * eca-main.h (has_realtime_objects): moved to eca-chainsetup.h * eca-main.h (is_slave_output): moved to eca-chainsetup.h * eca-main.h (init): moved to private scope * audioio-proxy-server (wait_for_full, wait_for_stop, wait_for_flush): added 2001-10-01 Kai Vehmanen * eca-audio-objects.h (all): functionality relocated to eca-chainsetup.h * eca-chainsetup-parser.h (all): added * eca-chainsetup.h (all): all public data members move to private scope * eca-chainsetup.h (create_*): moved to eca-object-factory.h 2001-09-23 Kai Vehmanen * eca-chainsetup.h (preprocess_options): removed * eca-session.h (preprocess_options): added * eca-session.h (interpret_general_options,interpret_general_options): changed * eca-session.h (interpret_chainsetup): renamed to interpret_chainsetup_option 2001-09-20 Kai Vehmanen * audiofx.h (init): added virtual function implementation 2001-08-19 Kai Vehmanen * library version changed to 8:0:0 * eca-session.h (add_chainsetup): doesn't throw exceptions anymore * eca-audio-objects.h (class): no longer inherits DEFINITION_BY_CONTRACT * eca-audio-objects.h (desctructor): changed from virtual to non-virtual * eca-audio-objects.h (is_valid): renamed to is_valid_for_connection() * eca-chainsetup.h (interpret_*): don't throw exceptions anymore * eca-static-objects-maps (create_plugins): doesn't throw exceptions anymore * eca-session.h (constructor): will throw an exception if fails * eca-control-base.h (class): no longer inherits DEFINITION_BY_CONTRACT * audioio-buffered-proxy.h (class): no longer inherits DEFINITION_BY_CONTRACT * midi-server.h (class): no longer inherits DEFINITION_BY_CONTRACT * generic-controller.h (class): no longer inherits DEFINITION_BY_CONTRACT * preset.h (class): no longer inherits DEFINITION_BY_CONTRACT 2001-05-02 Kai Vehmanen * ecasound 2.0.0 released 2001-04-27 Kai Vehmanen * library interface version 7 frozen 2001-04-25 Kai Vehmanen * generic-linear-envelope.h (all): added 2001-04-24 Kai Vehmanen * eca-control-objects.h (selected_chain_operator): added * eca-control-objects.h (selected_chain_operator_parameter): added * eca-control-objects.h (selected_controller): added * eca-control-objects.h (chain_operator_names): added * eca-control-objects.h (chain_operator_parameter_names): added * eca-control-objects.h (controller_names): added * eca-chain.h (chain_operator_name): added * eca-chain.h (chain_operator_parameter_name): added * eca-chain.h (controller_name): added * eca-chain.h (number_of_chain_operator_parameters): added 2001-04-23 Kai Vehmanen * eca-iamode-parser.h (action_requires_selected_audio_input): added * eca-iamode-parser.h (action_requires_selected_audio_output): added * eca-iamode-parser.h (action_requires_selected_audio_object): removed * eca-control-objects.h (get_audio_input): added * eca-control-objects.h (get_audio_output): added * eca-control-objects.h (get_audio_object): removed * eca-control-objects.h (select_audio_input_by_index): added * eca-control-objects.h (select_audio_output_by_index): added * eca-control-objects.h (select_audio_object_by_index): removed * eca-control-objects.h (attach_audio_input): added * eca-control-objects.h (attach_audio_output): added * eca-control-objects.h (attach_audio_object): removed * eca-control-objects.h (remove_audio_input): added * eca-control-objects.h (remove_audio_output): added * eca-control-objects.h (remove_audio_object): removed * eca-control-dump.h (dump_selected_audio_input): added * eca-control-dump.h (dump_audio_input_position): added * eca-control-dump.h (dump_audio_input_length): added * eca-control-dump.h (dump_audio_input_open_state): added * eca-control-dump.h (dump_selected_audio_output): added * eca-control-dump.h (dump_audio_output_position): added * eca-control-dump.h (dump_audio_output_length): added * eca-control-dump.h (dump_audio_output_open_state): added * eca-control-dump.h (dump_selected_audio_object): removed * eca-control-dump.h (dump_audio_object_position): removed * eca-control-dump.h (dump_audio_object_length): removed * eca-control-dump.h (dump_audio_object_open_state): removed * eca-control-objects.h (change_position_chains): added * eca-control-objects.h (select_audio_object): removed * eca-control-objects.h (rewind_audio_object): moved to protected scope * eca-control-objects.h (forward_audio_object): moved to protected scope * eca-control-objects.h (set_audio_object_position): moved to protected scope * eca-control-objects.h (wave_edit_audio_object): moved to protected scope * eca-control-objects.h (select_chainsetup_by_index): argument type changed * eca-control-objects.h (select_chains_by_index): added * eca-control-objects.h (audio_input_names,audio_output_names): added * eca-audio-objects.h (audio_input_names,audio_output_names): added 2001-04-09 Kai Vehmanen * eca-chainsetup-position.h (set_position_exact): added * eca-chainsetup-position.h (change_position_exact): renamed from change_position(double) * eca-chainsetup.h (change_position, set_position): added 2001-04-08 Kai Vehmanen * eca-control-objects.h (change_chainsetup_position): added * eca-control-objects.h (set_chainsetup_position): added 2001-03-20 Kai Vehmanen * eca-iamode-parser.h (registered_commands_list): added 2001-03-06 Kai Vehmanen * eca-audio-format.h (default_ecasound_audio_format): removed * eca-object-map.h (flush): added * eca-ladspa-plugin-map.h (all): removed * eca-controller-map.h (all): removed * eca-audio-object-map.h (all): removed * eca-chainop-map.h (all): removed * eca-object-factory.h (ladspa_map_object): added * eca-object-factory.h (controller_map_object,chain_operator_map_object): added * eca-object-factory.h (chain_operator_map_object): added * eca-object-factory.h (audio_io_map_object): added * eca-static-object-maps.h (eca_audio_device_map): removed * eca-static-object-maps.h (object map objects): changed into pointers * eca-static-object-maps.h (unregister_default_objects): added 2001-02-19 Kai Vehmanen * midi-server (register_handler, unregister_handler): added 2001-02-14 Kai Vehmanen * midi-parser.h (all): new module * midi-server.h (various): added * eca-midi.h (all): module dropped 2001-02-08 Kai Vehmanen * audioio-types.h (toggle_max_buffers,max_buffers): added * audioio-types.h (toggle_ignore_xruns,ignore_xruns): added * eca-audio-objects.h (toggle_max_buffers,max_buffers): added * eca-audio-objects.h (toggle_ignore_xruns,ignore_xruns): added * midiio.h (all): added * midiio-raw.h (all): added * midiio-server.h (all): added * midiio-client.h (all): added * eca-static-object-maps.h (register_default_midi_devices): added * eca-audio-objects.h (add_midi_device, remove_midi_device): added * eca-chainsetup.h (interpret_midi_device): added * eca-object-factory (create_midi_device): added * eca-audio-objects.h (set_default_midi_device,default_midi_device): added 2001-02-07 Kai Vehmanen * eca-iamode-parser.h (enum Commands): moved from public to protected scope 2001-02-06 Kai Vehmanen * eca-midi.h (various): many type changes 2000-12-13 Kai Vehmanen * audiofx.h (EFFECT_DCFIX,EFFECT_PITCH_SHIFTER): moved to audiofx.h * audiofx_misc.h (EFFECT_AUDIO_STAMP): added * audiofx_impl.h (all): removed * stamp-ctrl.h (all): added * audio-stamp.h (all): added * generic-controller.h (source_pointer): added 2000-12-12 Kai Vehmanen * eca-session.h (Engine_status): 'ep_status_error' added * eca-contol-interface.h (error): added 2000-12-10 Kai Vehmanen * osc-gen.h (all): completely rewritten * osc-gen-file.h (all): added 2000-12-09 Kai Vehmanen * eca-control-base.h (destructor): changed into non-virtual * eca-control-objects.h (destructor): changed into non-virtual * eca-control.h (destructor): changed into non-virtual * eca-control-interface.h (last_boolean): added * eca-chainsetup.h (constructor): new overloaded version added 2000-12-08 Kai Vehmanen * eca-control.h (): now inherits ECA_CONTROL_OBJECTS directly * eca-contro-dump.h (): dropped inheritance of ECA_CONTROL_OBJECTS; now a non-virtual, concrete class * eca-chain.h (various): added support for selecting individual chainops, controllers and their parameters * eca-control-objects (all chainop and ctrl related routines): layout changes * eca-audio-objects (first_selected_chain): added 2000-12-07 Kai Vehmanen * eca-operator.h (is_toggled, default_parameter_range): removed * eca-operator.h (parameter_description): added 2000-12-05 Kai Vehmanen * eca-main.h (ecasound_queue, ecasound_stop_cond, ecasound_stop_mutex): removed from global namespace * eca-control-base.h (ecasound_lockfile): removed from global namespace * eca-control-base.h (start_engine, start): 1st argument dropped * eca-control-base.h (start_normal, start_normal_thread): removed from global namespace * eca-control-base.h (various routines for ECI implementation): added * eca-control.h (print_last_error, print_last_value): added 2000-11-22 Kai Vehmanen * eca-audio-objects.h (set_double_buffer_size,double_buffer_size): added 2000-11-19 Kai Vehmanen * audioio-buffered-proxy.h (all): added * audioio-proxy-server.h (all): added * audioio-proxy-buffer.h (all): added 2000-11-17 Kai Vehmanen * preset.h (copy-constructor): from private to public scope 2000-11-17 Kai Vehmanen * resource-file.h (load, save): added 2000-11-09 Rob Coker * audiofx_envelope_modulation.h (): EFFECT_TREMOLO added 2000-11-01 Kai Vehmanen * audiofx_envelope_modulation.h (): EFFECT_PULSE_GATE_BPM added 2000-10-29 Rob Coker * audiofx_envelope_modulation.h (): file added 2000-10-21 Kai Vehmanen * eca-mthreaded-processor.h (): file removed * eca-fileio-mmap-fthread.h (): file removed 2000-10-17 Kai Vehmanen * eca-control-objects (set_default_audio_format): added parameter 'interleaving' * samplebuffer.h (copy_from_buffer_vector,copy_to_buffer_vector): added * audioio.h (finite_length_stream): added 2000-10-14 Kai Vehmanen * dynamic-parameters.h (): dropped inheritance of DEFINITION_BY_CONTRACT (three days, I changed my mind :)) 2000-10-11 Kai Vehmanen * dynamic-parameters.h (): now inherits DEFINITION_BY_CONTRACT * dynamic-parameters.h (default_parameter_range,is_toggle): moved to OPERATOR * dynamic-parameters.h (map_parameters, get_parameter_id): removed * dynamic-parameters.h (get_parameter_name): changed prototype 2000-10-10 Kai Vehmanen * audioio-types.h (AUDIO_IO_DEVICE): is_running(), is_prepared(), toggle_running_state() and toggle_prepared_state() added * eca-chainsetup.h (enable): changed exception specification * eca-session.h (connect_chainsetup): changed exception specification 2000-10-08 Kai Vehmanen * eca-version.h (): added version numbering as C defines * audioio-plugin.h (audio_io_interface_version): added * eca-object-map.h (object): added a second argument; affects 2000-10-07 Kai Vehmanen * eca-error.h (all): classes made non-virtual, many other big changes * audioio-mikmod.h (MIKMOD_INTERFACE): default_mikmod_path and default_mikmod_args combined into default_mikmod_cmd) * audioio-timidity.h (all): a new file * audioio.h (all): various changes and code cleanups * audioio-forked-stream.h (all): new file other object map classes 2000-09-24 Kai Vehmanen * audiofx_timebased.h (EFFECT_MODULATING_DELAY): constructor parameters changed 2000-09-17 Kai Vehmanen * library version changed to 7:0:0 * eca-object-factory.h (): new file * eca-chainop.h (CHAIN_OPERATOR): dropped inheritance of ECA_AUDIO_FORMAT * audiofx.h (set_samples_per_second,samples_per_second): added * audiofx.h (set_channels,channels): added * eca-chainsetup.h (add_default_output): added * eca-chainsetup.h (preprocess_options): added * eca-chainsetup.h (interpret_option):added * eca-chainsetup.h (interpret_object_option): added * eca-chainsetup.h (interpret_global_option): added * eca-chainsetup.h (interpret_*): most interpretation routines moved from public to private scope * various: renamed all enum type names from "ALL_CAPITAL" to "Starting_capital_only" * eca-audio-objects.h (interpret_audio_object): moved to eca-chainsetup.h * eca-audio-objects.h (create_audio_object): moved to eca-object-factory.h * eca-chainsetup.h (constructor): removed interaction with COMMAND_LINE objects 2000-09-16 Kai Vehmanen * ecasound 1.8.2r14 released * library interface version 6 frozen 2000-06-27 Kai Vehmanen * eca-audio-objects.h (attach_input_to_selected_chains,attach_input_to_selected_chains): changed parameter format 2000-06-18 Kai Vehmanen * audioio-alsa*.h (all): renamed all ALSA_PCMx_DEVICE classes to ALSA_PCM_DEVICE 2000-06-12 Kai Vehmanen * eca-chain.h (connected_input, connected_output): added 2000-06-11 Kai Vehmanen * audioio.h (samples_available,supported_io_modes): added * audioio-mp3.h (default cmds): new more generic interface * eca-control*.h (all): files and classes renamed; ECA_CONTROLLER* -> ECA_CONTROL* * eca-chainsetup-position.h (all): file and class renamed; ECA_CONTROLLER_POSITION -> ECA_CHAINSETUP_POSITION * eca-control-objects.h (chainsetup_names,chain_names): added * eca-control-objects.h (get_controller, remove_controller): added * eca-control-objects.h (get_chain,select_chain): added * eca-session.h (chainsetup_names): added * eca-audio-objects.h (chain_names): added * eca-chain.h (remove_controller): added 2000-06-10 Jeremy Hall * audioio-alsa3.h (all): added 2000-06-06 Kai Vehmanen * library version changed to 6:0:0 * development of ecasound 1.8.x started * moved all files from src/ and include/ subdirs to the same directory (top-level libecasound dir) * audioio.h (enum Io_type): replaces the unnamed enums 2000-05-29 Kai Vehmanen * audiofx_reverb.h: a new file containing more advanced reverb effects 2000-05-21 Kai Vehmanen * library version changed to 6:0:1 * audiofx_ladspa.h (unique_number): added * eca-ladspa-plugin-map.h (object, register_object): new overloaded versions 2000-05-02 Kai Vehmanen * library interface version 5 frozen 2000-04-26 Kai Vehmanen * eca-chain.h (selected_target): added 2000-04-15 Kai Vehmanen * eca-controller-objects.h (set_default_audio_format): signature changed * eca-audio-format.h (audio_format): added * eca-session.h (get_attached_chains_to_input, _output): renamed from get_connected_chains...() * eca-controller-base.h (attached_chains_input, _output): renamed from connected_chains...() * eca-audio-objects.h (get_attached_chains...): renamed from get_connected_chains...() 2000-04-14 Kai Vehmanen * audioio-alsa2-plugin.h: added, contains the class ALSA_PCM2_PLUGIN_DEVICE * eca-controller.h (direct_command): private function, added 2000-04-03 Kai Vehmanen * eca-controller-objects.h (set_chainsetup_output_mode): added * eca-alsa-dyn.h: removed as obsolete * audiofx_vst.h: added * eca-vst-plugin-map.h: added 2000-03-27 Kai Vehmanen * eca-static-object-maps (various): changes in map representation, affects all object maps 2000-03-24 Kai Vehmanen * eca-version.h (ecasound_library_version_current): added * eca-version.h (ecasound_library_version_revision): added * eca-version.h (ecasound_library_version_age): added * eca-version.h (ecasound_library_version): added * eca-version.h (ecasound_version): removed * eca-controller-objects.h (get_audio_format): no longer const 2000-03-23 Kai Vehmanen * samplebuffer_functions.h: added * samplebuffer.h: removed all non-template code 2000-03-22 Kai Vehmanen * eca-chainsetup.h (combine_options): moved to libkvutils 2000-03-20 Kai Vehmanen * eca-static-object-maps.h (eca_ladspa_plugin_map): added * audiofx_ladspa.h: added * eca-chainsetup.h (create_ladspa_plugin): added * ladspa.h: added * eca-ladspa-plugin-map.h: added 2000-03-18 Kai Vehmanen * eca-controller-dump.h (various): added, affects ECA_CONTROLLER, ECA_CONTROLLER_OBJECTS and ECA_IAMODE_PARSER 2000-03-13 Kai Vehmanen * eca-operator.h (various): added * eca-object.h (various): added 2000-03-12 Kai Vehmanen * dynamic-parameters.h (is_toggle): added * eca-audio-objects.h (audio_object_info): return type changed to void 2000-03-10 Kai Vehmanen * eca-object-map.h (various): template parameter is now the same as DYNAMIC_PARAMETERS::parameter_type * eca-object-map.h (registered_keywords): added 2000-03-09 Kai Vehmanen * dynamic-object.h (description): added * audioio.h (locked_audio_format): added 2000-03-05 Kai Vehmanen * audioio-types.h (various): major changes in class hiearchy * audioio.h (supported_io_modes): added 2000-03-03 Kai Vehmanen * eca-audio-format.h (set_audio_format): renamed from set_sample_format, added a new overloaded version 2000-03-03 Kai Vehmanen * eca-audio-objecs (create_loop_input, create_loop_output): added * eca-audio-objecs (create_audio_object): now a static member, removed exceptions 2000-03-02 Kai Vehmanen * dynamic-parameters.h (new_expr): added, affects all subclasses * audioio-types.h (constructor): removed default arguments, affects all subclasses * resource-file.h (resource_file): added * audioio.h (SI_MODE): enum removed, replaced with AUDIO_IO::{io_read,io_write,io_readwrite} * eca-static-object-maps.h (various): added * eca-audio-object-map.h (various): added 2000-02-29 Kai Vehmanen * dynamic-parameters.h (various): converted to a class template * dynamic-objects.h (various): converted to template class, affects all subclasses * audioio-types.h (various): reorganized file, device and buffering classes * audioio.h (label,io_mode): protected -> public * audioio.h (constructor): all arguments now optional * dynamic-parameters.h (valid_parameter): removed * dynamic-parameters.h (default_parameter_range): added * dynamic-parameters.h (name): removed 2000-02-24 Kai Vehmanen * audiofx_timebased.h (various) EFFECT_MODULATING_DELAY, EFFECT_CHORUS, EFFECT_FLANGE and EFFECT_MULTITAP_DELAY classes added 2000-02-23 Kai Vehmanen * audiofx_filter.h (various): class EFFECT_ALLPASS_FILTER added * audiofx_filter.h (various): class EFFECT_COMB_FILTER added * samplebuffer.h (various): made sample_rate a normal class member instead of a static member -> affect many other classes * eca-chainop.h (output_samples): added * eca-chainop.h (class): now inherits ECA_AUDIO_FORMAT * eca-chainsetup.h (is_enabled): added const member modifier * audiofx_timebased.h (various): class DELAY interface has changed 2000-02-22 Kai Vehmanen * eca-audio-objects.h (interpret_audioio_device): second parameter omitted 2000-02-21 Kai Vehmanen * eca-chainsetup.h: ECA_RESOURCES removed from constructor parameters * eca-chain.h (init): more arguments 2000-02-20 Kai Vehmanen * preset.h: added * file-preset.h: added * global-preset.h: added * eca-preset-map.h: added 2000-02-18 Kai Vehmanen * eca-chainsetup.h (create_chain_operator, create_controller): added * eca-chain.h (constructor): moved sample buffer objects outside, now chain's just have a pointer to a buffer 2000-02-15 Kai Vehmanen * resource-file.h (keywords): added 2000-02-14 Kai Vehmanen * audioio-ewf.h (various): new functionality * resource-file.h (load, save, is_modified, set_modified_state): removed * resource-file.h (set_resource_file, get_resource_file): renamed * eca-controller-base.h (resource_value): return value changed 2000-02-13 Kai Vehmanen * audioio.h (various): added support for class ECA_AUDIO_TIME 2000-02-11 Kai Vehmanen * audioio-types.h (prepare): added to AUDIO_IO_DEVICE and all its subclasses 2000-02-09 Kai Vehmanen * eca-debug.h (): class MAINDEBUG renamed to ECA_DEBUG * eca-debug.h (): new enums and debug-level specs 2000-02-08 Kai Vehmanen * eca-chain.h (select_controller): added * eca-chain.h (selected_controller): added * eca-chain.h (number_of_controllers): added * eca-chain.h (selected_chain_operator_as_target): added * eca-chain.h (selected_controller_as_target): added * eca-chainsetup.h (set_target_to_controller): added * generic-controller.h (status): added * eca-controller.h (controller_status): added 2000-02-05 Kai Vehmanen * eca-audio-objects.h (create_audio_object): const removed * eca-controller-base.h (run): added 2000-02-04 Kai Vehmanen * audioio.h (is_realtime): removed as obsolete * audioio.h (start, stop, latency): moved to audioio-types.h * library version changed to 5:0:0 2000-01-31 Kai Vehmanen * eca-control-position.h (change_position): added an overloaded version that takes a double argument * library version changed to 5:0:1 2000-01-29 Kai Vehmanen * library interface version 4 frozen * ecasound 1.6.12r10 released 2000-01-28 Kai Vehmanen * library version 4:0:0 feature freeze * ecasound 1.6.12d10 released 2000-01-25 Kai Vehmanen * eca-audio-time.h: added * eca-chainop.h (status): changed to const * eca-chainop.h (output_channels): changed to const 2000-01-22 Kai Vehmanen * eca-controller-base.h (is_finished): added 2000-01-15 Kai Vehmanen * samplebuffer.h (swap_bytes): removed * samplebuffer.h (copy): added * eca-audio-objects (get_type_from_extension): now a static member * eca-controller.h: split into eca-controller.h, eca-controller-base.h and eca-controller-objects.h - only minor changes to ECA_CONTROLLER interface 2000-01-13 Kai Vehmanen * audioio-alsa2.*: added * audioio-alsa.*: ALSADEVICE renamed to ALSA_PCM_DEVICE * audioio-lbalsa.*: ALSALBDEVICE renamed to ALSA_LOOPBACK_DEVICE 2000-01-07 Kai Vehmanen * audiofx_rcfilter.h, audiofx_rcfilter.src: added 1999-12-21 Kai Vehmanen * audioio-ewf.h: EWFFILE now directly inherits AUDIO_IO 1999-12-16 Kai Vehmanen * audiofx_amplitude.cpp: NOISEGATE_MONO -> NOISEGATE * library version changed to 4:0:0 1999-12-15 Kai Vehmanen * 1.6.9r9 released * library interface version 3 frozen 1999-12-11 Kai Vehmanen * dynamic-object.h: added * ctrl_source.h -> ctrl-source.h * gcontroller.* -> generic-controller.* * parameter control subsystem rewritten, affects all related classes (class inheriting from CONTROLLER_SOURCE, GENERIC_CONTROLLER, ECA_OBJECT_MAP, ECA_CHAIN, ECA_CHAINSETUP and so on) 1999-12-06 Kai Vehmanen * ctrl_source.h: controller sources now inheric from DYNAMIC_PARAMETERS - this required many changes to controller source classes * eca-chainop-map.h: renamed to eca-object-map.h * dynamic-parameters.h (name): added * dynamic-parameters.h (parameter_names): changed return type, affects all sub-classes * library version changed to 3:0:0 1999-12-04 Kai Vehmanen * 1.6.8r8 released * library interface version 2 frozen * library version changed to 2:0:1 1999-12-02 Kai Vehmanen * eca-controller.h (select_chainsetup_by_index): a new routine 1999-11-23 Kai Vehmanen * 1.6.7r7 released * library interface version 1 frozen 1999-11-08 Kai Vehmanen * major changes in nearly all interfaces * library version changed 1:0:0 1999-09-14 Kai Vehmanen * 1.5.12r6 released * first public release of libecasound; libtool version number 0:0:0 (current:revision:age) ----------------------------------------------------------------------- ecasound-2.9.1/libecasound/audiofx_misc.cpp0000644000076400007640000001520010664032032015715 00000000000000// ------------------------------------------------------------------------ // audiofx_misc.cpp: Miscellanous effect processing routines. // Copyright (C) 1999-2003,2005 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include "samplebuffer_iterators.h" #include "eca-operator.h" #include "audiofx_misc.h" #include "eca-logger.h" #include "eca-error.h" EFFECT_DCFIX::EFFECT_DCFIX (void) { } EFFECT_DCFIX::EFFECT_DCFIX (const EFFECT_DCFIX& x) { deltafixes_rep = x.deltafixes_rep; i_rep = x.i_rep; } void EFFECT_DCFIX::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { if (param == 1) { deltafixes_rep.resize(static_cast(value)); } else if (param > 1 && param - 2 < static_cast(deltafixes_rep.size())) { deltafixes_rep[param - 2] = value; } } CHAIN_OPERATOR::parameter_t EFFECT_DCFIX::get_parameter(int param) const { parameter_t result = 0.0f; if (param == 1) { result = static_cast(deltafixes_rep.size()); } else if (param > 1 && param - 2 < static_cast(deltafixes_rep.size())) { result = deltafixes_rep[param - 2]; } return result; } string EFFECT_DCFIX::parameter_names(void) const { std::vector t; t.push_back("channel-count"); for(int n = 0; n < static_cast(deltafixes_rep.size()); n++) { t.push_back("delta-ch" + kvu_numtostr(n + 1)); } return kvu_vector_to_string(t, ","); } void EFFECT_DCFIX::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); } void EFFECT_DCFIX::init(SAMPLE_BUFFER *insample) { i_rep.init(insample); set_channels(insample->number_of_channels()); if (channels() > static_cast(deltafixes_rep.size())) { deltafixes_rep.resize(channels()); } } void EFFECT_DCFIX::process(void) { for(int n = 0; n < channels(); n++) { i_rep.begin(n); while(!i_rep.end()) { *i_rep.current() = *i_rep.current() + deltafixes_rep[n]; i_rep.next(); } } } const int EFFECT_PITCH_SHIFT::resample_low_limit = 8; EFFECT_PITCH_SHIFT::EFFECT_PITCH_SHIFT (const EFFECT_PITCH_SHIFT& x) { pmod_rep = x.pmod_rep; target_rate_rep = x.target_rate_rep; sbuf_repp = 0; } void EFFECT_PITCH_SHIFT::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: double lowlimit = 1.0f / EFFECT_PITCH_SHIFT::resample_low_limit * 100.0f; if (value <= lowlimit) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING! Shift-% must be greater than " + kvu_numtostr(lowlimit) + "%! Limiting to the low-limit."); pmod_rep = lowlimit; } else { pmod_rep = value; } if (sbuf_repp != 0) { target_rate_rep = static_cast(samples_per_second() * 100.0 / pmod_rep); } else { target_rate_rep = 0; } break; } } CHAIN_OPERATOR::parameter_t EFFECT_PITCH_SHIFT::get_parameter(int param) const { switch (param) { case 1: return pmod_rep; } return 0.0; } void EFFECT_PITCH_SHIFT::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); switch(param) { case 1: pd->default_value = 100.0f; pd->bounded_above = true; /* 100x speed-up is a sensible upper limit */ pd->upper_bound = 10000.0f; pd->bounded_below = true; /* ~8x slow-down is a sensible lower limit: */ pd->lower_bound = 1.0f / EFFECT_PITCH_SHIFT::resample_low_limit * 100.0f; break; } } void EFFECT_PITCH_SHIFT::init(SAMPLE_BUFFER *insample) { sbuf_repp = insample; // truncate, not round, to integer target_rate_rep = static_cast((samples_per_second() * 100.0 / pmod_rep)); long int lowlimit = sbuf_repp->length_in_samples() * EFFECT_PITCH_SHIFT::resample_low_limit; sbuf_repp->reserve_length_in_samples(lowlimit); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Setting resampling lowlimit to " + kvu_numtostr(lowlimit) + " bytes."); sbuf_repp->resample_init_memory(samples_per_second(), target_rate_rep); sbuf_repp->resample_set_quality(50); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Resampling from " + kvu_numtostr(samples_per_second()) + " to " + kvu_numtostr(target_rate_rep) + "."); } void EFFECT_PITCH_SHIFT::release(void) { sbuf_repp = 0; } void EFFECT_PITCH_SHIFT::process(void) { sbuf_repp->resample(samples_per_second(), target_rate_rep); } long int EFFECT_PITCH_SHIFT::max_output_samples(long int i_samples) const { DBC_CHECK(sbuf_repp != 0); return static_cast(static_cast(target_rate_rep) / samples_per_second() * i_samples); } EFFECT_AUDIO_STAMP::EFFECT_AUDIO_STAMP(void) : sbuf_repp(0) { } EFFECT_AUDIO_STAMP::EFFECT_AUDIO_STAMP(const EFFECT_AUDIO_STAMP& arg) : sbuf_repp(0) { } void EFFECT_AUDIO_STAMP::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: set_id(static_cast(value)); break; } } CHAIN_OPERATOR::parameter_t EFFECT_AUDIO_STAMP::get_parameter(int param) const { switch (param) { case 1: return static_cast(id()); } return 0.0; } void EFFECT_AUDIO_STAMP::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { OPERATOR::parameter_description(param, pd); switch(param) { case 1: pd->default_value = 1; pd->description = get_parameter_name(param); pd->bounded_above = false; pd->bounded_below = true; pd->lower_bound = 1; pd->integer = true; break; } } void EFFECT_AUDIO_STAMP::init(SAMPLE_BUFFER *insample) { sbuf_repp = insample; } void EFFECT_AUDIO_STAMP::release(void) { sbuf_repp = 0; } void EFFECT_AUDIO_STAMP::process(void) { store(sbuf_repp); // std::cerr << "Storing audio stamp with id " << id() << "." << std::endl; } ecasound-2.9.1/libecasound/file-preset.h0000644000076400007640000000112010664032032015123 00000000000000#ifndef INCLUDED_FILE_PRESET_H #define INCLUDED_FILE_PRESET_H #include #include "preset.h" /** * File based effect preset * * @author Kai Vehmanen */ class FILE_PRESET : public PRESET { std::string filename_rep; public: std::string filename(void) const { return(filename_rep); } void set_filename(const std::string& v) { filename_rep = v; } virtual FILE_PRESET* clone(void) const; virtual FILE_PRESET* new_expr(void) const { return(new FILE_PRESET(filename_rep)); } virtual ~FILE_PRESET (void) { } FILE_PRESET(const std::string& file_name = ""); }; #endif ecasound-2.9.1/libecasound/eca-samplerate-aware.h0000644000076400007640000000265710664032032016704 00000000000000#ifndef INCLUDED_ECA_SAMPLERATE_AWARE_H #define INCLUDED_ECA_SAMPLERATE_AWARE_H #include "sample-specs.h" /** * Interface class implemented by all types that * require knowledge of system samplerate. Provides * funcitonality for setting and getting current * samplerate, and mechanism for notifying subclasses * of a samplerate change. * * @author Kai Vehmanen */ class ECA_SAMPLERATE_AWARE { public: /** @name Constructors and destructors */ /*@{*/ /** * Construtor. * * Note! The default is set to a very high value (8 * 48kHz) * to ensure we retain precision when using (sample-count,srate) * tuples for storing position and length information, even * in situations where the actual sample rate is not yet known. */ ECA_SAMPLERATE_AWARE (SAMPLE_SPECS::sample_rate_t srate = 384000); virtual ~ECA_SAMPLERATE_AWARE(void); /*@}*/ /** @name Public functions for getting audio format information */ /*@{*/ /** * Returns sampling rate in samples per second. * Note! Sometimes also called frames_per_second(). */ SAMPLE_SPECS::sample_rate_t samples_per_second(void) const { return(srate_rep); } /*@}*/ /** @name Public virtual functions for setting audio format information */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ private: SAMPLE_SPECS::sample_rate_t srate_rep; }; #endif /* INCLUDED_ECA_SAMPLERATE_AWARE */ ecasound-2.9.1/libecasound/eca-chainsetup_test.h0000644000076400007640000000407111141021054016635 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup_test.h: Unit test for ECA_CHAINSETUP // Copyright (C) 2002,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include "eca-chainsetup.h" #include "kvu_numtostr.h" #include "eca-logger.h" #include "eca-test-case.h" using namespace std; /** * Unit test for ECA_CHAINSETUP. * * FIXME: implementation not ready */ class ECA_CHAINSETUP_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for ECA_CHAINSETUP"); } virtual void do_run(void); public: virtual ~ECA_CHAINSETUP_TEST(void) { } private: void do_run_save_and_restore(void); }; void ECA_CHAINSETUP_TEST::do_run(void) { do_run_save_and_restore(); } void ECA_CHAINSETUP_TEST::do_run_save_and_restore(void) { /** * FIXME: * - create simple setup with multiple instance of all basic * object types and operations * - save to temp .ecs * - clear chainseup * - load saved .ecs * - verify chainsetup integrity and contents * - use -y to set offsets for audio objects; verify after reload * - save and test again (to get the whole: 'manual definition -> * save -> load -> save -> load' cycle) */ } ecasound-2.9.1/libecasound/audiofx_mixing.h0000644000076400007640000001166111170177052015736 00000000000000#ifndef _AUDIOFX_MIXING_H #define _AUDIOFX_MIXING_H #include #include "samplebuffer_iterators.h" #include "audiofx.h" #include "audiofx_amplitude.h" /** * Virtual base class for channel mixing and routing effects * @author Kai Vehmanen */ class EFFECT_MIXING : public EFFECT_BASE { public: typedef std::vector::size_type ch_type; virtual ~EFFECT_MIXING(void); }; /** * Channel copy (one-to-one copy) * @author Kai Vehmanen */ class EFFECT_CHANNEL_COPY : public EFFECT_MIXING { private: ch_type from_channel, to_channel; SAMPLE_ITERATOR_CHANNEL f_iter, t_iter; public: virtual std::string name(void) const { return("Channel copy"); } virtual std::string parameter_names(void) const { return("from-channel,to-channel"); } int output_channels(int i_channels) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_CHANNEL_COPY* clone(void) const { return new EFFECT_CHANNEL_COPY(*this); } EFFECT_CHANNEL_COPY* new_expr(void) const { return new EFFECT_CHANNEL_COPY(); } EFFECT_CHANNEL_COPY (parameter_t from_channel = 1.0, parameter_t to_channel = 1.0); }; /** * Channel move (copy one channel and mute the source) * @author Kai Vehmanen */ class EFFECT_CHANNEL_MOVE : public EFFECT_MIXING { private: ch_type from_channel, to_channel; SAMPLE_ITERATOR_CHANNEL f_iter, t_iter; public: virtual std::string name(void) const { return("Channel move"); } virtual std::string parameter_names(void) const { return("from-channel,to-channel"); } int output_channels(int i_channels) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; void init(SAMPLE_BUFFER *insample); void process(void); EFFECT_CHANNEL_MOVE* clone(void) const { return new EFFECT_CHANNEL_MOVE(*this); } EFFECT_CHANNEL_MOVE* new_expr(void) const { return new EFFECT_CHANNEL_MOVE(); } EFFECT_CHANNEL_MOVE (parameter_t from_channel = 1.0, parameter_t to_channel = 1.0); }; /** * Channel mute (mutes one channel) * @author Kai Vehmanen */ class EFFECT_CHANNEL_MUTE : public EFFECT_AMPLIFY_CHANNEL { public: virtual std::string name(void) const { return("Channel mute"); } virtual std::string parameter_names(void) const { return("channel"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; EFFECT_CHANNEL_MUTE* clone(void) const { return new EFFECT_CHANNEL_MUTE(*this); } EFFECT_CHANNEL_MUTE* new_expr(void) const { return new EFFECT_CHANNEL_MUTE(); } EFFECT_CHANNEL_MUTE (parameter_t channel = 1.0); }; /** * Channel copy (one-to-one copy) * @author Kai Vehmanen */ class EFFECT_MIX_TO_CHANNEL : public EFFECT_MIXING { private: typedef std::vector::size_type ch_type; int channels; ch_type to_channel; parameter_t sum; SAMPLE_ITERATOR_CHANNEL t_iter; SAMPLE_ITERATOR_INTERLEAVED i; public: virtual std::string name(void) const { return("Mix to channel"); } virtual std::string parameter_names(void) const { return("to-channel"); } int output_channels(int i_channels) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; void init(SAMPLE_BUFFER *insample); void process(void); EFFECT_MIX_TO_CHANNEL* clone(void) const { return new EFFECT_MIX_TO_CHANNEL(*this); } EFFECT_MIX_TO_CHANNEL* new_expr(void) const { return new EFFECT_MIX_TO_CHANNEL(); } EFFECT_MIX_TO_CHANNEL (parameter_t to_channel = 1.0); }; /** * Arbitrary channel routing * @author Kai Vehmanen */ class EFFECT_CHANNEL_ORDER : public EFFECT_MIXING { private: SAMPLE_ITERATOR_CHANNEL f_iter, t_iter; SAMPLE_BUFFER *sbuf_repp; SAMPLE_BUFFER bouncebuf_rep; std::string param_names_rep; std::vector chsrc_map_rep; int out_channels_rep; public: virtual std::string name(void) const { return("Channel select"); } virtual std::string parameter_names(void) const; int output_channels(int i_channels) const; virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual bool variable_params(void) const { return true; } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); EFFECT_CHANNEL_ORDER* clone(void) const; EFFECT_CHANNEL_ORDER* new_expr(void) const { return new EFFECT_CHANNEL_ORDER(); } EFFECT_CHANNEL_ORDER(void); }; #endif ecasound-2.9.1/libecasound/audioio.h0000644000076400007640000002411511161513242014346 00000000000000#ifndef INCLUDED_AUDIOIO_H #define INCLUDED_AUDIOIO_H #include #include "eca-audio-position.h" #include "eca-audio-time.h" #include "eca-audio-format.h" #include "dynamic-object.h" class SAMPLE_BUFFER; class AUDIO_IO_MANAGER; using std::string; /** * Virtual base class for all audio I/O objects. Different types * of audio objects include files, audio devices, sound * producing program modules, audio server clients, and so on. * * The class interface is divided into following sections: * * - type definitions * * - attributes * * - configuration (setting and getting configuration parameters) * * - functionality (control and runtime information) * * - runtime information * * - constructors and destructors * * @author Kai Vehmanen */ class AUDIO_IO : public DYNAMIC_OBJECT, public ECA_AUDIO_FORMAT, public ECA_AUDIO_POSITION { public: /** @name Public type definitions and constants */ /*@{*/ /** * Input/Output mode * * @see io_mode() * * io_read * * Device is opened for input. If opening a file, * it must exist. * * io_write * * Device is opened for output. If opening a file and * and output exists, it is first truncated. * * io_readwrite * * Device is opened for both reading and writing. If * opening a file, a new file is created if needed. * When switching from read to write or vica versa, * position should be reset before using the device. **/ enum Io_mode { io_read = 1, io_write = 2, io_readwrite = 4 }; class SETUP_ERROR { public: enum Error_type { sample_format, /* unsupported sample format */ channels, /* unsupported channel count */ sample_rate, /* unsupported sample_rate */ interleaving, /* non-interleaved or interleaved channel organization not supported */ io_mode, /* unsupported I/O mode */ buffersize, /* unsupported buffersize */ blockmode, /* non-blocking or blocking mode not supported */ dynamic_params, /* invalid dynamic parameters (for instance invalid label()) */ unexpected /* unexpected/unknown error */ }; const string& message(void) const; Error_type type(void) const; SETUP_ERROR(Error_type type, const string& message); private: Error_type type_rep; string message_rep; }; public: /*@}*/ /** @name Public functions for handling object managers */ /*@{*/ /** * Creates an object manager for this audio object type. * * @return 0 if no manager objects are not supported */ virtual AUDIO_IO_MANAGER* create_object_manager(void) const { return(0); } /*@}*/ /** @name Constructors and destructors */ /*@{*/ virtual AUDIO_IO* clone(void) const = 0; virtual AUDIO_IO* new_expr(void) const = 0; virtual ~AUDIO_IO(void); AUDIO_IO(const string& name = "uninitialized", int mode = io_read); /*@}*/ /** @name Attribute functions */ /*@{*/ virtual int supported_io_modes(void) const; virtual bool supports_nonblocking_mode(void) const; virtual bool finite_length_stream(void) const; virtual bool locked_audio_format(void) const; /*@}*/ /** @name Configuration * * For setting and getting configuration parameters. */ /*@{*/ /** * Sets the sample buffer size in sample frames. * * When reading data with read_buffer(), buffersize() * determines how many sample frames of data is * processed per call. * * Otherwise buffersize() is only used for initializing * devices and data structures. * * Device should always be able to write all sample * data passed to write_buffer(), independently from current * buffersize() value. * * @see buffersize() */ virtual void set_buffersize(long int samples) = 0; /** * Returns the current buffersize in sample frames. * * @see set_buffersize() */ virtual long int buffersize(void) const = 0; int io_mode(void) const; const string& label(void) const; string format_info(void) const; void set_io_mode(int mode); void set_label(const string& id_label); void toggle_nonblocking_mode(bool value); virtual string parameter_names(void) const { return("label"); } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; public: /*@}*/ /** @name Main functionality */ /*@{*/ /** * Reads samples and store them to buffer pointed by 'sbuf'. If * necessary, the target buffer will be resized (both length * and number of channels). * * The sample buffer event tags may also be set during * this method call (see SAMPLE_BUFFER documentation for more * details). * * It's important to note that SAMPLE_BUFFER audio format cannot be * changed during processing. This means that audio data must be converted * from audio object's internal format to that of 'sbuf' given as * argument. SAMPLE_BUFFER class provides tools for all normal conversion * operations. If you need direct access to object's data, a lower * abstraction level should be used (@see AUDIO_IO_BUFFERED). * * Note! The implementations should call set_position_in_samples() * or change_position_in_samples() in ECA_AUDIO_POSITION. * * @pre io_mode() == io_read || io_mode() == io_readwrite * @pre readable() == true * @pre sbuf != 0 * @post sbuf->length_in_samples() <= buffersize() * @post sbuf->number_of_channels() == channels() */ virtual void read_buffer(SAMPLE_BUFFER* sbuf) = 0; /** * Writes all data from sample buffer pointed by 'sbuf' to * this object. Notes concerning read_buffer() also apply to * this routine. * * Note! The implementations should call set_position_in_samples() * or change_position_in_samples() in ECA_AUDIO_POSITION. * * @pre io_mode() == io_write || io_mode() == io_readwrite * @pre writable() == true * @pre sbuf != 0 */ virtual void write_buffer(SAMPLE_BUFFER* sbuf) = 0; /** * Opens the audio object (possibly in exclusive mode). * This routine is used for initializing external connections * (opening files or devices, loading shared libraries, * opening IPC connections). As it's impossible to know in * advance what might happen, open() may throw an * exception. This way it becomes possible to provide * more verbose information about the problem that caused * open() to fail. * * At this point the various audio parameters are used * for the first time. Unless locked_audio_format() is 'true', * object tries to use the audio format parameters set prior to * this call. If object doesn't support the given parameter * combination, it can either try adjust them to closest * matching, or in the worst case, throw an SETUP_ERROR * exception (see above). * * @pre is_open() != true * @post readable() == true || writable() == true || is_open() != true */ virtual void open(void) throw (AUDIO_IO::SETUP_ERROR &); /** * Closes audio object. After calling this routine, * all resources (for instance files and devices) must * be freed so that they can be used by other processes. * * @pre is_open() == true * @post readable() != true * @post writable() != true */ virtual void close(void); /*@}*/ /** @name Runtime information */ /*@{*/ /** * Returns a file descriptor id suitable for poll() and * select() system calls. If polling is not supported, * returns value of '-1'. */ virtual int poll_descriptor(void) const { return(-1); } /** * If 'supports_nonblocking_mode() == true', this function returns * the number of samples frames that is available for reading, or * alternatively, how many sample frames can be written without * blocking. This function can be used for implementing nonblocking * input and output with devices supporting it. * * Note, you should use set_buffersize() for setting how * many sample frames read_buffer() will ask from the device. * * require: * supports_nonblocking_mode() == true */ virtual long int samples_available(void) const { return(0); } /** * Has device been opened (with open())? */ bool is_open(void) const { return(open_rep); } /** * Whether all data has been processed? If opened in mode 'io_read', * this means that end of stream has been reached. If opened in * 'io_write' or 'io_readwrite' modes, finished status usually * means that an error has occured (no space left, etc). After * finished() has returned 'true', further calls to read_buffer() * and/or write_buffer() won't process any data. * * For output for which 'finite_length_stream()' is true, when * 'finished()' returns true, that means an error has occured. * Otherwise 'finished()' just tells that further attempts to do * i/o will fail. */ virtual bool finished(void) const = 0; virtual bool nonblocking_mode(void) const; virtual bool readable(void) const; virtual bool writable(void) const; virtual string status(void) const; ECA_AUDIO_TIME length(void) const; ECA_AUDIO_TIME position(void) const; /*@}*/ /** @name Functions overridden and reimplemented from * ECA_AUDIO_POSITION and ECA_AUDIO_FORMAT */ /*@{*/ SAMPLE_SPECS::sample_rate_t samples_per_second(void) const; virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); virtual void set_audio_format(const ECA_AUDIO_FORMAT& f_str); /*@}*/ /** @name Functions implemented from ECA_AUDIO_POSITION */ /*@{*/ virtual bool supports_seeking(void) const; virtual bool supports_seeking_sample_accurate(void) const; virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ protected: /** @name Functions provided for subclasses. */ /*@{*/ void position(const ECA_AUDIO_TIME& v); void length(const ECA_AUDIO_TIME& v); std::string parameter_get_to_string(int param) const; std::string parameter_set_to_string(int param, std::string value) const; /*@{*/ private: int io_mode_rep; string id_label_rep; bool nonblocking_rep; bool open_rep; }; #endif ecasound-2.9.1/libecasound/audio-stamp.h0000644000076400007640000000154310664032032015140 00000000000000#ifndef INCLUDED_AUDIO_STAMP_H #define INCLUDED_AUDIO_STAMP_H #include #include "samplebuffer.h" class AUDIO_STAMP { public: int id(void) const; void fetch_stamp(SAMPLE_BUFFER* x); AUDIO_STAMP(void); protected: void set_id(int n); void store(const SAMPLE_BUFFER* x); private: SAMPLE_BUFFER buffer_rep; int id_rep; bool id_set_rep; }; class AUDIO_STAMP_SERVER { public: void register_stamp(AUDIO_STAMP* stamp); void fetch_stamp(int id, SAMPLE_BUFFER* x); private: std::map stamp_map_rep; }; class AUDIO_STAMP_CLIENT { public: int id(void) const; void register_server(AUDIO_STAMP_SERVER* server); AUDIO_STAMP_CLIENT(void); protected: void set_id(int n); void fetch_stamp(SAMPLE_BUFFER* x); private: int id_rep; bool id_set_rep; AUDIO_STAMP_SERVER* server_repp; }; #endif ecasound-2.9.1/libecasound/audioio-acseq.h0000644000076400007640000000356711032517543015455 00000000000000#ifndef INCLUDED_AUDIOIO_CLIP_SEQUENCER_H #define INCLUDED_AUDIOIO_CLIP_SEQUENCER_H #include "audioio-seqbase.h" /** * Audio clip sequencer class. Allows to loop, play parts * of, and play files at a specific moment of time. * * Related design patterns: * - Proxy (GoF207 * * @author Kai Vehmanen */ class AUDIO_CLIP_SEQUENCER : public AUDIO_SEQUENCER_BASE { public: enum { cseq_none = 0, cseq_loop = 1, cseq_select = 2, cseq_play_at = 3 }; /** @name Public functions */ /*@{*/ AUDIO_CLIP_SEQUENCER (void); virtual ~AUDIO_CLIP_SEQUENCER(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return("Audio clip sequencer"); } virtual std::string description(void) const { return("Audio clip sequencer. Supports looping and slicing of audio file segments."); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual std::string parameter_names(void) const; virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_CLIP_SEQUENCER* clone(void) const; virtual AUDIO_CLIP_SEQUENCER* new_expr(void) const { return new AUDIO_CLIP_SEQUENCER(); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); /*@}*/ /** @name New functions */ /*@{*/ /*@}*/ private: mutable std::vector params_rep; int child_param_offset_rep; int cseq_mode_rep; AUDIO_CLIP_SEQUENCER& operator=(const AUDIO_CLIP_SEQUENCER& x) { return *this; } AUDIO_CLIP_SEQUENCER (const AUDIO_CLIP_SEQUENCER& x) { } }; #endif ecasound-2.9.1/libecasound/Makefile.am0000644000076400007640000002520511740524567014620 00000000000000# ---------------------------------------------------------------------- # File: ecasound/libecasound/Makefile.am # Description: Ecasound main library # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- EXTRA_DIST = ChangeLog AUTOMAKE_OPTIONS = foreign SUBDIRS = plugins # ---------------------------------------------------------------------- # build targets and compiler options target defines # ---------------------------------------------------------------------- if ECA_AM_DEBUG_MODE lib_LTLIBRARIES = libecasound_debug.la else lib_LTLIBRARIES = libecasound.la endif TESTS = libecasound_tester check_PROGRAMS = libecasound_tester # ---------------------------------------------------------------------- # compiler and linker options # ---------------------------------------------------------------------- # if ECA_AM_ALL_STATIC # FIXME: always link ecasound-plugins statically if ECA_AM_DEBUG_MODE eca_libadd = $(top_builddir)/libecasound/plugins/libecasound_plugins_debug.la $(ECA_S_EXTRA_LIBS) else eca_libadd = $(top_builddir)/libecasound/plugins/libecasound_plugins.la $(ECA_S_EXTRA_LIBS) endif eca_ldflags = -version-info @LIBECASOUND_VERSION@:0:@LIBECASOUND_VERSION_AGE@ if ECA_AM_DEBUG_MODE libecasound_tester_libs = $(top_builddir)/libecasound/libecasound_debug.la \ $(top_builddir)/kvutils/libkvutils_debug.la else libecasound_tester_libs = $(top_builddir)/libecasound/libecasound.la \ $(top_builddir)/kvutils/libkvutils.la endif # note! Automake >= 1.5 will install stripped libraries # with "make install-strip". Older versions won't # strip libraries even if INSTALL_STRIP_FLAG is set. # also libtool 1.3.2 and older have problems # with stripping libraries. INCLUDES = -I$(srcdir) \ -I$(top_srcdir) \ -I$(top_srcdir)/kvutils \ $(ECA_S_EXTRA_CPPFLAGS) # ---------------------------------------------------------------------- # header files # ---------------------------------------------------------------------- ecasound_audiofx_include = \ audiofx.h \ audiofx_misc.h \ audiofx_amplitude.h \ audiofx_compressor.h \ audiofx_analysis.h \ audiofx_envelope_modulation.h \ audiofx_filter.h \ audiofx_rcfilter.h \ audiofx_reverb.h \ audiofx_timebased.h \ audiogate.h \ audiofx_mixing.h \ audiofx_ladspa.h \ audiofx_lv2.h \ audiofx_lv2_world.h \ audio-stamp.h ecasound_preset_include = \ preset.h \ preset_impl.h \ file-preset.h \ global-preset.h ecasound_audioio_include = \ audioio.h \ audioio-buffered.h \ audioio-device.h \ audioio-plugin.h \ audioio-manager.h \ audioio-cdr.h \ audioio-cdr_impl.h \ audioio-ewf.h \ audioio-mp3.h \ audioio-mp3_impl.h \ audioio-ogg.h \ audioio-wave.h \ audioio-raw.h \ audioio-oss.h \ audioio-oss_impl.h \ audioio-null.h \ audioio-rtnull.h \ audioio-mikmod.h \ audioio-loop.h \ audioio-forked-stream.h \ audioio-timidity.h \ audioio-db-server.h \ audioio-db-server_impl.h \ audioio-db-buffer.h \ audioio-db-client.h \ audioio-proxy.h \ audioio-typeselect.h \ audioio-resample.h \ audioio-reverse.h \ audioio-flac.h \ audioio-aac.h \ audioio-tone.h \ audioio-seqbase.h \ audioio-acseq.h \ audioio-barrier.h ecasound_midi_include = \ midi-server.h \ midi-client.h \ midi-parser.h \ midiio.h \ midiio-raw.h \ midiio-aseq.h ecasound_controller_include = \ ctrl-source.h \ midi-cc.h \ oscillator.h \ osc-gen.h \ osc-gen-file.h \ osc-sine.h \ linear-envelope.h \ two-stage-linear-envelope.h \ stamp-ctrl.h \ generic-linear-envelope.h ecasound_general_include = \ eca-chain.h \ eca-chainop.h \ eca-chainsetup-edit.h \ eca-error.h \ eca-logger.h \ eca-logger-default.h \ eca-logger-interface.h \ eca-logger-wellformed.h \ eca-engine.h \ eca-engine-driver.h \ eca-engine_impl.h \ eca-session.h \ eca-resources.h \ resource-file.h \ layer.h \ eca-static-object-maps.h \ eca-object-map.h \ eca-preset-map.h \ samplebuffer.h \ samplebuffer_impl.h \ samplebuffer_functions.h \ samplebuffer_iterators.h \ sample-specs.h \ sample-ops_impl.h \ eca-sample-conversion.h \ eca-version.h \ eca-object-factory.h \ eca-chainsetup.h \ eca-chainsetup_impl.h \ eca-chainsetup-bufparams.h \ eca-chainsetup-parser.h \ eca-chainsetup-position.h \ eca-control.h \ eca-control-dump.h \ eca-control-main.h \ eca-control-mt.h \ eca-iamode-parser.h \ eca-iamode-parser_impl.h \ eca-audio-position.h \ eca-fileio.h \ eca-fileio-stream.h \ eca-fileio-mmap.h \ eca-osc.h \ dynamic-parameters.h \ dynamic-object.h \ eca-object.h \ eca-operator.h \ generic-controller.h \ eca-samplerate-aware.h \ eca-audio-format.h \ eca-audio-time.h \ jack-connections.h ecasound_extra_include = \ ladspa.h ecasound_test_framework_include = \ eca-test-repository.h \ eca-test-case.h \ audiofx_amplitude_test.h \ audioio_test.h \ audioio-device_test.h \ eca-audio-time_test.h \ eca-chainsetup_test.h \ eca-chainsetup-parser_test.h \ eca-control_test.h \ eca-session_test.h \ eca-object-factory_test.h \ eca-sample-conversion_test.h \ generic-linear-envelope_test.h \ samplebuffer_test.h # note! also remembers to update install-data-local and # uninstall-data targets noinst_HEADERS = $(ecasound_audiofx_include) \ $(ecasound_preset_include) \ $(ecasound_audioio_include) \ $(ecasound_midi_include) \ $(ecasound_controller_include) \ $(ecasound_general_include) \ $(ecasound_extra_include) \ $(ecasound_test_framework_include) # ---------------------------------------------------------------------- # source files # ---------------------------------------------------------------------- ecasound_audiofx_src = audiofx.cpp \ audiofx_misc.cpp \ audiofx_amplitude.cpp \ audiofx_compressor.cpp \ audiofx_analysis.cpp \ audiofx_envelope_modulation.cpp \ audiofx_filter.cpp \ audiofx_rcfilter.cpp \ audiofx_reverb.cpp \ audiofx_timebased.cpp \ audiogate.cpp \ audiofx_mixing.cpp \ audiofx_ladspa.cpp \ audiofx_lv2.cpp \ audiofx_lv2_world.cpp \ audio-stamp.cpp ecasound_preset_src = global-preset.cpp \ preset.cpp \ file-preset.cpp ecasound_audioio1_src = audioio-cdr.cpp \ audioio-ewf.cpp \ audioio-mp3.cpp \ audioio-ogg.cpp \ audioio-wave.cpp \ audioio.cpp \ audioio-buffered.cpp \ audioio-device.cpp \ audioio-null.cpp \ audioio-raw.cpp \ audioio-mikmod.cpp \ audioio-rtnull.cpp \ audioio-loop.cpp \ audioio-forked-stream.cpp \ audioio-timidity.cpp \ audioio-db-server.cpp \ audioio-db-buffer.cpp \ audioio-db-client.cpp \ audioio-typeselect.cpp \ audioio-resample.cpp \ audioio-reverse.cpp \ audioio-proxy.cpp \ audioio-flac.cpp \ audioio-aac.cpp \ audioio-tone.cpp \ audioio-seqbase.cpp \ audioio-acseq.cpp if ECA_AM_COMPILE_OSS ecasound_audioio2_src = audioio-oss.cpp else ecasound_audioio2_src = endif if ECA_AM_COMPILE_JACK jack_connections_src = jack-connections.cpp else jack_connections_src = endif ecasound_midi_src = \ midi-server.cpp \ midi-client.cpp \ midi-parser.cpp \ midiio.cpp \ midiio-raw.cpp \ midiio-aseq.cpp ecasound_controller_src = \ midi-cc.cpp \ osc-gen.cpp \ osc-gen-file.cpp \ osc-sine.cpp \ linear-envelope.cpp \ two-stage-linear-envelope.cpp \ stamp-ctrl.cpp \ generic-linear-envelope.cpp ecasound_general_src = eca-chain.cpp \ eca-engine.cpp \ samplebuffer.cpp \ samplebuffer_functions.cpp \ eca-session.cpp \ eca-resources.cpp \ resource-file.cpp \ eca-logger.cpp \ eca-logger-default.cpp \ eca-logger-interface.cpp \ eca-logger-wellformed.cpp \ layer.cpp \ samplebuffer_iterators.cpp \ eca-version.cpp \ eca-operator.cpp \ generic-controller.cpp \ eca-object-factory.cpp \ eca-chainsetup.cpp \ eca-chainsetup-bufparams.cpp \ eca-chainsetup-parser.cpp \ eca-chainsetup-position.cpp \ eca-control.cpp \ eca-control-base.cpp \ eca-control-dump.cpp \ eca-control-main.cpp \ eca-control-mt.cpp \ eca-control-objects.cpp \ eca-iamode-parser.cpp \ eca-samplerate-aware.cpp \ eca-audio-position.cpp \ eca-audio-format.cpp \ eca-audio-time.cpp \ eca-fileio-stream.cpp \ eca-fileio-mmap.cpp \ eca-osc.cpp \ eca-static-object-maps.cpp \ eca-object-map.cpp \ eca-preset-map.cpp ecasound_common1_src = $(ecasound_audioio1_src) \ $(ecasound_audioio2_src) \ $(jack_connections_src) \ $(ecasound_midi_src) \ $(ecasound_general_src) if ECA_AM_DISABLE_EFFECTS ecasound_common2_src = else ecasound_common2_src = $(ecasound_audiofx_src) \ $(ecasound_preset_src) \ $(ecasound_controller_src) endif libecasound_tester_src = \ libecasound_tester.cpp \ eca-test-repository.cpp \ eca-test-case.cpp libecasound_la_SOURCES = $(ecasound_common1_src) $(ecasound_common2_src) libecasound_debug_la_SOURCES = $(ecasound_common1_src) $(ecasound_common2_src) libecasound_la_LDFLAGS = -export-dynamic $(eca_ldflags) -static libecasound_la_LIBADD = $(eca_libadd) libecasound_debug_la_LDFLAGS = $(libecasound_la_LDFLAGS) libecasound_debug_la_LIBADD = $(libecasound_la_LIBADD) libecasound_tester_SOURCES = $(libecasound_tester_src) #libecasound_tester_CFLAGS = $(AM_CFLAGS) libecasound_tester_LDADD = $(libecasound_tester_libs) # Pass pkgdatadir to CPPFLAGS AM_CPPFLAGS += "-DECA_PKGDATADIR=\"${pkgdatadir}\"" # --------------------------------------------------------------------- # Install targets - note! we don't install $ecasound_extra_include # nor $ecasound_test_framework_include install-data-local: $(INSTALL) -d $(DESTDIR)$(includedir)/libecasound cd $(srcdir) ; \ $(INSTALL_DATA) \ $(ecasound_audiofx_include) \ $(ecasound_preset_include) \ $(ecasound_audioio_include) \ $(ecasound_controller_include) \ $(ecasound_midi_include) \ $(ecasound_general_include) \ $(DESTDIR)$(includedir)/libecasound $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL_SCRIPT) libecasound-config $(DESTDIR)$(bindir)/libecasound-config # --------------------------------------------------------------------- # Uninstall targets uninstall-local: cd $(DESTDIR)$(includedir)/libecasound && \ rm -f $(ecasound_audiofx_include) \ $(ecasound_preset_include) \ $(ecasound_audioio_include) \ $(ecasound_controller_include) \ $(ecasound_midi_include) \ $(ecasound_general_include) rmdir $(DESTDIR)$(includedir)/libecasound || echo "Skipping" rm -f $(DESTDIR)$(bindir)/libecasound-config rmdir $(DESTDIR)$(bindir) || echo "Skipping" ecasound-2.9.1/libecasound/audiofx_ladspa.cpp0000644000076400007640000003144411612474705016251 00000000000000// ------------------------------------------------------------------------ // audiofx_ladspa.cpp: Wrapper class for LADSPA plugins // Copyright (C) 2000-2004,2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // References: // http://www.ladspa.org // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "samplebuffer.h" #include "audiofx_ladspa.h" #include "eca-error.h" #include "eca-logger.h" EFFECT_LADSPA::EFFECT_LADSPA (const LADSPA_Descriptor *pdesc) throw(ECA_ERROR&) { plugin_desc = pdesc; if ((plugin_desc->Properties & LADSPA_PROPERTY_INPLACE_BROKEN) == LADSPA_PROPERTY_INPLACE_BROKEN) throw(ECA_ERROR("AUDIOFX_LADSPA", "Inplace-broken plugins not supported.")); /* FIXME: strip linefeeds and other forbidden characters; write down to * to ECA_OBJECT docs what chars are allowed and what are not... */ name_rep = string(plugin_desc->Name); unique_rep = string(plugin_desc->Label); maker_rep = string(plugin_desc->Maker); unique_number_rep = static_cast(plugin_desc->UniqueID); buffer_repp = 0; init_ports(); } EFFECT_LADSPA::~EFFECT_LADSPA (void) { release(); if (plugin_desc != 0) { for(unsigned int n = 0; n < plugins_rep.size(); n++) { if (plugin_desc->deactivate != 0) plugin_desc->deactivate(plugins_rep[n]); if (plugin_desc->cleanup != 0) plugin_desc->cleanup(plugins_rep[n]); } } } std::string EFFECT_LADSPA::description(void) const { return name_rep + " - Author: '" + maker_rep + "'"; } EFFECT_LADSPA* EFFECT_LADSPA::clone(void) const { EFFECT_LADSPA* result = new EFFECT_LADSPA(plugin_desc); for(int n = 0; n < number_of_params(); n++) { result->set_parameter(n + 1, get_parameter(n + 1)); } return result; } void EFFECT_LADSPA::init_ports(void) { // note: run from plugin constructor port_count_rep = plugin_desc->PortCount; in_audio_ports = 0; out_audio_ports = 0; for(unsigned long m = 0; m < port_count_rep; m++) { if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_AUDIO) == LADSPA_PORT_AUDIO) { if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_INPUT) == LADSPA_PORT_INPUT) ++in_audio_ports; else ++out_audio_ports; } if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_CONTROL) == LADSPA_PORT_CONTROL) { struct PARAM_DESCRIPTION pd; parse_parameter_hint_information(m, params.size() + 1, &pd); params.push_back(pd.default_value); param_descs_rep.push_back(pd); if (params.size() > 1) param_names_rep += ","; string tmp (kvu_string_search_and_replace(string(plugin_desc->PortNames[m]), ",", "\\,")); param_names_rep += kvu_string_search_and_replace(tmp, ":", "\\:"); } } } void EFFECT_LADSPA::parse_parameter_hint_information(int portnum, int paramnum, struct PARAM_DESCRIPTION *pd) { LADSPA_PortRangeHintDescriptor hintdescriptor = plugin_desc->PortRangeHints[portnum].HintDescriptor; /* if srate not set, use 44.1kHz (used only for calculating * param hint values */ SAMPLE_SPECS::sample_rate_t srate = samples_per_second(); /* FIXME: this is just ugly! */ if (srate <= 0) { srate = 44100; } /** * For LADSPA v1.1, parameter hint information is * used as advertised by the plugin. LADSPA v1.0 * API doesn't specify how to initialize control * ports to sane initial values, so we just try to * make an educated guess based on the lower and * upper bounds. * * 1) v1.1 hint information available * 2) lowb == x and upperb == n/a * a) x < 0, initval = 0 * b) x >= 0, initval = x * 3) lowb == n/a and upperb == x * a) x > 0, initval = 0 * b) x <= 0, initval = x * 4) lowb == x and upperb == y * a) x < 0 and y > 0, initval = 0 * b) x < 0 and y < 0, initval = y * c) x > 0 and y > 0, initval = x * 5) lowb == n/a and upperb == n/a, initval = 1 */ /* parameter name */ pd->description = string(plugin_desc->PortNames[portnum]); /* upper and lower bounds */ if (LADSPA_IS_HINT_BOUNDED_BELOW(hintdescriptor)) { pd->bounded_below = true; if (LADSPA_IS_HINT_SAMPLE_RATE(hintdescriptor)) pd->lower_bound = plugin_desc->PortRangeHints[portnum].LowerBound * srate; else pd->lower_bound = plugin_desc->PortRangeHints[portnum].LowerBound; } else { pd->bounded_below = false; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hintdescriptor)) { pd->bounded_above = true; if (LADSPA_IS_HINT_SAMPLE_RATE(hintdescriptor)) pd->upper_bound = plugin_desc->PortRangeHints[portnum].UpperBound * srate; else pd->upper_bound = plugin_desc->PortRangeHints[portnum].UpperBound; } else { pd->bounded_above = false; } /* defaults - case 1 */ if (LADSPA_IS_HINT_HAS_DEFAULT(hintdescriptor)) { if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hintdescriptor)) { pd->default_value = pd->lower_bound; } /* FIXME: add support for logarithmic defaults */ else if (LADSPA_IS_HINT_DEFAULT_LOW(hintdescriptor)) { pd->default_value = pd->lower_bound * 0.75f + pd->upper_bound * 0.25f; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hintdescriptor)) { pd->default_value = pd->lower_bound * 0.50f + pd->upper_bound * 0.50f; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hintdescriptor)) { pd->default_value = pd->lower_bound * 0.25f + pd->upper_bound * 0.75f; } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hintdescriptor)) { pd->default_value = pd->upper_bound; } else if (LADSPA_IS_HINT_DEFAULT_0(hintdescriptor)) { pd->default_value = 0.0f; } else if (LADSPA_IS_HINT_DEFAULT_1(hintdescriptor)) { pd->default_value = 1.0f; } else if (LADSPA_IS_HINT_DEFAULT_100(hintdescriptor)) { pd->default_value = 100.0f; } else if (LADSPA_IS_HINT_DEFAULT_440(hintdescriptor)) { pd->default_value = 440.0f; } else { ECA_LOG_MSG(ECA_LOGGER::info, "No LADSPA hint info found for plugin '" + name_rep + "'."); } } /* defaults - case 2 */ else if (LADSPA_IS_HINT_BOUNDED_BELOW(hintdescriptor) && !LADSPA_IS_HINT_BOUNDED_ABOVE(hintdescriptor)) { if (pd->lower_bound < 0) pd->default_value = 0.0f; else pd->default_value = pd->lower_bound; } /* defaults - case 3 */ else if (!LADSPA_IS_HINT_BOUNDED_BELOW(hintdescriptor) && LADSPA_IS_HINT_BOUNDED_ABOVE(hintdescriptor)) { if (pd->upper_bound > 0) pd->default_value = 0.0f; else pd->default_value = pd->upper_bound; } /* defaults - case 4 */ else if (LADSPA_IS_HINT_BOUNDED_BELOW(hintdescriptor) && LADSPA_IS_HINT_BOUNDED_ABOVE(hintdescriptor)) { if (pd->lower_bound < 0 && pd->upper_bound > 0) pd->default_value = 0.0f; else if (pd->lower_bound < 0 && pd->upper_bound < 0) pd->default_value = pd->upper_bound; else pd->default_value = pd->lower_bound; } /* defaults - case 5 */ else { DBC_CHECK(!LADSPA_IS_HINT_BOUNDED_BELOW(hintdescriptor) && !LADSPA_IS_HINT_BOUNDED_ABOVE(hintdescriptor)); if (LADSPA_IS_HINT_SAMPLE_RATE(hintdescriptor)) pd->default_value = srate; else pd->default_value = 1.0f; } if (LADSPA_IS_HINT_TOGGLED(hintdescriptor)) pd->toggled = true; else pd->toggled = false; if (LADSPA_IS_HINT_INTEGER(hintdescriptor)) pd->integer = true; else pd->integer = false; if (LADSPA_IS_HINT_LOGARITHMIC(hintdescriptor)) pd->logarithmic = true; else pd->logarithmic = false; if ((plugin_desc->PortDescriptors[portnum] & LADSPA_PORT_OUTPUT) == LADSPA_PORT_CONTROL) pd->output = true; else pd->output = false; } void EFFECT_LADSPA::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const { DBC_CHECK(param >= 0); DBC_CHECK(param <= static_cast(param_descs_rep.size())); *pd = param_descs_rep[param - 1]; } void EFFECT_LADSPA::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { if (param > 0 && (param - 1 < static_cast(params.size()))) { // cerr << "ladspa: setting param " << param << " to " << value << "." << endl; params[param - 1] = value; } } CHAIN_OPERATOR::parameter_t EFFECT_LADSPA::get_parameter(int param) const { if (param > 0 && (param - 1 < static_cast(params.size()))) { // cerr << "ladspa: getting param " << param << " with value " << params[param - 1] << "." << endl; return(params[param - 1]); } return(0.0); } int EFFECT_LADSPA::output_channels(int i_channels) const { // note: We have two separate cases: either one plugin // is instantiated for each channel, or one plugin // per chain. See EFFECT_LADSPA::init(). if (in_audio_ports > 1 || out_audio_ports > 1) { return out_audio_ports; } return i_channels; } void EFFECT_LADSPA::init(SAMPLE_BUFFER *insample) { EFFECT_BASE::init(insample); DBC_CHECK(samples_per_second() > 0); if (buffer_repp != insample) { release(); buffer_repp = insample; buffer_repp->get_pointer_reflock(); } if (plugin_desc != 0) { for(unsigned int n = 0; n < plugins_rep.size(); n++) { if (plugin_desc->deactivate != 0) plugin_desc->deactivate(plugins_rep[n]); plugin_desc->cleanup(plugins_rep[n]); } } // NOTE: the fancy definition :) // if ((in_audio_ports > 1 && // in_audio_ports <= channels() && // out_audio_ports <= channels()) || // (out_audio_ports > 1 && // in_audio_ports <= channels() && // out_audio_ports <= channels())) {} if (in_audio_ports > 1 || out_audio_ports > 1) { plugins_rep.resize(1); plugins_rep[0] = reinterpret_cast(plugin_desc->instantiate(plugin_desc, samples_per_second())); int inport = 0; int outport = 0; for(unsigned long m = 0; m < port_count_rep; m++) { if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_AUDIO) == LADSPA_PORT_AUDIO) { if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_INPUT) == LADSPA_PORT_INPUT) { if (inport < channels()) plugin_desc->connect_port(plugins_rep[0], m, buffer_repp->buffer[inport]); ++inport; } else { if (outport < channels()) plugin_desc->connect_port(plugins_rep[0], m, buffer_repp->buffer[outport]); ++outport; } } } if (inport > channels()) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: chain has less channels than plugin has input ports (" + name() + ")."); if (outport > channels()) ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: chain has less channels than plugin has output ports (" + name() + ")."); } else { plugins_rep.resize(channels()); for(unsigned int n = 0; n < plugins_rep.size(); n++) { plugins_rep[n] = reinterpret_cast(plugin_desc->instantiate(plugin_desc, samples_per_second())); for(unsigned long m = 0; m < port_count_rep; m++) { if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_AUDIO) == LADSPA_PORT_AUDIO) { plugin_desc->connect_port(plugins_rep[n], m, buffer_repp->buffer[n]); } } } } ECA_LOG_MSG(ECA_LOGGER::system_objects, "Instantiated " + kvu_numtostr(plugins_rep.size()) + " LADSPA plugin(s), each with " + kvu_numtostr(in_audio_ports) + " audio input port(s) and " + kvu_numtostr(out_audio_ports) + " output port(s), to chain with " + kvu_numtostr(channels()) + " channel(s) and srate of " + kvu_numtostr(samples_per_second()) + "."); int data_index = 0; for(unsigned long m = 0; m < port_count_rep; m++) { if ((plugin_desc->PortDescriptors[m] & LADSPA_PORT_CONTROL) == LADSPA_PORT_CONTROL) { for(unsigned int n = 0; n < plugins_rep.size(); n++) { plugin_desc->connect_port(plugins_rep[n], m, &(params[data_index])); } ++data_index; } } for(unsigned long m = 0; m < plugins_rep.size(); m++) if (plugin_desc->activate != 0) plugin_desc->activate(plugins_rep[m]); } void EFFECT_LADSPA::release(void) { if (buffer_repp != 0) { buffer_repp->release_pointer_reflock(); } buffer_repp = 0; } void EFFECT_LADSPA::process(void) { for(unsigned long m = 0; m < plugins_rep.size(); m++) plugin_desc->run(plugins_rep[m], buffer_repp->length_in_samples()); } ecasound-2.9.1/libecasound/midiio.h0000644000076400007640000001014710664032032014167 00000000000000#ifndef INCLUDED_MIDIIO_H #define INCLUDED_MIDIIO_H #include #include "dynamic-object.h" /** * Virtual base for all MIDI I/O classes. * * - type definitions * * - attributes * * - configuration (setting and getting configuration parameters) * * - functionality (control and runtime information) * * - runtime information * * - constructors and destructors * * @author Kai Vehmanen */ class MIDI_IO : public DYNAMIC_OBJECT { public: /** @name Public type definitions and constants */ /*@{*/ /** * Input/Output mode * * @see io_mode() * * io_read * * Object is opened for input. If opening a file, * it must exist. * * io_write * * Object is opened for output. If opening a file and * and output exists, it is first truncated. * * io_readwrite * * Object is opened for both reading and writing. If * opening a file, a new file is created if needed. * When switching from read to write or vica versa, * position should be reset before using the device. **/ enum Io_mode { io_read = 1, io_write = 2, io_readwrite = 4 }; /*@}*/ public: /** @name Constructors and destructors */ /*@{*/ virtual MIDI_IO* clone(void) const = 0; virtual MIDI_IO* new_expr(void) const = 0; virtual ~MIDI_IO(void); MIDI_IO(const std::string& name = "unknown", int mode = io_read); /*@}*/ /** @name Attribute functions */ /*@{*/ virtual int supported_io_modes(void) const; virtual bool supports_nonblocking_mode(void) const; /*@}*/ /** @name Configuration * * For setting and getting configuration parameters. */ /*@{*/ int io_mode(void) const; const std::string& label(void) const; void io_mode(int mode); void label(const std::string& id_label); void toggle_nonblocking_mode(bool value); virtual std::string parameter_names(void) const { return("label"); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Main functionality */ /*@{*/ public: /** * Low-level routine for reading MIDI bytes. Number of read bytes * is returned. This must be implemented by all subclasses. */ virtual long int read_bytes(void* target_buffer, long int bytes) = 0; /** * Low-level routine for writing MIDI bytes. Number of bytes written * is returned. This must be implemented by all subclasses. */ virtual long int write_bytes(void* target_buffer, long int bytes) = 0; /** * Opens the MIDI object (possibly in exclusive mode). * This routine is meant for opening files and devices, * loading libraries, etc. * * ensure: * readable() == true || writable() == true */ virtual void open(void) = 0; /** * Closes the MIDI object. After calling this routine, * all resources (ie. soundcard) must be freed * (they can be used by other processes). * * ensure: * readable() != true * writable() != true */ virtual void close(void) = 0; /*@}*/ /** @name Runtime information */ /*@{*/ /** * Returns a file descriptor id suitable for poll() and * select() system calls. If polling is not supported, * returns value of '-1'. */ virtual int poll_descriptor(void) const { return(-1); } /** * Has device been opened (with open())? */ bool is_open(void) const { return(open_rep); } /** * Whether all data has been processed? If opened in mode 'io_read', * this means that end of stream has been reached. If opened in * 'io_write' or 'io_readwrite' modes, finished status usually * means that an error has occured (no space left, etc). After * finished() has returned 'true', further calls to read() * and/or write() won't process any data. */ virtual bool finished(void) const = 0; virtual bool nonblocking_mode(void) const; virtual bool readable(void) const; virtual bool writable(void) const; /*@}*/ protected: void toggle_open_state(bool value); private: int io_mode_rep; std::string id_label_rep; bool nonblocking_rep; bool readable_rep; bool writable_rep; bool open_rep; }; #endif ecasound-2.9.1/libecasound/audioio-cdr_impl.h0000644000076400007640000000031110664032032016125 00000000000000#ifndef _AUDIOIO_CDR_IMPL_H #define _AUDIOIO_CDR_IMPL_H #define BYTE 1 #define WORD 2 #define LONG 4 #define FLOAT 5 #define DOUBLE 6 // #define SECTORSIZE (2352 / 2) #define SECTORSIZE 2352 #endif ecasound-2.9.1/libecasound/eca-control-mt.cpp0000644000076400007640000001223211762413374016105 00000000000000// ------------------------------------------------------------------------ // eca-control-mt.h: ECA_CONTROL_MT class implementation // Copyright (C) 2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #include "eca-control-mt.h" #include "eca-control.h" ECA_CONTROL_MT::ECA_CONTROL_MT(ECA_SESSION* psession) { pthread_mutexattr_t mutex_attr; pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex_rep, &mutex_attr); ec_repp = new ECA_CONTROL(psession); } ECA_CONTROL_MT::~ECA_CONTROL_MT(void) { pthread_mutex_destroy(&mutex_rep); delete ec_repp; } void ECA_CONTROL_MT::lock_control(void) { pthread_mutex_lock(&mutex_rep); } void ECA_CONTROL_MT::unlock_control(void) { pthread_mutex_unlock(&mutex_rep); } void ECA_CONTROL_MT::engine_start(void) { pthread_mutex_lock(&mutex_rep); ec_repp->engine_start(); pthread_mutex_unlock(&mutex_rep); } int ECA_CONTROL_MT::start(void) { int res; pthread_mutex_lock(&mutex_rep); res = ec_repp->start(); pthread_mutex_unlock(&mutex_rep); return res; } void ECA_CONTROL_MT::stop(void) { pthread_mutex_lock(&mutex_rep); ec_repp->stop(); pthread_mutex_unlock(&mutex_rep); } void ECA_CONTROL_MT::stop_on_condition(void) { pthread_mutex_lock(&mutex_rep); ec_repp->stop_on_condition(); pthread_mutex_unlock(&mutex_rep); } int ECA_CONTROL_MT::run(bool batchmode) { int res; pthread_mutex_lock(&mutex_rep); res = ec_repp->run(batchmode); pthread_mutex_unlock(&mutex_rep); return res; } void ECA_CONTROL_MT::quit(void) { pthread_mutex_lock(&mutex_rep); ec_repp->quit(); pthread_mutex_unlock(&mutex_rep); } void ECA_CONTROL_MT::quit_async(void) { /* note: does not need locking! */ ec_repp->quit_async(); } bool ECA_CONTROL_MT::is_running(void) const { /* note: thread-safe as the member function is thread-safe, * but ordering across CPUs is not guaranteed (one * might get stale data */ return ec_repp->is_running(); } bool ECA_CONTROL_MT::is_connected(void) const { /* see note for is_running() */ return ec_repp->is_connected(); } bool ECA_CONTROL_MT::is_selected(void) const { /* see note for is_running() */ return ec_repp->is_selected(); } bool ECA_CONTROL_MT::is_finished(void) const { /* see note for is_running() */ return ec_repp->is_finished(); } bool ECA_CONTROL_MT::is_valid(void) const { /* see note for is_running() */ return ec_repp->is_valid(); } bool ECA_CONTROL_MT::is_engine_created(void) const { /* see note for is_running() */ return ec_repp->is_engine_created(); } bool ECA_CONTROL_MT::is_engine_ready_for_commands(void) const { /* see note for is_running() */ return ec_repp->is_engine_ready_for_commands(); } const ECA_CHAINSETUP* ECA_CONTROL_MT::get_connected_chainsetup(void) const { /* note: locking even though this is const */ const ECA_CHAINSETUP* res; pthread_mutex_lock(&mutex_rep); res = ec_repp->get_connected_chainsetup(); pthread_mutex_unlock(&mutex_rep); return res; } void ECA_CONTROL_MT::connect_chainsetup(struct eci_return_value *retval) { pthread_mutex_lock(&mutex_rep); ec_repp->connect_chainsetup(retval); pthread_mutex_unlock(&mutex_rep); } void ECA_CONTROL_MT::disconnect_chainsetup(void) { pthread_mutex_lock(&mutex_rep); ec_repp->disconnect_chainsetup(); pthread_mutex_unlock(&mutex_rep); } bool ECA_CONTROL_MT::execute_edit_on_connected(const ECA::chainsetup_edit_t& edit) { bool res; pthread_mutex_lock(&mutex_rep); res = ec_repp->execute_edit_on_connected(edit); pthread_mutex_unlock(&mutex_rep); return res; } bool ECA_CONTROL_MT::execute_edit_on_selected(const ECA::chainsetup_edit_t& edit, int index) { bool res; pthread_mutex_lock(&mutex_rep); res = ec_repp->execute_edit_on_selected(edit); pthread_mutex_unlock(&mutex_rep); return res; } void ECA_CONTROL_MT::command(const std::string& cmd_and_args, struct eci_return_value *retval) { pthread_mutex_lock(&mutex_rep); ec_repp->command(cmd_and_args, retval); pthread_mutex_unlock(&mutex_rep); } void ECA_CONTROL_MT::command_float_arg(const std::string& cmd, double arg, struct eci_return_value *retval) { pthread_mutex_lock(&mutex_rep); ec_repp->command_float_arg(cmd, arg, retval); pthread_mutex_unlock(&mutex_rep); } void ECA_CONTROL_MT::print_last_value(struct eci_return_value *retval) const { /* note: a const function that only depends on 'retval', so * this is safe */ ec_repp->print_last_value(retval); } ecasound-2.9.1/libecasound/audiofx_filter.cpp0000644000076400007640000005427711755703025016301 00000000000000// ------------------------------------------------------------------------ // audiofx_filter.cpp: Routines for filter effects. // Copyright (C) 1999,2004,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include "samplebuffer_iterators.h" #include "sample-ops_impl.h" #include "eca-logger.h" #include "audiofx_filter.h" static void priv_resize_buffer(std::vector *buffer, int count) { buffer->resize(count); for(int i = 0; i < count; i++) (*buffer)[i] = 0.0; } EFFECT_FILTER::~EFFECT_FILTER(void) { } EFFECT_BANDPASS::EFFECT_BANDPASS (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w) { /* to avoid accessing uninitialized data */ width = 1; center = 1; C = 1; set_parameter(1, centerf); set_parameter(2, w); } void EFFECT_BANDPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: center = value; D = 2 * cos(2 * M_PI * center / (CHAIN_OPERATOR::parameter_t)samples_per_second()); b[0] = -C * D * a[0]; break; case 2: if (value != 0) width = value; else width = center / 2; C = 1.0 / tan(M_PI * width / (CHAIN_OPERATOR::parameter_t)samples_per_second()); D = 2 * cos(2 * M_PI * center / (CHAIN_OPERATOR::parameter_t)samples_per_second()); a[0] = 1.0 / (1.0 + C); a[1] = 0.0; a[2] = -a[0]; b[0] = -C * D * a[0]; b[1] = (C - 1.0) * a[0]; break; } } CHAIN_OPERATOR::parameter_t EFFECT_BANDPASS::get_parameter(int param) const { switch (param) { case 1: return center; case 2: return width; } return 0.0; } EFFECT_BANDREJECT::EFFECT_BANDREJECT (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w) { set_parameter(1, centerf); set_parameter(2, w); } void EFFECT_BANDREJECT::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: center = value; D = 2 * cos(2 * M_PI * center / (CHAIN_OPERATOR::parameter_t)samples_per_second()); a[1] = -D * a[0]; b[0] = a[1]; break; case 2: if (value != 0) width = value; else width = center / 2; C = tan(M_PI * width / (CHAIN_OPERATOR::parameter_t)samples_per_second()); a[0] = 1.0 / (1.0 + C); a[1] = -D * a[0]; a[2] = a[0]; b[0] = a[1]; b[1] = (1.0 - C) * a[0]; break; } } CHAIN_OPERATOR::parameter_t EFFECT_BANDREJECT::get_parameter(int param) const { switch (param) { case 1: return center; case 2: return width; } return 0.0; } void EFFECT_BW_FILTER::init(SAMPLE_BUFFER *insample) { i.init(insample); set_channels(insample->number_of_channels()); const size_t buflen = 2; sin.resize(insample->number_of_channels(), std::vector (buflen)); sout.resize(insample->number_of_channels(), std::vector (buflen)); for(int i = 0; i < insample->number_of_channels(); i++) { for(size_t j = 0; j < buflen; j++) { sin[i][j] = 0.0f; sout[i][j] = 0.0f; } } } void EFFECT_BW_FILTER::process(void) { i.begin(); while(!i.end()) { outputSample = ecaops_flush_to_zero(a[0] * (*i.current()) + a[1] * sin[i.channel()][0] + a[2] * sin[i.channel()][1] - b[0] * sout[i.channel()][0] - b[1] * sout[i.channel()][1]); sin[i.channel()][1] = sin[i.channel()][0]; sin[i.channel()][0] = *i.current(); sout[i.channel()][1] = sout[i.channel()][0]; sout[i.channel()][0] = outputSample; *i.current() = outputSample; i.next(); } } void EFFECT_BW_FILTER::process_notused(SAMPLE_BUFFER* sbuf) { // sbuf->first(); // while(sbuf->is_readable()) { // outputSample = *sbuf->current_sample() * a[0] // + sin[0] * a[1] // + sin[1] * a[2] // - sout[0] * b[0] // - sout[1] * b[1]; // sin[1] = sin[0]; // sin[0] = *(sbuf->current_sample()); // sout[1] = sout[0]; // sout[0] = outputSample; // sbuf->current_sample()->operator=(outputSample); // sbuf->next(); // } } void EFFECT_BW_FILTER::init_values(void) { // for(int j = 0; j < 2;j++) { // sin[j].sample[SAMPLE_BUFFER::ch_left] = 0.0; // sin[j].sample[SAMPLE_BUFFER::ch_right] = 0.0; // sout[j].sample[SAMPLE_BUFFER::ch_left] = 0.0; // sout[j].sample[SAMPLE_BUFFER::ch_right] = 0.0; // } } EFFECT_HIGHPASS::EFFECT_HIGHPASS (CHAIN_OPERATOR::parameter_t cutoff) { set_parameter(1, cutoff); } void EFFECT_HIGHPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: cutOffFreq = value; C = tan(M_PI * cutOffFreq / (CHAIN_OPERATOR::parameter_t)samples_per_second()); a[0] = 1.0 / (1.0 + sqrt(2.0) * C + C * C); a[1] = -2.0 * a[0]; a[2] = a[0]; b[0] = 2 * (C * C - 1.0) * a[0]; b[1] = (1.0 - sqrt(2.0) * C + C * C) * a[0]; break; } } CHAIN_OPERATOR::parameter_t EFFECT_HIGHPASS::get_parameter(int param) const { switch (param) { case 1: return cutOffFreq; } return 0.0; } EFFECT_ALLPASS_FILTER::EFFECT_ALLPASS_FILTER (void) : feedback_gain(0.0), D(0.0) { } void EFFECT_ALLPASS_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: D = value; // assert(inbuf.size() == outbuf.size()); for(int n = 0; n < static_cast(inbuf.size()); n++) { if (inbuf[n].size() > D) inbuf[n].resize(static_cast(D)); // if (outbuf[n].size() > D) inbuf[n].resize(D); } break; case 2: feedback_gain = value / 100.0; break; } } CHAIN_OPERATOR::parameter_t EFFECT_ALLPASS_FILTER::get_parameter(int param) const { switch (param) { case 1: return D; case 2: return feedback_gain * 100.0; } return 0.0; } void EFFECT_ALLPASS_FILTER::init(SAMPLE_BUFFER* insample) { i.init(insample); set_channels(insample->number_of_channels()); inbuf.resize(insample->number_of_channels()); for(size_t i = 0; i < inbuf.size(); i++) inbuf[i].clear(); } void EFFECT_ALLPASS_FILTER::process(void) { i.begin(); while(!i.end()) { if (inbuf[i.channel()].size() >= D) { inbuf[i.channel()].push_back(*i.current()); // *i.current() = -feedback_gain * (*i.current()) + // inbuf[i.channel()].front() + // feedback_gain * outbuf[i.channel()].front(); *i.current() = ecaops_flush_to_zero(-feedback_gain * (*i.current()) + (feedback_gain * inbuf[i.channel()].front() + *i.current()) * (1.0 - feedback_gain * feedback_gain)); // feedback_gain * outbuf[i.channel()].front(); // outbuf[i.channel()].push_back(*i.current()); inbuf[i.channel()].pop_front(); // outbuf[i.channel()].pop_front(); } else { inbuf[i.channel()].push_back(*i.current()); *i.current() = ecaops_flush_to_zero(*i.current() * (1.0 - feedback_gain)); // outbuf[i.channel()].push_back(*i.current()); } i.next(); } } EFFECT_COMB_FILTER::EFFECT_COMB_FILTER (int delay_in_samples, CHAIN_OPERATOR::parameter_t radius) { set_parameter(1, (CHAIN_OPERATOR::parameter_t)delay_in_samples); set_parameter(2, radius); } void EFFECT_COMB_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: { C = value; std::vector >::iterator p = buffer.begin(); while(p != buffer.end()) { if (p->size() > C) { p->resize(static_cast(C)); } ++p; } break; } case 2: D = value; break; } } CHAIN_OPERATOR::parameter_t EFFECT_COMB_FILTER::get_parameter(int param) const { switch (param) { case 1: return C; case 2: return D; } return 0.0; } void EFFECT_COMB_FILTER::init(SAMPLE_BUFFER* insample) { i.init(insample); set_channels(insample->number_of_channels()); buffer.resize(insample->number_of_channels()); for(size_t i = 0; i < buffer.size(); i++) buffer[i].clear(); } void EFFECT_COMB_FILTER::process(void) { i.begin(); while(!i.end()) { if (buffer[i.channel()].size() >= C) { *i.current() = (*i.current()) + (pow(D, C) * buffer[i.channel()].front()); buffer[i.channel()].push_back(*i.current()); buffer[i.channel()].pop_front(); } else { buffer[i.channel()].push_back(*i.current()); } i.next(); } } EFFECT_INVERSE_COMB_FILTER::EFFECT_INVERSE_COMB_FILTER (int delay_in_samples, CHAIN_OPERATOR::parameter_t radius) { // // delay in number of samples // circle radius // set_parameter(1, (CHAIN_OPERATOR::parameter_t)delay_in_samples); set_parameter(2, radius); } void EFFECT_INVERSE_COMB_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: C = value; break; case 2: D = value; break; } } CHAIN_OPERATOR::parameter_t EFFECT_INVERSE_COMB_FILTER::get_parameter(int param) const { switch (param) { case 1: return C; case 2: return D; } return 0.0; } void EFFECT_INVERSE_COMB_FILTER::init(SAMPLE_BUFFER* insample) { i.init(insample); set_channels(insample->number_of_channels()); buffer.resize(insample->number_of_channels()); for(size_t i = 0; i < buffer.size(); i++) buffer[i].clear(); priv_resize_buffer(&laskuri, insample->number_of_channels()); } void EFFECT_INVERSE_COMB_FILTER::process(void) { i.begin(); while(!i.end()) { buffer[i.channel()].push_back(*i.current()); if (laskuri[i.channel()] >= C) { *i.current() = (*i.current()) - (pow(D, C) * buffer[i.channel()].front()); buffer[i.channel()].pop_front(); } else { laskuri[i.channel()]++; } i.next(); } } EFFECT_LOWPASS::EFFECT_LOWPASS (CHAIN_OPERATOR::parameter_t cutoff) { set_parameter(1, cutoff); } void EFFECT_LOWPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: set_cutoff(value, samples_per_second()); break; } } CHAIN_OPERATOR::parameter_t EFFECT_LOWPASS::get_parameter(int param) const { switch (param) { case 1: return cutOffFreq; } return 0.0; } void EFFECT_LOWPASS::set_cutoff(CHAIN_OPERATOR::parameter_t value, long int srate) { cutOffFreq = value; C = 1.0 / tan(M_PI * cutOffFreq / (CHAIN_OPERATOR::parameter_t)srate); a[0] = 1.0 / (1.0 + sqrt(2.0) * C + C * C); a[1] = 2.0 * a[0]; a[2] = a[0]; b[0] = 2 * (1.0 - C * C) * a[0]; b[1] = (1.0 - sqrt(2.0) * C + C * C) * a[0]; } EFFECT_LOWPASS_SIMPLE::EFFECT_LOWPASS_SIMPLE (CHAIN_OPERATOR::parameter_t cutoff) { set_parameter(1, cutoff); } void EFFECT_LOWPASS_SIMPLE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: cutOffFreq = value; A = 2.0 * M_PI * cutOffFreq / samples_per_second(); B = exp(-A / samples_per_second()); break; } } CHAIN_OPERATOR::parameter_t EFFECT_LOWPASS_SIMPLE::get_parameter(int param) const { switch (param) { case 1: return cutOffFreq; } return 0.0; } void EFFECT_LOWPASS_SIMPLE::init(SAMPLE_BUFFER *insample) { i.init(insample); set_channels(insample->number_of_channels()); priv_resize_buffer(&outhist, insample->number_of_channels()); priv_resize_buffer(&tempin, insample->number_of_channels()); priv_resize_buffer(&temphist, insample->number_of_channels()); } void EFFECT_LOWPASS_SIMPLE::process(void) { i.begin(); while(!i.end()) { tempin[i.channel()] = *i.current(); temphist[i.channel()] = outhist[i.channel()]; outhist[i.channel()] = tempin[i.channel()]; tempin[i.channel()] *= A * 0.5; temphist[i.channel()] *= B * 0.5; *i.current() = ecaops_flush_to_zero(tempin[i.channel()] + temphist[i.channel()]); i.next(); } } EFFECT_RESONANT_BANDPASS::EFFECT_RESONANT_BANDPASS (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w) { /* to avoid accessing uninitialized data */ width = 1; center = 1; set_parameter(1, centerf); set_parameter(2, w); } void EFFECT_RESONANT_BANDPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: center = value; break; case 2: if (value != 0) width = value; else width = center / 2.0; break; } // R = 1.0 - M_PI * width / (CHAIN_OPERATOR::parameter_t)samples_per_second(); // R = 1.0 - ((width / (CHAIN_OPERATOR::parameter_t)samples_per_second()) / 2.0); R = 1.0 - M_PI * (width / (CHAIN_OPERATOR::parameter_t)samples_per_second()); c = R * R; pole_angle = (((2.0 * R) / (1.0 + c)) * cos((center / (CHAIN_OPERATOR::parameter_t)samples_per_second() * 2.0 * M_PI))); pole_angle = acos(pole_angle); a = (1.0 - c) * sin(pole_angle); b = 2.0 * R * cos(pole_angle); } CHAIN_OPERATOR::parameter_t EFFECT_RESONANT_BANDPASS::get_parameter(int param) const { switch (param) { case 1: return center; case 2: return width; } return 0.0; } void EFFECT_RESONANT_BANDPASS::init(SAMPLE_BUFFER* insample) { i.init(insample); set_channels(insample->number_of_channels()); priv_resize_buffer(&outhist1, insample->number_of_channels()); priv_resize_buffer(&outhist2, insample->number_of_channels()); } void EFFECT_RESONANT_BANDPASS::process(void) { i.begin(); while(!i.end()) { *i.current() = ecaops_flush_to_zero(a * (*i.current()) + b * outhist1[i.channel()] - c * outhist2[i.channel()]); outhist2[i.channel()] = outhist1[i.channel()]; outhist1[i.channel()] = *i.current(); i.next(); } } EFFECT_RESONANT_LOWPASS::EFFECT_RESONANT_LOWPASS (CHAIN_OPERATOR::parameter_t co, CHAIN_OPERATOR::parameter_t res, CHAIN_OPERATOR::parameter_t g) : ProtoCoef(2), Coef(2) { cutoff = co; Q = res; gain_orig = gain = g; laskuri = 0.0; pi = 4.0 * atan(1.0); // --- // Setup filter s-domain coefficients // --- ProtoCoef[0].a0 = 1.0; ProtoCoef[0].a1 = 0; ProtoCoef[0].a2 = 0; ProtoCoef[0].b0 = 1.0; ProtoCoef[0].b1 = 0.765367 / Q; // Divide by resonance or Q ProtoCoef[0].b2 = 1.0; ProtoCoef[1].a0 = 1.0; ProtoCoef[1].a1 = 0; ProtoCoef[1].a2 = 0; ProtoCoef[1].b0 = 1.0; ProtoCoef[1].b1 = 1.847759 / Q; // Divide by resonance or Q ProtoCoef[1].b2 = 1.0; szxform(0); szxform(1); } void EFFECT_RESONANT_LOWPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: cutoff = value; break; case 2: Q = value; break; case 3: gain_orig = value; break; } refresh_values(); } CHAIN_OPERATOR::parameter_t EFFECT_RESONANT_LOWPASS::get_parameter(int param) const { switch (param) { case 1: return cutoff; case 2: return Q; case 3: return gain_orig; } return 0.0; } void EFFECT_RESONANT_LOWPASS::refresh_values(void) { if (cutoff == 0.0) cutoff = 0.1; gain = gain_orig; // ProtoCoef[0].a0 = 1.0; ProtoCoef[0].a1 = 0; ProtoCoef[0].a2 = 0; // ProtoCoef[0].b0 = 1.0; ProtoCoef[0].b1 = 0.765367 / Q; // Divide by resonance or Q ProtoCoef[0].b2 = 1.0; // ProtoCoef[1].a0 = 1.0; ProtoCoef[1].a1 = 0; ProtoCoef[1].a2 = 0; // ProtoCoef[1].b0 = 1.0; ProtoCoef[1].b1 = 1.847759 / Q; // Divide by resonance or Q ProtoCoef[1].b2 = 1.0; szxform(0); szxform(1); } void EFFECT_RESONANT_LOWPASS::szxform(int section) { wp = 2.0 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * tan(pi * cutoff / (CHAIN_OPERATOR::parameter_t)samples_per_second()); // --- // a0 and b0 are presumed to be 1, so... ProtoCoef[section].a2 = ProtoCoef[section].a2 / (wp * wp); ProtoCoef[section].a1 = ProtoCoef[section].a1 / wp; ProtoCoef[section].b2 = ProtoCoef[section].b2 / (wp * wp); ProtoCoef[section].b1 = ProtoCoef[section].b1 / wp; // --- // alpha (Numerator in s-domain) ad = 4.0 * ProtoCoef[section].a2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() + 2.0 * ProtoCoef[section].a1 * (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].a0; // --- // beta (Denominator in s-domain) bd = 4.0 * ProtoCoef[section].b2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() + 2.0 * ProtoCoef[section].b1 * (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].b0; // --- /* update gain constant for this section */ gain *= ad/bd; // --- // Denominator Coef[section].A = (2.0 * ProtoCoef[section].b0 - 8.0 * ProtoCoef[section].b2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second()) / bd; // --- // beta1 Coef[section].B = (4.0 * ProtoCoef[section].b2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() - 2.0 * ProtoCoef[section].b1 * (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].b0) / bd; // --- // beta2 // --- // Nominator Coef[section].C = (2.0 * ProtoCoef[section].a0 - 8.0 * ProtoCoef[section].a2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second()) / ad; // --- // alpha1 Coef[section].D = (4.0 * ProtoCoef[section].a2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() - 2.0 * ProtoCoef[section].a1 * (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].a0) / ad; // --- // alpha2 } void EFFECT_RESONANT_LOWPASS::init(SAMPLE_BUFFER* insample) { i.init(insample); set_channels(insample->number_of_channels()); priv_resize_buffer(&outhist0, insample->number_of_channels()); priv_resize_buffer(&outhist1, insample->number_of_channels()); priv_resize_buffer(&outhist2, insample->number_of_channels()); priv_resize_buffer(&outhist3, insample->number_of_channels()); priv_resize_buffer(&newhist0, insample->number_of_channels()); priv_resize_buffer(&newhist1, insample->number_of_channels()); } void EFFECT_RESONANT_LOWPASS::process(void) { i.begin(); while(!i.end()) { *i.current() = (*i.current()) * gain; // first section: // -------------- // poles: *i.current() = (*i.current()) - outhist0[i.channel()] * Coef[0].A; newhist0[i.channel()] = ecaops_flush_to_zero((*i.current()) - outhist1[i.channel()] * Coef[0].B); // zeros: *i.current() = newhist0[i.channel()] + outhist0[i.channel()] * Coef[0].C; *i.current() = (*i.current()) + outhist1[i.channel()] * Coef[0].D; outhist1[i.channel()] = outhist0[i.channel()]; outhist0[i.channel()] = newhist0[i.channel()]; // second section: // -------------- // poles: *i.current() = (*i.current()) - outhist2[i.channel()] * Coef[1].A; newhist1[i.channel()] = ecaops_flush_to_zero((*i.current()) - outhist3[i.channel()] * Coef[1].B); // zeros: *i.current() = newhist1[i.channel()] + outhist2[i.channel()] * Coef[1].C; *i.current() = (*i.current()) + outhist3[i.channel()] * Coef[1].D; outhist3[i.channel()] = outhist2[i.channel()]; outhist2[i.channel()] = newhist1[i.channel()]; i.next(); } } // EFFECT_RESONANT_LOWPASS::EFFECT_RESONANT_LOWPASS (const // EFFECT_RESONANT_LOWPASS& x) // : outhist(4), newhist(2), ProtoCoef(2), Coef(2) // { // outhist = x.outhist; // newhist = x.newhist; // for(vector::size_type p = 0; p != x.ProtoCoef.size(); p++) { // ProtoCoef[p].a0 = x.ProtoCoef[p].a0; // ProtoCoef[p].a1 = x.ProtoCoef[p].a1; // ProtoCoef[p].a2 = x.ProtoCoef[p].a2; // ProtoCoef[p].b0 = x.ProtoCoef[p].b0; // ProtoCoef[p].b1 = x.ProtoCoef[p].b1; // ProtoCoef[p].b2 = x.ProtoCoef[p].b2; // ++p; // } // for(vector::size_type p = 0; p != x.Coef.size(); p++) { // Coef[p].A = x.Coef[p].A; // Coef[p].B = x.Coef[p].B; // Coef[p].C = x.Coef[p].C; // Coef[p].D = x.Coef[p].D; // ++p; // } // cutoff = x.cutoff; // Q = x.Q; // gain = x.gain; // gain_orig = x.gain_orig; // pi = x.pi; // laskuri = x.laskuri; // ad = x.ad; // bd = x.bd; // wp = x.wp; // } EFFECT_RESONATOR::EFFECT_RESONATOR (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w) : cona(1), conb(2) { /* to avoid accessing uninitialized data */ width = 1; center = 1; set_parameter(1, centerf); set_parameter(2, w); } void EFFECT_RESONATOR::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: center = value; break; case 2: if (value != 0) width = value; else width = center / 2; break; } conb[1] = exp(-(2 * M_PI) * (width / (CHAIN_OPERATOR::parameter_t)samples_per_second())); conb[0] = (-4.0 * conb[1]) / (1.0 + conb[1]) * cos(2 * M_PI * (center / (CHAIN_OPERATOR::parameter_t)samples_per_second())); cona[0] = (1.0 - conb[1]) * sqrt(1.0 - (conb[0] * conb[0]) / (4.0 * conb[1])); } CHAIN_OPERATOR::parameter_t EFFECT_RESONATOR::get_parameter(int param) const { switch (param) { case 1: return center; case 2: return width; } return 0.0; } void EFFECT_RESONATOR::init(SAMPLE_BUFFER* insample) { i.init(insample); set_channels(insample->number_of_channels()); priv_resize_buffer(&saout0, insample->number_of_channels()); priv_resize_buffer(&saout1, insample->number_of_channels()); } void EFFECT_RESONATOR::process(void) { i.begin(); while(!i.end()) { *i.current() = cona[0] * (*i.current()) - conb[0] * saout0[i.channel()] - conb[1] * saout1[i.channel()]; saout1[i.channel()] = saout0[i.channel()]; saout0[i.channel()] = ecaops_flush_to_zero(*i.current()); i.next(); } } ecasound-2.9.1/libecasound/midiio-aseq.cpp0000644000076400007640000001527210664032032015455 00000000000000// ------------------------------------------------------------------------ // midiio-aseq.cpp: Input and output of MIDI streams using // ALSA Sequencer // Copyright (C) 2005 Pedro Lopez-Cabanillas // Copyright (C) 2005 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #ifdef ECA_COMPILE_ALSA #include #include #include #include "midiio-aseq.h" #include "eca-logger.h" MIDI_IO_ASEQ::MIDI_IO_ASEQ(const std::string& name) { label("alsaseq"); device_name_rep = name; } MIDI_IO_ASEQ::~MIDI_IO_ASEQ(void) { if (is_open()) close(); } void MIDI_IO_ASEQ::open(void) { int open_flags = 0, port_flags = 0; switch(io_mode()) { case io_read: { open_flags = SND_SEQ_OPEN_INPUT; port_flags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; break; } case io_write: { open_flags = SND_SEQ_OPEN_OUTPUT; port_flags = SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; break; } case io_readwrite: { open_flags = SND_SEQ_OPEN_DUPLEX; port_flags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; break; } } ECA_LOG_MSG(ECA_LOGGER::system_objects, "Opening ALSA sequencer"); int err = snd_seq_open(&seq_handle_repp, "default", open_flags, SND_SEQ_NONBLOCK); if (err < 0) { toggle_open_state(false); } else { toggle_open_state(true); } // Set client name. snd_seq_set_client_name(seq_handle_repp, "ecasound"); // Create a simple port port_rep = snd_seq_create_simple_port( seq_handle_repp, "ecasound", port_flags, SND_SEQ_PORT_TYPE_MIDI_GENERIC); // Parse the device name, and connect it to the port when successful snd_seq_addr_t subs; err = snd_seq_parse_address(seq_handle_repp, &subs, device_name_rep.c_str()); if( err == 0) { switch(io_mode()) { case io_read: snd_seq_connect_to(seq_handle_repp, port_rep, subs.client, subs.port); break; case io_write: snd_seq_connect_from(seq_handle_repp, port_rep, subs.client, subs.port); break; case io_readwrite: snd_seq_connect_to(seq_handle_repp, port_rep, subs.client, subs.port); snd_seq_connect_from(seq_handle_repp, port_rep, subs.client, subs.port); break; } } // Create the encoder/decoder instance err = snd_midi_event_new( buffer_size_rep = 16, &coder_repp ); // ... finished_rep = false; } void MIDI_IO_ASEQ::close(void) { // Release the xxcoder instance snd_midi_event_free( coder_repp ); // Delete the port snd_seq_delete_port( seq_handle_repp, port_rep ); // Close the sequencer client snd_seq_close( seq_handle_repp ); toggle_open_state(false); } int MIDI_IO_ASEQ::poll_descriptor(void) const { struct pollfd *pfds; int npfds; npfds = snd_seq_poll_descriptors_count(seq_handle_repp, POLLIN|POLLOUT); pfds = reinterpret_cast(alloca(sizeof(*pfds) * npfds)); snd_seq_poll_descriptors(seq_handle_repp, pfds, npfds, POLLIN|POLLOUT); return pfds->fd; } bool MIDI_IO_ASEQ::finished(void) const { return finished_rep; } long int MIDI_IO_ASEQ::read_bytes(void* target_buffer, long int bytes) { snd_seq_event_t *event; int err = 0, position = 0; if ( bytes > buffer_size_rep ) { snd_midi_event_resize_buffer ( coder_repp, bytes ); buffer_size_rep = bytes; } while (true) { if (snd_seq_event_input_pending(seq_handle_repp, 1) == 0) { return position; } err = snd_seq_event_input(seq_handle_repp, &event); if (err < 0) { break; } if ( event->type == SND_SEQ_EVENT_CONTROLLER || event->type == SND_SEQ_EVENT_CONTROL14 || event->type == SND_SEQ_EVENT_NONREGPARAM || event->type == SND_SEQ_EVENT_REGPARAM || event->type == SND_SEQ_EVENT_SYSEX ) { err = snd_midi_event_decode( coder_repp, ((unsigned char *)target_buffer) + position, bytes - position, event ); if (err < 0) { break; } position += err; if ( position >= bytes) return position; } } finished_rep = true; ECA_LOG_MSG(ECA_LOGGER::system_objects, std::string("error while reading from ALSA sequencer: ") + snd_strerror(err)); return err; } long int MIDI_IO_ASEQ::write_bytes(void* target_buffer, long int bytes) { snd_seq_event_t ev; int err = 0; if ( bytes > buffer_size_rep ) { snd_midi_event_resize_buffer ( coder_repp, bytes ); buffer_size_rep = bytes; } snd_seq_ev_clear(&ev); snd_seq_ev_set_source(&ev, port_rep); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); err = snd_midi_event_encode( coder_repp, (unsigned char *)target_buffer, bytes, &ev ); if (err == bytes) { snd_seq_event_output(seq_handle_repp, &ev); snd_seq_drain_output(seq_handle_repp); return err; } finished_rep = true; return err; } void MIDI_IO_ASEQ::set_parameter(int param, std::string value) { switch (param) { case 1: label(value); break; case 2: device_name_rep = value; break; } } std::string MIDI_IO_ASEQ::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return device_name_rep; } return ""; } /** * FIXME: This is an alternative to using the poll_descriptor() * interface... */ bool MIDI_IO_ASEQ::pending_messages(unsigned long timeout) const { struct pollfd *pfds; int result = 0; int npfds = snd_seq_poll_descriptors_count(seq_handle_repp, POLLIN); pfds = (struct pollfd *)alloca(sizeof(*pfds) * npfds); snd_seq_poll_descriptors(seq_handle_repp, pfds, npfds, POLLIN); result = poll(pfds, npfds, timeout); return (result > 0); } #endif /* COMPILE_ALSA */ ecasound-2.9.1/libecasound/eca-fileio-mmap.cpp0000644000076400007640000001067011162771671016213 00000000000000// ------------------------------------------------------------------------ // eca-fileio-mmap.cpp: mmap based file-I/O and buffering routines. // Copyright (C) 1999-2002,2009 Kai Vehmanen // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include /* memcpy */ #include #include #include #ifdef HAVE_SYS_MMAN_H #include #endif #include #include #include "eca-fileio.h" #include "eca-fileio-mmap.h" ECA_FILE_IO_MMAP::ECA_FILE_IO_MMAP(void) { } ECA_FILE_IO_MMAP::~ECA_FILE_IO_MMAP(void) { } void ECA_FILE_IO_MMAP::open_file(const std::string& fname, const std::string& fmode) { #ifdef HAVE_MMAP int openflags = O_RDWR; int mmapflags = PROT_READ | PROT_WRITE; fname_rep = fname; if (fmode == "rb") { openflags = O_RDONLY; mmapflags = PROT_READ; } else if (fmode == "wb") { openflags = O_WRONLY; mmapflags = PROT_WRITE; } fd_rep = ::open(fname.c_str(), openflags); if (!fd_rep) { file_ready_rep = false; mode_rep = ""; } else { file_ready_rep = true; file_ended_rep = false; mode_rep = fmode; fposition_rep = 0; flength_rep = get_file_length(); // cerr << fname_rep << ": mmaping region from 0 to " << // flength_rep << "." << endl; buffer_repp = (caddr_t)::mmap(0, flength_rep, mmapflags, MAP_SHARED, fd_rep, 0); if (buffer_repp == MAP_FAILED) { file_ready_rep = false; mode_rep = ""; } } #else /* HAVE_MMAP */ file_ready_rep = false; mode_rep = ""; #endif } void ECA_FILE_IO_MMAP::close_file(void) { // cerr << fname_rep << ": munmaping region." << endl; #ifdef HAVE_MMAP ::munmap(buffer_repp, flength_rep); ::close(fd_rep); #endif } void ECA_FILE_IO_MMAP::read_to_buffer(void* obuf, off_t bytes) { if (is_file_ready() == false) { bytes_rep = 0; file_ended_rep = true; return; } if (fposition_rep + bytes > flength_rep) bytes = flength_rep - fposition_rep; // cerr << fname_rep << ": mmap read " << fposition_rep << " -> "; std::memcpy(obuf, buffer_repp + fposition_rep, bytes); // cerr << fposition_rep + bytes << "." << endl; set_file_position(fposition_rep + bytes, false); bytes_rep = bytes; } void ECA_FILE_IO_MMAP::write_from_buffer(void* obuf, off_t bytes) { if (is_file_ready() == false) { bytes_rep = 0; file_ended_rep = true; return; } if (fposition_rep + bytes > flength_rep) bytes = flength_rep - fposition_rep; std::memcpy(buffer_repp + fposition_rep, obuf, bytes); set_file_position(fposition_rep + bytes, false); bytes_rep = bytes; } off_t ECA_FILE_IO_MMAP::file_bytes_processed(void) const { return(bytes_rep); } bool ECA_FILE_IO_MMAP::is_file_ready(void) const { return(file_ready_rep); } bool ECA_FILE_IO_MMAP::is_file_ended(void) const { return(file_ended_rep); } bool ECA_FILE_IO_MMAP::is_file_error(void) const { return(!file_ready_rep && !file_ended_rep); } void ECA_FILE_IO_MMAP::set_file_position(off_t newpos, bool seek) { fposition_rep = newpos; if (fposition_rep >= flength_rep) { fposition_rep = flength_rep; file_ready_rep = false; file_ended_rep = true; } else { file_ready_rep = true; file_ended_rep = false; } } void ECA_FILE_IO_MMAP::set_file_position_advance(off_t fw) { set_file_position(fposition_rep + fw, false); } void ECA_FILE_IO_MMAP::set_file_position_end(void) { fposition_rep = get_file_length(); } off_t ECA_FILE_IO_MMAP::get_file_position(void) const { return(fposition_rep); } off_t ECA_FILE_IO_MMAP::get_file_length(void) const { struct stat stattemp; fstat(fd_rep, &stattemp); return((off_t)stattemp.st_size); } ecasound-2.9.1/libecasound/eca-logger.h0000644000076400007640000000660411067734242014737 00000000000000#ifndef INCLUDE_ECA_LOGGER_H #define INCLUDE_ECA_LOGGER_H #include #include /** * Forward declarations */ class ECA_LOGGER_INTERFACE; /** * A logging subsystem implemented as a singleton * class. * * Related design patterns: * - Singleton (GoF127) * * @author Kai Vehmanen */ class ECA_LOGGER { public: /** * Log level is a bitmasked integer value that is used to * categorize different log message types. * * disabled = no output * * errors = error messages * * info = high-level info about user-visible objects * and concepts, warning messages; low volume * * subsystems = notifications of control flow transitions * between high-level subsystems; low volume * * module_names = include module names in log output * * user_objects = info about user-visible objects (audio i/o, * chain operators, controllers); high volume * * system_objects = info about internal objects; high volume * * functions = info about internal operation of individual * functions and algorithms; high volume bursts * * continuous = debug info printed for during processing; * continuous high volume * * eiam_return_values = return values for EIAM commands * * @see level_to_string() */ typedef enum { disabled = 0, errors = 1, info = 2, subsystems = 4, module_names = 8, user_objects = 16, system_objects = 32, functions = 64, continuous = 128, eiam_return_values = 256 } Msg_level_t; /** * Returns a reference to a logging system * implementation object. * * Note! Return value is a reference to * avoid accidental deletion of * the singleton object. */ static ECA_LOGGER_INTERFACE& instance(void); /** * Replace the default logging sybsystem * with a custom implementation. * * Note! Ownership of 'logger' is transferred * to the singleton object. */ static void attach_logger(ECA_LOGGER_INTERFACE* logger); /** * Detaches the current logger implementation. */ static void detach_logger(void); /** * Returns description of log level 'arg'. */ static const char* level_to_string(Msg_level_t arg); private: static ECA_LOGGER_INTERFACE* interface_impl_repp; static pthread_mutex_t lock_rep; /** * @name Constructors and destructors * * To prevent accidental use, located in private scope and * without a valid definition. */ /*@{*/ ECA_LOGGER(void); ECA_LOGGER(const ECA_LOGGER&); ECA_LOGGER& operator=(const ECA_LOGGER&); ~ECA_LOGGER(void); /*@}*/ }; /** * Macro definitions */ /** * Issues a log message. * * @param x log level, type 'ECA_LOGGER::Msg_level_t' * @param y log message, type 'const std:string&' */ #define ECA_LOG_MSG(x,y) \ do { ECA_LOGGER::instance().msg(x, __FILE__, y); } while(0) /** * Issue a log message, but do not print out the module prefix. * A variant of ECA_LOG_MSG(). */ #define ECA_LOG_MSG_NOPREFIX(x,y) \ do { ECA_LOGGER::instance().msg(x, std::string(), y); } while(0) /** * To make ECA_LOG_MSG work we need to include the * public interface ECA_LOGGER_INTERFACE. */ #include "eca-logger-interface.h" #endif /* INCLUDE_ECA_LOGGER_H */ ecasound-2.9.1/libecasound/audioio-forked-stream.h0000644000076400007640000000410111141362451017102 00000000000000#ifndef INCLUDED_AUDIOIO_FORKED_STREAM_H #define INCLUDED_AUDIOIO_FORKED_STREAM_H #include #include #include "audioio-barrier.h" #include "sample-specs.h" /** * Helper class providing routines for forking new processes * and creating read/write pipes between the child and the * parent process. * * @author Kai Vehmanen */ class AUDIO_IO_FORKED_STREAM : public AUDIO_IO_BARRIER { private: int pid_of_parent_rep; int pid_of_child_rep; int fd_rep; bool last_fork_rep; bool sigkill_sent_rep; std::string tmpfile_repp; bool tmp_file_created_rep; bool use_named_pipe_rep; std::string command_rep; std::string object_rep; TEMPORARY_FILE_DIRECTORY tempfile_dir_rep; void init_temp_directory(void); void fork_child_for_fifo_read(void); void init_state_before_fork(void); public: virtual void stop_io(void); protected: /** * Initializes the command string. This must be done before any other set_* * calls. */ void set_fork_command(const std::string& cmd) { command_rep = cmd; } void set_fork_file_name(const std::string& filename); void set_fork_pipe_name(void); void set_fork_channels(int channels); void set_fork_sample_rate(long int sample_rate); void set_fork_bits(int bits); void fork_child_for_read(void); void fork_child_for_write(void); void clean_child(bool force = false); const std::string& fork_command(void) const { return(command_rep); } bool wait_for_child(void) const; bool child_fork_succeeded(void) const { return(last_fork_rep); } int pid_of_child(void) const { return(pid_of_child_rep); } int file_descriptor(void) const { return(fd_rep); } virtual bool do_supports_seeking(void) const = 0; virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) = 0; public: AUDIO_IO_FORKED_STREAM(void) : pid_of_parent_rep(-1), pid_of_child_rep(-1), fd_rep(0), last_fork_rep(false), sigkill_sent_rep(false), tmp_file_created_rep(false), use_named_pipe_rep(false) { } virtual ~AUDIO_IO_FORKED_STREAM(void); }; #endif ecasound-2.9.1/libecasound/eca-control-dump.cpp0000644000076400007640000001120310664032032016413 00000000000000// ------------------------------------------------------------------------ // eca-control-dump.cpp: Class for dumping status information to // a standard output stream // Copyright (C) 2000 Kai Vehmanen // // 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 #include #include #include #include #include #include "audioio.h" #include "eca-chainop.h" #include "eca-control.h" #include "eca-control-dump.h" void ECA_CONTROL_DUMP::dump_status(void) { dump("dump-status", ctrl_repp->engine_status()); } void ECA_CONTROL_DUMP::dump_position(void) { dump("dump-position", kvu_numtostr(ctrl_repp->position_in_seconds_exact(), ctrl_repp->float_to_string_precision())); } void ECA_CONTROL_DUMP::dump_length(void) { dump("dump-length", kvu_numtostr(ctrl_repp->length_in_seconds_exact(), ctrl_repp->float_to_string_precision())); } void ECA_CONTROL_DUMP::dump_chainsetup_status(void) { if (ctrl_repp->is_connected() == true) dump("dump-cs-status", "connected"); else if (ctrl_repp->is_selected() == true) dump("dump-cs-status", "selected"); else dump("dump-cs-status", ""); } void ECA_CONTROL_DUMP::dump_selected_chain(void) { const std::vector& t = ctrl_repp->selected_chains(); if (t.empty() == false) { dump("dump-c-selected", kvu_vector_to_string(t, ",")); } else dump("dump-c-selected", ""); } void ECA_CONTROL_DUMP::dump_selected_audio_input(void) { const AUDIO_IO* t = ctrl_repp->get_audio_input(); if (t != 0) { dump("dump-ai-selected", t->label()); } else dump("dump-ai-selected", ""); } void ECA_CONTROL_DUMP::dump_selected_audio_output(void) { const AUDIO_IO* t = ctrl_repp->get_audio_output(); if (t != 0) { dump("dump-ao-selected", t->label()); } else dump("dump-ao-selected", ""); } void ECA_CONTROL_DUMP::dump_audio_input_position(void) { const AUDIO_IO* t = ctrl_repp->get_audio_input(); if (t != 0) { dump("dump-ai-position", kvu_numtostr(t->position_in_seconds_exact(), ctrl_repp->float_to_string_precision())); } else dump("dump-ai-position", ""); } void ECA_CONTROL_DUMP::dump_audio_output_position(void) { const AUDIO_IO* t = ctrl_repp->get_audio_output(); if (t != 0) { dump("dump-ao-position", kvu_numtostr(t->position_in_seconds_exact(), ctrl_repp->float_to_string_precision())); } else dump("dump-ao-position", ""); } void ECA_CONTROL_DUMP::dump_audio_input_length(void) { const AUDIO_IO* t = ctrl_repp->get_audio_input(); if (t != 0) { dump("dump-ai-length", kvu_numtostr(t->length_in_seconds_exact(), ctrl_repp->float_to_string_precision())); } else dump("dump-ai-length", ""); } void ECA_CONTROL_DUMP::dump_audio_output_length(void) { const AUDIO_IO* t = ctrl_repp->get_audio_output(); if (t != 0) { dump("dump-ao-length", kvu_numtostr(t->length_in_seconds_exact(), ctrl_repp->float_to_string_precision())); } else dump("dump-ao-length", ""); } void ECA_CONTROL_DUMP::dump_audio_input_open_state(void) { const AUDIO_IO* t = ctrl_repp->get_audio_input(); if (t != 0) { if (t->is_open() == true) dump("dump-ai-open-state", "open"); else dump("dump-ai-open-state", "closed"); } else dump("dump-ai-open-state", ""); } void ECA_CONTROL_DUMP::dump_audio_output_open_state(void) { const AUDIO_IO* t = ctrl_repp->get_audio_output(); if (t != 0) { if (t->is_open() == true) dump("dump-ao-open-state", "open"); else dump("dump-ao-open-state", "closed"); } else dump("dump-ao-open-state", ""); } void ECA_CONTROL_DUMP::dump_chain_operator_value(int chainop, int param) { ctrl_repp->select_chain_operator(chainop); const CHAIN_OPERATOR* t = ctrl_repp->get_chain_operator(); if (t != 0) { dump("dump-cop-value", kvu_numtostr(t->get_parameter(param), ctrl_repp->float_to_string_precision())); } else dump("dump-cop-value", ""); } ecasound-2.9.1/libecasound/eca-fileio-stream.cpp0000644000076400007640000001155711162771714016557 00000000000000// ------------------------------------------------------------------------ // eca-fileio-stream.cpp: File-I/O and buffering routines using normal // file streams. // Copyright (C) 1999-2002,2009 Kai Vehmanen // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include /* LONG_MAX */ #include #include /* stat() */ #include /* stat() */ #ifdef HAVE_SYS_TYPES_H #include /* off_t */ #endif #include #include "eca-logger.h" #include "eca-fileio.h" #include "eca-fileio-stream.h" ECA_FILE_IO_STREAM::~ECA_FILE_IO_STREAM(void) { if (mode_rep != "") close_file(); } void ECA_FILE_IO_STREAM::open_file(const std::string& fname, const std::string& fmode) { fname_rep = fname; f1 = std::fopen(fname_rep.c_str(), fmode.c_str()); if (!f1) { mode_rep = ""; } else { mode_rep = fmode; } standard_mode = false; curpos_rep = 0; } void ECA_FILE_IO_STREAM::open_stdin(void) { f1 = stdin; mode_rep = "rb"; standard_mode = true; curpos_rep = 0; } void ECA_FILE_IO_STREAM::open_stdout(void) { f1 = stdout; mode_rep = "wb"; standard_mode = true; curpos_rep = 0; } void ECA_FILE_IO_STREAM::open_stderr(void) { f1 = stderr; mode_rep = "wb"; standard_mode = true; curpos_rep = 0; } void ECA_FILE_IO_STREAM::close_file(void) { if (standard_mode != true) std::fclose(f1); mode_rep = ""; } void ECA_FILE_IO_STREAM::read_to_buffer(void* obuf, off_t bytes) { if (is_file_ready() == true) { last_rep = std::fread(obuf, 1, bytes, f1); curpos_rep += last_rep; } else { last_rep = 0; } } void ECA_FILE_IO_STREAM::write_from_buffer(void* obuf, off_t bytes) { if (is_file_ready() == true) { last_rep = std::fwrite(obuf, 1, bytes, f1); curpos_rep += last_rep; } else { last_rep = 0; } } off_t ECA_FILE_IO_STREAM::file_bytes_processed(void) const { return(last_rep); } bool ECA_FILE_IO_STREAM::is_file_ready(void) const { if (mode_rep == "" || std::feof(f1) || std::ferror(f1)) return(false); return(true); } bool ECA_FILE_IO_STREAM::is_file_error(void) const { if (std::ferror(f1)) return(true); return(false); } void ECA_FILE_IO_STREAM::set_file_position(off_t newpos) { curpos_rep = newpos; if (standard_mode != true) { /* fseeko doesn't seem to work with glibc 2.1.x */ #if _FILE_OFFSET_BITS==64 off_t seekpos = 0; off_t seekstep = 0; int whence = SEEK_SET; while(curpos_rep - seekpos >= 0) { if (curpos_rep - seekpos > LONG_MAX) seekstep = LONG_MAX; else seekstep = curpos_rep - seekpos; /* null seek, break */ if (seekstep == 0 && whence == SEEK_CUR) break; // std::cerr << "(eca-fileio-stream) fw-seeking from " << seekpos << " to " << seekpos+seekstep << std::endl; int res = std::fseek(f1, seekstep, whence); if (res != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "(eca-fileio-stream) fseek() error! (lfs)."); curpos_rep = 0; std::fseek(f1, 0, SEEK_SET); break; } if (seekpos == 0) whence = SEEK_CUR; seekpos += seekstep; } #else /* note: curpos_rep is of type off_t, there might be a size * mismatch between long int and off_t, but both * are signed integers */ std::fseek(f1, static_cast(curpos_rep), SEEK_SET); #endif } } void ECA_FILE_IO_STREAM::set_file_position_advance(off_t fw) { if (standard_mode != true) { set_file_position(curpos_rep + fw); } } void ECA_FILE_IO_STREAM::set_file_position_end(void) { if (standard_mode == false) { int res = std::fseek(f1, 0, SEEK_END); if (res != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "(eca-fileio-stream) fseek() error! (seek_end)."); } else { curpos_rep = get_file_length(); } } } off_t ECA_FILE_IO_STREAM::get_file_position(void) const { if (standard_mode == true) return(0); return(curpos_rep); } off_t ECA_FILE_IO_STREAM::get_file_length(void) const { if (standard_mode == true) return(0); struct stat temp; stat(fname_rep.c_str(), &temp); off_t lentemp = temp.st_size; return(lentemp); } ecasound-2.9.1/libecasound/eca-preset-map.h0000644000076400007640000000234010664032032015514 00000000000000#ifndef INCLUDED_ECA_PRESET_MAP_H #define INCLUDED_ECA_PRESET_MAP_H #include #include #include "preset.h" #include "eca-object-map.h" #include "resource-file.h" class ECA_OBJECT; /** * Dynamic register for storing effect presets * * @see ECA_OBJECT_MAP * * @author Kai Vehmanen */ class ECA_PRESET_MAP : public ECA_OBJECT_MAP { public: /** @name Constructors and destructors */ /*@{*/ ECA_PRESET_MAP(void); virtual ~ECA_PRESET_MAP(void); /*@}*/ /** @name Object registration */ /*@{*/ virtual void register_object(const std::string& keyword, const std::string& matchstr, ECA_OBJECT* object); virtual void unregister_object(const std::string& keyword); /*@}*/ /** @name Object creation using object prototypes instances */ /*@{*/ virtual const ECA_OBJECT* object(const std::string& keyword) const; virtual const ECA_OBJECT* object_expr(const string& expr) const; /*@}*/ /** @name Query the object map */ /*@{*/ virtual bool has_keyword(const std::string& keyword) const; virtual const std::list& registered_objects(void) const; /*@}*/ private: std::list preset_keywords_rep; void load_preset_file(const std::string& fname); }; #endif ecasound-2.9.1/libecasound/audioio-cdr.h0000644000076400007640000000365511033000766015122 00000000000000#ifndef INCLUDED_AUDIOIO_CDR_H #define INCLUDED_AUDIOIO_CDR_H #include #include #include #include /* off_t */ #include "sample-specs.h" #include "audioio-buffered.h" typedef struct { public: int16_t sample[2]; // signed short int } SAMPLE; /** * Class for handling CDR-files * * CDR -format is used on audio-CDs: * * - 16bit samples, 44100kHz, stereo * * - sample frame layout: (MSB-left, LSB-left, MSB-right, LSB-right) * * - files are padded sector size (2352 bytes) * * @author Kai Vehmanen */ class CDRFILE : public AUDIO_IO_BUFFERED { static const int sectorsize = 2352; long int samples_read; FILE* fobject; void pad_to_sectorsize(void); void set_length_in_bytes(void); CDRFILE(const CDRFILE& x) { } CDRFILE& operator=(const CDRFILE& x) { return *this; } void seek_position_in_samples(long pos); unsigned short swapw(unsigned short us) { return ((us >> 8) | (us << 8)) & 0xffff; } void swap_bytes(SAMPLE* t) { t->sample[SAMPLE_SPECS::ch_left] = swapw(t->sample[SAMPLE_SPECS::ch_left]); t->sample[SAMPLE_SPECS::ch_right] = swapw(t->sample[SAMPLE_SPECS::ch_right]); } public: std::string name(void) const { return("CD-R audio file"); } std::string description(void) const { return("CD-R/CDDA audio files. This format is used when mastering audio-CDs."); } virtual bool locked_audio_format(void) const { return(true); } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const; virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); CDRFILE (const std::string& name = ""); virtual ~CDRFILE(void); CDRFILE* clone(void) const; CDRFILE* new_expr(void) const { return new CDRFILE(); } }; #endif ecasound-2.9.1/libecasound/eca-control-mt.h0000644000076400007640000000747711762413351015564 00000000000000// ------------------------------------------------------------------------ // eca-control-mt.h: Multithreaded implementation of ECA_CONTROL_INTERFACE // Copyright (C) 2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #ifndef INCLUDED_ECA_CONTROL_MT_H #define INCLUDED_ECA_CONTROL_MT_H #include #include "eca-control-main.h" class ECA_CONTROL; class ECA_SESSION; /** * High-level interface to libecasound functionality * * @see ECA_CONTROL_MAIN, ECA_CONTROL * * Related design patters: Facade (GoF185) * * @author Kai Vehmanen */ class ECA_CONTROL_MT : public ECA_CONTROL_MAIN { public: /** @name Constructors and dtors */ /*@{*/ ECA_CONTROL_MT(ECA_SESSION* psession); virtual ~ECA_CONTROL_MT (void); /*@}*/ // ------------------------------------------------------------------- /** @name Lock object exclusively to perform transactions */ /*@{*/ void lock_control(void); void unlock_control(void); /*@}*/ // ------------------------------------------------------------------- /** @name Runtime control */ /*@{*/ virtual void engine_start(void); virtual int start(void); virtual void stop(void); virtual void stop_on_condition(void); virtual int run(bool batchmode = true); virtual void quit(void); virtual void quit_async(void); virtual bool is_running(void) const; virtual bool is_connected(void) const; virtual bool is_selected(void) const; virtual bool is_finished(void) const; virtual bool is_valid(void) const; virtual bool is_engine_created(void) const; virtual bool is_engine_ready_for_commands(void) const; virtual const ECA_CHAINSETUP* get_connected_chainsetup(void) const; virtual void connect_chainsetup(struct eci_return_value *retval); virtual void disconnect_chainsetup(void); /*@}*/ // ------------------------------------------------------------------- /** @name Execute edit objects */ /*@{*/ virtual bool execute_edit_on_connected(const ECA::chainsetup_edit_t& edit); virtual bool execute_edit_on_selected(const ECA::chainsetup_edit_t& edit, int index = -1); /*@}*/ /** @name Building blocks for ECI -Ecasound Control Interface */ /*@{*/ /** * Parses and executes a string containing a single Ecasound * Interactive Mode (EIAM) command and its arguments. * * Result of the command can be queried with last_value_to_string(). */ virtual void command(const std::string& cmd_and_args, struct eci_return_value *retval); /** * A special version of 'command()' which parses a command taking * a single double parameter. * * Result of the command can be queried with last_value_to_string(). */ virtual void command_float_arg(const std::string& cmd, double arg, struct eci_return_value *retval); virtual void print_last_value(struct eci_return_value *retval) const; // ------------------------------------------------------------------- private: mutable pthread_mutex_t mutex_rep; ECA_CONTROL *ec_repp; ECA_CONTROL_MT& operator=(const ECA_CONTROL_MT& v) { return *this; } ECA_CONTROL_MT(const ECA_CONTROL_MT* v) {} }; #endif /* INCLUDED_ECA_CONTROL_IF_H */ ecasound-2.9.1/libecasound/eca-engine-driver.h0000644000076400007640000000322311560606715016211 00000000000000#ifndef INCLUDED_ECA_ENGINE_DRIVER_H #define INCLUDED_ECA_ENGINE_DRIVER_H class ECA_ENGINE; class ECA_CHAINSETUP; /** * Virtual base class for implementing ecasound * engine driver objects. * * Drivers are used to synchronize engine * execution to external timing sources. * For example soundcard's interrupt generation * can serve as a driver. * * @author Kai Vehmanen */ class ECA_ENGINE_DRIVER { public: /** @name Public API for driver execution */ /*@{*/ /** * Launches the driver. Returns an error if any problems are * detected during drier operation. * * @pre engine != 0 * @pre engine->is_valid() == true * @pre engine->connected_chainsetup() == csetup * @return zero on success; -1 on error */ virtual int exec(ECA_ENGINE* engine, ECA_CHAINSETUP* csetup) = 0; /*@}*/ /** @name Public API for external requests */ /*@{*/ /** * Signals that driver should start operating * the engine. Once started, driver is allowed * to call ECA_ENGINE functions. */ virtual void start(void) = 0; /** * Signals that driver should stop operation. * Once stopped, driver must not call * any non-const ECA_ENGINE functions. * * @param drain whether to block until all queued data is processed * by realtime devices before stopping */ virtual void stop(bool drain = false) = 0; /** * Signals that driver should stop operation * and return from its exec() method. * After exiting, driver must not call any * ECA_ENGINE functions. */ virtual void exit(void) = 0; /*@}*/ virtual ~ECA_ENGINE_DRIVER(void) {} }; #endif /* INCLUDED_ECA_ENGINE_DRIVER_H */ ecasound-2.9.1/libecasound/eca-control.h0000644000076400007640000003376611762503450015146 00000000000000// ------------------------------------------------------------------------ // eca-control.h: ECA_CONTROL class // Copyright (C) 2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #ifndef INCLUDED_ECA_CONTROL_H #define INCLUDED_ECA_CONTROL_H #include #include #include #include "kvu_locks.h" #include "ctrl-source.h" #include "eca-audio-format.h" #include "eca-chainop.h" #include "eca-chainsetup-edit.h" #include "eca-control-dump.h" #include "eca-control-main.h" #include "eca-iamode-parser.h" #include "sample-specs.h" class AUDIO_IO; class CHAIN_OPERATOR; class GENERIC_CONTROLLER; class ECA_CHAINSETUP; class ECA_ENGINE; class ECA_OBJECT_MAP; class ECA_SESSION; /** * High-level interface to libecasound functionality * * @see ECA_CONTROL_MAIN, ECA_CONTROL_MT * * Related design patters: Facade (GoF185) * * @author Kai Vehmanen */ class ECA_CONTROL : public ECA_IAMODE_PARSER, public ECA_CONTROL_MAIN { public: /** @name Constructors and dtors */ /*@{*/ ECA_CONTROL (ECA_SESSION* psession); ~ECA_CONTROL (void); /*@}*/ // ------------------------------------------------------------------- /** @name ECA_CONTROL_MAIN subset */ virtual bool is_running(void) const; virtual bool is_connected(void) const; virtual bool is_selected(void) const; virtual bool is_finished(void) const; virtual bool is_valid(void) const; virtual bool is_engine_created(void) const; virtual bool is_engine_ready_for_commands(void) const; virtual void engine_start(void); virtual int start(void); virtual void stop(void); virtual void stop_on_condition(void); virtual int run(bool batchmode = true); virtual void quit(void); virtual void quit_async(void); virtual void connect_chainsetup(struct eci_return_value *retval); virtual void disconnect_chainsetup(void); virtual const ECA_CHAINSETUP* get_connected_chainsetup(void) const; virtual bool execute_edit_on_connected(const ECA::chainsetup_edit_t& edit); virtual bool execute_edit_on_selected(const ECA::chainsetup_edit_t& edit, int index = -1); virtual void print_last_value(struct eci_return_value *retval) const; virtual void command(const std::string& cmd_and_args, struct eci_return_value *retval); virtual void command_float_arg(const std::string& cmd, double arg, struct eci_return_value *retval); /*@}*/ // ------------------------------------------------------------------- /** @name Public functions for observing status * (note: implemented in eca-control-base.cpp) */ /*@{*/ std::string engine_status(void) const; SAMPLE_SPECS::sample_pos_t length_in_samples(void) const; double length_in_seconds_exact(void) const; SAMPLE_SPECS::sample_pos_t position_in_samples(void) const; double position_in_seconds_exact(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Public functions for resource file access */ /*@{*/ /** * Get resource values from ~/.ecasoundrc */ std::string resource_value(const std::string& key) const; /*@}*/ // ------------------------------------------------------------------- /** @name Public functions for chainsetup setup * (note: implementated in eca-control-objects.cpp) */ /*@{*/ void add_chainsetup(const std::string& name); void remove_chainsetup(void); void load_chainsetup(const std::string& filename); void save_chainsetup(const std::string& filename); void select_chainsetup(const std::string& name); void select_chainsetup_by_index(int index); void edit_chainsetup(void); std::string selected_chainsetup(void) const; std::string connected_chainsetup(void) const; void change_chainsetup_position(double seconds); void change_chainsetup_position_samples(SAMPLE_SPECS::sample_pos_t samples); void set_chainsetup_position(double seconds); void set_chainsetup_position_samples(SAMPLE_SPECS::sample_pos_t samples); double chainsetup_position(double seconds) const; const ECA_CHAINSETUP* get_chainsetup(void) const; const ECA_CHAINSETUP* get_chainsetup_filename(const std::string& filename) const; std::vector chainsetup_names(void) const; const std::string& chainsetup_filename(void) const; int chainsetup_buffersize(void) const; void set_chainsetup_filename(const std::string& name); void set_chainsetup_parameter(const std::string& name); void set_chainsetup_sample_format(const std::string& name); void set_chainsetup_processing_length_in_seconds(double value); void set_chainsetup_processing_length_in_samples(SAMPLE_SPECS::sample_pos_t value); void set_chainsetup_output_mode(int output_mode); void toggle_chainsetup_looping(void); void set_chainsetup_buffersize(int bsize); /*@}*/ // ------------------------------------------------------------------- /** @name Public functions for chain setup * (note: implemented in eca-control-objects.cpp) */ /*@{*/ void add_chain(const std::string& names); void add_chains(const std::string& names); void add_chains(const std::vector& names); void remove_chains(void); void select_chains_by_index(const std::vector& index_numbers); void select_chain(const std::string& chain); void select_chains(const std::vector& chains); void deselect_chains(const std::vector& chains); void select_all_chains(void); const std::vector& selected_chains(void) const; std::vector chain_names(void) const; const CHAIN* get_chain(void) const; bool chain_is_bypassed(void) const; bool chain_is_muted(void) const; void clear_chains(void); void rename_chain(const std::string& name); void set_chain_muting(const string &arg); void set_chain_bypass(const string &arg); /*@}*/ // ------------------------------------------------------------------- /** @name Managing chain operators and controllers * (note: implemented in eca-control-objects.cpp) */ /*@{*/ void add_audio_input(const std::string& filename); void remove_audio_input(void); void attach_audio_input(void); void select_audio_input(const std::string& name); void select_audio_input_by_index(int index); void add_audio_output(const std::string& filename); void add_default_output(void); void remove_audio_output(void); void attach_audio_output(void); void select_audio_output(const std::string& name); void select_audio_output_by_index(int index); void set_default_audio_format(const std::string& sfrm, int channels, long int srate, bool interleaving); void set_default_audio_format(const ECA_AUDIO_FORMAT& format); void set_default_audio_format_to_selected_input(void); void set_default_audio_format_to_selected_output(void); std::string attached_chains_input(AUDIO_IO* aiod) const; std::string attached_chains_output(AUDIO_IO* aiod) const; std::vector attached_chains(const std::string& name) const; const AUDIO_IO* get_audio_input(void); std::vector audio_input_names(void) const; const AUDIO_IO* get_audio_output(void); std::vector audio_output_names(void) const; const ECA_AUDIO_FORMAT& default_audio_format(void) const; ECA_AUDIO_FORMAT get_audio_format(AUDIO_IO* aobj) const; /*@}*/ // ------------------------------------------------------------------- /** @name Managing chain operators and controllers * (note: implemented in eca-control-objects.cpp) */ /*@{*/ void add_chain_operator(const std::string& chainop_params); void add_chain_operator(CHAIN_OPERATOR* cotmp); void bypass_chain_operator(const string& arg); bool chain_operator_is_bypassed(void) const; void remove_chain_operator(void); void select_chain_operator(int chainop_id); void select_chain_operator_parameter(int param); void set_chain_operator_parameter(CHAIN_OPERATOR::parameter_t value); void set_chain_operator_parameter(int chain, int op, int param, CHAIN_OPERATOR::parameter_t value); int selected_chain_operator(void) const; int selected_chain_operator_parameter(void) const; const CHAIN_OPERATOR* get_chain_operator(void) const; CHAIN_OPERATOR::parameter_t get_chain_operator_parameter(void) const; std::vector chain_operator_names(void) const; std::vector chain_operator_parameter_names(void) const; void add_controller(const std::string& gcontrol_params); void select_controller(int ctrl_id); void select_controller_parameter(int param); void set_controller_parameter(CHAIN_OPERATOR::parameter_t value); void remove_controller(void); int selected_controller(void) const; int selected_controller_parameter(void) const; int selected_controller_target(void) const; const GENERIC_CONTROLLER* get_controller(void) const; CONTROLLER_SOURCE::parameter_t get_controller_parameter(void) const; std::vector controller_names(void) const; std::vector controller_parameter_names(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Public functions for executing ECI commands */ /*@{*/ /** * See ECA_IAMODE_PARSER for detailed decsription of 'action_id'. * * Result of the command can be queried with last_value_to_string(). */ void action(int action_id, const std::vector& args); std::string last_error(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Implemenetations of ECI status commands */ /*@{*/ /** * Return info about chainsetups */ std::string chainsetup_status(void) const; /** * Return info about current chain status * * require: * is_selected() == true * selected_chains().size() > 0 */ std::string chain_status(void) const; /** * Return info about inputs and outputs */ std::string aio_status(void) const; /** * Return info about chain operators (selected chainsetup) * * require: * is_selected() == true */ std::string chain_operator_status(void) const; /** * Return info about controllers (selected chainsetup) * * require: * is_selected() == true */ std::string controller_status(void) const; void aio_register(void); void cop_register(void); void preset_register(void); void ladspa_register(void); void lv2_register(void); void ctrl_register(void); void operator_descriptions_helper(const ECA_OBJECT_MAP& arg, std::string* result); void cop_descriptions(void); void preset_descriptions(void); void ladspa_descriptions(bool use_id); void lv2_descriptions(void); void ctrl_descriptions(void); /*@}*/ // ------------------------------------------------------------------- /** @name Helper functions */ /*@{*/ int float_to_string_precision(void) const { return(float_to_string_precision_rep); } /*@}*/ // ------------------------------------------------------------------- protected: void set_float_to_string_precision(int precision); std::string float_to_string(double n) const; private: void set_last_string_list(const std::vector& s); void set_last_string(const std::list& s); void set_last_string(const std::string& s); void set_last_float(double v); void set_last_integer(int v); void set_last_long_integer(long int v); void set_last_error(const std::string& s); void clear_last_values(void); static void* start_normal_thread(void *ptr); void start_engine_sub(bool batchmode); void close_engine(void); void run_engine(void); std::string chainsetup_details_to_string(const ECA_CHAINSETUP* cs) const; void audio_input_as_selected(void); void audio_output_as_selected(void); void rewind_audio_object(double seconds); void forward_audio_object(double seconds); void set_audio_object_position(double seconds); void set_audio_object_position_samples(SAMPLE_SPECS::sample_pos_t samples); void wave_edit_audio_object(void); CHAIN* get_chain_priv(void) const; void action(int action_id); void check_action_preconditions(int action_id); void chainsetup_option(const std::string& cmd); void set_action_argument(const std::string& s); void set_action_argument(const std::vector& s); void set_action_argument(double v); void clear_action_arguments(void); double first_action_argument_as_float(void) const; std::string first_action_argument_as_string(void) const; int first_action_argument_as_int(void) const; long int first_action_argument_as_long_int(void) const; SAMPLE_SPECS::sample_pos_t first_action_argument_as_samples(void) const; const std::vector& action_arguments_as_vector(void) const; void fill_command_retval(struct eci_return_value *retval) const; bool action_helper_check_cop_op_args(int copid, int coppid); ECA_ENGINE* engine_repp; ECA_SESSION* session_repp; ECA_CHAINSETUP* selected_chainsetup_repp; ECA_CONTROL_DUMP ctrl_dump_rep; bool req_batchmode_rep; pthread_t th_cqueue_rep; ATOMIC_INTEGER engine_exited_rep; int engine_pid_rep; int last_exec_res_rep; bool joining_rep; int float_to_string_precision_rep; AUDIO_IO* selected_audio_object_repp; AUDIO_IO* selected_audio_input_repp; AUDIO_IO* selected_audio_output_repp; struct eci_return_value last_retval_rep; bool wellformed_mode_rep; std::vector action_args_rep; double action_arg_f_rep; bool action_arg_f_set_rep; bool action_ok; bool action_reconnect; bool action_restart; }; #endif ecasound-2.9.1/libecasound/oscillator.h0000644000076400007640000000165011034532355015074 00000000000000#ifndef INCLUDED_OSCILLATOR_H #define INCLUDED_OSCILLATOR_H #include #include #include "ctrl-source.h" /** * Base class for various oscillators * * Unlike finite controller sources, oscillators * produce new values infinately. */ class OSCILLATOR : public CONTROLLER_SOURCE { public: virtual void set_initial_value(parameter_t arg) {} /** * Constructor * * @param freq Oscillator frequency * @param phase Initial phase, multiple of pi */ OSCILLATOR(parameter_t freq = 0, parameter_t initial_phase = 0) { freq_value = freq; phase_value = initial_phase * M_PI; } private: parameter_t freq_value, phase_value; protected: parameter_t phase_offset(void) const { return(phase_value); } parameter_t frequency(void) const { return(freq_value); } void phase_offset(parameter_t v) { phase_value = v; } void frequency(parameter_t v) { freq_value = v; } }; #endif ecasound-2.9.1/libecasound/eca-test-repository.h0000644000076400007640000000314311141027232016632 00000000000000#ifndef INCLUDE_ECA_TEST_REPOSITORY_H #define INCLUDE_ECA_TEST_REPOSITORY_H #include #include #include #include "eca-test-case.h" /** * A testing subsystem implemented as a * singleton class. * * Note! Also the non-static part of this class * implements the ECA_TEST_CASE interface. * This means you can use the repository * just like a single test case (Composite * design pattern). * * Related design patterns: * - Singleton (GoF127) * - Composite (GoF163) * * @author Kai Vehmanen */ class ECA_TEST_REPOSITORY : public ECA_TEST_CASE { public: /** * Returns a reference to a unit testing object. * * Note! Return value is a reference to * avoid accidental deletion of * the singleton object. */ static ECA_TEST_REPOSITORY& instance(void); protected: virtual void do_run(void); virtual void do_run(const std::string& name); virtual std::string do_name(void) const { return("ECA_TEST_REPOSITORY"); } private: void do_run_worker(ECA_TEST_CASE* testcase); static ECA_TEST_REPOSITORY* interface_impl_repp; static pthread_mutex_t lock_rep; std::list test_cases_rep; /** * @name Constructors and destructors * * To prevent accidental use, located in private scope and * without a valid definition. */ /*@{*/ ECA_TEST_REPOSITORY(void); ~ECA_TEST_REPOSITORY(void); ECA_TEST_REPOSITORY(const ECA_TEST_REPOSITORY&) {} ECA_TEST_REPOSITORY& operator=(const ECA_TEST_REPOSITORY&) { return *this; } /*@}*/ }; #endif /* INCLUDE_ECA_TEST_REPOSITORY_H */ ecasound-2.9.1/libecasound/eca-resources.h0000644000076400007640000000203410664032032015451 00000000000000#ifndef INCLUDED_ECA_RESOURCES_H #define INCLUDED_ECA_RESOURCES_H #include class RESOURCE_FILE; /** * Class for representing ecasound user settings stored * in global ({prefix}/share/ecasound/ecasoundrc) and * user-specific (~/.ecasoundrc) resource files. */ class ECA_RESOURCES { public: std::string resource(const std::string& tag) const; bool boolean_resource(const std::string& tag) const; bool has(const std::string& tag) const; bool has_any(void) const; void resource(const std::string& tag, const std::string& value); ECA_RESOURCES(void); ~ECA_RESOURCES(void); public: /** * If non-empty, will override all other resource files for * newly created ECA_RESOURCES instances. */ static std::string rc_override_file; private: ECA_RESOURCES(const ECA_RESOURCES&); ECA_RESOURCES& operator=(const ECA_RESOURCES&); RESOURCE_FILE* globalrc_repp; RESOURCE_FILE* userrc_repp; RESOURCE_FILE* overriderc_repp; std::string user_resource_directory_rep; bool resources_found_rep; }; #endif ecasound-2.9.1/libecasound/layer.h0000644000076400007640000000506010664032032014027 00000000000000/* layer.h Created by SMF aka Antoine Laydier . Minor modifications by Kai Vehmanen . 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _LAYER_ #define _LAYER_ /*============================================================================= HEADERs =============================================================================*/ #include /*============================================================================= CLASSes =============================================================================*/ //----------------------------------------------------------------------------- // class Layer //----------------------------------------------------------------------------- /** * Mp3 header parsing */ class Layer { public: const char * mode_name(void); const char * layer_name(void); const char * version_name(void); const char * version_num(void); unsigned int bitrate(void); unsigned int sfreq(void); unsigned long length(void); unsigned int pcmPerFrame(void); int mode(void); bool get(const char* filename); static const char * mode_names[5]; static const char * layer_names[3]; static const char * version_names[3]; static const char * version_nums[3]; static const unsigned int bitrates[3][3][15]; static const unsigned int s_freq[3][4]; static const int MPG_MD_STEREO; static const int MPG_MD_JOINT_STEREO; static const int MPG_MD_DUAL_CHANNEL; static const int MPG_MD_MONO; static const int MPG_MD_LR_LR; static const int MPG_MD_LR_I; static const int MPG_MD_MS_LR; static const int MPG_MD_MS_I; private: int version_rep; int lay_rep; int error_protection_rep; int bitrate_index_rep; int sampling_frequency_rep; int padding_rep; int extension_rep; int mode_rep; int mode_ext_rep; int copyright_rep; int original_rep; int emphasis_rep; int stereo_rep; unsigned int pcm_rep; unsigned long fileSize_rep; }; #endif ecasound-2.9.1/libecasound/midi-client.cpp0000644000076400007640000000252610664032032015450 00000000000000// ------------------------------------------------------------------------ // midi-client.cpp: Top-level interface for MIDI-clients // Copyright (C) 2001,2005 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 "midi-server.h" #include "midi-client.h" MIDI_CLIENT::MIDI_CLIENT(void) : id_rep(0), id_set_rep(false), server_repp(0) { } int MIDI_CLIENT::id(void) const { return(id_rep); } void MIDI_CLIENT::set_id(int n) { id_rep = n; id_set_rep = true; } void MIDI_CLIENT::register_server(MIDI_SERVER* server) { server_repp = server; } ecasound-2.9.1/libecasound/eca-control-main.cpp0000644000076400007640000000603511172651507016412 00000000000000// ------------------------------------------------------------------------ // eca-control-main.h: ECA_CONTROL_MAIN // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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, see . // ------------------------------------------------------------------------ #include #include #include "kvu_dbc.h" #include "kvu_numtostr.h" #include "kvu_utils.h" #include "eca-control-main.h" #include "eca-logger.h" ECA_CONTROL_MAIN::~ECA_CONTROL_MAIN (void) { } std::string ECA_CONTROL_MAIN::return_value_to_string(const struct eci_return_value *retval, int float_precision) { std::string result; if (retval->type == eci_return_value::retval_none) { ; /* nop */ } else if (retval->type == eci_return_value::retval_error) { result = retval->string_val; } else if (retval->type == eci_return_value::retval_string) { result = retval->string_val; } else if (retval->type == eci_return_value::retval_string_list) { result = kvu_vector_to_string(kvu_vector_search_and_replace(retval->string_list_val, ",", "\\,"), ","); } else if (retval->type == eci_return_value::retval_integer) { result = kvu_numtostr(retval->m.int_val); } else if (retval->type == eci_return_value::retval_long_integer) { result = kvu_numtostr(retval->m.long_int_val); } else if (retval->type == eci_return_value::retval_float) { result = kvu_numtostr(retval->m.float_val, float_precision); } else { DBC_NEVER_REACHED(); } return result; } const char* ECA_CONTROL_MAIN::return_value_type_to_string(const struct eci_return_value *retval) { if (retval->type == eci_return_value::retval_none) return "-"; else if (retval->type == eci_return_value::retval_error) return "e"; else if (retval->type == eci_return_value::retval_string) return "s"; else if (retval->type == eci_return_value::retval_string_list) return "S"; else if (retval->type == eci_return_value::retval_integer) return "i"; else if (retval->type == eci_return_value::retval_long_integer) return "li"; else if (retval->type == eci_return_value::retval_float) return "f"; else DBC_NEVER_REACHED(); return NULL; } void ECA_CONTROL_MAIN::clear_return_value(struct eci_return_value *retval) { if (retval == 0) return; retval->type = eci_return_value::retval_none; retval->string_list_val.resize(0); retval->string_val.resize(0); retval->m.long_int_val = 0; } ecasound-2.9.1/libecasound/eca-samplerate-aware.cpp0000644000076400007640000000245010664032032017226 00000000000000// ------------------------------------------------------------------------ // eca-samplerate-aware.: Interface class implemented by all types that // require knowledge of system samplerate // Copyright (C) 2002 Kai Vehmanen // // 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 "eca-samplerate-aware.h" ECA_SAMPLERATE_AWARE::ECA_SAMPLERATE_AWARE(SAMPLE_SPECS::sample_rate_t srate) : srate_rep(srate) { } ECA_SAMPLERATE_AWARE::~ECA_SAMPLERATE_AWARE(void) { } void ECA_SAMPLERATE_AWARE::set_samples_per_second(long int v) { srate_rep = v; } ecasound-2.9.1/libecasound/midiio-aseq.h0000644000076400007640000000271410664032032015117 00000000000000#ifndef INCLUDED_MIDIIO_ASEQ_H #define INCLUDED_MIDIIO_ASEQ_H #include #include #include "midiio.h" /** * Input and output of raw MIDI streams using * ALSA sequencer * * @author Pedro Lopez-Cabanillas */ class MIDI_IO_ASEQ : public MIDI_IO { public: MIDI_IO_ASEQ (const std::string& name = ""); virtual ~MIDI_IO_ASEQ(void); virtual MIDI_IO_ASEQ* clone(void) const { return(new MIDI_IO_ASEQ(*this)); } virtual MIDI_IO_ASEQ* new_expr(void) const { return new MIDI_IO_ASEQ(); } virtual std::string name(void) const { return("ALSA Sequencer MIDI"); } virtual int supported_io_modes(void) const { return(io_read | io_write | io_readwrite); } virtual bool supports_nonblocking_mode(void) const { return(true); } virtual std::string parameter_names(void) const { return("label,device_name"); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; virtual void open(void); virtual void close(void); virtual int poll_descriptor(void) const; virtual long int read_bytes(void* target_buffer, long int bytes); virtual long int write_bytes(void* target_buffer, long int bytes); virtual bool finished(void) const; virtual bool pending_messages(unsigned long timeout) const; private: snd_seq_t* seq_handle_repp; snd_midi_event_t* coder_repp; int buffer_size_rep; int port_rep; bool finished_rep; std::string device_name_rep; }; #endif ecasound-2.9.1/libecasound/samplebuffer_functions.h0000644000076400007640000000746511262073612017475 00000000000000// ------------------------------------------------------------------------ // samplebuffer_functions.cpp: Extra functions for SAMPLE_BUFFER class // Copyright (C) 2000,2001,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 INCLUDED_SAMPLEBUFFER_FUNCTIONS_H #define INCLUDED_SAMPLEBUFFER_FUNCTIONS_H #include #include "samplebuffer.h" /** * Various simple functions that operate on sample buffer data. This * class really is just an extension of class SAMPLE_BUFFER. */ class SAMPLE_BUFFER_FUNCTIONS { public: typedef SAMPLE_BUFFER::sample_t sample_t; static sample_t max_value(const SAMPLE_BUFFER& buf, SAMPLE_BUFFER::channel_size_t channel) { sample_t t = SAMPLE_SPECS::impl_min_value; for(SAMPLE_BUFFER::buf_size_t m = 0; m < buf.buffersize_rep; m++) { if (buf.buffer[channel][m] > t) t = buf.buffer[channel][m]; } return(t); } static sample_t min_value(const SAMPLE_BUFFER& buf, SAMPLE_BUFFER::channel_size_t channel) { sample_t t = SAMPLE_SPECS::impl_max_value; for(SAMPLE_BUFFER::buf_size_t m = 0; m < buf.buffersize_rep; m++) { if (buf.buffer[channel][m] < t) t = buf.buffer[channel][m]; } return(t); } static sample_t average_amplitude(const SAMPLE_BUFFER& buf) { sample_t temp_avg = 0.0; for(int n = 0; n < buf.channel_count_rep; n++) { for(SAMPLE_BUFFER::buf_size_t m = 0; m < buf.buffersize_rep; m++) { temp_avg += fabs(buf.buffer[n][m] - SAMPLE_SPECS::silent_value); } } return(temp_avg / buf.channel_count_rep / buf.buffersize_rep); } static sample_t RMS_volume(const SAMPLE_BUFFER& buf) { sample_t temp_avg = 0.0; for(int n = 0; n < buf.channel_count_rep; n++) { for(SAMPLE_BUFFER::buf_size_t m = 0; m < buf.buffersize_rep; m++) { temp_avg += buf.buffer[n][m] * buf.buffer[n][m]; } } return(sqrt(temp_avg / buf.channel_count_rep / buf.buffersize_rep)); } static sample_t average_amplitude(const SAMPLE_BUFFER& buf, SAMPLE_BUFFER::channel_size_t channel, SAMPLE_BUFFER::buf_size_t count_samples) { sample_t temp_avg = 0.0; if (count_samples == 0) count_samples = static_cast(buf.channel_count_rep); for(SAMPLE_BUFFER::buf_size_t n = 0; n < buf.buffersize_rep; n++) { temp_avg += fabs(buf.buffer[channel][n] - SAMPLE_SPECS::silent_value); } return(temp_avg / count_samples); } static sample_t RMS_volume(const SAMPLE_BUFFER& buf, SAMPLE_BUFFER::channel_size_t channel, SAMPLE_BUFFER::buf_size_t count_samples) { sample_t temp_avg = 0.0; if (count_samples == 0) count_samples = static_cast(buf.channel_count_rep); for(SAMPLE_BUFFER::buf_size_t n = 0; n < buf.buffersize_rep; n++) { temp_avg += buf.buffer[channel][n] * buf.buffer[channel][n]; } return(sqrt(temp_avg / count_samples)); } static void fill_with_random_samples(SAMPLE_BUFFER *sbuf); static bool is_almost_equal(const SAMPLE_BUFFER& a, const SAMPLE_BUFFER& b, int bitprec = 24, bool verbose_stderr = false); }; #endif ecasound-2.9.1/libecasound/audioio-buffered.h0000644000076400007640000000305710664032032016130 00000000000000#ifndef INCLUDED_AUDIOIO_BUFFERED_H #define INCLUDED_AUDIOIO_BUFFERED_H #include "audioio.h" class SAMPLE_BUFFER; /** * A lower level interface for audio I/O objects. Derived classes * must implement routines for reading and/or writing buffers of raw data. */ class AUDIO_IO_BUFFERED : public AUDIO_IO { public: virtual ~AUDIO_IO_BUFFERED(void); AUDIO_IO_BUFFERED(void); virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual void set_buffersize(long int samples); virtual long int buffersize(void) const { return(buffersize_rep); } /** * Low-level routine for reading samples. Number of read sample * frames is returned. This must be implemented by all subclasses. */ virtual long int read_samples(void* target_buffer, long int sample_frames) = 0; /** * Low-level routine for writing samples. This must be implemented * by all subclasses. */ virtual void write_samples(void* target_buffer, long int sample_frames) = 0; /** @name Reimplemented functions from ECA_AUDIO_FORMAT */ /*@{*/ virtual void set_channels(SAMPLE_SPECS::channel_t v); virtual void set_sample_format(Sample_format v) throw(ECA_ERROR&); /*@{*/ protected: void reserve_buffer_space(long int bytes); unsigned char* get_iobuf(void) const { return(iobuf_uchar_repp); } size_t get_iobuf_size(void) const { return(iobuf_size_rep); } private: long int buffersize_rep; unsigned char* iobuf_uchar_repp; // buffer for raw-I/O size_t iobuf_size_rep; }; #endif // INCLUDED_AUDIO_IO_BUFFERED ecasound-2.9.1/libecasound/audiofx_rcfilter.cpp0000644000076400007640000001012211755701413016602 00000000000000// ------------------------------------------------------------------------ // audiofx_rcfilter.cpp: Simulation of an 3rd-order 36dB active RC-lowpass // Copyright (C) 2000 Stefan Fendt, Kai Vehmanen (C++ version) // Copyright (C) 2012 Kai Vehmanen // // 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 #include #include "samplebuffer_iterators.h" #include "eca-logger.h" #include "audiofx_rcfilter.h" EFFECT_RC_LOWPASS_FILTER::EFFECT_RC_LOWPASS_FILTER (CHAIN_OPERATOR::parameter_t cutoff, CHAIN_OPERATOR::parameter_t resonance) { set_parameter(1, cutoff); set_parameter(2, resonance); } void EFFECT_RC_LOWPASS_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { switch (param) { case 1: cutoff_rep = value; break; case 2: resonance_rep = value; break; } } CHAIN_OPERATOR::parameter_t EFFECT_RC_LOWPASS_FILTER::get_parameter(int param) const { switch (param) { case 1: return(cutoff_rep); case 2: return(resonance_rep); } return(0.0); } static void priv_resize_buffer(std::vector *buffer, int count, SAMPLE_SPECS::sample_t value) { buffer->resize(count); for(int i = 0; i < count; i++) (*buffer)[i] = value; } void EFFECT_RC_LOWPASS_FILTER::init(SAMPLE_BUFFER *insample) { i.init(insample); priv_resize_buffer(&lp1_old, insample->number_of_channels(), 0.0015); priv_resize_buffer(&lp2_old, insample->number_of_channels(), -0.00067); priv_resize_buffer(&lp3_old, insample->number_of_channels(), 0.0); priv_resize_buffer(&hp1_old, insample->number_of_channels(), 0.0); priv_resize_buffer(&feedback, insample->number_of_channels(), 0.0); } void EFFECT_RC_LOWPASS_FILTER::process(void) { i.begin(); while(!i.end()) { output_temp = *i.current(); output_temp += (feedback[i.channel()] * resonance_rep); // -- // The two lines above prevent the filter from clipping if it is // self-oscillating. This is necessary for a good simulation because // real analouge RC-filters can't clip when oscillating, too. Clipping // used to simulate saturation of an amp (as many TB-303-emulators do) // is dissatisfying ! We should use an Amp-simulation instead to avoid // digital clipping ... if (output_temp > SAMPLE_SPECS::impl_max_value) output_temp = SAMPLE_SPECS::impl_max_value; else if (output_temp < SAMPLE_SPECS::impl_min_value) output_temp = SAMPLE_SPECS::impl_min_value; // -- // Ok, this is the first step of the filter. We simulate an simple // non-active RC-lowpass ... lp1_old[i.channel()] = output_temp * cutoff_rep + lp1_old[i.channel()] * (1.0 - cutoff_rep); lp2_old[i.channel()] = lp1_old[i.channel()] * cutoff_rep + lp2_old[i.channel()] * (1.0 - cutoff_rep); lp3_old[i.channel()] = lp2_old[i.channel()] * cutoff_rep + lp3_old[i.channel()] * (1.0 - cutoff_rep); // -- // A simple non-active highpass hp1_old[i.channel()] = output_temp - lp3_old[i.channel()]; // -- // Now we add a feedback of this bandpass-filtered signal to the // input of the filter again. (Look some lines above for that!) feedback[i.channel()] = hp1_old[i.channel()]; // -- // We catch the out-value of the filter after the second lp-filter // this provides 24-db filtering even with moderate resonance. *i.current() = lp3_old[i.channel()]; i.next(); } } ecasound-2.9.1/libecasound/eca-session.h0000644000076400007640000000757710664032032015143 00000000000000#ifndef INCLUDED_ECA_SESSION_H #define INCLUDED_ECA_SESSION_H #include #include #include #include "eca-error.h" class AUDIO_IO; class ECA_CHAIN; class ECA_CHAINSETUP; /** * Class representing a set of chainsetups. Provided * functionality includes creating, removing, * selecting and connecting of chainsetups. * * Notes: Friendship access to data members is * allowed for ECA_CONTROL objects. */ class ECA_SESSION { public: // -- // type definitions and constants friend class ECA_CONTROL_BASE; friend class ECA_CONTROL_OBJECTS; friend class ECA_CONTROL; public: // -- // Public/const routines // -- const std::vector& get_chainsetups(void) const { return chainsetups_rep; } const ECA_CHAINSETUP* get_selected_chainsetup(void) const { return selected_chainsetup_repp; } const ECA_CHAINSETUP* get_connected_chainsetup(void) const { return connected_chainsetup_repp; } const ECA_CHAINSETUP* get_chainsetup_with_name(const std::string& name) const; bool is_selected_chainsetup_connected(void) const { return(selected_chainsetup_repp == connected_chainsetup_repp); } // -- // Constructors and destructors // -- ECA_SESSION(void); ECA_SESSION(COMMAND_LINE& cline) throw(ECA_ERROR&); ~ECA_SESSION(void); private: // --- // Status data // --- std::vector chainsetups_rep; ECA_CHAINSETUP* connected_chainsetup_repp; ECA_CHAINSETUP* selected_chainsetup_repp; bool cs_defaults_set_rep; // --- // Setup interpretation // --- void set_cs_param_defaults(void); void preprocess_options(std::vector* opts); void create_chainsetup_options(COMMAND_LINE& cline, std::vector* options); int interpret_general_options(const std::vector& inopts, std::vector* outopts); int interpret_general_option(const std::string& opts); int interpret_chainsetup_option(const std::string& argu); int interpret_general_option(COMMAND_LINE& cline, std::vector* options); bool is_session_option(const std::string& arg) const; // --- // Function for handling chainsetups // --- void add_chainsetup(const std::string& name); void add_chainsetup(ECA_CHAINSETUP* comline_setup); void remove_chainsetup(void); /** * Select chainsetup with name 'name' * * require: * name.empty() != true && * * ensure: * (selected_chainsetup->name() == name) || * (selected_chainsetup == 0) */ void select_chainsetup(const std::string& name); /** * Save selected chainsetup * * require: * selected_chainsetup != 0 */ void save_chainsetup(void) throw(ECA_ERROR&); /** * Save selected chainsetup to file 'filename' * * require: * selected_chainsetup != 0 && * filename.empty() != true */ void save_chainsetup(const std::string& filename) throw(ECA_ERROR&); /** * Load chainsetup from file "filename" * * require: * filename.empty() != true * * ensure: * selected_chainsetup->filename() == filename */ void load_chainsetup(const std::string& filename); /** * Connect selected chainsetup * * require: * selected_chainsetup != 0 && * selected_chainsetup->is_valid() * * ensure: * selected_chainsetup == connected_chainsetup */ void connect_chainsetup(void) throw(ECA_ERROR&); /** * Disconnect connected chainsetup * * require: * connected_chainsetup != 0 * * ensure: * connected_chainsetup == 0 */ void disconnect_chainsetup(void); /** * Gets a vector of all chainsetup names. */ std::vector chainsetup_names(void) const; void update_controller_sources(void); // -- // Make sure that objects of this class aren't copy constucted/assigned // -- ECA_SESSION (const ECA_SESSION& x) { } ECA_SESSION& operator=(const ECA_SESSION& x) { return *this; } }; #endif ecasound-2.9.1/libecasound/audioio-aac.h0000644000076400007640000000447011141362354015076 00000000000000#ifndef INCLUDED_AUDIOIO_AAC_H #define INCLUDED_AUDIOIO_AAC_H #include #include #include "audioio-buffered.h" #include "audioio-forked-stream.h" /** * Interface to FAAC/FAAD encoder and decoder using UNIX pipe i/o. * * @author Kai Vehmanen */ class AAC_FORKED_INTERFACE : public AUDIO_IO_BUFFERED, public AUDIO_IO_FORKED_STREAM { private: static std::string default_input_cmd; static std::string default_output_cmd; public: static void set_input_cmd(const std::string& value); static void set_output_cmd(const std::string& value); public: AAC_FORKED_INTERFACE (const std::string& name = ""); virtual ~AAC_FORKED_INTERFACE(void); virtual AAC_FORKED_INTERFACE* clone(void) const { return new AAC_FORKED_INTERFACE(*this); } virtual AAC_FORKED_INTERFACE* new_expr(void) const { return new AAC_FORKED_INTERFACE(*this); } virtual std::string name(void) const { return("AAC stream"); } virtual std::string description(void) const { return("Interface to FAAC/FAAD encoder and decoder using UNIX pipe i/o."); } virtual std::string parameter_names(void) const { return("label"); } virtual bool locked_audio_format(void) const { return true; } virtual int supported_io_modes(void) const { return (io_read | io_write); } virtual bool supports_seeking(void) const { return false; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const { return(finished_rep); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; virtual void start_io(void); virtual void stop_io(void); // -- // Realtime related functions // -- protected: /* functions called by AUDIO_IO_FORKED_STREAM that require * the use of AUDIO_IO methods */ virtual bool do_supports_seeking(void) const { return supports_seeking(); } virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { set_position_in_samples(pos); } private: bool triggered_rep; bool finished_rep; long int bytes_rep; int filedes_rep; FILE* f1_rep; void fork_input_process(void); void fork_output_process(void); }; #endif ecasound-2.9.1/libecasound/audioio-null.h0000644000076400007640000000231411141057331015313 00000000000000#ifndef INCLUDED_AUDIOIO_NULL_H #define INCLUDED_AUDIOIO_NULL_H #include "audioio-buffered.h" /** * Audio object that endlessly consumes and produces audio data. * And is incredibly fast. :) */ class NULLFILE : public AUDIO_IO_BUFFERED { public: virtual std::string name(void) const { return("Null audio object"); } virtual void open(void) throw (AUDIO_IO::SETUP_ERROR &) { AUDIO_IO::open(); } virtual void close(void) { AUDIO_IO::close(); } virtual long int read_samples(void* target_buffer, long int samples) { for(long int n = 0; n < static_cast(samples * frame_size()); n++) ((char*)target_buffer)[n] = 0; return(samples); } virtual void write_samples(void* target_buffer, long int samples) { } virtual bool finished(void) const { return false; } virtual bool supports_seeking(void) const { return true; } virtual bool finite_length_stream(void) const { return false; } virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos) { return pos; } NULLFILE(const std::string& name = "null"); virtual ~NULLFILE(void); NULLFILE* clone(void) const { return new NULLFILE(*this); } NULLFILE* new_expr(void) const { return new NULLFILE(); } }; #endif ecasound-2.9.1/libecasound/eca-object-map.h0000644000076400007640000000434511141420572015470 00000000000000#ifndef INCLUDED_ECA_OBJECT_MAP_H #define INCLUDED_ECA_OBJECT_MAP_H #include #include #include #include "eca-object.h" /** * A virtual base class representing generic object maps. * * Object maps are used to centralize object creation. * To add an object to the map, a prototype instance * is registered. Each object is associated with * a keyword and a regex expression that can be used * for object look up and creation. * * Most parts of the library don't require info about * object details. Object maps make it possible to * hide these details completely, and in one place. * * Related design patterns: * - Prototype (GoF117) * - Factory Method (GoF107) * * @author Kai Vehmanen */ class ECA_OBJECT_MAP { public: /** @name Constructors and destructors */ /*@{*/ ECA_OBJECT_MAP(void); virtual ~ECA_OBJECT_MAP(void); /*@}*/ /** @name Object map features */ /*@{*/ void toggle_case_sensitive_expressions(bool v); bool case_sensitive_expressions(void) const; /*@}*/ /** @name Object registration */ /*@{*/ virtual void register_object(const std::string& keyword, const std::string& expr, ECA_OBJECT* object); virtual void unregister_object(const std::string& keyword); /*@}*/ /** @name Object creation using object prototypes instances */ /*@{*/ virtual const ECA_OBJECT* object(const std::string& keyword) const; virtual const ECA_OBJECT* object_expr(const string& expr) const; /*@}*/ /** @name Query the object map */ /*@{*/ virtual const std::list& registered_objects(void) const; virtual bool has_keyword(const std::string& keyword) const; virtual bool has_object(const ECA_OBJECT* obj) const; virtual std::string expr_to_keyword(const std::string& expr) const; virtual std::string keyword_to_expr(const std::string& keyword) const; virtual std::string object_identifier(const ECA_OBJECT* object) const; /*@}*/ private: ECA_OBJECT_MAP(const ECA_OBJECT_MAP&); ECA_OBJECT_MAP& operator=(const ECA_OBJECT_MAP&); std::list object_keywords_rep; mutable std::map object_map; mutable std::map object_expr_map; bool expr_case_sensitive_rep; }; #endif ecasound-2.9.1/libecasound/jack-connections.h0000644000076400007640000000072311065163721016152 00000000000000#ifndef INCLUDED_JACK_CONNECTIONS_H #define INCLUDED_JACK_CONNECTIONS_H #include /** * Utility class to manage JACK port connections. */ class JACK_CONNECTIONS { public: static bool connect(const char* src, const char* dest); static bool disconnect(const char* src, const char* dest); static bool list_connections(std::string* output); private: JACK_CONNECTIONS(void); ~JACK_CONNECTIONS(void); }; #endif /* INCLUDED_JACK_CONNECTIONS_H */ ecasound-2.9.1/libecasound/eca-control-dump.h0000644000076400007640000000642510664032032016072 00000000000000#ifndef INCLUDED_ECA_CONTROL_DUMP_H #define INCLUDED_ECA_CONTROL_DUMP_H #include #include class ECA_CONTROL; /** * Class for dumping status information to a standard output stream. * @author Kai Vehmanen */ class ECA_CONTROL_DUMP { public: // -- // Global info // -- /** * Dumps engine status - 'running', 'stopped', 'finished' or 'notready'. */ void dump_status(void); /** * Dumps the global position. Printed in seconds using a floating-point * representation. */ void dump_position(void); /** * Dumps the overall processing length. Printed in seconds using a floating-point * representation. */ void dump_length(void); // -- // Chainsetups and chains // -- /** * Dumps status std::string for the currently selected chainsetup - 'connected', * 'selected' or an empty std::string. */ void dump_chainsetup_status(void); /** * Dumps the name of currently selected chain. */ void dump_selected_chain(void); // -- // Audio objects // -- /** * Dumps label of currently selected audio input. If no * input is selected, dumps an empty std::string. */ void dump_selected_audio_input(void); /** * Dumps position of currently selected audio input. * Printed in seconds, using a floating-point representation. */ void dump_audio_input_position(void); /** * Dumps length of currently selected audio input. * Printed in seconds, using a floating-point representation. */ void dump_audio_input_length(void); /** * Dumps audio input state info. Either 'open' or 'closed'. */ void dump_audio_input_open_state(void); /** * Dumps label of currently selected audio output. If no * output is selected, dumps an empty std::string. */ void dump_selected_audio_output(void); /** * Dumps position of currently selected audio outputs. * Printed in seconds, using a floating-point representation. */ void dump_audio_output_position(void); /** * Dumps length of currently selected audio output. * Printed in seconds, using a floating-point representation. */ void dump_audio_output_length(void); /** * Dumps audio output state info. Either 'open' or 'closed'. */ void dump_audio_output_open_state(void); // -- // Chain operators // -- /** * Dumps chain operator parameter value * * @param chainop operator index 1...n * @param param parameter index 1...n */ void dump_chain_operator_value(int chainop, int param); /** * Set target stream for dumping. */ void set_dump_target(std::ostream* target) { dostream_repp = target; internal_rep = false; } /** * Set target stream for dumping. */ void set_dump_target(const std::string& filename) { dostream_repp = new std::ofstream(filename.c_str()); internal_rep = true; } /** * Class constructor */ ECA_CONTROL_DUMP (ECA_CONTROL* ctrl) : ctrl_repp(ctrl), dostream_repp(&std::cout), internal_rep(false) { } /** * Virtual destructor */ ~ECA_CONTROL_DUMP (void) { if (internal_rep == true) delete dostream_repp; } private: ECA_CONTROL* ctrl_repp; std::ostream* dostream_repp; bool internal_rep; void dump(const std::string& key, const std::string& value) { *dostream_repp << key << " " << value << std::endl; } }; #endif ecasound-2.9.1/libecasound/audioio-cdr.cpp0000644000076400007640000001144211141406120015440 00000000000000// ------------------------------------------------------------------------ // audioio-cdr.cpp: CDDA/CDR audio file format input/output // Copyright (C) 1999,2001,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include /* LONG_MAX */ #include /* stat() */ #include /* stat() */ #ifdef HAVE_SYS_TYPES_H #include /* off_t */ #else typedef long int off_t; #endif #include #include "sample-specs.h" #include "audioio-cdr.h" #include "eca-logger.h" CDRFILE::CDRFILE(const std::string& name) { set_label(name); } CDRFILE::~CDRFILE(void) { if (is_open() == true) { close(); } } CDRFILE* CDRFILE::clone(void) const { CDRFILE* target = new CDRFILE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void CDRFILE::open(void) throw(AUDIO_IO::SETUP_ERROR &) { set_channels(2); set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_be); set_samples_per_second(44100); switch(io_mode()) { case io_read: { fobject = std::fopen(label().c_str(),"rb"); if (!fobject) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-CDR: Can't open " + label() + " for reading.")); set_length_in_bytes(); break; } case io_write: { fobject = std::fopen(label().c_str(),"wb"); if (!fobject) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-CDR: Can't open " + label() + " for writing.")); break; } case io_readwrite: { fobject = std::fopen(label().c_str(),"r+b"); if (!fobject) { fobject = std::fopen(label().c_str(),"w+b"); if (!fobject) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-CDR: Can't open " + label() + " for read&write.")); } set_length_in_bytes(); break; } } AUDIO_IO::open(); } void CDRFILE::close(void) { if (io_mode() != io_read) pad_to_sectorsize(); std::fclose(fobject); AUDIO_IO::close(); } bool CDRFILE::finished(void) const { if (std::ferror(fobject) || std::feof(fobject)) return true; return false; } long int CDRFILE::read_samples(void* target_buffer, long int samples) { return std::fread(target_buffer, frame_size(), samples, fobject); } void CDRFILE::write_samples(void* target_buffer, long int samples) { std::fwrite(target_buffer, frame_size(), samples, fobject); } SAMPLE_SPECS::sample_pos_t CDRFILE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { if (is_open() == true) { off_t curpos_rep = pos * frame_size(); DBC_CHECK(curpos_rep >= 0); /* fseeko doesn't seem to work with glibc 2.1.x */ #if _FILE_OFFSET_BITS==64 off_t seekpos = 0; off_t seekstep = 0; int whence = SEEK_SET; while(curpos_rep - seekpos > 0) { if (curpos_rep - seekpos > LONG_MAX) seekstep = LONG_MAX; else seekstep = curpos_rep - seekpos; // std::cerr << "(audioio-cdr) fw-seeking from " << seekpos << " to " << seekpos+seekstep << std::endl; int res = std::fseek(fobject, seekstep, whence); if (res != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "fseek() error! (lfs)."); curpos_rep = 0; std::fseek(fobject, 0, SEEK_SET); break; } if (seekpos == 0) whence = SEEK_CUR; seekpos += seekstep; } #else DBC_CHECK(sizeof(long int) == sizeof(off_t)); std::fseek(fobject, static_cast(curpos_rep), SEEK_SET); #endif } return pos; } void CDRFILE::pad_to_sectorsize(void) { int padsamps = CDRFILE::sectorsize - ((length_in_samples() * frame_size()) % CDRFILE::sectorsize); if (padsamps == CDRFILE::sectorsize) { return; } for(int n = 0; n < padsamps; n++) ::fputc(0,fobject); DBC_DECLARE(long int endpos); DBC_DECLARE(endpos = std::ftell(fobject)); DBC_CHECK((endpos % CDRFILE::sectorsize) == 0); } void CDRFILE::set_length_in_bytes(void) { struct stat temp; stat(label().c_str(), &temp); set_length_in_samples(temp.st_size / frame_size()); } ecasound-2.9.1/libecasound/midiio.cpp0000644000076400007640000000751510664032032014527 00000000000000// ------------------------------------------------------------------------ // midiio.cpp: Routines common for all MIDI IO-devices. // Copyright (C) 2000 Kai Vehmanen // // 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 #include #include "midiio.h" #include "samplebuffer.h" #include "eca-error.h" #include "eca-logger.h" // =================================================================== // Attributes /** * Returns info about supported I/O modes (bitwise-OR) * * By default, all I/O modes are supported. */ int MIDI_IO::supported_io_modes(void) const { return(io_read | io_readwrite | io_write); } /** * Whether device supports non-blocking I/O mode. * * By default, nonblocking mode is not supported. */ bool MIDI_IO::supports_nonblocking_mode(void) const { return(false); } // =================================================================== // Configuration (setting and getting configuration parameters) /** * Returns info about the current I/O mode. */ int MIDI_IO::io_mode(void) const { return(io_mode_rep); } /** * Set object input/output-mode. If the requested mode isn't * supported, the nearest supported mode is used. Because * of this, it's wise to afterwards check whether the requested * mode was accepted. * * require: * is_open() != true */ void MIDI_IO::io_mode(int mode) { io_mode_rep = mode; } /** * Sets object label. Label is used to identify the object instance. * Unlike ECA_OBJECT::name(), label() is not necessarily unique * among different class instances. Device and file names are typical * label values. * * require: * is_open() != true */ void MIDI_IO::label(const std::string& id_label) { id_label_rep = id_label; } /** * Enable/disbale nonblocking mode. * * require: * is_open() != true */ void MIDI_IO::toggle_nonblocking_mode(bool value) { nonblocking_rep = value; } /** * Returns the current label. See documentation for * label(const std::string&). */ const std::string& MIDI_IO::label(void) const { return(id_label_rep); } void MIDI_IO::set_parameter(int param, std::string value) { if (param == 1) label(value); } std::string MIDI_IO::get_parameter(int param) const { if (param == 1) return(label()); return(""); } // =================================================================== // Runtime information /** * Is nonblocking mode is enabled? */ bool MIDI_IO::nonblocking_mode(void) const { return(nonblocking_rep); } /** * Is the MIDI object ready for reading? */ bool MIDI_IO::readable(void) const { return(is_open() && io_mode() != io_write); } /** * Is the MIDI object ready for writing? */ bool MIDI_IO::writable(void) const { return(is_open() && io_mode() != io_read); } /** * Sets device's state to enabled or disabled. */ void MIDI_IO::toggle_open_state(bool value) { open_rep = value; } // =================================================================== // Constructors and destructors MIDI_IO::~MIDI_IO(void) { } MIDI_IO::MIDI_IO(const std::string& name, int mode) { label(name); io_mode(mode); nonblocking_rep = false; readable_rep = writable_rep = open_rep = false; } ecasound-2.9.1/libecasound/audiofx_compressor.cpp0000644000076400007640000003002610664032032017161 00000000000000// ------------------------------------------------------------------------ // audiofx_compressor.cpp: C++ implementation of John S. Dyson's // compressor code. If you want the original // C-sources, mail me. // Copyright (C) 1999-2000 Kai Vehmanen // // Copyright for the actual algorithm (compressor2.c): // *************************************************** /* * Copyright (c) 1996, John S. Dyson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This code (easily) runs realtime on a P5-166 w/EDO, Triton-II on FreeBSD. * * More info/comments: dyson@freebsd.org * * This program provides compression of a stereo 16bit audio stream, * such as that contained by a 16Bit wav file. Extreme measures have * been taken to make the compression as subtile as possible. One * possible purpose for this code would be to master cassette tapes from * CD's for playback in automobiles where dynamic range needs to be * restricted. * * Suitably recoded for an embedded DSP, this would make a killer audio * compressor for broadcast or recording. When writing this code, I * ignored the issues of roundoff error or trucation -- Pentiums have * really nice FP processors :-). */ // ------------------------------------------------------------------------ #include #include #include #include #include "samplebuffer_iterators.h" #include "audiofx_amplitude.h" #include "eca-logger.h" ADVANCED_COMPRESSOR::ADVANCED_COMPRESSOR (double peak_limit, double release_time, double cfrate, double crate) : rlevelsqn(ADVANCED_COMPRESSOR::NFILT), rlevelsqe(ADVANCED_COMPRESSOR::NEFILT) { init_values(); set_parameter(1, peak_limit); set_parameter(2, release_time); set_parameter(3, cfrate); set_parameter(4, crate); MESSAGE_ITEM otemp; otemp.setprecision(2); otemp << "(audiofx_compressor) Advanced compressor enabled;"; otemp << " peak limit " << peakpercent; otemp << " release time " << release_time; otemp << " cfrate " << fastgaincompressionratio; otemp << " crate " << compressionratio << "."; ECA_LOG_MSG(ECA_LOGGER::info, otemp.to_string()); } void ADVANCED_COMPRESSOR::init_values(void) { mingain = 10000; maxgain = 0; /* These filters should filter at least the lowest audio freq */ rlevelsq0filter = .001; rlevelsq1filter = .010; /* These are the attack time for the rms measurement */ rlevelsq0ffilter = .001; rlevelsqefilter = .001; /* * maximum gain for fast compressor */ maxfastgain = 3; /* * maximum gain for slow compressor */ maxslowgain = 9; /* * Level below which gain tracking shuts off */ floorlevel = SAMPLE_SPECS::max_amplitude * 0.06; // was 2000 // floorlevel = 2000; /* * Slow compressor time constants */ rmastergain0filter = .000003; rpeakgainfilter = .001; rpeaklimitdelay = 2500; rgain = rmastergain0 = 1.0; rlevelsq0 = levelsq1 = 0; rlevelsq1 = 0; compress = 1; ndelay = (int)(1.0 / rlevelsq0ffilter); // ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audiofx_compressor) Number of delays : " + // kvu_numtostr(ndelay) + "."); rightdelay.resize(ndelay); leftdelay.resize(ndelay); // rlevelsqn = new vector (NFILT + 1); // rlevelsqe = new vector (NEFILT + 1); rpeakgain0 = 1.0; rpeakgain1 = 1.0; rpeaklimitdelay = 0; ndelayptr = 0; lastrgain = 1.0; for(i = 0; i < NFILT;i++) rlevelsqn[i] = 0.0; for(i = 0; i < NEFILT;i++) rlevelsqe[i] = 0.0; /* set defaults to some sane values */ peakpercent = 100.0f; releasetime = 0; fratio = 1.0; ratio = 1.0; } ADVANCED_COMPRESSOR::~ADVANCED_COMPRESSOR (void) { } void ADVANCED_COMPRESSOR::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) { // cerr << "Param: " << param << ", value: " << value << ".\n"; switch (param) { case 1: { // --- // target level for compression // --- maxlevel = SAMPLE_SPECS::max_amplitude * 0.9; // limiter level (was 32000) // maxlevel = 32000; peakpercent = value; if (peakpercent == 0) peakpercent = 69; targetlevel = maxlevel * peakpercent / 100.0; break; } case 2: { // -- // Linear gain filters as opposed to the level measurement filters // -- DBC_CHECK(samples_per_second() != 0); releasetime = value; if (releasetime == 0) releasetime = 0.01; rgainfilter = 1.0 / (releasetime * samples_per_second()); break; } case 3: { // -- // compression ratio for fast gain. This will determine how // much the audio is made more dense. .5 is equiv to 2:1 // compression. 1.0 is equiv to inf:1 compression. // -- fratio = value; if (fratio == 0) fratio = 0.5; fastgaincompressionratio = fratio; break; } case 4: { // -- // overall ompression ratio. // -- ratio = value; if (ratio == 0) ratio = 1.0; compressionratio = ratio; break; } } } CHAIN_OPERATOR::parameter_t ADVANCED_COMPRESSOR::get_parameter(int param) const { switch (param) { case 1: return(peakpercent); case 2: return(releasetime); case 3: return(fratio); case 4: return(ratio); } return(0.0); } double ADVANCED_COMPRESSOR::hardlimit(double value, double knee, double limit) { // double lrange = (limit - knee); double ab = fabs(value); /* if (ab > knee) { double abslimit = (limit * 1.1); if (ab < abslimit) value = knee + lrange * sin( ((value - knee)/abslimit) * (3.14 / (4*1.1))); } */ if (ab >= limit) value = value > 0 ? limit : -limit; return value; } void ADVANCED_COMPRESSOR::init(SAMPLE_BUFFER* insample) { iter.init(insample); set_channels(insample->number_of_channels()); set_samples_per_second(samples_per_second()); } void ADVANCED_COMPRESSOR::process(void) { iter.begin(); while(!iter.end()) { // right = insample->get_right() * 32767.0; // left = insample->get_left() * 32767.0; left = (*iter.current(0)); right = (*iter.current(1)); rightdelay[ndelayptr] = right; leftdelay[ndelayptr] = left; ndelayptr++; // cerr << "1.l:" << left << "\n"; // cerr << "1.r:" << right << "\n"; // cerr << "2.l:" << leftdelay[ndelayptr - 1] << "should be 1=2\n"; if (ndelayptr >= ndelay) ndelayptr = 0; /* enable/disable compression */ skipmode = 0; if (compress == 0) { skipmode = 1; goto skipagc; } levelsq0 = (right) * (right) + (left) * (left); // if (ndelayptr == 0) { // cerr << "3.1.l: " << "rlevelsq0 " << rlevelsq0 << "\n"; // cerr << "3.2.l: " << "rlevelsq0ffilter " << rlevelsq0ffilter << "\n"; // cerr << "3.2.l: " << "rlevelsq0filter " << rlevelsq0filter << "\n"; // } if (levelsq0 > rlevelsq0) { rlevelsq0 = (levelsq0 * rlevelsq0ffilter) + rlevelsq0 * (1 - rlevelsq0ffilter); } else { rlevelsq0 = (levelsq0 * rlevelsq0filter) + rlevelsq0 * (1 - rlevelsq0filter); } if (rlevelsq0 <= floorlevel * floorlevel) goto skipagc; // if (ndelayptr == 0) // cerr << "3.3.l: " << "rlevelsq0 " << rlevelsq0 << "\n"; if (rlevelsq0 > rlevelsq1) { rlevelsq1 = rlevelsq0; } else { rlevelsq1 = rlevelsq0 * rlevelsq1filter + rlevelsq1 * (1 - rlevelsq1filter); } // vika.. rlevelsq1 joskus menee pahasti yli ayrauden // if (ndelayptr == 0) // cerr << "3.3.l: " << "rlevelsq1 " << rlevelsq1 << "\n"; rlevelsqn[0] = rlevelsq1; for(i = 0; i < NFILT-1; i++) { if (rlevelsqn[i] > rlevelsqn[i+1]) rlevelsqn[i+1] = rlevelsqn[i]; else rlevelsqn[i+1] = rlevelsqn[i] * rlevelsq1filter + rlevelsqn[i+1] * (1 - rlevelsq1filter); } efilt = rlevelsqefilter; levelsqe = rlevelsqe[0] = rlevelsqn[NFILT-1]; for(i = 0; i < NEFILT-1; i++) { // if (rlevelsqe[i] > FLT_MAX) rlevelsqe[i] = FLT_MAX; // else { rlevelsqe[i+1] = rlevelsqe[i] * efilt + rlevelsqe[i+1] * (1.0 - efilt); if (rlevelsqe[i+1] > levelsqe) levelsqe = rlevelsqe[i+1]; efilt *= 1.0 / 1.5; } gain = targetlevel / sqrt(levelsqe); if (compressionratio < 0.99) { if (compressionratio == 0.50) gain = sqrt(gain); else gain = exp(log(gain) * compressionratio); } if (gain < rgain) rgain = gain * rlevelsqefilter/2 + rgain * (1 - rlevelsqefilter/2); else rgain = gain * rgainfilter + rgain * (1 - rgainfilter); lastrgain = rgain; if ( gain < lastrgain) lastrgain = gain; skipagc:; tgain = lastrgain; leftd = leftdelay[ndelayptr]; rightd = rightdelay[ndelayptr]; // cerr << "4.l:" << leftd << ", ndelayptr " << ndelayptr << "\n"; fastgain = tgain; if (fastgain > maxfastgain) fastgain = maxfastgain; if (fastgain < 0.0001) fastgain = 0.0001; if (fastgaincompressionratio == 0.25) { qgain = sqrt(sqrt(fastgain)); } else if (fastgaincompressionratio == 0.5) { qgain = sqrt(fastgain); } else if (fastgaincompressionratio == 1.0) { qgain = fastgain; } else { qgain = exp(log(fastgain) * fastgaincompressionratio); } // cerr << "4.4-qgain: " << qgain << "\n"; tslowgain = tgain / qgain; if (tslowgain > maxslowgain) tslowgain = maxslowgain; if (tslowgain < rmastergain0) rmastergain0 = tslowgain; else rmastergain0 = tslowgain * rmastergain0filter + (1 - rmastergain0filter) * rmastergain0; slowgain = rmastergain0; if (skipmode == 0) npeakgain = slowgain * qgain; /**/ newright = rightd * npeakgain; if (fabs(newright) >= maxlevel) nrgain = maxlevel / fabs(newright); else nrgain = 1.0; newleft = leftd * npeakgain; if (fabs(newleft) >= maxlevel) nlgain = maxlevel / fabs(newleft); else nlgain = 1.0; // cerr << "4.5.l:" << newleft << "\n"; ngain = nrgain; if (nlgain < ngain) ngain = nlgain; ngsq = ngain * ngain; if (ngsq <= rpeakgain0) { // --debug // if (ngsq < rpeakgain0) // cerr << "*"; rpeakgain0 = ngsq /* * 0.50 + rpeakgain0 * 0.50 */; rpeaklimitdelay = peaklimitdelay; } else if (rpeaklimitdelay == 0) { if (nrgain > 1.0) tnrgain = 1.0; else tnrgain = nrgain; rpeakgain0 = tnrgain * rpeakgainfilter + (1.0 - rpeakgainfilter) * rpeakgain0; } if (rpeakgain0 <= rpeakgain1) { rpeakgain1 = rpeakgain0; rpeaklimitdelay = peaklimitdelay; } else if (rpeaklimitdelay == 0) { rpeakgain1 = rpeakgainfilter * rpeakgain0 + (1.0 - rpeakgainfilter) * rpeakgain1; } else { --rpeaklimitdelay; } sqrtrpeakgain = sqrt(rpeakgain1); totalgain = npeakgain * sqrtrpeakgain; right = newright * sqrtrpeakgain; *iter.current(1) = right; //insample->put_left(left / 32767.0); // *righta = hardlimit(right, 32200, 32767); // cerr << "5.l:" << newleft << "\n"; left = newleft * sqrtrpeakgain; *iter.current(0) = left; // insample->put_left(left / 32767.0); // cerr << "6.l:" << left << "\n"; // // *lefta = hardlimit(left, 32200, 32767); // if (right != *righta || left != *lefta) { // fprintf(stderr,"!"); // } if (totalgain > maxgain) maxgain = totalgain; if (totalgain < mingain) mingain = totalgain; if (right > extra_maxlevel) extra_maxlevel = right; if (left > extra_maxlevel) extra_maxlevel = left; iter.next(); } // cerr << "post:" << insample->get_left() << "\n"; } ecasound-2.9.1/libecasound/audioio-loop.cpp0000644000076400007640000001016611501252077015655 00000000000000// ------------------------------------------------------------------------ // audioio-loop.cpp: Audio object that routes data between reads and writes // Copyright (C) 2000-2001,2004,2007,2008,2010 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include "samplebuffer.h" #include "sample-specs.h" #include "audioio-buffered.h" #include "audioio-loop.h" #include "eca-error.h" #include "eca-logger.h" using std::string; LOOP_DEVICE::LOOP_DEVICE(string tag) : AUDIO_IO("loop", io_readwrite), tag_rep(tag), sbuf(buffersize(), 0) { writes_rep = 0; registered_inputs_rep = 0; registered_outputs_rep = 0; filled_rep = false; finished_rep = false; empty_rounds_rep = 0; } LOOP_DEVICE::~LOOP_DEVICE(void) { if (is_open() == true) { close(); } } void LOOP_DEVICE::open(void) throw(AUDIO_IO::SETUP_ERROR&) { /* FIXME: once the enum is moved to sample-specs.h, * set this to whatever is set as the default * in sample-specs.h */ set_sample_format(ECA_AUDIO_FORMAT::sfmt_f32); AUDIO_IO::open(); } LOOP_DEVICE* LOOP_DEVICE::clone(void) const { LOOP_DEVICE* target = new LOOP_DEVICE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } bool LOOP_DEVICE::finished(void) const { return finished_rep; } SAMPLE_SPECS::sample_pos_t LOOP_DEVICE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { writes_rep = 0; empty_rounds_rep = 0; filled_rep = false; finished_rep = false; return pos; } void LOOP_DEVICE::read_buffer(SAMPLE_BUFFER* buffer) { if (empty_rounds_rep == 0) { if (filled_rep == true) { buffer->copy_all_content(sbuf); /* note: read_buffer() should never be called in the middle * of the 'X * write_buffer()' sequence (where X is the number * of chain outputs connected to this loop device */ DBC_CHECK(writes_rep == 0); } else { buffer->number_of_channels(channels()); buffer->make_silent(); } } else { finished_rep = true; buffer->number_of_channels(channels()); buffer->make_silent(); } DBC_ENSURE(buffer->number_of_channels() == channels()); } void LOOP_DEVICE::write_buffer(SAMPLE_BUFFER* buffer) { ++writes_rep; /* first write of a new engine iteration (and after a read) */ if (writes_rep == 1) { change_position_in_samples(buffer->length_in_samples()); extend_position(); sbuf.number_of_channels(channels()); sbuf.make_silent(); } /* check if this is the last write for this engine iteration */ if (writes_rep == registered_outputs_rep) writes_rep = 0; /* store data from 'buffer' */ if (buffer->is_empty() != true) { empty_rounds_rep = 0; sbuf.add_with_weight(*buffer, registered_outputs_rep); filled_rep = true; } /* empty 'buffer' */ else { ++empty_rounds_rep; } DBC_CHECK(sbuf.number_of_channels() == channels()); } void LOOP_DEVICE::set_parameter(int param, string value) { switch (param) { case 1: AUDIO_IO::set_parameter(param, value); break; case 2: tag_rep = value; break; } } string LOOP_DEVICE::get_parameter(int param) const { switch (param) { case 1: return AUDIO_IO::get_parameter(param); case 2: return tag_rep; } return ""; } ecasound-2.9.1/libecasound/audioio-tone.h0000644000076400007640000000520611033002702015301 00000000000000#ifndef INCLUDED_AUDIOIO_TONE_H #define INCLUDED_AUDIOIO_TONE_H #include #include "audioio.h" #include "samplebuffer.h" #include "samplebuffer_iterators.h" #include "sample-specs.h" #include "eca-audio-time.h" /** * Sine generator * * @author Kai Vehmanen * @author Richard W.E. Furse */ class AUDIO_IO_TONE : public AUDIO_IO { public: /** @name Public functions */ /*@{*/ AUDIO_IO_TONE (const std::string& name = ""); virtual ~AUDIO_IO_TONE(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return("Tone generator"); } virtual std::string description(void) const { return("Audio input that produces sine and other basic tones for testing and other purposes."); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ /* none */ /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_IO_TONE* clone(void) const; virtual AUDIO_IO_TONE* new_expr(void) const { return new AUDIO_IO_TONE(); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual bool locked_audio_format(void) const { return false; } virtual bool supports_seeking(void) const { return true; } virtual bool finite_length_stream(void) const; virtual bool finished(void) const { return finished_rep; } virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual void set_buffersize(long int samples) { buffersize_rep = samples; } virtual long int buffersize(void) const { return buffersize_rep; } virtual std::string parameter_names(void) const { return("tone,type,frequency,duration"); } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; /*@}*/ private: SAMPLE_BUFFER buffer_rep; SAMPLE_ITERATOR_INTERLEAVED i; long int buffersize_rep; bool finished_rep; unsigned long m_lPhase; unsigned long m_lPhaseStep; SAMPLE_SPECS::sample_t m_fCachedFrequency; SAMPLE_SPECS::sample_t m_fLimitFrequency; SAMPLE_SPECS::sample_t m_fPhaseStepScalar; /** @name New functions */ /*@{*/ void setPhaseStepFromFrequency(const SAMPLE_SPECS::sample_t fFrequency, bool force); /*@}*/ AUDIO_IO_TONE& operator=(const AUDIO_IO_TONE& x) { return *this; } AUDIO_IO_TONE (const AUDIO_IO_TONE& x) { } }; #endif ecasound-2.9.1/libecasound/eca-resources.cpp0000644000076400007640000001156611173134055016022 00000000000000// ------------------------------------------------------------------------ // eca_resources.cpp: User settings (ecasoundrc) // Copyright (C) 1999-2002,2004,2005,2007 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include /* getenv */ #include "kvu_dbc.h" #include "eca-logger.h" #include "eca-resources.h" #include "eca-version.h" #include "resource-file.h" using std::string; std::string ECA_RESOURCES::rc_override_file; ECA_RESOURCES::ECA_RESOURCES(void) : resources_found_rep(true) { if (ECA_RESOURCES::rc_override_file.size() == 0) { /* case: load global and user resource files normally */ string ecasound_resource_path (ECA_PKGDATADIR); globalrc_repp = new RESOURCE_FILE(ecasound_resource_path + "/ecasoundrc"); if (globalrc_repp->keywords().size() == 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "WARNING: Global resource file \"" + ecasound_resource_path + "/ecasoundrc" + "\" not available! Ecasound may not function properly!"); resources_found_rep = false; } char* home_dir = getenv("HOME"); if (home_dir != NULL) { string user_ecasoundrc_path = string(home_dir) + "/.ecasound"; user_resource_directory_rep = user_ecasoundrc_path; userrc_repp = new RESOURCE_FILE(user_ecasoundrc_path + "/ecasoundrc"); if (userrc_repp && userrc_repp->has("user-resource-directory") == true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Old resource data found in \"" + user_ecasoundrc_path + "\". You can reset configuration parameters by removing the old rc-file."); } } else userrc_repp = 0; overriderc_repp = 0; } else { /* case: override, do not use global/user resource files */ globalrc_repp = userrc_repp = 0; overriderc_repp = new RESOURCE_FILE(ECA_RESOURCES::rc_override_file); if (overriderc_repp->keywords().size() == 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "WARNING: Override resource file \"" + ECA_RESOURCES::rc_override_file + "\" not available! Ecasound may not function properly!"); resources_found_rep = false; } } } ECA_RESOURCES::~ECA_RESOURCES(void) { if (userrc_repp && userrc_repp->is_modified() == true) { userrc_repp->resource("ecasound-version", ecasound_library_version); userrc_repp->save(); } if (globalrc_repp != 0) delete globalrc_repp; if (userrc_repp != 0) delete userrc_repp; if (overriderc_repp != 0) delete overriderc_repp; } /** * Set resource 'tag' value to 'value'. If value wasn't * previously defined, it's added. */ void ECA_RESOURCES::resource(const string& tag, const string& value) { if (userrc_repp) userrc_repp->resource(tag, value); } /** * Returns value of resource 'tag'. Priority is given * to user-specified resources over global resources. */ string ECA_RESOURCES::resource(const string& tag) const { if (tag == "user-resource-directory") return user_resource_directory_rep; if (userrc_repp && userrc_repp->has(tag)) return userrc_repp->resource(tag); if (globalrc_repp && globalrc_repp->has(tag)) return globalrc_repp->resource(tag); if (overriderc_repp && overriderc_repp->has(tag)) return overriderc_repp->resource(tag); return string(); } /** * Returns true if resource 'tag' is 'true', otherwise false */ bool ECA_RESOURCES::boolean_resource(const string& tag) const { if (userrc_repp && userrc_repp->has(tag)) return userrc_repp->boolean_resource(tag); if (globalrc_repp && globalrc_repp->has(tag)) return globalrc_repp->boolean_resource(tag); if (overriderc_repp && overriderc_repp->has(tag)) return overriderc_repp->boolean_resource(tag); return false; } /** * Whether resource 'tag' is specified in the resource file */ bool ECA_RESOURCES::has(const string& tag) const { if ((globalrc_repp && globalrc_repp->has(tag)) || (userrc_repp && userrc_repp->has(tag)) || (overriderc_repp && overriderc_repp->has(tag))) return true; return false; } /** * Are any resource values available? */ bool ECA_RESOURCES::has_any(void) const { return resources_found_rep; } ecasound-2.9.1/libecasound/midiio-raw.h0000644000076400007640000000243610664032032014760 00000000000000#ifndef INCLUDED_MIDIIO_RAW_H #define INCLUDED_MIDIIO_RAW_H #include #include "midiio.h" /** * Input and output of raw MIDI streams using standard * UNIX file operations. * * @author Kai Vehmanen */ class MIDI_IO_RAW : public MIDI_IO { public: MIDI_IO_RAW (const std::string& name = ""); virtual ~MIDI_IO_RAW(void); virtual MIDI_IO_RAW* clone(void) const { return(new MIDI_IO_RAW(*this)); } virtual MIDI_IO_RAW* new_expr(void) const { return new MIDI_IO_RAW(); } virtual std::string name(void) const { return("Raw MIDI"); } virtual int supported_io_modes(void) const { return(io_read | io_write | io_readwrite); } virtual bool supports_nonblocking_mode(void) const { return(true); } virtual int poll_descriptor(void) const { return(fd_rep); } virtual std::string parameter_names(void) const { return("label,device_name"); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; virtual void open(void); virtual void close(void); virtual long int read_bytes(void* target_buffer, long int bytes); virtual long int write_bytes(void* target_buffer, long int bytes); virtual bool finished(void) const; private: int fd_rep; bool finished_rep; std::string device_name_rep; }; #endif ecasound-2.9.1/libecasound/osc-gen.cpp0000644000076400007640000001600611747065162014620 00000000000000// ------------------------------------------------------------------------ // osc-gen.cpp: Generic oscillator // Copyright (C) 1999-2002,2008,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // This program is fre 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 #include #include #include #include "eca-object-factory.h" #include "osc-gen.h" #include "oscillator.h" #include "eca-logger.h" /* For hunting bugs in envelope code */ //#define DEBUG_ENVELOPE_POINTS #ifdef DEBUG_ENVELOPE_POINTS #define _DEBUG_ENVELOPE(x) do { x; } while(0) #include #else #define _DEBUG_ENVELOPE(x) #endif size_t GENERIC_OSCILLATOR::current_stage(double pos) { size_t start, n; // note: like 'std::fmod(pos, loop_length_rep)' but faster double loop_pos = pos - static_cast(pos / loop_length_rep) * loop_length_rep; // note: optimize for the case where position changes // linearly start = last_stage_rep; for(n = start;;) { double pos_scaled = loop_pos / loop_length_rep; double p1 = envtable_rep[n].pos; double p2 = envtable_rep[n + 1].pos; _DEBUG_ENVELOPE(std::cout << "looking for stage " + kvu_numtostr(n) + ", stages " + kvu_numtostr(envtable_rep.size()) + ", pos " + kvu_numtostr(pos) + ", looppos " + kvu_numtostr(loop_pos) + ", scaled " + kvu_numtostr(pos_scaled) + ", p1 " + kvu_numtostr(p1) + ", p2 " + kvu_numtostr(p2) << "\n"); if (pos_scaled >= p1 && pos_scaled < p2) { _DEBUG_ENVELOPE(std::cout << "found stage " + kvu_numtostr(n) << "\n"); last_pos_scaled_rep = pos_scaled; break; } n++; if (n + 1 == envtable_rep.size()) n = 0; if (n == start) { static bool once = true; if (once) { ECA_LOG_MSG(ECA_LOGGER::info, "ERROR: invalid envelop"); once = false; } break; } } _DEBUG_ENVELOPE(if (last_stage_rep != n) { \ std::cout << "stage change from " \ << kvu_numtostr(last_stage_rep) \ <<" to " << kvu_numtostr(n) << "\n"; } ); last_stage_rep = n; return n; } CONTROLLER_SOURCE::parameter_t GENERIC_OSCILLATOR::value(double pos) { size_t stage = current_stage(pos); double retval = 0.0f; /* case: hold/step */ if (mode_rep == 0) { retval = envtable_rep[stage].val; _DEBUG_ENVELOPE(std::cout << "hold value " << retval << ", stage " << stage << "\n"); } /* case: linear interpolation */ else { double p1 = envtable_rep[stage].pos; double p2 = envtable_rep[stage + 1].pos; double v1 = envtable_rep[stage].val; double v2 = envtable_rep[stage + 1].val; double mult = 1.0 - ((p2 - last_pos_scaled_rep) / (p2 - p1)); retval = v1 + (mult * (v2 - v1)); _DEBUG_ENVELOPE(std::cout << "linear value " << retval << ", stage " << stage << ", v1 " << v1 << ", v2 " << v2 << ", scaledpos " << last_pos_scaled_rep << "\n"); } return retval; } GENERIC_OSCILLATOR::GENERIC_OSCILLATOR(double freq, int mode) : OSCILLATOR(freq, 0.0) { last_stage_rep = 0; set_param_count(0); set_parameter(1, get_parameter(1)); set_parameter(2, mode); } void GENERIC_OSCILLATOR::init(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "Generic oscillator init with params: " + ECA_OBJECT_FACTORY::operator_parameters_to_eos(this)); if (envtable_rep.size() < 2) envtable_rep.resize(2); } GENERIC_OSCILLATOR::~GENERIC_OSCILLATOR (void) { } void GENERIC_OSCILLATOR::set_param_count(int params) { param_names_rep = "freq,mode,pcount,start_val,end_val"; if (params > 0) { for(int n = 0; n < params; n++) { std::string num = kvu_numtostr(n + 1); param_names_rep += ",pos"; param_names_rep += num; param_names_rep += ",val"; param_names_rep += num; } } } std::string GENERIC_OSCILLATOR::parameter_names(void) const { return param_names_rep; } void GENERIC_OSCILLATOR::prepare_envelope(void) { size_t len = 2 + (params_rep.size() + 1) / 2; envtable_rep.resize(len); envtable_rep[0].pos = 0.0; envtable_rep[0].val = first_value_rep; size_t n = 0; size_t p1_offset = 1; size_t p_end_offset = params_rep.size() / 2 + p1_offset; for(; n < params_rep.size(); n++) { envtable_rep[n / 2 + p1_offset].pos = params_rep[n]; if (++n == params_rep.size()) break; envtable_rep[n / 2 + p1_offset].val = params_rep[n]; } DBC_CHECK(p_end_offset < envtable_rep.size()); envtable_rep[p_end_offset].pos = 1.0; envtable_rep[p_end_offset].val = last_value_rep; } void GENERIC_OSCILLATOR::set_parameter(int param, CONTROLLER_SOURCE::parameter_t value) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "setting param " + kvu_numtostr(param) + " (" + get_parameter_name(param) + ")" + " => " + kvu_numtostr(value)); switch (param) { case 1: frequency(value); loop_length_rep = 1.0f / frequency(); // length of one wave in seconds break; case 2: mode_rep = static_cast(value); break; case 3: set_param_count(static_cast(value)); break; case 4: first_value_rep = value; break; case 5: last_value_rep = value; break; default: { int pointnum = param - 5; if (pointnum > 0) { if (pointnum > static_cast(params_rep.size())) params_rep.resize(pointnum); params_rep[pointnum - 1] = value; } prepare_envelope(); break; } } } CONTROLLER_SOURCE::parameter_t GENERIC_OSCILLATOR::get_parameter(int param) const { switch (param) { case 1: return frequency(); case 2: return static_cast(mode_rep); case 3: return static_cast((number_of_params() - 5) / 2); case 4: return static_cast(first_value_rep); case 5: return static_cast(last_value_rep); default: int pointnum = param - 5; if (pointnum > 0) { if (pointnum <= static_cast(params_rep.size())) { return static_cast(params_rep[pointnum - 1]); } } } return 0.0; } ecasound-2.9.1/libecasound/sample-specs.h0000644000076400007640000000413310664032032015307 00000000000000// ------------------------------------------------------------------------ // sample-specs.h: Sample value defaults and constants. // Copyright (C) 1999-2004 Kai Vehmanen // // Attributes: // eca-style-version: 2 // public-libecasound-API: yes // // 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 INCLUDED_SAMPLE_SPECS_H #define INCLUDED_SAMPLE_SPECS_H /** * Sample value defaults and constants. */ namespace SAMPLE_SPECS { /** * Type used to represent one sample value; should * be a floating point value (floating-point type) */ typedef float sample_t; /** * Type used to represent position in sample * frames (signed integer). */ #if defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE || defined __GNUG__ typedef long long int sample_pos_t; #else typedef long int sample_pos_t; #endif /** * Type used to represent sample rate values (signed integer). */ typedef long int sample_rate_t; /** * Type used to identify individual channels (signed integer). */ typedef int channel_t; static const sample_t silent_value = 0.0f; // do not change! static const sample_t max_amplitude = 1.0f; static const sample_t impl_max_value = silent_value + max_amplitude; static const sample_t impl_min_value = silent_value - max_amplitude; static const channel_t ch_left = 0; static const channel_t ch_right = 1; } #endif ecasound-2.9.1/libecasound/eca-logger.cpp0000644000076400007640000000657310664032032015265 00000000000000// ------------------------------------------------------------------------ // eca-logger.cpp: A logging subsystem implemented as a singleton class // Copyright (C) 2002 Kai Vehmanen // // 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 #include #include "eca-logger-interface.h" #include "eca-logger-default.h" #include "eca-logger.h" ECA_LOGGER_INTERFACE* ECA_LOGGER::interface_impl_repp = 0; pthread_mutex_t ECA_LOGGER::lock_rep = PTHREAD_MUTEX_INITIALIZER; static const char *level_descs[] = { "ERROR ", /* 0 */ "INFO ", "SUBSYST.", "MODULE ", "OBJECTS ", "SYSTEM ", "FUNCTION", "CONTINU.", "EIAM ", "UNKNOWN " /* 9 */ }; ECA_LOGGER_INTERFACE& ECA_LOGGER::instance(void) { // // Note! Below we use the Double-Checked Locking Pattern // to protect against concurrent access if (ECA_LOGGER::interface_impl_repp == 0) { KVU_GUARD_LOCK guard(&ECA_LOGGER::lock_rep); if (ECA_LOGGER::interface_impl_repp == 0) { ECA_LOGGER::interface_impl_repp = new ECA_LOGGER_DEFAULT(); } } return(*interface_impl_repp); } void ECA_LOGGER::attach_logger(ECA_LOGGER_INTERFACE* logger) { int oldloglevel = -1; if (interface_impl_repp != 0) { oldloglevel = interface_impl_repp->get_log_level_bitmask(); } ECA_LOGGER::detach_logger(); if (ECA_LOGGER::interface_impl_repp == 0) { KVU_GUARD_LOCK guard(&ECA_LOGGER::lock_rep); if (ECA_LOGGER::interface_impl_repp == 0) { ECA_LOGGER::interface_impl_repp = logger; if (oldloglevel != -1) { logger->set_log_level_bitmask(oldloglevel); } } } DBC_ENSURE(ECA_LOGGER::interface_impl_repp == logger); } /** * Detaches the current logger implementation. */ void ECA_LOGGER::detach_logger(void) { if (ECA_LOGGER::interface_impl_repp != 0) { KVU_GUARD_LOCK guard(&ECA_LOGGER::lock_rep); if (ECA_LOGGER::interface_impl_repp != 0) { delete ECA_LOGGER::interface_impl_repp; ECA_LOGGER::interface_impl_repp = 0; } } DBC_ENSURE(ECA_LOGGER::interface_impl_repp == 0); } const char* ECA_LOGGER::level_to_string(ECA_LOGGER::Msg_level_t arg) { switch(arg) { case ECA_LOGGER::errors: return level_descs[0]; case ECA_LOGGER::info: return level_descs[1]; case ECA_LOGGER::subsystems: return level_descs[2]; case ECA_LOGGER::module_names: return level_descs[3]; case ECA_LOGGER::user_objects: return level_descs[4]; case ECA_LOGGER::system_objects: return level_descs[5]; case ECA_LOGGER::functions: return level_descs[6]; case ECA_LOGGER::continuous: return level_descs[7]; case ECA_LOGGER::eiam_return_values: return level_descs[8]; default: return level_descs[9]; } } ecasound-2.9.1/libecasound/audioio-db-client.cpp0000644000076400007640000002353311755263413016556 00000000000000// ------------------------------------------------------------------------ // audioio-db-client.cpp: Client class for double-buffering providing // additional layer of buffering for objects // derived from AUDIO_IO. // Copyright (C) 2000-2005,2009,2011,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 /* open(), close() */ #include #include #include "samplebuffer.h" #include "eca-logger.h" #include "audioio-db-client.h" /** * Constructor. The given client object is registered to * the given db server as a client object. * * Ownership of 'aobject' is transfered to this db client * object if 'transfer_ownership' is true. */ AUDIO_IO_DB_CLIENT::AUDIO_IO_DB_CLIENT (AUDIO_IO_DB_SERVER *pserver, AUDIO_IO* aobject, bool transfer_ownership) : pserver_repp(pserver), free_child_rep(transfer_ownership) { set_child(aobject); pbuffer_repp = 0; xruns_rep = 0; finished_rep = false; recursing_rep = false; ECA_LOG_MSG(ECA_LOGGER::user_objects, std::string("DB-client created for ") + child()->label() + "."); // just in case the child object has already been configured fetch_initial_child_data(); } /** * Copy attributes from the proxied (child) object. */ void AUDIO_IO_DB_CLIENT::fetch_initial_child_data(void) { // note! the child object is one that is configured // at this point set_audio_format(child()->audio_format()); set_position_in_samples(child()->position_in_samples()); set_length_in_samples(child()->length_in_samples()); set_buffersize(child()->buffersize()); set_io_mode(child()->io_mode()); set_label(child()->label()); toggle_nonblocking_mode(child()->nonblocking_mode()); } /** * Desctructor. Unregisters the client from the db * server. */ AUDIO_IO_DB_CLIENT::~AUDIO_IO_DB_CLIENT(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "destructor " + label() + "."); if (is_open() == true) { close(); } if (pserver_repp != 0) { bool was_running = false; if (pserver_repp->is_running() == true) { was_running = true; pserver_repp->stop(); pserver_repp->wait_for_stop(); DBC_CHECK(pserver_repp->is_running() != true); } pserver_repp->unregister_client(child()); pbuffer_repp = 0; if (was_running == true) { pserver_repp->start(); } } if (free_child_rep != true) { /* to avoid deleting the original registered child */ release_child_no_delete(); } if (xruns_rep > 0) std::cerr << "(audioio-db-client) There were total " << xruns_rep << " xruns." << std::endl; } /** * Whether all data has been processed? If opened in mode 'io_read', * this means that end of stream has been reached. If opened in * 'io_write' or 'io_readwrite' modes, finished status usually * means that an error has occured (no space left, etc). After * finished() has returned 'true', further calls to read_buffer() * and/or write_buffer() won't process any data. */ bool AUDIO_IO_DB_CLIENT::finished(void) const { return finished_rep; } /** * Reads samples to buffer pointed by 'sbuf'. If necessary, the target * buffer will be resized. */ void AUDIO_IO_DB_CLIENT::read_buffer(SAMPLE_BUFFER* sbuf) { DBC_CHECK(pbuffer_repp != 0); if (pbuffer_repp->read_space() > 0) { SAMPLE_BUFFER* source = pbuffer_repp->sbufs_rep[pbuffer_repp->readptr_rep.get()]; sbuf->copy_all_content(*source); pbuffer_repp->advance_read_pointer(); pserver_repp->signal_client_activity(); change_position_in_samples(sbuf->length_in_samples()); } else { sbuf->number_of_channels(channels()); if (pbuffer_repp->finished_rep.get() == 1) { finished_rep = true; sbuf->length_in_samples(0); } else { xruns_rep++; sbuf->length_in_samples(0); std::cerr << "(audioio-db-client) WARNING: Underrun in reading from \"" << child()->label() << "\". Trying to recover." << std::endl; } } // -------- DBC_ENSURE(sbuf->number_of_channels() == channels()); // -------- } /** * Writes all data from sample buffer pointed by 'sbuf'. Notes * concerning read_buffer() also apply to this routine. */ void AUDIO_IO_DB_CLIENT::write_buffer(SAMPLE_BUFFER* sbuf) { DBC_CHECK(pbuffer_repp != 0); if (pbuffer_repp->write_space() > 0) { SAMPLE_BUFFER* target = pbuffer_repp->sbufs_rep[pbuffer_repp->writeptr_rep.get()]; target->copy_all_content(*sbuf); target->number_of_channels(channels()); pbuffer_repp->advance_write_pointer(); pserver_repp->signal_client_activity(); change_position_in_samples(sbuf->length_in_samples()); extend_position(); } else { if (pbuffer_repp->finished_rep.get() == 1) finished_rep = true; else { /* NOTE: not always rt-safe, but it's better to break rt-safety than * to lose recorded data */ std::cerr << "(audioio-db-client) WARNING: Overrun in writing to \"" << child()->label() << "\". Trying to recover." << std::endl; xruns_rep++; pserver_repp->wait_for_full(); if (recursing_rep != true && pbuffer_repp->write_space() > 0) { recursing_rep = true; this->write_buffer(sbuf); recursing_rep = false; } else { seek_position(position_in_samples()); // hack to force a restart of the db server std::cerr << "(audioio-db-client) Serious trouble with the disk-io subsystem! (output)" << std::endl; } } } } /** * Stops the DB server in case it's running. * Returns true if server was running. The return * value should be passed to restore_db_server_state() * function. */ bool AUDIO_IO_DB_CLIENT::pause_db_server_if_running(void) { bool was_running = false; if (pserver_repp->is_running() == true) { was_running = true; pserver_repp->stop(); pserver_repp->wait_for_stop(); DBC_CHECK(pserver_repp->is_running() != true); } return was_running; } void AUDIO_IO_DB_CLIENT::restore_db_server_state(bool was_running) { if (was_running == true) { pserver_repp->start(); pserver_repp->wait_for_full(); DBC_CHECK(pserver_repp->is_running() == true); } } /** * Seeks to the current position. * * Note! Seeking involves stopping the whole db * server, so it's a costly operation. */ SAMPLE_SPECS::sample_pos_t AUDIO_IO_DB_CLIENT::seek_position(SAMPLE_SPECS::sample_pos_t pos) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "seek " + label() + " to pos " + kvu_numtostr(pos) + "."); SAMPLE_SPECS::sample_pos_t res = child()->position_in_samples(); if (child()->supports_seeking() == true) { bool was_running = pause_db_server_if_running(); child()->seek_position_in_samples(pos); res = child()->position_in_samples(); if (pbuffer_repp != 0) { pbuffer_repp->reset(); } finished_rep = false; restore_db_server_state(was_running); } /* note: important that we override the AUDIO_IO_PROXY * default implementation as it does the wrong thing */ return AUDIO_IO::seek_position(res); } /** * Opens the child audio object (possibly in exclusive mode). * This routine is meant for opening files and devices, * loading libraries, etc. */ void AUDIO_IO_DB_CLIENT::open(void) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "open " + label() + "."); if (child()->is_open() != true) { child()->open(); } set_audio_format(child()->audio_format()); set_length_in_samples(child()->length_in_samples()); if (pbuffer_repp == 0) { pserver_repp->register_client(child()); pbuffer_repp = pserver_repp->get_client_buffer(child()); for(unsigned int n = 0; n < pbuffer_repp->sbufs_rep.size(); n++) { pbuffer_repp->sbufs_rep[n]->number_of_channels(channels()); pbuffer_repp->sbufs_rep[n]->length_in_samples(buffersize()); } if (io_mode() == AUDIO_IO::io_read) pbuffer_repp->io_mode_rep = AUDIO_IO::io_read; else pbuffer_repp->io_mode_rep = AUDIO_IO::io_write; } AUDIO_IO::open(); } /** * Closes the child audio object. After calling this routine, * all resources (ie. soundcard) must be freed * (they can be used by other processes). */ void AUDIO_IO_DB_CLIENT::close(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "close " + label() + "."); if (child()->is_open() == true) child()->close(); AUDIO_IO::close(); } void AUDIO_IO_DB_CLIENT::start_io(void) { AUDIO_IO_PROXY::start_io(); /* note: In case child object does not support seeking, and * position is not zero, it is undefined what the child * object position will be after start_io(). Try to * handle this case gracefully. */ if (child()->supports_seeking() != true && position_in_samples() != 0) { bool was_running = pause_db_server_if_running(); // note: this is not fully accurate, but the best // information we have available at this point set_position_in_samples(child()->position_in_samples()); /* as position might have changed, flush the buffers */ if (pbuffer_repp != 0) { pbuffer_repp->reset(); } restore_db_server_state(was_running); } } void AUDIO_IO_DB_CLIENT::stop_io(void) { AUDIO_IO_PROXY::stop_io(); } ecasound-2.9.1/libecasound/audioio-plugin.h0000644000076400007640000000045410664032032015642 00000000000000#ifndef INCLUDED_AUDIOIO_PLUGIN_H #define INCLUDED_AUDIOIO_PLUGIN_H class AUDIO_IO; typedef AUDIO_IO * (*audio_io_descriptor)(void); typedef int (*audio_io_interface_version)(void); typedef const char * (*audio_io_keyword)(void); typedef const char * (*audio_io_keyword_regex)(void); #endif ecasound-2.9.1/libecasound/eca-chainsetup-edit.h0000644000076400007640000000637211762477213016554 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup-edit.h: Chainsetup edit object // Copyright (C) 2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 INCLUDED_ECA_CHAINSETUP_EDIT_H #define INCLUDED_ECA_CHAINSETUP_EDIT_H class CHAIN; class ECA_CHAINSETUP; namespace ECA { enum Chainsetup_edit_type { edit_c_bypass = 0, edit_c_muting, edit_cop_add, edit_cop_bypass, edit_cop_set_param, edit_ctrl_add, edit_ctrl_set_param, }; /* * Chainsetup edit objects are defined for all operations * that can be performed either from the real-time engine * (if modifying chainsetup that is currently run), or * from the non-real-time control thread (modifying * selected but not running chainsetup). * * Using edit objects avoids duplicated code to describe * and parse the needed actions in both ECA_ENGINE and * ECA_CONTROL. */ struct chainsetup_edit { Chainsetup_edit_type type; const ECA_CHAINSETUP *cs_ptr; /* FIXME: should a version tag be added as way to invalidate * edit objects in case chainsetup is modified */ union { struct { int chain; /**< @see ECA_CHAINSETUP::get_chain_index() */ int val; } c_bypass; struct { int chain; /**< @see ECA_CHAINSETUP::get_chain_index() */ int val; } c_muting; struct { int chain; /**< @see ECA_CHAINSETUP::get_chain_index() */ int op; /**< @see CHAIN::set_parameter() */ int param; /**< @see CHAIN::set_parameter() */ double value; /**< @see CHAIN::set_parameter() */ } cop_set_param; struct { int chain; /**< @see ECA_CHAINSETUP::get_chain_index() */ int op; /**< @see CHAIN::bypass_operator() */ int bypass; /**< @see CHAIN::bypass_operator() */ } cop_bypass; struct { int chain; /**< @see ECA_CHAINSETUP::get_chain_index() */ } c_generic_param; struct { int chain; /**< @see ECA_CHAINSETUP::get_chain_index() */ int op; /**< @see CHAIN::set_controller_parameter() */ int param; /**< @see CHAIN::set_controller_parameter() */ double value; /**< @see CHAIN::set_controller_parameter() */ } ctrl_set_param; } m; bool need_chain_reinit; std::string param; /**< arbitrary string parameter, semantics depend on 'type' */ }; typedef struct chainsetup_edit chainsetup_edit_t; } #endif /* INCLUDED_ECA_CHAINSETUP_EDIT_H */ ecasound-2.9.1/libecasound/audioio-oss.h0000644000076400007640000000416510664032032015153 00000000000000#ifndef INCLUDED_AUDIOIO_OSS_H #define INCLUDED_AUDIOIO_OSS_H #include #include #include #include #include #include #include #include #include #ifndef AFMT_S32_LE #define AFMT_S32_LE 0x00001000 #endif #ifndef AFMT_S32_BE #define AFMT_S32_BE 0x00002000 #endif #include "audioio-device.h" /** * Class for handling Open Sound System -devices (OSS/Linux * and OSS/Lite). * @author Kai Vehmanen */ class OSSDEVICE : public AUDIO_IO_DEVICE { public: OSSDEVICE (const std::string& name = "/dev/dsp", bool precise_sample_rates = false); virtual ~OSSDEVICE(void); virtual OSSDEVICE* clone(void) const; virtual OSSDEVICE* new_expr(void) const { return new OSSDEVICE(); } virtual std::string name(void) const { return("OSS soundcard device"); } virtual std::string description(void) const { return("Open Sound System -devices (OSS/Linux and OSS/Free)."); } /** @name Function reimplemented from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return(io_read | io_write); } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); /*@}*/ /** @name Function reimplemented from AUDIO_IO_DEVICE */ /*@{*/ virtual void start(void); virtual void stop(void); virtual long int delay(void) const; virtual long int latency(void) const { return(buffersize()); } virtual long int prefill_space(void) const { if (io_mode() != io_read) return(buffersize() * fragment_count); else return(0); } /*@}*/ private: OSSDEVICE(const OSSDEVICE& x) { } OSSDEVICE& operator=(const OSSDEVICE& x) { return *this; } int audio_fd; audio_buf_info audiobuf; // soundcard.h count_info audioinfo; // soundcard.h fd_set fds; int fragment_size; int fragment_count; long int bytes_read; int oss_caps; struct timeval start_time; bool precise_srate_mode; }; #endif ecasound-2.9.1/libecasound/audiofx_envelope_modulation.cpp0000644000076400007640000001423210664032032021036 00000000000000// ------------------------------------------------------------------------ // audiofx_envelope-modulation.cpp: Effects which modify/modulate signal // envelope // Copyright (C) 2000 Rob Coker // // 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 // // ------------------------------------------------------------------------ // // History: // // 2003-08-21 Kai Vehmanen // - Fixed a timing resolution bug in the envelope modulation code. // This involved changing from float to fixed point presentation for // the position counters to avoid loss of precision (led to unexpected // drift in pulse timing). // 2000-11-01 Rob Coker // - Initial version. // // ------------------------------------------------------------------------ #include #include #include "samplebuffer_iterators.h" #include "audiofx_envelope_modulation.h" #include "eca-logger.h" #include "eca-error.h" EFFECT_ENV_MOD::~EFFECT_ENV_MOD(void) { } EFFECT_PULSE_GATE::EFFECT_PULSE_GATE (parameter_t freq_Hz, parameter_t onTime_percent) { set_parameter(1, freq_Hz); set_parameter(2, onTime_percent); freq_rep = 1.0; on_time_rep = 0; current_rep = 0; period_rep = 0; on_from_rep = 0; } EFFECT_PULSE_GATE::~EFFECT_PULSE_GATE(void) { } void EFFECT_PULSE_GATE::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { /* NOP, see audiofx.cpp:set_samples_per_second(); */ EFFECT_ENV_MOD::set_samples_per_second(v); } void EFFECT_PULSE_GATE::set_parameter(int param, parameter_t value) { switch (param) { case 1: if (value > 0) { freq_rep = value; period_rep = static_cast(1.0f / freq_rep * samples_per_second() + 0.5f); // samples } else { MESSAGE_ITEM otemp; otemp << "(audiofx_envelope_modulation) WARNING! Frequency must be greater than 0! "; ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } break; case 2: if ((value > 0) && (value < 100)) { on_time_rep = value; on_from_rep = static_cast((on_time_rep / 100.0) * period_rep + 0.5f); } else { MESSAGE_ITEM otemp; otemp << "(audiofx_envelope_modulation) WARNING! on time must be between 0 and 100 inclusive! "; ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } break; } } CHAIN_OPERATOR::parameter_t EFFECT_PULSE_GATE::get_parameter(int param) const { switch (param) { case 1: return(freq_rep); case 2: return (on_time_rep); } return(0.0); } void EFFECT_PULSE_GATE::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); set_channels(sbuf->number_of_channels()); EFFECT_ENV_MOD::init(sbuf); } void EFFECT_PULSE_GATE::process(void) { i.begin(); // iterate through all samples, one sample-frame at a // time (interleaved) while(!i.end()) { ++current_rep; if (current_rep >= period_rep) { current_rep = 0; } if (current_rep > on_from_rep) { for(int n = 0; n < channels(); n++) { *i.current(n) = 0.0; } } i.next(); } } EFFECT_PULSE_GATE_BPM::EFFECT_PULSE_GATE_BPM (parameter_t bpm, parameter_t ontime_percent) { set_parameter(1, bpm); set_parameter(2, ontime_percent); } EFFECT_PULSE_GATE_BPM::~EFFECT_PULSE_GATE_BPM(void) { } void EFFECT_PULSE_GATE_BPM::set_parameter(int param, parameter_t value) { switch (param) { case 1: pulsegate_rep.set_parameter(1, value / 60.0f); break; case 2: pulsegate_rep.set_parameter(2, value); break; } } CHAIN_OPERATOR::parameter_t EFFECT_PULSE_GATE_BPM::get_parameter(int param) const { switch (param) { case 1: return (pulsegate_rep.get_parameter(1) * 60.0f); break; case 2: return (pulsegate_rep.get_parameter(2)); break; } return(0.0); } void EFFECT_PULSE_GATE_BPM::init(SAMPLE_BUFFER* sbuf) { pulsegate_rep.init(sbuf); EFFECT_ENV_MOD::init(sbuf); } void EFFECT_PULSE_GATE_BPM::process(void) { pulsegate_rep.process(); } void EFFECT_PULSE_GATE_BPM::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v) { pulsegate_rep.set_samples_per_second(v); EFFECT_ENV_MOD::set_samples_per_second(v); } EFFECT_TREMOLO::EFFECT_TREMOLO (parameter_t freq_bpm, parameter_t depth_percent) { set_parameter(1, freq_bpm); set_parameter(2, depth_percent); currentTime = 0.0; } EFFECT_TREMOLO::~EFFECT_TREMOLO(void) { } void EFFECT_TREMOLO::set_parameter(int param, parameter_t value) { switch (param) { case 1: if (value > 0) { freq = value/(2*60); // convert from bpm to Hz } else { MESSAGE_ITEM otemp; otemp << "(audiofx_envelope_modulation) WARNING! bpm must be greater than 0! "; ECA_LOG_MSG(ECA_LOGGER::info, otemp.to_string()); } break; case 2: depth = (value/100.0); // from percent to fraction break; } } CHAIN_OPERATOR::parameter_t EFFECT_TREMOLO::get_parameter(int param) const { switch (param) { case 1: return freq*120; break; case 2: return depth*100.0; break; } return(0.0); } void EFFECT_TREMOLO::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); set_channels(sbuf->number_of_channels()); incrTime = 1.0/samples_per_second(); EFFECT_ENV_MOD::init(sbuf); } void EFFECT_TREMOLO::process(void) { i.begin(); // iterate through all samples, one sample-frame at a // time (interleaved) while(!i.end()) { currentTime += incrTime; double envelope = (1-depth)+depth*fabs(sin(2*3.1416*currentTime*freq)); if (envelope < 0) { envelope = 0; } for(int n = 0; n < channels(); n++) { *i.current(n) *= envelope; } i.next(); } } ecasound-2.9.1/libecasound/libecasound-config.in0000755000076400007640000000175511167714635016656 00000000000000#!/bin/sh usage() { echo "usage: $0 [OPTIONS]" cat << EOH options: [--prefix] [--libs] [--libs_debug] [--ldflags] [--cflags] [--version] EOH exit 1; } prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ libecasound_version=@LIBECASOUND_VERSION@ libkvutils_version=@LIBKVUTILS_VERSION@ flags="" while test $# -gt 0 do case $1 in --prefix) flags="$flags $prefix" ;; --libs) flags="$flags -L$libdir -lecasound -lkvutils @ECA_S_EXTRA_LIBS@" ;; --libs_debug) flags="$flags -L$libdir -lecasound_debug -lkvutils_debug @ECA_S_EXTRA_LIBS@" ;; --ldflags) case "$libdir" in /usr/lib);; *) flags="$flags -Wl,--rpath -Wl,$libdir" ;; esac ;; --cflags) flags="$flags -I$includedir/libecasound -I$includedir/kvutils @ECA_S_EXTRA_CPPFLAGS@" ;; --version) echo @VERSION@ ;; *) echo "$0: unknown option $1" echo usage ;; esac shift done if test -n "$flags" then echo $flags fi ecasound-2.9.1/libecasound/samplebuffer.cpp0000644000076400007640000012004311755262345015736 00000000000000// ------------------------------------------------------------------------ // samplebuffer.cpp: Class representing a buffer of audio samples. // Copyright (C) 1999-2005,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // References: // - libsamplerate: // http://www.mega-nerd.com/SRC/ // - liboil: // http://liboil.freedesktop.org/ // http://library.gnome.org/devel/liboil/ // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include /* ceil(), floor() */ #include /* memcpy */ #include /* not cstdlib we need e.g. posix_memalign() */ #include #include #include #ifdef ECA_COMPILE_SAMPLERATE #include #endif #ifdef ECA_USE_LIBOIL extern "C" { #include } #endif #include "eca-sample-conversion.h" #include "samplebuffer.h" #include "samplebuffer_impl.h" #include "eca-logger.h" /* Debug resampling operations */ // #define DEBUG_RESAMPLING #ifdef DEBUG_RESAMPLING #define DEBUG_RESAMPLING_STATEMENT(x) x #else #define DEBUG_RESAMPLING_STATEMENT(x) ((void)0) #endif #ifdef WORDS_BIGENDIAN static const bool is_system_littleendian = false; #else static const bool is_system_littleendian = true; #endif using namespace std; static void priv_alloc_sample_buf(SAMPLE_SPECS::sample_t **memptr, size_t size) { #ifdef HAVE_POSIX_MEMALIGN /* align buffers to 128bit/16octet boundary */ posix_memalign(reinterpret_cast(memptr), 16, size); #else *memptr = reinterpret_cast(malloc(size)); #endif } /** * Constructs a new sample buffer object. */ SAMPLE_BUFFER::SAMPLE_BUFFER (buf_size_t buffersize, channel_size_t channels) : channel_count_rep(channels), buffersize_rep(buffersize), reserved_samples_rep(buffersize) { // --- DBC_REQUIRE(buffersize >= 0); DBC_REQUIRE(channels >= 0); // --- /* catch if someone changes SAMPLE_SPECS::silent_value */ DBC_DECLARE(float f = 0.0f); DBC_CHECK(static_cast(f) == 0); DBC_CHECK(sizeof(f) == 4); impl_repp = new SAMPLE_BUFFER_impl; buffer.resize(channels); for(size_t n = 0; n < buffer.size(); n++) { priv_alloc_sample_buf(&buffer[n], sizeof(sample_t) * reserved_samples_rep); } make_silent(); impl_repp->rt_lock_rep = false; impl_repp->lockref_rep = 0; impl_repp->old_buffer_repp = 0; #ifdef ECA_COMPILE_SAMPLERATE impl_repp->quality_rep = 50; impl_repp->src_state_rep.resize(channels); #else impl_repp->quality_rep = 5; #endif #ifdef ECA_USE_LIBOIL oil_init(); #endif ECA_LOG_MSG(ECA_LOGGER::functions, "Buffer created, channels: " + kvu_numtostr(buffer.size()) + ", length-samples: " + kvu_numtostr(buffersize_rep) + "."); // --- DBC_ENSURE(buffer.size() == static_cast(channel_count_rep)); // --- } /** * Destructor. */ SAMPLE_BUFFER::~SAMPLE_BUFFER (void) { DBC_CHECK(impl_repp->lockref_rep == 0); for(size_t n = 0; n < buffer.size(); n++) { if (buffer[n] != 0) { ::free(buffer[n]); buffer[n] = 0; } } if (impl_repp->old_buffer_repp != 0) { ::free(impl_repp->old_buffer_repp); impl_repp->old_buffer_repp = 0; } #ifdef ECA_COMPILE_SAMPLERATE for(size_t n = 0; n < impl_repp->src_state_rep.size(); n++) { if (impl_repp->src_state_rep[n] != 0) { src_delete(impl_repp->src_state_rep[n]); impl_repp->src_state_rep[n] = 0; } } #endif delete impl_repp; } /** * Channel-wise addition. Buffer length is increased if necessary. * Only channels, that are present in both source and destination, are * modified. * * Note: event tags are not copied! * * @post length_in_samples() >= x.length_in_samples() */ void SAMPLE_BUFFER::add_matching_channels(const SAMPLE_BUFFER& x) { #ifdef ECA_USE_LIBOIL if (x.length_in_samples() > length_in_samples()) { length_in_samples(x.length_in_samples()); } int min_c_count = (channel_count_rep <= x.channel_count_rep) ? channel_count_rep : x.channel_count_rep; for(channel_size_t q = 0; q < min_c_count; q++) { oil_add_f32(reinterpret_cast(buffer[q]), reinterpret_cast(buffer[q]), reinterpret_cast(x.buffer[q]), x.length_in_samples()); } #else add_matching_channels_ref(x); #endif } /** * Unoptimized version of add_matching_channels(). */ void SAMPLE_BUFFER::add_matching_channels_ref(const SAMPLE_BUFFER& x) { if (x.length_in_samples() > length_in_samples()) { length_in_samples(x.length_in_samples()); } int min_c_count = (channel_count_rep <= x.channel_count_rep) ? channel_count_rep : x.channel_count_rep; for(channel_size_t q = 0; q < min_c_count; q++) { for(buf_size_t t = 0; t < x.length_in_samples(); t++) { buffer[q][t] += x.buffer[q][t]; } } } /** * Channel-wise, weighted addition. Before addition every sample is * multiplied by '1/weight'. Buffer length is increased if necessary. * Only channels, that are present in both source and destination, are * modified. * * Note: event tags are not copied! * * @pre weight != 0 * @post length_in_samples() >= x.length_in_samples() */ void SAMPLE_BUFFER::add_with_weight(const SAMPLE_BUFFER& x, int weight) { // --- DBC_REQUIRE(weight != 0); // --- /* note: gcc does a suprisingly good job for this function, * so additional optimizations don't seem worthwhile */ if (x.length_in_samples() > length_in_samples()) { length_in_samples(x.length_in_samples()); } int min_c_count = (channel_count_rep <= x.channel_count_rep) ? channel_count_rep : x.channel_count_rep; for(channel_size_t q = 0; q < min_c_count; q++) { for(buf_size_t t = 0; t < x.length_in_samples(); t++) { buffer[q][t] += (x.buffer[q][t] / weight); } } } /** * Channel-wise copy. Buffer length is adjusted if necessary. * * Note: event tags are not copied! * * @post length_in_samples() == x.length_in_samples() */ void SAMPLE_BUFFER::copy_matching_channels(const SAMPLE_BUFFER& x) { length_in_samples(x.length_in_samples()); int min_c_count = (channel_count_rep <= x.channel_count_rep) ? channel_count_rep : x.channel_count_rep; for(channel_size_t q = 0; q < min_c_count; q++) { std::memcpy(buffer[q], x.buffer[q], sizeof(sample_t) * length_in_samples()); /* ref implementation: * for(buf_size_t t = 0; t < length_in_samples(); t++) { * buffer[q][t] = x.buffer[q][t]; * } */ } } /** * Copy all audio contents from 'x'. After copying, length, channel * count, and event tag set match to those of 'x'. * * @post length_in_samples() == x.length_in_samples() * @post number_of_channels() == number_of_channels() * @post for all I: event_tag_test(I) == x.event_tag_test(I) */ void SAMPLE_BUFFER::copy_all_content(const SAMPLE_BUFFER& x) { length_in_samples(x.length_in_samples()); number_of_channels(x.number_of_channels()); for(channel_size_t q = 0; q < number_of_channels(); q++) { std::memcpy(buffer[q], x.buffer[q], sizeof(sample_t) * length_in_samples()); /* ref implementation: * { * for(buf_size_t t = 0; t < length_in_samples(); t++) { * buffer[q][t] = x.buffer[q][t]; * } */ } event_tags_set(x); } /** * Ranged channel-wise copy. Copies samples in range * 'start_pos' - 'end_pos-1' from buffer 'x' to current * buffer position 'to_pos'. The 'src' object must have * equal number of channels as the current object. * * Note: event tags are not copied! * * @pre start_pos <= end_pos * @pre * @pre to_pos < length_in_samples() */ void SAMPLE_BUFFER::copy_range(const SAMPLE_BUFFER& src, buf_size_t src_start_pos, buf_size_t src_end_pos, buf_size_t dst_to_pos) { // --- DBC_REQUIRE(src_start_pos <= src_end_pos); DBC_REQUIRE(dst_to_pos < length_in_samples()); DBC_REQUIRE(number_of_channels() == src.number_of_channels()); // --- if (src_end_pos > src.length_in_samples()) src_end_pos = src.length_in_samples(); for(channel_size_t q = 0; q < channel_count_rep; q++) { buf_size_t dst_i = dst_to_pos; for(buf_size_t src_i = src_start_pos; src_i < src_end_pos && dst_i < length_in_samples(); src_i++, dst_i++) { buffer[q][dst_i] = src.buffer[q][src_i]; #ifdef SAMPLEBUFFER_COPY_RANGE_VERBOSE_DEBUG if (dst_i == 0 || src_i == 0 || src_i == src_end_pos - 1 ||dst_i == length_in_samples() - 1) { std::fprintf(stderr, "dst[%d][%ld] = src[%d][%ld]\n", q, dst_i, q, src_i); } #endif } } } void SAMPLE_BUFFER::multiply_by(SAMPLE_BUFFER::sample_t factor, int channel) { #ifdef ECA_USE_LIBOIL oil_scalarmultiply_f32_ns(reinterpret_cast(buffer[channel]), reinterpret_cast(buffer[channel]), reinterpret_cast(&factor), buffersize_rep); #else multiply_by_ref(factor, channel); #endif } void SAMPLE_BUFFER::multiply_by(SAMPLE_BUFFER::sample_t factor) { for(channel_size_t n = 0; n < channel_count_rep; n++) { multiply_by(factor, n); } } void SAMPLE_BUFFER::multiply_by_ref(SAMPLE_BUFFER::sample_t factor) { for(channel_size_t n = 0; n < channel_count_rep; n++) { for(buf_size_t m = 0; m < buffersize_rep; m++) { buffer[n][m] *= factor; } } } void SAMPLE_BUFFER::multiply_by_ref(SAMPLE_BUFFER::sample_t factor, int channel) { for(buf_size_t m = 0; m < buffersize_rep; m++) { buffer[channel][m] *= factor; } } /** * Divides all samples by 'dvalue'. */ void SAMPLE_BUFFER::divide_by(SAMPLE_BUFFER::sample_t dvalue) { multiply_by(1.0 / dvalue); } void SAMPLE_BUFFER::divide_by_ref(SAMPLE_BUFFER::sample_t dvalue) { multiply_by_ref(1.0 / dvalue); } /** * Clears the buffer to zero length. Note that this is * different from a silent buffer. */ void SAMPLE_BUFFER::make_empty(void) { SAMPLE_BUFFER::length_in_samples(0); } /** * Mutes one channel of the buffer. * * @pre channel >= 0 * @pre channel < number_of_channels() */ void SAMPLE_BUFFER::make_silent(int channel) { DBC_REQUIRE(channel >= 0); DBC_REQUIRE(channel < number_of_channels()); std::memset(buffer[channel], 0, buffersize_rep * sizeof(SAMPLE_SPECS::silent_value)); /* - the generic version: */ /* for(buf_size_t s = 0; s < buffersize_rep; s++) { buffer[n][s] = SAMPLE_SPECS::silent_value; } */ } /** * Unoptimized version of make_silent(int). */ void SAMPLE_BUFFER::make_silent_ref(int channel) { for(buf_size_t s = 0; s < buffersize_rep; s++) { buffer[channel][s] = SAMPLE_SPECS::silent_value; } } /** * Mutes the whole buffer. */ void SAMPLE_BUFFER::make_silent(void) { for(channel_size_t n = 0; n < channel_count_rep; n++) { make_silent(n); } } /** * Mute a range of samples. * * @pre start_pos >= 0 * @pre end_pos >= 0 */ void SAMPLE_BUFFER::make_silent_range(buf_size_t start_pos, buf_size_t end_pos) { // -- DBC_REQUIRE(start_pos >= 0); DBC_REQUIRE(end_pos >= 0); // -- for(channel_size_t n = 0; n < channel_count_rep; n++) { std::memset(buffer[n] + start_pos, 0, sizeof(sample_t) * (end_pos < buffersize_rep ? end_pos : buffersize_rep)); } } /** * Unoptimized version of make_silent_range() */ void SAMPLE_BUFFER::make_silent_range_ref(buf_size_t start_pos, buf_size_t end_pos) { // -- DBC_REQUIRE(start_pos >= 0); DBC_REQUIRE(end_pos >= 0); // -- for(channel_size_t n = 0; n < channel_count_rep; n++) { for(buf_size_t s = start_pos; s < end_pos && s < buffersize_rep; s++) { buffer[n][s] = SAMPLE_SPECS::silent_value; } } } /** * Limits all samples to valid values. */ void SAMPLE_BUFFER::limit_values(void) { for(channel_size_t n = 0; n < channel_count_rep; n++) { for(buf_size_t m = 0; m < buffersize_rep; m++) { if (buffer[n][m] > SAMPLE_SPECS::impl_max_value) buffer[n][m] = SAMPLE_SPECS::impl_max_value; else if (buffer[n][m] < SAMPLE_SPECS::impl_min_value) buffer[n][m] = SAMPLE_SPECS::impl_min_value; } } #if 0 /* slower than the naive implementation */ { float min = SAMPLE_SPECS::impl_min_value; float max = SAMPLE_SPECS::impl_max_value; for(channel_size_t n = 0; n < channel_count_rep; n++) { oil_clip_f32(reinterpret_cast(buffer[n]), sizeof(float), reinterpret_cast(buffer[n]), sizeof(float), buffersize_rep, &min, &max); } } #endif } /** Unoptimized version of limit_values() */ void SAMPLE_BUFFER::limit_values_ref(void) { limit_values(); } /** * Resamples samplebuffer contents. Resampling * changes buffer length by 'to_rate/from_rate'. * * @post to_rate / from_rate * old_length_in_samples - length_in_samples() >= -1 */ void SAMPLE_BUFFER::resample(SAMPLE_SPECS::sample_rate_t from_rate, SAMPLE_SPECS::sample_rate_t to_rate) { #ifndef ECA_COMPILE_SAMPLERATE DBC_DECLARE(buf_size_t old_length_in_samples = length_in_samples()); #endif #ifdef ECA_COMPILE_SAMPLERATE if (impl_repp->quality_rep > 5) { resample_secret_rabbit_code(from_rate, to_rate); } else #endif { DBC_CHECK(impl_repp->quality_rep <= 5); resample_with_memory(from_rate, to_rate); } #ifndef ECA_COMPILE_SAMPLERATE /* with libsamplerate, the output sample count can vary from call to call */ DBC_CHECK((static_cast(to_rate) / from_rate * old_length_in_samples - length_in_samples()) >= -1); #endif } /** * Set resampling quality. * * Depending on build options, not all quality levels * are necessarily supported. If the requested quality level * exceeds the available resamplers, the quality setting * is set to the highest available algorithm. You can use * the get_resample_quality() function to query the current level. * * @param quality value between 0 (lowest) to 100 (highest) */ void SAMPLE_BUFFER::resample_set_quality(int quality) { #ifdef ECA_COMPILE_SAMPLERATE impl_repp->quality_rep = quality; #else if (quality > 10) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Libsamplerate is required for high-quality resampling. " "Using the internal resampler instead."); impl_repp->quality_rep = 5; } #endif } /** * Returns current resampling quality. * * @param value between 0 (lowest) to 100 (highest) */ int SAMPLE_BUFFER::resample_get_quality(void) const { return impl_repp->quality_rep; } void SAMPLE_BUFFER::export_helper(unsigned char* obuffer, buf_size_t* optr, sample_t value, ECA_AUDIO_FORMAT::Sample_format fmt) { switch (fmt) { case ECA_AUDIO_FORMAT::sfmt_u8: { obuffer[(*optr)++] = eca_sample_convert_float_to_u8(value); break; } case ECA_AUDIO_FORMAT::sfmt_s16_le: { int16_t s16temp = eca_sample_convert_float_to_s16(value); // little endian: (LSB, MSB) (Intel). obuffer[(*optr)++] = (unsigned char)(s16temp & 0xff); obuffer[(*optr)++] = (unsigned char)((s16temp >> 8) & 0xff); break; } case ECA_AUDIO_FORMAT::sfmt_s16_be: { int16_t s16temp = eca_sample_convert_float_to_s16(value); // big endian: (MSB, LSB) (Motorola). obuffer[(*optr)++] = (unsigned char)((s16temp >> 8) & 0xff); obuffer[(*optr)++] = (unsigned char)(s16temp & 0xff); break; } case ECA_AUDIO_FORMAT::sfmt_s24_le: { int32_t s32temp = eca_sample_convert_float_to_s32(value); /* skip the LSB-byte of s32temp (s32temp & 0xff) */ obuffer[(*optr)++] = (unsigned char)((s32temp >> 8) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 16) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 24) & 0xff); break; } case ECA_AUDIO_FORMAT::sfmt_s24_be: { int32_t s32temp = eca_sample_convert_float_to_s32(value); obuffer[(*optr)++] = (unsigned char)((s32temp >> 24) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 16) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 8) & 0xff); /* skip the LSB-byte of s32temp (s32temp & 0xff) */ break; } case ECA_AUDIO_FORMAT::sfmt_s32_le: { int32_t s32temp = eca_sample_convert_float_to_s32(value); obuffer[(*optr)++] = (unsigned char)(s32temp & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 8) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 16) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 24) & 0xff); break; } case ECA_AUDIO_FORMAT::sfmt_s32_be: { int32_t s32temp = eca_sample_convert_float_to_s32(value); obuffer[(*optr)++] = (unsigned char)((s32temp >> 24) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 16) & 0xff); obuffer[(*optr)++] = (unsigned char)((s32temp >> 8) & 0xff); obuffer[(*optr)++] = (unsigned char)(s32temp & 0xff); break; } case ECA_AUDIO_FORMAT::sfmt_f32_le: { union { int32_t i; float f; } f32temp; f32temp.f = (float)value; obuffer[(*optr)++] = (unsigned char)(f32temp.i & 0xff); obuffer[(*optr)++] = (unsigned char)((f32temp.i >> 8) & 0xff); obuffer[(*optr)++] = (unsigned char)((f32temp.i >> 16) & 0xff); obuffer[(*optr)++] = (unsigned char)((f32temp.i >> 24) & 0xff); break; } case ECA_AUDIO_FORMAT::sfmt_f32_be: { union { int32_t i; float f; } f32temp; f32temp.f = (float)value; obuffer[(*optr)++] = (unsigned char)((f32temp.i >> 24) & 0xff); obuffer[(*optr)++] = (unsigned char)((f32temp.i >> 16) & 0xff); obuffer[(*optr)++] = (unsigned char)((f32temp.i >> 8) & 0xff); obuffer[(*optr)++] = (unsigned char)(f32temp.i & 0xff); break; } default: { ECA_LOG_MSG(ECA_LOGGER::info, "Unknown sample format! [1]."); } } } /** * Exports contents of sample buffer to 'target'. Sample data * will be converted according to the given arguments * (sample format and endianess). If 'chcount > 1', channels * will be written interleaved. * * Note! If chcount > number_of_channels(), empty * channels will be automatically added. * * @pre target != 0 * @pre chcount > 0 * @ensure number_of_channels() >= chcount */ void SAMPLE_BUFFER::export_interleaved(unsigned char* target, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t chcount) { // -------- DBC_REQUIRE(target != 0); DBC_REQUIRE(chcount > 0); // -------- if (chcount > channel_count_rep) number_of_channels(chcount); buf_size_t osize = 0; for(buf_size_t isize = 0; isize < buffersize_rep; isize++) { for(channel_size_t c = 0; c < chcount; c++) { sample_t stemp = buffer[c][isize]; if (stemp > SAMPLE_SPECS::impl_max_value) stemp = SAMPLE_SPECS::impl_max_value; else if (stemp < SAMPLE_SPECS::impl_min_value) stemp = SAMPLE_SPECS::impl_min_value; SAMPLE_BUFFER::export_helper(target, &osize, stemp, fmt); } } // ------- DBC_ENSURE(number_of_channels() >= chcount); // ------- } /** * Same as 'export_data()', but 'target' data is * written in non-interleaved format. * * Note! If chcount > number_of_channels(), empty * channels will be automatically added. * * @pre target != 0 * @pre chcount > 0 * @ensure number_of_channels() >= chcount */ void SAMPLE_BUFFER::export_noninterleaved(unsigned char* target, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t chcount) { // -------- DBC_REQUIRE(target != 0); DBC_REQUIRE(chcount > 0); // -------- if (chcount > channel_count_rep) number_of_channels(chcount); buf_size_t osize = 0; for(channel_size_t c = 0; c < chcount; c++) { for(buf_size_t isize = 0; isize < buffersize_rep; isize++) { sample_t stemp = buffer[c][isize]; if (stemp > SAMPLE_SPECS::impl_max_value) stemp = SAMPLE_SPECS::impl_max_value; else if (stemp < SAMPLE_SPECS::impl_min_value) stemp = SAMPLE_SPECS::impl_min_value; SAMPLE_BUFFER::export_helper(target, &osize, stemp, fmt); } } // ------- DBC_ENSURE(number_of_channels() >= chcount); // ------- } void SAMPLE_BUFFER::import_helper(const unsigned char *ibuffer, buf_size_t* iptr, sample_t* obuffer, buf_size_t optr, ECA_AUDIO_FORMAT::Sample_format fmt) { unsigned char a[2]; unsigned char b[4]; switch (fmt) { case ECA_AUDIO_FORMAT::sfmt_u8: { obuffer[optr] = eca_sample_convert_u8_to_float(ibuffer[(*iptr)++]); } break; case ECA_AUDIO_FORMAT::sfmt_s16_le: { // little endian: (LSB, MSB) (Intel) // big endian: (MSB, LSB) (Motorola) if (is_system_littleendian) { a[0] = ibuffer[(*iptr)++]; a[1] = ibuffer[(*iptr)++]; } else { a[1] = ibuffer[(*iptr)++]; a[0] = ibuffer[(*iptr)++]; } int16_t tmp; memcpy(&tmp, a, sizeof(tmp)); obuffer[optr] = eca_sample_convert_s16_to_float(tmp); } break; case ECA_AUDIO_FORMAT::sfmt_s16_be: { if (!is_system_littleendian) { a[0] = ibuffer[(*iptr)++]; a[1] = ibuffer[(*iptr)++]; } else { a[1] = ibuffer[(*iptr)++]; a[0] = ibuffer[(*iptr)++]; } int16_t tmp; memcpy(&tmp, a, sizeof(tmp)); obuffer[optr] = eca_sample_convert_s16_to_float(tmp); } break; case ECA_AUDIO_FORMAT::sfmt_s24_le: { if (is_system_littleendian) { b[0] = 0; /* LSB */ b[1] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[3] = ibuffer[(*iptr)++]; } else { b[3] = 0; /* LSB */ b[2] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[0] = ibuffer[(*iptr)++]; } int32_t tmp; memcpy(&tmp, b, sizeof(tmp)); obuffer[optr] = eca_sample_convert_s32_to_float(tmp); } break; case ECA_AUDIO_FORMAT::sfmt_s24_be: { if (is_system_littleendian) { b[3] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[0] = 0; /* LSB */ } else { b[0] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[3] = 0; /* LSB */ } int32_t tmp; memcpy(&tmp, b, sizeof(tmp)); obuffer[optr] = eca_sample_convert_s32_to_float(tmp); } break; case ECA_AUDIO_FORMAT::sfmt_s32_le: { if (is_system_littleendian) { b[0] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[3] = ibuffer[(*iptr)++]; } else { b[3] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[0] = ibuffer[(*iptr)++]; } int32_t tmp; memcpy(&tmp, b, sizeof(tmp)); obuffer[optr] = eca_sample_convert_s32_to_float(tmp); } break; case ECA_AUDIO_FORMAT::sfmt_s32_be: { if (is_system_littleendian) { b[3] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[0] = ibuffer[(*iptr)++]; } else { b[0] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[3] = ibuffer[(*iptr)++]; } int32_t tmp; memcpy(&tmp, b, sizeof(tmp)); obuffer[optr] = eca_sample_convert_s32_to_float(tmp); } break; case ECA_AUDIO_FORMAT::sfmt_f32_le: { if (is_system_littleendian) { b[0] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[3] = ibuffer[(*iptr)++]; } else { b[3] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[0] = ibuffer[(*iptr)++]; } memcpy(&obuffer[optr], b, sizeof(obuffer[optr])); } break; case ECA_AUDIO_FORMAT::sfmt_f32_be: { if (is_system_littleendian) { b[3] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[0] = ibuffer[(*iptr)++]; } else { b[0] = ibuffer[(*iptr)++]; b[1] = ibuffer[(*iptr)++]; b[2] = ibuffer[(*iptr)++]; b[3] = ibuffer[(*iptr)++]; } memcpy(&obuffer[optr], b, sizeof(obuffer[optr])); } break; default: { ECA_LOG_MSG(ECA_LOGGER::info, "Unknown sample format! [4]."); } } } /** * Import audio from external raw buffer. Sample data * will be converted to internal sample format using the * given arguments (sample format and endianess). * Channels will be read interleaved. * * @pre source != 0 * @pre samples_read >= 0 */ void SAMPLE_BUFFER::import_interleaved(unsigned char* source, buf_size_t samples_read, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t chcount) { // -------- DBC_REQUIRE(source != 0); DBC_REQUIRE(samples_read >= 0); // -------- if (channel_count_rep != chcount) number_of_channels(chcount); if (buffersize_rep != samples_read) length_in_samples(samples_read); buf_size_t isize = 0; for(buf_size_t osize = 0; osize < buffersize_rep; osize++) { for(channel_size_t c = 0; c < chcount; c++) { import_helper(source, &isize, buffer[c], osize, fmt); } } } /** * Same as 'import_interleaved()', but 'source' data is * assumed to be in non-interleaved format. * * @pre source != 0 * @pre samples_read >= 0 */ void SAMPLE_BUFFER::import_noninterleaved(unsigned char* source, buf_size_t samples_read, ECA_AUDIO_FORMAT::Sample_format fmt, channel_size_t chcount) { // -------- DBC_REQUIRE(source != 0); DBC_REQUIRE(samples_read >= 0); // -------- if (channel_count_rep != chcount) number_of_channels(chcount); if (buffersize_rep != samples_read) length_in_samples(samples_read); buf_size_t isize = 0; for(channel_size_t c = 0; c < chcount; c++) { for(buf_size_t osize = 0; osize < buffersize_rep; osize++) { import_helper(source, &isize, buffer[c], osize, fmt); } } } /** * Sets the number of audio channels. */ void SAMPLE_BUFFER::number_of_channels(channel_size_t len) { // std::cerr << "(samplebuffer_impl) ch-count changes from " << channel_count_rep << " to " << len << ".\n"; if (len > static_cast(buffer.size())) { DBC_CHECK(impl_repp->rt_lock_rep != true); size_t old_size = buffer.size(); buffer.resize(len); for(channel_size_t n = old_size; n < len; n++) { priv_alloc_sample_buf(&buffer[n], sizeof(sample_t) * reserved_samples_rep); } ECA_LOG_MSG(ECA_LOGGER::functions, "Increasing channel-count (1)."); } /* note! channel_count_rep and buffer.size() necessarily * weren't the same before this call, so we need * to double check for old data */ if (len > channel_count_rep) { for(channel_size_t n = channel_count_rep; n < len; n++) { for(buf_size_t m = 0; m < reserved_samples_rep; m++) { buffer[n][m] = SAMPLE_SPECS::silent_value; } } // ECA_LOG_MSG(ECA_LOGGER::system_objects, "Increasing channel-count (2)."); } channel_count_rep = len; } /** * Sets the length of buffer in samples. * * Note: if length is increased, the added samples * are muted. */ void SAMPLE_BUFFER::length_in_samples(buf_size_t len) { DBC_REQUIRE(len >= 0); DBC_CHECK(buffersize_rep <= reserved_samples_rep); if (len > reserved_samples_rep) { DBC_CHECK(impl_repp->rt_lock_rep != true); DBC_CHECK(impl_repp->lockref_rep == 0); reserved_samples_rep = len * 2; for(size_t n = 0; n < buffer.size(); n++) { sample_t *prev_buffer = buffer[n]; priv_alloc_sample_buf(&buffer[n], sizeof(sample_t) * reserved_samples_rep); for (buf_size_t m = 0; m < buffersize_rep; m++) buffer[n][m] = prev_buffer[m]; ::free(prev_buffer); } if (impl_repp->old_buffer_repp != 0) { ::free(impl_repp->old_buffer_repp); priv_alloc_sample_buf(&impl_repp->old_buffer_repp, sizeof(sample_t) * reserved_samples_rep); } } if (len > buffersize_rep) { for(size_t n = 0; n < buffer.size(); n++) { /* note: mute starting from 'buffersize_rep' */ for(buf_size_t m = buffersize_rep; m < reserved_samples_rep; m++) { buffer[n][m] = SAMPLE_SPECS::silent_value; } } } buffersize_rep = len; } /** * Prepares sample buffer object for resampling * operations with params 'from_srate' and * 'to_srate'. This functions is meant for * doing memory allocations and other similar * operations which cannot be performed * with realtime guarantees. */ void SAMPLE_BUFFER::resample_init_memory(SAMPLE_SPECS::sample_rate_t from_srate, SAMPLE_SPECS::sample_rate_t to_srate) { #ifdef ECA_COMPILE_SAMPLERATE ECA_LOG_MSG(ECA_LOGGER::system_objects, "Resampler selected: libsamplerate (Secret Rabbit Code)."); #else ECA_LOG_MSG(ECA_LOGGER::system_objects, "Resampler selected: internal resampler."); #endif double step = 1.0; if (from_srate != 0) { step = static_cast(to_srate) / from_srate; } /* add at least one word of extra space */ buf_size_t new_buffer_size = static_cast((step * buffersize_rep)) + sizeof(buf_size_t); if (new_buffer_size > reserved_samples_rep) { reserved_samples_rep = new_buffer_size * 2; #ifdef ECA_DEBUG_MODE DBC_CHECK(impl_repp->rt_lock_rep != true); DBC_CHECK(impl_repp->lockref_rep == 0); #endif for(int c = 0; c < channel_count_rep; c++) { ::free(buffer[c]); priv_alloc_sample_buf(&buffer[c], sizeof(sample_t) * reserved_samples_rep); } } #ifdef ECA_COMPILE_SAMPLERATE impl_repp->src_state_rep.resize(channel_count_rep); for(int c = 0; c < channel_count_rep; c++) { if (impl_repp->src_state_rep[c] == 0) { int error; impl_repp->src_state_rep[c] = src_new((impl_repp->quality_rep > 75) ? SRC_SINC_BEST_QUALITY : SRC_SINC_MEDIUM_QUALITY, 1, &error); DBC_CHECK(impl_repp->src_state_rep[c] != 0); } } #endif if (impl_repp->old_buffer_repp == 0) { #ifdef ECA_DEBUG_MODE DBC_CHECK(impl_repp->rt_lock_rep != true); #endif priv_alloc_sample_buf(&impl_repp->old_buffer_repp, sizeof(sample_t) * reserved_samples_rep); } if (impl_repp->resample_memory_rep.size() < static_cast(channel_count_rep)) { #ifdef ECA_DEBUG_MODE DBC_CHECK(impl_repp->rt_lock_rep != true); #endif impl_repp->resample_memory_rep.resize(channel_count_rep, 0.0f); } } void SAMPLE_BUFFER::reserve_channels(channel_size_t num) { channel_size_t oldcount = number_of_channels(); number_of_channels(num); number_of_channels(oldcount); } void SAMPLE_BUFFER::reserve_length_in_samples(buf_size_t len) { buf_size_t oldlen = length_in_samples(); length_in_samples(len); length_in_samples(oldlen); } /** * Sets the realtime-lock state. When realtime-lock * is enabled, all non-rt-safe operations * like for instance memory allocations are * blocked. * * @param state true=lock, false=unlock */ void SAMPLE_BUFFER::set_rt_lock(bool state) { impl_repp->rt_lock_rep = state; } /** * Increases reference count of 'buffer' data * area. * * This should be issued when an object uses * direct access to the samplebuffer's * audio data buffer. * * Note! release_pointer_reflock() must be * called after caller stops accessing * 'buffer'. */ void SAMPLE_BUFFER::get_pointer_reflock(void) { impl_repp->lockref_rep++; } /** * Increases reference count of 'buffer' data * area. * * @see get_pointer_reflock() */ void SAMPLE_BUFFER::release_pointer_reflock(void) { impl_repp->lockref_rep--; DBC_ENSURE(impl_repp->lockref_rep >= 0); } /** * Adds all event tags that are set for 'sbuf' (bitwise-OR). */ void SAMPLE_BUFFER::event_tags_add(const SAMPLE_BUFFER& sbuf) { impl_repp->event_tags_rep |= sbuf.impl_repp->event_tags_rep; } /** * Sets only those event flags that are set for 'sbuf'. */ void SAMPLE_BUFFER::event_tags_set(const SAMPLE_BUFFER& sbuf) { impl_repp->event_tags_rep = sbuf.impl_repp->event_tags_rep; } /** * Clears all tags matching 'tagmask' */ void SAMPLE_BUFFER::event_tags_clear(Tag_name tagmask) { event_tag_set(tagmask, false); } /** * Set/clears the event tag 'tag'. */ void SAMPLE_BUFFER::event_tag_set(Tag_name tag, bool val) { if (val) impl_repp->event_tags_rep |= tag; else impl_repp->event_tags_rep &= ~tag; } bool SAMPLE_BUFFER::event_tag_test(Tag_name tag) { return (impl_repp->event_tags_rep & tag) ? true : false; } /** * Resamples samplebuffer contents. * * Note! 'resample_init_memory()' must be called before * before calling this function. */ void SAMPLE_BUFFER::resample_nofilter(SAMPLE_SPECS::sample_rate_t from, SAMPLE_SPECS::sample_rate_t to) { double step = static_cast(to) / from; buf_size_t old_buffer_size = buffersize_rep; // truncate, not round, to integer length_in_samples(static_cast(std::floor(step * buffersize_rep))); DEBUG_RESAMPLING_STATEMENT(std::cerr << "resample_no_f from " << from << " to " << to << "." << std::endl); DBC_CHECK(impl_repp->old_buffer_repp != 0); for(int c = 0; c < channel_count_rep; c++) { std::memcpy(impl_repp->old_buffer_repp, buffer[c], old_buffer_size * sizeof(sample_t)); DBC_CHECK(buffersize_rep <= reserved_samples_rep); double counter = 0.0; buf_size_t new_buffer_index = 0; buf_size_t interpolate_index = 0; buffer[c][0] = impl_repp->old_buffer_repp[0]; for(buf_size_t old_buffer_index = 1; old_buffer_index < old_buffer_size; old_buffer_index++) { counter += step; if (step <= 1) { if (counter >= new_buffer_index + 1) { new_buffer_index++; if (new_buffer_index >= buffersize_rep) break; buffer[c][new_buffer_index] = impl_repp->old_buffer_repp[old_buffer_index]; } } else { new_buffer_index = static_cast(std::ceil(counter)); if (new_buffer_index >= buffersize_rep) new_buffer_index = buffersize_rep - 1; for(buf_size_t t = interpolate_index + 1; t < new_buffer_index; t++) { buffer[c][t] = impl_repp->old_buffer_repp[old_buffer_index - 1] + ((impl_repp->old_buffer_repp[old_buffer_index] - impl_repp->old_buffer_repp[old_buffer_index-1]) * static_cast(t - interpolate_index) / (new_buffer_index - interpolate_index)); } buffer[c][new_buffer_index] = impl_repp->old_buffer_repp[old_buffer_index]; } interpolate_index = new_buffer_index; } } } /** * Resamples samplebuffer contents. * * Note! 'resample_init_memory()' must be called before * before calling this function. */ void SAMPLE_BUFFER::resample_with_memory(SAMPLE_SPECS::sample_rate_t from, SAMPLE_SPECS::sample_rate_t to) { double step = (double)to / from; buf_size_t old_buffer_size = buffersize_rep; // truncate, not round, to integer length_in_samples(static_cast(std::floor(step * buffersize_rep))); DBC_CHECK(impl_repp->old_buffer_repp != 0); DEBUG_RESAMPLING_STATEMENT(std::cerr << "(samplebuffer) resample_w_m from " << from << " to " << to << "." << std::endl); if (impl_repp->resample_memory_rep.size() < static_cast(channel_count_rep)) { DBC_CHECK(impl_repp->rt_lock_rep != true); impl_repp->resample_memory_rep.resize(channel_count_rep, 0.0f); } length_in_samples(buffersize_rep); for(int c = 0; c < channel_count_rep; c++) { std::memcpy(impl_repp->old_buffer_repp, buffer[c], old_buffer_size * sizeof(sample_t)); DBC_CHECK(buffersize_rep <= reserved_samples_rep); double counter = 0.0; buf_size_t new_buffer_index = 0; buf_size_t interpolate_index = -1; sample_t from_point; for(buf_size_t old_buffer_index = 0; old_buffer_index < old_buffer_size; old_buffer_index++) { counter += step; if (step <= 1) { if (counter >= new_buffer_index + 1) { new_buffer_index++; if (new_buffer_index >= buffersize_rep) break; buffer[c][new_buffer_index] = impl_repp->old_buffer_repp[old_buffer_index]; } } else { new_buffer_index = static_cast(std::ceil(counter)); if (old_buffer_index == 0) from_point = impl_repp->resample_memory_rep[c]; else from_point = impl_repp->old_buffer_repp[old_buffer_index-1]; if (new_buffer_index >= buffersize_rep) new_buffer_index = buffersize_rep - 1; for(buf_size_t t = interpolate_index + 1; t < new_buffer_index; t++) { buffer[c][t] = from_point + ((impl_repp->old_buffer_repp[old_buffer_index] - from_point) * static_cast(t - interpolate_index) / (new_buffer_index - interpolate_index)); } buffer[c][new_buffer_index] = impl_repp->old_buffer_repp[old_buffer_index]; } interpolate_index = new_buffer_index; } impl_repp->resample_memory_rep[c] = impl_repp->old_buffer_repp[old_buffer_size - 1]; } } void SAMPLE_BUFFER::resample_secret_rabbit_code(SAMPLE_SPECS::sample_rate_t from_srate, SAMPLE_SPECS::sample_rate_t to_srate) { #ifdef ECA_COMPILE_SAMPLERATE SRC_DATA params; long ch_out_count = -1; double step = static_cast(to_srate) / from_srate; buf_size_t old_buffer_size = buffersize_rep; /* modify buffersize_rep (size of dst buffer) */ length_in_samples(static_cast(std::floor(step * buffersize_rep))); DBC_CHECK(impl_repp->old_buffer_repp != 0); DEBUG_RESAMPLING_STATEMENT(std::cerr << "(samplebuffer) resample_s_r_c from " << from_srate << " to " << to_srate << "." << std::endl); for(int c = 0; c < channel_count_rep; c++) { std::memcpy(impl_repp->old_buffer_repp, buffer[c], old_buffer_size * sizeof(sample_t)); DBC_CHECK(buffersize_rep <= reserved_samples_rep); // A pointer to the input data samples. params.data_in = impl_repp->old_buffer_repp; // The number of frames of data pointed to by data_in. params.input_frames = old_buffer_size; // A pointer to the output data samples. params.data_out = buffer[c]; // Maximum number of frames pointer to by data_out. // note: was 'reserved_samples_rep' but this led // to corrupted output params.output_frames = reserved_samples_rep; /* buffersize_rep; */ // Equal to output_sample_rate / input_sample_rate. params.src_ratio = step; params.end_of_input = 0; // update the step int ret = src_set_ratio(impl_repp->src_state_rep[c], step); DBC_CHECK(ret == 0); // Perform the sample rate conversion ret = src_process(impl_repp->src_state_rep[c], ¶ms); DBC_CHECK(ret == 0); if (ret) { /* make sure we avoid segfault in all cases */ params.output_frames_gen = 0; params.input_frames_used = old_buffer_size; } DBC_CHECK(::labs(params.input_frames_used - old_buffer_size) == 0); #ifdef ECA_DEBUG_MODE /* make sure all input samples have been used */ if (old_buffer_size != params.input_frames_used) { std::cerr << "input_frames_over=" << old_buffer_size - params.input_frames_used << ".\n"; } /* check that all channels are processed in the same way */ if (c == 0) ch_out_count = params.output_frames_gen; DBC_CHECK(ch_out_count == params.output_frames_gen); #endif /* ECA_DEBUG_MODE */ } DEBUG_RESAMPLING_STATEMENT(std::cerr << "(samplebuffer) src_src input=" << old_buffer_size << ", target=" << buffersize_rep << ", processed=" << params.input_frames_used << ", space_for=" << reserved_samples_rep << ", out=" << params.output_frames_gen << std::endl); #ifdef ECA_DEBUG_MODE if ((params.output_frames_gen - buffersize_rep) > 1) { std::cerr << "(samplebuffer) src_src input=" << old_buffer_size << ", target=" << buffersize_rep << ", processed=" << params.input_frames_used << ", space_for=" << reserved_samples_rep << ", out=" << params.output_frames_gen << std::endl; } #endif if (params.output_frames_gen != buffersize_rep) { /* note: we set buffersize_rep directly and bypass * length_in_samples(), but in this case it is safe as * we have used 'reserved_samples_rep' as the upper limit */ buffersize_rep = params.output_frames_gen; } #endif /* ECA_COMPILE_SAMPLERATE */ } void SAMPLE_BUFFER::resample_extfilter(SAMPLE_SPECS::sample_rate_t from_srate, SAMPLE_SPECS::sample_rate_t to_srate) { } void SAMPLE_BUFFER::resample_simplefilter(SAMPLE_SPECS::sample_rate_t from_srate, SAMPLE_SPECS::sample_rate_t to_srate) { } ecasound-2.9.1/libecasound/audioio_test.h0000644000076400007640000000455310664032032015411 00000000000000// ------------------------------------------------------------------------ // audioio_test.h: Unit test for AUDIO_IO // Copyright (C) 2002 Kai Vehmanen // // 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 #include "audioio.h" #include "eca-object-factory.h" #include "eca-object-map.h" #include "kvu_numtostr.h" #include "eca-logger.h" #include "eca-test-case.h" using namespace std; /** * Unit test for AUDIO_IO. * * FIXME: implementation not ready */ class AUDIO_IO_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("Unit test for AUDIO_IO"); } virtual void do_run(void); public: virtual ~AUDIO_IO(void) { } }; void AUDIO_IOTEST::do_run(void) { /** * - create AUDIO_IO types from ECA_OBJECT_FACTORY * - check that type supports both read and write modes * - create a test filename * - repeat for permutations of 'audio_format' * and buffersize: * - open for write * - verify is_open ' * - write random length of data (len1, predefined content) * - close * - verify close * - if read_n_write mode supported: * - open for read_write * - verify is_open * - seek_to_end * - write random length of data (len2, predefined content) * - close * - verify close * - open for read * - verify is_open * - read clip1 from start (seek + read) * - read clip2 from random pos * - verify that clip1 and clip2 match written data * - check file length against len1+len2 * - close * - verify close * - remove file */ } ecasound-2.9.1/libecasound/midi-cc.h0000644000076400007640000000226611034532033014223 00000000000000#ifndef INCLUDE_MIDI_CC_H #define INCLUDE_MIDI_CC_H #include #include "ctrl-source.h" #include "midi-client.h" /** * Interface to MIDI continuous controllers */ class MIDI_CONTROLLER : public CONTROLLER_SOURCE, public MIDI_CLIENT { public: /** @name Functions implemented from CONTROLLER_SOURCE */ /*@{*/ virtual void init(void); virtual parameter_t value(double pos_secs); virtual void set_initial_value(parameter_t arg); /*@}*/ /** @name Functions implemented from DYNAMIC_PARAMETERS */ /*@{*/ std::string parameter_names(void) const { return("controller,channel"); } void set_parameter(int param, parameter_t value); parameter_t get_parameter(int param) const; std::string name(void) const { return("MIDI-Controller"); } /*@}*/ /** @name Functions implemented from ECA_OBJECT */ /*@{*/ MIDI_CONTROLLER* clone(void) const { return new MIDI_CONTROLLER(*this); } MIDI_CONTROLLER* new_expr(void) const { return new MIDI_CONTROLLER(); } /*@}*/ MIDI_CONTROLLER(int controller_number = 0, int midi_channel = 0); private: int controller_rep, channel_rep; parameter_t init_value_rep; bool trace_request_rep; }; #endif ecasound-2.9.1/libecasound/audiofx_amplitude.h0000644000076400007640000002131711167663416016440 00000000000000#ifndef INCLUDED_AUDIOFX_AMPLITUDE_H #define INCLUDED_AUDIOFX_AMPLITUDE_H #include #include #include "samplebuffer_iterators.h" #include "audiofx.h" /** * Virtual base for amplitude effects and dynamic processors. * @author Kai Vehmanen */ class EFFECT_AMPLITUDE : public EFFECT_BASE { public: static parameter_t db_to_linear(parameter_t value); virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual ~EFFECT_AMPLITUDE(void); protected: SAMPLE_BUFFER *cur_sbuf_repp; }; #include "audiofx_compressor.h" /** * Amplifier for adjusting signal level (linear) * @author Kai Vehmanen */ class EFFECT_AMPLIFY: public EFFECT_AMPLITUDE { parameter_t gain_rep; SAMPLE_ITERATOR i; SAMPLE_BUFFER* sbuf_repp; public: virtual std::string name(void) const { return("Amplify"); } virtual std::string parameter_names(void) const { return("amp-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); virtual void process_ref(void); EFFECT_AMPLIFY (parameter_t multiplier_percent = 100.0); virtual ~EFFECT_AMPLIFY(void); EFFECT_AMPLIFY* clone(void) const { return new EFFECT_AMPLIFY(*this); } EFFECT_AMPLIFY* new_expr(void) const { return new EFFECT_AMPLIFY(); } }; /** * Amplifier for adjusting signal level (dB) * @author Kai Vehmanen */ class EFFECT_AMPLIFY_DB: public EFFECT_AMPLITUDE { private: parameter_t gain_rep; parameter_t gain_db_rep; int channel_rep; SAMPLE_BUFFER *sbuf_repp; SAMPLE_ITERATOR_CHANNEL i_ch; SAMPLE_ITERATOR i_all; public: virtual std::string name(void) const { return("Amplify (dB)"); } virtual std::string parameter_names(void) const { return("gain-db,channel"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void release(void); virtual void process(void); virtual void process_ref(void); virtual int output_channels(int i_channels) const; EFFECT_AMPLIFY_DB(parameter_t gain = 0.0f, int channel = 0); virtual ~EFFECT_AMPLIFY_DB(void); EFFECT_AMPLIFY_DB* clone(void) const { return new EFFECT_AMPLIFY_DB(*this); } EFFECT_AMPLIFY_DB* new_expr(void) const { return new EFFECT_AMPLIFY_DB(); } }; /** * Amplifier with clip control. * @author Kai Vehmanen */ class EFFECT_AMPLIFY_CLIPCOUNT : public EFFECT_AMPLITUDE { parameter_t gain; int nm, num_of_clipped, maxnum_of_clipped; SAMPLE_ITERATOR i; public: virtual std::string name(void) const { return("Amplify with clipping control"); } virtual std::string parameter_names(void) const { return("amp-%,max-clipped-samples"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_AMPLIFY_CLIPCOUNT* new_expr(void) const { return new EFFECT_AMPLIFY_CLIPCOUNT(); } EFFECT_AMPLIFY_CLIPCOUNT* clone(void) const { return new EFFECT_AMPLIFY_CLIPCOUNT(*this); } EFFECT_AMPLIFY_CLIPCOUNT (parameter_t multiplier_percent = 100.0, int max_clipped = 0); }; /** * Channel amplifier * @author Kai Vehmanen */ class EFFECT_AMPLIFY_CHANNEL: public EFFECT_AMPLITUDE { parameter_t gain; int channel_rep; SAMPLE_ITERATOR_CHANNEL i; public: virtual std::string name(void) const { return("Channel amplify"); } virtual std::string parameter_names(void) const { return("amp-%,channel"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual int output_channels(int i_channels) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual void process_ref(void); EFFECT_AMPLIFY_CHANNEL* clone(void) const { return new EFFECT_AMPLIFY_CHANNEL(*this); } EFFECT_AMPLIFY_CHANNEL* new_expr(void) const { return new EFFECT_AMPLIFY_CHANNEL(); } EFFECT_AMPLIFY_CHANNEL (parameter_t multiplier_percent = 100.0, int channel = 1); }; /** * Limiter effect * @author Kai Vehmanen */ class EFFECT_LIMITER: public EFFECT_AMPLITUDE { parameter_t limit_rep; SAMPLE_ITERATOR i; public: virtual std::string name(void) const { return("Limiter"); } virtual std::string parameter_names(void) const { return("limit-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_LIMITER (parameter_t multiplier_percent = 100.0); virtual ~EFFECT_LIMITER(void); EFFECT_LIMITER* clone(void) const { return new EFFECT_LIMITER(*this); } EFFECT_LIMITER* new_expr(void) const { return new EFFECT_LIMITER(); } }; /** * Dynamic compressor. * @author Kai Vehmanen */ class EFFECT_COMPRESS : public EFFECT_AMPLITUDE { parameter_t crate; parameter_t threshold; SAMPLE_ITERATOR_CHANNELS i; parameter_t delta, ratio, new_value; bool first_time; std::vector lastin, lastout; public: virtual std::string name(void) const { return("Compressor"); } virtual std::string parameter_names(void) const { return("compression-rate-dB,threshold-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_COMPRESS* clone(void) const { return new EFFECT_COMPRESS(*this); } EFFECT_COMPRESS* new_expr(void) const { return new EFFECT_COMPRESS(); } EFFECT_COMPRESS (const EFFECT_COMPRESS& x); EFFECT_COMPRESS (parameter_t compress_rate = 1.0, parameter_t thold = 10.0); }; /** * Noise gate with attack and release * @author Kai Vehmanen */ class EFFECT_NOISEGATE : public EFFECT_AMPLITUDE { SAMPLE_ITERATOR_CHANNELS i; parameter_t th_level; parameter_t th_time; parameter_t atime, htime, rtime; std::vector th_time_lask; std::vector attack_lask; std::vector hold_lask; std::vector release_lask; std::vector gain; enum { ng_waiting, ng_attacking, ng_active, ng_holding, ng_releasing }; std::vector ng_status; public: virtual std::string name(void) const { return("Noisegate"); } virtual std::string description(void) const { return("Noise gate with attack and release."); } virtual std::string parameter_names(void) const { return("threshold-level-%,pre-hold-time-msec,attack-time-msec,post-hold-time-msec,release-time-msec"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); EFFECT_NOISEGATE* clone(void) const { return new EFFECT_NOISEGATE(*this); } EFFECT_NOISEGATE* new_expr(void) const { return new EFFECT_NOISEGATE(); } EFFECT_NOISEGATE (parameter_t thlevel_percent = 100.0, parameter_t thtime = 50.0, parameter_t atime = 50.0, parameter_t htime = 50.0, parameter_t rtime = 50.0); }; /** * Panning effect for controlling the stereo image. * @author Kai Vehmanen */ class EFFECT_NORMAL_PAN : public EFFECT_AMPLITUDE { private: SAMPLE_ITERATOR_CHANNEL i; parameter_t right_percent_rep; parameter_t l_gain, r_gain; public: virtual std::string name(void) const { return("Normal pan"); } virtual std::string description(void) const { return("Panning effect for controlling the stereo image."); } virtual std::string parameter_names(void) const { return("right-%"); } virtual void parameter_description(int param, struct PARAM_DESCRIPTION *pd) const; virtual int output_channels(int i_channels) const { return(2); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual void init(SAMPLE_BUFFER *insample); virtual void process(void); virtual void process_ref(void); EFFECT_NORMAL_PAN* clone(void) const { return new EFFECT_NORMAL_PAN(*this); } EFFECT_NORMAL_PAN* new_expr(void) const { return new EFFECT_NORMAL_PAN(); } EFFECT_NORMAL_PAN(parameter_t right_percent = 50.0); }; #endif ecasound-2.9.1/libecasound/eca-logger-default.h0000644000076400007640000000134311261610475016351 00000000000000#ifndef INCLUDE_ECA_LOGGER_DEFAULT_H #define INCLUDE_ECA_LOGGER_DEFAULT_H #include #include #include "eca-logger-interface.h" /** * Default logging subsystem implementation. * * Outputs traces to an ostream object (by default to * std::cerr). * * @author Kai Vehmanen */ class ECA_LOGGER_DEFAULT : public ECA_LOGGER_INTERFACE { public: virtual void do_msg(ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message); virtual void do_flush(void); virtual void do_log_level_changed(void); virtual ~ECA_LOGGER_DEFAULT(void); ECA_LOGGER_DEFAULT(std::ostream& output = std::cerr); private: std::ostream& output_rep; }; #endif /* INCLUDE_ECA_LOGGER_DEFAULT_H */ ecasound-2.9.1/libecasound/audioio-raw.cpp0000644000076400007640000001135011033002244015456 00000000000000// ------------------------------------------------------------------------ // audioio-raw.cpp: Raw/headerless audio file format input/output // Copyright (C) 1999-2001 Kai Vehmanen // // 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 #include #include #include #include #include #include #include "audioio-buffered.h" #include "audioio-raw.h" #include "eca-error.h" #include "eca-logger.h" RAWFILE::RAWFILE(const std::string& name) { set_label(name); fio_repp = 0; mmaptoggle_rep = "0"; } RAWFILE::~RAWFILE(void) { if (is_open() == true) { close(); } } RAWFILE* RAWFILE::clone(void) const { RAWFILE* target = new RAWFILE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return(target); } /** * Opens the raw audio i/o device. * * Note! Cases where label() matches either "stdin", "stdout" * or "stderr" are handled as special cases. */ void RAWFILE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { switch(io_mode()) { case io_read: { if (label() == "stdin" || label().at(0) == '-') { fio_repp = new ECA_FILE_IO_STREAM(); fio_repp->open_stdin(); } else { if (mmaptoggle_rep == "1") { ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-wave) using mmap() mode for file access"); fio_repp = new ECA_FILE_IO_MMAP(); } else fio_repp = new ECA_FILE_IO_STREAM(); fio_repp->open_file(label(),"rb"); if (fio_repp->is_file_ready() != true) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-RAW: Couldn't open file " + label() + " for reading.")); } } break; } case io_write: { fio_repp = new ECA_FILE_IO_STREAM(); if (label() == "stdout" || label().at(0) == '-') { std::cerr << "(audioio-raw) Outputting to standard output [w].\n"; fio_repp->open_stdout(); } else if (label() == "stderr" || label().at(0) == '-') { fio_repp->open_stderr(); } else { fio_repp->open_file(label(),"wb"); if (fio_repp->is_file_ready() != true) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-RAW: Couldn't open file " + label() + " for writing.")); } } break; } case io_readwrite: { fio_repp = new ECA_FILE_IO_STREAM(); if (label() == "stdout" || label().at(0) == '-') { std::cerr << "(audioio-raw) Outputting to standard output [rw].\n"; fio_repp->open_stdout(); } else { fio_repp->open_file(label(),"r+b"); if (fio_repp->file_mode() == "") { fio_repp->open_file(label(),"w+b"); if (fio_repp->is_file_ready() != true) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-RAW: Couldn't open file " + label() + " for read&write.")); } } } } } set_length_in_bytes(); AUDIO_IO::open(); } void RAWFILE::close(void) { if (fio_repp != 0) { fio_repp->close_file(); delete fio_repp; fio_repp = 0; } AUDIO_IO::close(); } bool RAWFILE::finished(void) const { if (fio_repp->is_file_error() || !fio_repp->is_file_ready()) return true; return false; } long int RAWFILE::read_samples(void* target_buffer, long int samples) { fio_repp->read_to_buffer(target_buffer, frame_size() * samples); return(fio_repp->file_bytes_processed() / frame_size()); } void RAWFILE::write_samples(void* target_buffer, long int samples) { fio_repp->write_from_buffer(target_buffer, frame_size() * samples); } SAMPLE_SPECS::sample_pos_t RAWFILE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { if (is_open() == true) { fio_repp->set_file_position(pos * frame_size()); } return pos; } void RAWFILE::set_length_in_bytes(void) { set_length_in_samples(fio_repp->get_file_length() / frame_size()); } void RAWFILE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: mmaptoggle_rep = value; break; } } string RAWFILE::get_parameter(int param) const { switch (param) { case 1: return(label()); case 2: return(mmaptoggle_rep); } return(""); } ecasound-2.9.1/libecasound/eca-sample-conversion.h0000644000076400007640000000534611501140617017114 00000000000000// ------------------------------------------------------------------------ // eca-sample-conversion.h: Routines for convering between sample formats. // Copyright (C) 2002,2003 Kai Vehmanen // // 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 INCLUDED_ECA_SAMPLE_CONVERSION_H #define INCLUDED_ECA_SAMPLE_CONVERSION_H #include /** * Type definitions */ #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef UINT8_MIN #define UINT8_MIN (0) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif /** * Function definitions */ static inline uint8_t eca_sample_convert_float_to_u8(float inval) { const float pos_limit = ((float)0x7f) / 0x80; if (inval >= pos_limit) return UINT8_MAX; return (uint8_t)(inval * 0x80 + 0x80); } static inline int16_t eca_sample_convert_float_to_s16(float inval) { const float pos_limit = ((float)0x7fff) / 0x8000; if (inval >= pos_limit) return INT16_MAX; return (int16_t)(inval * 0x8000); } static inline int32_t eca_sample_convert_float_to_s32(float inval) { /* 32bit float precision is limited to 24bit */ const float pos_limit_24b = ((float)0x7fffff) / 0x800000; if (inval >= pos_limit_24b) return INT32_MAX; return (int32_t)(inval * 0x80000000); } static inline float eca_sample_convert_u8_to_float(uint8_t inval) { #if 0 /* NOTE: this is sub-optimal, but at least gcc-2.91.66 otherwise * compiles the test incorrectly) */ int16_t inval_b = inval; if (inval_b <= INT8_MAX) return(((((float)inval) - INT8_MAX) / INT8_MAX)); #endif return ((float)(inval - 0x80)) / 0x80; } static inline float eca_sample_convert_s16_to_float(int16_t inval) { return ((float)inval) / 0x8000; } static inline float eca_sample_convert_s32_to_float(int32_t inval) { return ((float)inval) / 0x80000000; } #endif ecasound-2.9.1/libecasound/midi-server.h0000644000076400007640000000544510664032032015150 00000000000000#ifndef INCLUDED_MIDI_SERVER_H #define INCLUDED_MIDI_SERVER_H #include #include #include #include #include #include #include #include "midiio.h" /** * Interface class for specifying custom MIDI-handlers. */ class MIDI_HANDLER { public: virtual void insert(unsigned char byte) = 0; virtual ~MIDI_HANDLER(void) {} }; /** * MIDI i/o engine. * * @author Kai Vehmanen */ class MIDI_SERVER { friend void* start_midi_server_io_thread(void *ptr); public: static const unsigned int max_queue_size_rep; public: bool is_running(void) const; bool is_enabled(void) const; void enable(void); void disable(void); void init(void); void start(void); void stop(void); void set_schedrealtime(bool v) { schedrealtime_rep = v; } void set_schedpriority(int v) { schedpriority_rep = v; } void register_client(MIDI_IO* mobject); void unregister_client(MIDI_IO* mobject); void register_handler(MIDI_HANDLER* handler); void unregister_handler(MIDI_HANDLER* handler); void add_mmc_send_id(int id); void remove_mmc_send_id(int id); void set_mmc_receive_id(int id) { mmc_receive_id_rep = id; } int mmc_receive_id(int id) const { return(mmc_receive_id_rep); } void toggle_midi_sync_send(bool v) { midi_sync_send_rep = v; } void toggle_midi_sync_receive(bool v) { midi_sync_receive_rep = v; } bool is_midi_sync_send_enabled(void) const { return(midi_sync_send_rep); } bool is_midi_sync_receive_enabled(void) const { return(midi_sync_receive_rep); } void send_midi_bytes(int dev_id, unsigned char* buf, int bytes); void add_controller_trace(int channel, int ctrl, int initial_value = 0); void remove_controller_trace(int channel, int ctrl); int last_controller_value(int channel, int ctrl) const; MIDI_SERVER (void); ~MIDI_SERVER(void); private: std::deque buffer_rep; mutable std::map,int> controller_values_rep; unsigned char running_status_rep; int current_ctrl_channel_rep; int current_ctrl_number; std::list mmc_send_ids_rep; int mmc_receive_id_rep; std::vector clients_rep; bool midi_sync_send_rep; bool midi_sync_receive_rep; std::vector handlers_rep; pthread_t io_thread_rep; bool thread_running_rep; bool schedrealtime_rep; int schedpriority_rep; ATOMIC_INTEGER exit_request_rep; ATOMIC_INTEGER stop_request_rep; ATOMIC_INTEGER running_rep; MIDI_SERVER& operator=(const MIDI_SERVER& x) { return *this; } MIDI_SERVER (const MIDI_SERVER& x) { } void io_thread(void); void parse_receive_queue(void); void send_mmc_command(unsigned int cmd); void send_mmc_start(void); void send_mmc_stop(void); void send_midi_start(void); void send_midi_continue(void); void send_midi_stop(void); }; #endif ecasound-2.9.1/libecasound/samplebuffer_iterators.h0000644000076400007640000001032611161425434017470 00000000000000#ifndef INCLUDED_SAMPLEBUFFER_ITERATORS_H #define INCLUDED_SAMPLEBUFFER_ITERATORS_H #include "samplebuffer.h" /** * Iterate through all samples. No specific order. * * Related design patterns: * - Iterator (GoF257) */ class SAMPLE_ITERATOR { private: SAMPLE_BUFFER* target; SAMPLE_BUFFER::buf_size_t index; // index of the current sample SAMPLE_BUFFER::channel_size_t channel_index; // index of current channel public: /** * Prepare iterator for processing. */ void init(SAMPLE_BUFFER* buf) { target = buf; } /** * Start iteration from the first audio item; */ void begin(void); /** * True if iterator is past the last audio item. */ inline bool end(void) { return(channel_index >= static_cast(target->channel_count_rep)); } /** * Move iterator to the next audio item. */ void next(void); /** * Returns a pointer to the current sample. */ inline SAMPLE_SPECS::sample_t* current(void) { return(&(target->buffer[channel_index][index])); } }; /** * Iterate through all samples of one channel. * * Notice! This iterator can be used to add extra * channels to the sample data. * * Related design patterns: * - Iterator (GoF257) */ class SAMPLE_ITERATOR_CHANNEL { private: SAMPLE_BUFFER* target; SAMPLE_BUFFER::buf_size_t index; // index of the current sample SAMPLE_BUFFER::channel_size_t channel_index; // index of current channel public: /** * Prepare iterator for processing. */ void init(SAMPLE_BUFFER* buf, int channel = 0); /** * Start iteration from the first sample of 'channel'. More channels * are allocated, if sample buffer has fewer channels than asked for. * * @param channel number of iterated channel (0, 1, ... , n) */ void begin(int channel); /** * Start iteration from the first audio item (using the previously * set channel). */ void begin(void) { index = 0; } /** * Move iterator to the next audio item. */ void next(void) { ++index; } /** * True if iterator is past the last audio item. */ inline bool end(void) { return(static_cast(index) >= target->buffersize_rep); } /** * Returns a pointer to the current sample. */ inline SAMPLE_SPECS::sample_t* current(void) { return(&target->buffer[channel_index][index]); } }; /** * Iterate through all samples, one channel at a time. * * Related design patterns: * - Iterator (GoF257) */ class SAMPLE_ITERATOR_CHANNELS { private: SAMPLE_BUFFER* target; SAMPLE_BUFFER::buf_size_t index; // index of the current sample SAMPLE_BUFFER::channel_size_t channel_index; // index of current channel public: /** * Prepare iterator for processing. */ void init(SAMPLE_BUFFER* buf) { target = buf; } /** * Start iteration from the first audio item; */ void begin(void); /** * Move iterator to the next audio item. */ void next(void); /** * True if iterator is past the last audio item. */ inline bool end(void) { return(channel_index >= static_cast(target->channel_count_rep)); } /** * Returns a pointer to the current sample. */ inline SAMPLE_SPECS::sample_t* current(void) { return(&(target->buffer[channel_index][index])); } /** * Returns current channel index (starting from 0) */ inline int channel(void) const { return(channel_index); } }; /** * Iterate through all samples, one sample frame (interleaved) at a time. * * Related design patterns: * - Iterator (GoF257) */ class SAMPLE_ITERATOR_INTERLEAVED { private: SAMPLE_BUFFER* target; SAMPLE_BUFFER::buf_size_t index; // index of the current sample public: /** * Prepare iterator for processing. */ void init(SAMPLE_BUFFER* buf) { target = buf; } /** * Start iteration from the first audio item; */ void begin(void) { index = 0; } /** * Move iterator to the next audio item. */ inline void next(void) { ++index; } /** * True if iterator is past the last audio item. */ inline bool end(void) { return(static_cast(index) >= target->buffersize_rep); } /** * Returns a pointer to the current sample. */ inline SAMPLE_SPECS::sample_t* current(int channel) { return(&target->buffer[channel][index]); } }; #endif ecasound-2.9.1/libecasound/eca-audio-time.h0000644000076400007640000000257211034134155015504 00000000000000#ifndef INCLUDED_ECA_AUDIO_TIME_H #define INCLUDED_ECA_AUDIO_TIME_H #include #include "sample-specs.h" /** * Generic class for representing time in audio environment */ class ECA_AUDIO_TIME { private: SAMPLE_SPECS::sample_pos_t samples_rep; mutable SAMPLE_SPECS::sample_rate_t sample_rate_rep; mutable bool rate_set_rep; static const SAMPLE_SPECS::sample_rate_t default_srate = 384000; static const SAMPLE_SPECS::sample_rate_t invalid_srate = -1; public: enum format_type { format_hour_min_sec, format_min_sec, format_seconds, format_samples }; ECA_AUDIO_TIME(SAMPLE_SPECS::sample_pos_t samples, SAMPLE_SPECS::sample_rate_t sample_rate); ECA_AUDIO_TIME(double time_in_seconds); ECA_AUDIO_TIME(format_type type, const std::string& time); ECA_AUDIO_TIME(const std::string& time); ECA_AUDIO_TIME(void); void set(format_type type, const std::string& time); void set_seconds(double seconds); void set_time_string(const std::string& time); void set_samples(SAMPLE_SPECS::sample_pos_t samples); void set_samples_per_second(long int srate); void set_samples_per_second_keeptime(long int srate); void mark_as_invalid(void); std::string to_string(format_type type) const; double seconds(void) const; SAMPLE_SPECS::sample_rate_t samples_per_second(void) const; SAMPLE_SPECS::sample_pos_t samples(void) const; bool valid(void) const; }; #endif ecasound-2.9.1/libecasound/eca-control-base.cpp0000644000076400007640000004224711762412271016403 00000000000000// ------------------------------------------------------------------------ // eca-control-base.cpp: Base class providing basic functionality // for controlling the ecasound library // Copyright (C) 1999-2004,2006,2008,2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include #include #include #include #include #include #include #include #include #include "eca-engine.h" #include "eca-session.h" #include "eca-chainsetup.h" #include "eca-resources.h" #include "eca-control.h" #include "eca-error.h" #include "eca-logger.h" /** * Import namespaces */ using std::list; using std::string; using std::vector; /** * Definitions for member functions */ /** * Helper function for starting the slave thread. */ void* ECA_CONTROL::start_normal_thread(void *ptr) { ECA_CONTROL* ctrl_base = static_cast(ptr); ctrl_base->engine_pid_rep = getpid(); DBC_CHECK(ctrl_base->engine_pid_rep >= 0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Engine thread started with pid: " + kvu_numtostr(ctrl_base->engine_pid_rep)); ctrl_base->run_engine(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Engine thread " + kvu_numtostr(ctrl_base->engine_pid_rep) + " will exit.\n"); ctrl_base->engine_pid_rep = -1; return 0; } /** * Initializes the engine * * @pre is_connected() == true * @pre is_engine_created() != true */ void ECA_CONTROL::engine_start(void) { // -------- DBC_REQUIRE(is_connected() == true); DBC_REQUIRE(is_engine_created() != true); // -------- start_engine_sub(false); } /** * Start the processing engine * * @pre is_connected() == true * @pre is_running() != true * @post is_engine_created() == true * * @return negative on error, zero on success */ int ECA_CONTROL::start(void) { // -------- DBC_REQUIRE(is_connected() == true); DBC_REQUIRE(is_running() != true); // -------- int result = 0; ECA_LOG_MSG(ECA_LOGGER::subsystems, "Controller/Processing started"); if (is_engine_created() != true) { /* request_batchmode=false */ start_engine_sub(false); } if (is_engine_created() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "Can't start processing: couldn't start engine."); result = -1; } else { engine_repp->command(ECA_ENGINE::ep_start, 0.0); } // -------- DBC_ENSURE(result != 0 || is_engine_created() == true); // -------- return result; } /** * Starts the processing engine and blocks until * processing is finished. * * @param batchmode if true, runs until finished/stopped state is reached, and * then returns; if false, will run infinitely * * @pre is_connected() == true * @pre is_running() != true * @post is_finished() == true || * processing_started == true && is_running() != true || * processing_started != true && * (is_engine_created() != true || * is_engine_created() == true && * engine_repp->status() != ECA_ENGINE::engine_status_stopped)) * * @return negative on error, zero on success */ int ECA_CONTROL::run(bool batchmode) { // -------- DBC_REQUIRE(is_connected() == true); DBC_REQUIRE(is_running() != true); // -------- ECA_LOG_MSG(ECA_LOGGER::subsystems, "Controller/Starting batch processing"); bool processing_started = false; int result = -1; if (is_engine_created() != true) { /* request_batchmode=true */ start_engine_sub(batchmode); } if (is_engine_created() != true) { ECA_LOG_MSG(ECA_LOGGER::info, "Can't start processing: couldn't start the engine. (2)"); } else { engine_repp->command(ECA_ENGINE::ep_start, 0.0); DBC_CHECK(is_finished() != true); result = 0; /* run until processing is finished; in batchmode run forever (or * until error occurs) */ while(is_finished() != true || batchmode != true) { /* sleep for 250ms */ kvu_sleep(0, 250000000); if (processing_started != true) { if (is_running() == true || is_finished() == true || engine_exited_rep.get() == 1) { /* make a note that engine state changed to 'running' */ processing_started = true; } else if (is_engine_created() == true) { if (engine_repp->status() == ECA_ENGINE::engine_status_error) { /* not running, so status() is either 'not_ready' or 'error' */ ECA_LOG_MSG(ECA_LOGGER::info, "Can't start processing: engine startup failed. (3)"); result = -2; break; } /* other valid state alternatives: */ DBC_CHECK(engine_repp->status() == ECA_ENGINE::engine_status_stopped || engine_repp->status() == ECA_ENGINE::engine_status_notready); } else { /* ECA_CONTROL_BASE destructor has been run and * engine_repp is now 0 (--> is_engine_created() != true) */ break; } } else { /* engine was started successfully (processing_started == true) */ if (is_running() != true) { /* operation successfully completed, exit from run() unless * infinite operation is requested (batchmode) */ if (batchmode == true) break; } } } } if (last_exec_res_rep < 0) { /* error occured during processing */ result = -3; } ECA_LOG_MSG(ECA_LOGGER::subsystems, std::string("Controller/Batch processing finished (") + kvu_numtostr(result) + ")"); // -------- DBC_ENSURE(is_finished() == true || (processing_started == true && is_running()) != true || (processing_started != true && (is_engine_created() != true || (is_engine_created() == true && engine_repp->status() != ECA_ENGINE::engine_status_stopped)))); // -------- return result; } /** * Stops the processing engine. * * @see stop_on_condition() * * @pre is_engine_created() == true * @post is_running() == false */ void ECA_CONTROL::stop(void) { // -------- DBC_REQUIRE(is_engine_created() == true); // -------- ECA_LOG_MSG(ECA_LOGGER::subsystems, "Controller/Processing stopped"); engine_repp->command(ECA_ENGINE::ep_stop, 0.0); // -------- // ensure: // assert(is_running() == false); // -- there's a small timeout so assertion cannot be checked // -------- } /** * Stop the processing engine using thread-to-thread condition * signaling. * * @pre is_engine_created() == true * @post is_running() == false */ void ECA_CONTROL::stop_on_condition(void) { // -------- DBC_REQUIRE(is_engine_created() == true); // -------- ECA_LOG_MSG(ECA_LOGGER::subsystems, "Controller/Processing stopped (cond)"); engine_repp->command(ECA_ENGINE::ep_stop, 0.0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Received stop-cond"); // -- // blocks until engine has stopped (or 5 sec has passed); engine_repp->wait_for_stop(5); // -------- DBC_ENSURE(is_running() == false); // -------- } /** * Stops the processing engine. * Call will block until engine has terminated. */ void ECA_CONTROL::quit(void) { close_engine(); } /** * Stops the processing engine. A thread-safe variant of * quit(). Call will not block. * */ void ECA_CONTROL::quit_async(void) { if (is_engine_ready_for_commands() != true) return; engine_repp->command(ECA_ENGINE::ep_exit, 0.0); } /** * Starts the processing engine. * * @pre is_connected() == true * @pre is_engine_ready_for_commands() != true */ void ECA_CONTROL::start_engine_sub(bool batchmode) { // -------- DBC_REQUIRE(is_connected() == true); DBC_REQUIRE(is_engine_ready_for_commands() != true); // -------- DBC_CHECK(engine_exited_rep.get() != 1); unsigned int p = session_repp->connected_chainsetup_repp->first_selected_chain(); if (p < session_repp->connected_chainsetup_repp->chains.size()) session_repp->connected_chainsetup_repp->selected_chain_index_rep = p; if (engine_repp) close_engine(); DBC_CHECK(is_engine_created() != true); engine_repp = new ECA_ENGINE (session_repp->connected_chainsetup_repp); DBC_CHECK(is_engine_created() == true); /* to relay the batchmode parameter to created new thread */ req_batchmode_rep = batchmode; pthread_attr_t th_attr; pthread_attr_init(&th_attr); int retcode_rep = pthread_create(&th_cqueue_rep, &th_attr, start_normal_thread, static_cast(this)); if (retcode_rep != 0) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Unable to create a new thread for engine."); ECA_ENGINE *engine_tmp = engine_repp; engine_repp = 0; delete engine_tmp; } DBC_ENSURE(is_engine_created() == true); } /** * Routine used for launching the engine. */ void ECA_CONTROL::run_engine(void) { last_exec_res_rep = 0; last_exec_res_rep = engine_repp->exec(req_batchmode_rep); engine_exited_rep.set(1); } /** * Closes the processing engine. * * ensure: * is_engine_created() != true * is_engine_ready_for_commands() != true */ void ECA_CONTROL::close_engine(void) { if (is_engine_created() != true) return; engine_repp->command(ECA_ENGINE::ep_exit, 0.0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Waiting for engine thread to exit."); if (joining_rep != true) { joining_rep = true; int res = pthread_join(th_cqueue_rep,NULL); joining_rep = false; ECA_LOG_MSG(ECA_LOGGER::system_objects, "pthread_join returned: " + kvu_numtostr(res)); } else { DBC_CHECK(engine_pid_rep >= 0); int i; for (i = 0; i < 30; i++) { if (engine_exited_rep.get() ==1) break; /* 100ms sleep */ kvu_sleep(0, 100000000); } ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: engine is stuck, sending SIGKILL."); DBC_CHECK(engine_pid_rep >= 0); /* note: we use SIGKILL as SIGTERM, SIGINT et al are blocked and * handled by the watchdog thread */ pthread_kill(th_cqueue_rep, SIGKILL); } if (engine_exited_rep.get() == 1) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Engine thread has exited successfully."); delete engine_repp; engine_repp = 0; engine_exited_rep.set(0); } else { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Problems while shutting down the engine!"); } // --- DBC_ENSURE(is_engine_created() != true); DBC_ENSURE(is_engine_ready_for_commands() != true); // --- } /** * Is currently selected chainsetup valid? * * @pre is_selected() */ bool ECA_CONTROL::is_valid(void) const { // -------- DBC_REQUIRE(is_selected()); // -------- /* use is_valid_for_connection() instead of is_valid() to * report any detected errors via the logging subsystem */ return selected_chainsetup_repp->is_valid_for_connection(true); } /** * Returns true if active chainsetup exists and is connected. */ bool ECA_CONTROL::is_connected(void) const { if (session_repp->connected_chainsetup_repp == 0) { return false; } return (session_repp->connected_chainsetup_repp->is_valid() && session_repp->connected_chainsetup_repp->is_enabled()); } /** * Returns true if some chainsetup is selected. */ bool ECA_CONTROL::is_selected(void) const { return selected_chainsetup_repp != 0; } /** * Returns true if processing engine is running. */ bool ECA_CONTROL::is_running(void) const { return (is_engine_created() == true && engine_repp->status() == ECA_ENGINE::engine_status_running); } /** * Returns true if engine has finished processing. Engine state is * either "finished" or "error". */ bool ECA_CONTROL::is_finished(void) const { return (is_engine_created() == true && (engine_repp->status() == ECA_ENGINE::engine_status_finished || engine_repp->status() == ECA_ENGINE::engine_status_error)); } string ECA_CONTROL::resource_value(const string& key) const { ECA_RESOURCES ecarc; return ecarc.resource(key); } /** * Returns the length of the selected chainsetup (in samples). * * @pre is_selected() == true */ SAMPLE_SPECS::sample_pos_t ECA_CONTROL::length_in_samples(void) const { // -------- DBC_REQUIRE(is_selected()); // -------- SAMPLE_SPECS::sample_pos_t cslen = 0; if (selected_chainsetup_repp->length_set() == true) { cslen = selected_chainsetup_repp->length_in_samples(); } if (selected_chainsetup_repp->max_length_set() == true) { cslen = selected_chainsetup_repp->max_length_in_samples(); } return cslen; } /** * Returns the length of the selected chainsetup (in seconds). * * @pre is_selected() == true */ double ECA_CONTROL::length_in_seconds_exact(void) const { // -------- DBC_REQUIRE(is_selected()); // -------- double cslen = 0.0f; if (selected_chainsetup_repp->length_set() == true) { cslen = selected_chainsetup_repp->length_in_seconds_exact(); } if (selected_chainsetup_repp->max_length_set() == true) { cslen = selected_chainsetup_repp->max_length_in_seconds_exact(); } return cslen; } /** * Returns the current position of the selected chainsetup (in samples). * * @pre is_selected() == true */ SAMPLE_SPECS::sample_pos_t ECA_CONTROL::position_in_samples(void) const { // -------- DBC_REQUIRE(is_selected()); // -------- return selected_chainsetup_repp->position_in_samples(); } /** * Returns the current position of the selected chainsetup (in seconds). * * @pre is_selected() == true */ double ECA_CONTROL::position_in_seconds_exact(void) const { // -------- DBC_REQUIRE(is_selected()); // -------- return selected_chainsetup_repp->position_in_seconds_exact(); } /** * Returns true if engine object has been created. * If true, the engine object is available for use, but * the related engine thread is not necessarily running. * * @see is_engine_ready_for_commands() */ bool ECA_CONTROL::is_engine_created(void) const { return (engine_repp != 0); } /** * Returns true if engine is running and ready to receive * control commands via the message queue. * * In practise running means that the engine thread * has been created and it is running the exec() method * of the engine. * * @see is_engine_created() */ bool ECA_CONTROL::is_engine_ready_for_commands(void) const { bool started = is_engine_created(); if (started != true) return false; /* note: has been started, but run_engine() has returned */ if (engine_pid_rep < 0) return false; DBC_CHECK(engine_repp != 0); if (engine_repp->status() == ECA_ENGINE::engine_status_notready) return false; return true; } /** * Return info about engine status. */ string ECA_CONTROL::engine_status(void) const { if (is_engine_created() == true) { switch(engine_repp->status()) { case ECA_ENGINE::engine_status_running: { return "running"; } case ECA_ENGINE::engine_status_stopped: { return "stopped"; } case ECA_ENGINE::engine_status_finished: { return "finished"; } case ECA_ENGINE::engine_status_error: { return "error"; } case ECA_ENGINE::engine_status_notready: { return "not ready"; } default: { return "unknown status"; } } } return "not started"; } void ECA_CONTROL::set_last_string(const list& s) { string s_rep; DBC_CHECK(s_rep.size() == 0); list::const_iterator p = s.begin(); while(p != s.end()) { s_rep += *p; ++p; if (p != s.end()) s_rep += "\n"; } set_last_string(s_rep); } void ECA_CONTROL::set_last_string_list(const vector& s) { last_retval_rep.type = eci_return_value::retval_string_list; last_retval_rep.string_list_val = s; } void ECA_CONTROL::set_last_string(const string& s) { last_retval_rep.type = eci_return_value::retval_string; last_retval_rep.string_val = s; } void ECA_CONTROL::set_last_float(double v) { last_retval_rep.type = eci_return_value::retval_float; last_retval_rep.m.float_val = v; } void ECA_CONTROL::set_last_integer(int v) { last_retval_rep.type = eci_return_value::retval_integer; last_retval_rep.m.int_val = v; } void ECA_CONTROL::set_last_long_integer(long int v) { last_retval_rep.type = eci_return_value::retval_long_integer; last_retval_rep.m.long_int_val = v; } void ECA_CONTROL::set_last_error(const string& s) { last_retval_rep.type = eci_return_value::retval_error; last_retval_rep.string_val = s; } string ECA_CONTROL::last_error(void) const { if (last_retval_rep.type == eci_return_value::retval_error) return last_retval_rep.string_val; return string(); } void ECA_CONTROL::clear_last_values(void) { ECA_CONTROL_MAIN::clear_return_value(&last_retval_rep); } void ECA_CONTROL::set_float_to_string_precision(int precision) { float_to_string_precision_rep = precision; } std::string ECA_CONTROL::float_to_string(double n) const { return kvu_numtostr(n, float_to_string_precision_rep); } ecasound-2.9.1/libecasound/midi-client.h0000644000076400007640000000066010664032032015112 00000000000000#ifndef INCLUDED_MIDI_CLIENT_H #define INCLUDED_MIDI_CLIENT_H class MIDI_SERVER; /** * Top-level interface for MIDI-clients */ class MIDI_CLIENT { public: int id(void) const; void register_server(MIDI_SERVER* server); MIDI_CLIENT(void); protected: void set_id(int n); MIDI_SERVER* server(void) const { return(server_repp); } private: int id_rep; bool id_set_rep; MIDI_SERVER* server_repp; }; #endif ecasound-2.9.1/libecasound/audioio-device.h0000644000076400007640000001262212260762753015621 00000000000000#ifndef INCLUDED_AUDIOIO_DEVICE_H #define INCLUDED_AUDIOIO_DEVICE_H #include "audioio-buffered.h" /** * Virtual base class for real-time devices. * * A realtime device... * * - is disabled after device is opened * * - is enabled with start() * * - once enabled, will handle I/O at a constant speed * based on the sample format paremeters * * - is disabled with stop() * * @author Kai Vehmanen */ class AUDIO_IO_DEVICE : public AUDIO_IO_BUFFERED { public: /** @name Public static functions */ /*@{*/ /** * Whether given object is an AUDIO_IO_DEVICE object. */ static bool is_realtime_object(const AUDIO_IO* aobj); /*@}*/ /** @name Constructors and destructors */ /*@{*/ AUDIO_IO_DEVICE(void); virtual ~AUDIO_IO_DEVICE(void); /*@}*/ /** @name Main functionality */ /*@{*/ virtual void write_buffer(SAMPLE_BUFFER* sbuf); /*@}*/ /** @name Configuration * * For setting and getting configuration parameters. */ /*@{*/ /** * Whether to ignore possible under- and overrun * situations. If enabled, device should try to * recover from these situations, ie. keep on * running. If disabled, processing should be aborted * if an xrun occurs. Should be set before opening * the device. Defaults to 'true'. * * @pre is_open() != true */ virtual void toggle_ignore_xruns(bool v) { ignore_xruns_rep = v; } /** * Whether the device should maximize the use * of internal buffering. If disabled, the device * should use minimal amount of internal buffering. The * recommended size is two or three fragments, each * buffersize() sample frames in size. If enabled, * device is free to use as much as buffering as * is possible. The default state is enabled. * * The exact amount of buffering can be checked * with the latency() function. * * @pre is_open() != true */ virtual void toggle_max_buffers(bool v) { max_buffers_rep = v; } /** * Returns the current setting for xrun handling. */ virtual bool ignore_xruns(void) const { return ignore_xruns_rep; } /** * Returns the current setting for how internal * buffering is used. */ virtual bool max_buffers(void) const { return max_buffers_rep; } /** * Returns the systematic latency in sample frames. * This value is usually a multiple of buffersize(). * Note that the latency introduced by prefilling * outputs is not included in this figure. * * @see delay() * @see prefill_space() * * @pre is_open() == true */ virtual long int latency(void) const { return 0; } /** * How much data in sample frames can be prefilled * to a output device before processing is started * with start() (after prepare())? * * Note! Prefilling will have an affect to * output latency. * * @see latency() */ virtual long int prefill_space(void) const { return 0; } /*@}*/ /** @name Main functionality */ /*@{*/ /** * Prepare device for processing. After this call, device is * ready for input/output (buffer can be pre-filled). * * require: * is_running() != true * * ensure: * (io_mode() == si_read && readable() == true) || writable() */ virtual void prepare(void) { is_prepared_rep = true; } /** * Start prosessing sample data. Underruns will occur if the * calling program can't handle data at the speed of the * source device. Write_buffer() calls are blocked if necessary. * * Note! For output devices, at least one buffer of data * must have been written before issuing start()! * * require: * is_running() != true * is_prepared() == true * * ensure: * is_running() == true */ virtual void start(void) { is_running_rep = true; } /** * Stop processing. Doesn't usually concern non-realtime devices. * I/O is not allowed after this call. This should be used when * audio object is not going to be used for a while. * * @param drain if true, block until all samples already written * are played out (ignored in read mode) * * require: * is_running() == true * * ensure: * is_running() != true * is_prepared() != true * readable() == false * writable() == false */ virtual void stop(bool drain = false) { is_running_rep = false; is_prepared_rep = false; } /*@}*/ /** @name Runtime information */ /*@{*/ /** * Returns the delay between current read/write position * and the exact hardware i/o location. For instance * with soundcard hardware this value tells the distance * to the exact audio frame currently being played or * recorded. * * @see latency() * @see position_in_samples() * * @pre is_running() == true * @post delay() <= latency() */ virtual long int delay(void) const { return 0; } /** * Whether device has been started? */ bool is_running(void) const { return is_running_rep; } /** * Whether device has been prepared for processing? */ bool is_prepared(void) const { return is_prepared_rep; } /*@}*/ /** @name Functions reimplemented from AUDIO_IO */ /*@{*/ virtual bool supports_seeking(void) const { return true; } virtual bool finished(void) const { return is_open() == false; } virtual std::string status(void) const; /*@}*/ private: bool is_running_rep; bool is_prepared_rep; bool ignore_xruns_rep; bool max_buffers_rep; }; #endif ecasound-2.9.1/libecasound/eca-engine.h0000644000076400007640000001714112260762753014727 00000000000000#ifndef INCLUDED_ECA_ENGINE_H #define INCLUDED_ECA_ENGINE_H #include #include "sample-specs.h" #include "eca-engine-driver.h" #include "eca-chainsetup-edit.h" class AUDIO_IO; class AUDIO_IO_DB_CLIENT; class AUDIO_IO_DEVICE; class CHAIN; class CHAIN_OPERATOR; class ECA_CHAINSETUP; class ECA_ENGINE; class ECA_ENGINE_impl; class SAMPLE_BUFFER; /** * Default engine driver */ class ECA_ENGINE_DEFAULT_DRIVER : public ECA_ENGINE_DRIVER { public: virtual int exec(ECA_ENGINE* engine, ECA_CHAINSETUP* csetup); virtual void start(void); virtual void stop(bool drain = false); virtual void exit(void); private: ECA_ENGINE* engine_repp; bool exit_request_rep; }; /** * ECA_ENGINE is the actual processing engine. * It is initialized with a pointer to a * ECA_CHAINSETUP object, which has all information * needed at runtime. In other words ECA_ENGINE is * used to execute the chainsetup. You could say * ECA_ENGINE renders the final product according * to instruction given in ECA_CHAINSETUP. * * In most use cases ECA_ENGINE operation * involves multiple threads. The main thread * contexts are: * * - control context in which * ECA_ENGINE::exec() is executed * * - driver context; depending on the * used driver, this can be either * a separate thread or same as the * control thread * * - external context; other threads * sending commands to the engine * * Notes: This class is closely tied to * ECA_CHAINSETUP. Its private data and * function members can be accessed by * ECA_ENGINE through friend-access. */ class ECA_ENGINE { public: /** @name Public type definitions and constants */ /*@{*/ /** * Engine operation states */ enum Engine_status { engine_status_running, engine_status_stopped, engine_status_finished, engine_status_error, engine_status_notready }; typedef enum Engine_status Engine_status_t; /** * Commands used in ECA_ENGINE<->ECA_CONTROL communication. */ enum Engine_command { ep_prepare = 0, ep_start, ep_stop, ep_stop_with_drain, ep_debug, ep_exit, // -- ep_exec_edit, // -- ep_rewind, ep_forward, ep_setpos, ep_setpos_samples, ep_setpos_live_samples, }; typedef enum Engine_command Engine_command_t; struct complex_command { Engine_command_t type; union { struct { double value; } engine; struct { int chain; int op; int param; double value; } legacy; } m; ECA::chainsetup_edit_t cs; }; typedef struct complex_command complex_command_t; /*@}*/ /** @name Public functions */ /*@{*/ ECA_ENGINE(ECA_CHAINSETUP* eparam); ~ECA_ENGINE(void); int exec(bool batch_mode); void command(Engine_command_t cmd, double arg); void command(complex_command_t ccmd); void wait_for_stop(int timeout); void wait_for_exit(int timeout); /*@}*/ /** @name Public functions for observing engine status information */ /*@{*/ bool is_valid(void) const; bool is_finite_length(void) const; Engine_status_t status(void) const; /*@}*/ /** @name API for engine driver objects (@see ECA_ENGINE_DRIVER) */ /*@{*/ void check_command_queue(void); void wait_for_commands(void); void init_engine_state(void); void update_engine_state(void); void engine_iteration(void); void prepare_operation(void); void start_operation(void); void stop_operation(bool drain = false); void update_cache_chain_connections(void); void update_cache_latency_values(void); bool is_prepared(void) const; bool is_running(void) const; bool batch_mode(void) const { return(batchmode_enabled_rep); } SAMPLE_SPECS::sample_pos_t current_position_in_samples(void) const; double current_position_in_seconds_exact(void) const; const ECA_CHAINSETUP* connected_chainsetup(void) const { return(csetup_repp); } /*@}*/ private: /** @name Private data and functions */ /*@{*/ /** * Number of sample-frames of data is prefilled to * rt-outputs before starting processing. */ static const long int prefill_threshold_constant = 16348; static const int prefill_blocks_constant = 3; ECA_ENGINE_impl* impl_repp; bool use_midi_rep; bool batchmode_enabled_rep; bool processing_range_set_rep; bool prepared_rep; bool running_rep; bool started_rep; bool was_running_rep; bool driver_local; bool finished_rep; int outputs_finished_rep; int driver_errors_rep; int inputs_not_finished_rep; long int prefill_threshold_rep; long int preroll_samples_rep; long int recording_offset_rep; /*@}*/ /** @name Pointers to connected chainsetup */ /*@{*/ ECA_CHAINSETUP* csetup_repp; ECA_ENGINE_DRIVER* driver_repp; std::vector* chains_repp; std::vector* inputs_repp; std::vector* outputs_repp; /*@}*/ /** @name Audio data buffers */ /*@{*/ SAMPLE_BUFFER* mixslot_repp; std::vector cslots_rep; /*@}*/ /** * @name Various audio object maps. * * The main purpose of these maps is to make * it easier to iterate audio objects with * certain attributes. */ /*@{*/ std::vector realtime_inputs_rep; std::vector realtime_outputs_rep; std::vector realtime_objects_rep; std::vector non_realtime_inputs_rep; std::vector non_realtime_outputs_rep; std::vector non_realtime_objects_rep; /*@}*/ /** @name Cache objects for chainsetup and audio * object information */ /*@{*/ std::vector input_chain_count_rep; std::vector output_chain_count_rep; /** @name Attribute functions */ /*@{*/ long int buffersize(void) const; int max_channels(void) const; /*@}*/ /** @name Private functions for transport control */ /*@{*/ void request_start(void); void request_stop(bool drain = false); void signal_stop(void); void signal_exit(void); void signal_editlock(void); void conditional_start(void); void conditional_stop(void); void start_servers(void); void stop_servers(void); void prepare_realtime_objects(void); void start_realtime_objects(void); void reset_realtime_devices(void); void start_forked_objects(void); void stop_forked_objects(void); void state_change_to_finished(void); /*@}*/ /** @name Private functions for observing and modifying position */ /*@{*/ void set_position(double seconds); void set_position(int seconds) { set_position((double)seconds); } void set_position_samples(SAMPLE_SPECS::sample_pos_t samples); void set_position_samples_live(SAMPLE_SPECS::sample_pos_t samples); void change_position(double seconds); void prehandle_control_position(void); void posthandle_control_position(void); /*@}*/ /** @name Private functions for command queue handling */ /*@{*/ void interpret_queue(void); /*@}*/ /** @name Private functions for setup and cleanup */ /*@{*/ void init_variables(void); void init_connection_to_chainsetup(void); void init_driver(void); void init_prefill(void); void init_servers(void); void init_chains(void); void cleanup(void); void reinit_chains(bool force = false); void create_cache_object_lists(void); void init_profiling(void); void dump_profile_info(void); /*@}*/ /** @name Private functions for signal routing */ /*@{*/ void inputs_to_chains(void); void process_chains(void); void mix_to_outputs(bool skip_realtime_target_outputs); /*@}*/ /** @name Hidden/unimplemented functions */ /*@{*/ ECA_ENGINE& operator=(const ECA_ENGINE& x) { return *this; } /*@}*/ }; #endif ecasound-2.9.1/libecasound/audioio-ogg.h0000644000076400007640000000461511141362345015127 00000000000000#ifndef INCLUDED_AUDIOIO_OGG_H #define INCLUDED_AUDIOIO_OGG_H #include #include #include "audioio-buffered.h" #include "audioio-forked-stream.h" /** * Interface for Ogg Vorbis decoders and encoders using UNIX * pipe i/o. By default ogg123 and vorbize are used. * * @author Kai Vehmanen */ class OGG_VORBIS_INTERFACE : public AUDIO_IO_BUFFERED, public AUDIO_IO_FORKED_STREAM { private: static std::string default_input_cmd; static std::string default_output_cmd; public: static void set_input_cmd(const std::string& value); static void set_output_cmd(const std::string& value); static long int default_output_default_bitrate; public: OGG_VORBIS_INTERFACE (const std::string& name = ""); virtual ~OGG_VORBIS_INTERFACE(void); virtual OGG_VORBIS_INTERFACE* clone(void) const { return new OGG_VORBIS_INTERFACE(*this); } virtual OGG_VORBIS_INTERFACE* new_expr(void) const { return new OGG_VORBIS_INTERFACE(*this); } virtual std::string name(void) const { return "Ogg Vorbis stream"; } virtual std::string description(void) const { return "Interface for Ogg Vorbis decoders and encoders using UNIX pipe i/o."; } virtual std::string parameter_names(void) const { return "label,bitrate"; } virtual bool locked_audio_format(void) const { return true; } virtual int supported_io_modes(void) const { return io_read | io_write; } virtual bool supports_seeking(void) const { return false; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR &); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const { return(finished_rep); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; virtual void start_io(void); virtual void stop_io(void); protected: /* functions called by AUDIO_IO_FORKED_STREAM that require * the use of AUDIO_IO methods */ virtual bool do_supports_seeking(void) const { return supports_seeking(); } virtual void do_set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { set_position_in_samples(pos); } private: bool triggered_rep; bool finished_rep; long int bytes_rep; long int bitrate_rep; int filedes_rep; FILE* f1_rep; void fork_input_process(void); void fork_output_process(void); }; #endif ecasound-2.9.1/libecasound/eca-chainsetup.h0000644000076400007640000003533112260762753015626 00000000000000// ------------------------------------------------------------------------ // eca-chainsetup.h: Class representing an ecasound chainsetup object. // Copyright (C) 1999-2004,2006,2013 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 INCLUDED_ECA_CHAINSETUP_H #define INCLUDED_ECA_CHAINSETUP_H #include #include #include #include #include "eca-chainsetup-position.h" #include "eca-chainsetup-parser.h" #include "eca-chainsetup-edit.h" #include "eca-error.h" class AUDIO_IO; class AUDIO_IO_MANAGER; class AUDIO_IO_DB_SERVER; class CHAIN; class CHAIN_OPERATOR; class CONTROLLER_SOURCE; class ECA_AUDIO_FORMAT; class ECA_CHAINSETUP_BUFPARAMS; class ECA_CHAINSETUP_impl; class ECA_ENGINE_DRIVER; class ECA_RESOURCES; class GENERIC_CONTROLLER; class LOOP_DEVICE; class MIDI_IO; class MIDI_SERVER; using std::map; using std::list; using std::string; using std::vector; /** * Class representing an ecasound chainsetup object. * * Chainsetup is the central data object. It contains * audio inputs, outputs, chains, operators and also * information about how they are connected. * * Notes: ECA_CHAINSETUP is closely coupled to the * ECA_CHAINSETUP_PARSER and ECA_ENGINE. * In addition, to ease implementation, * also ECA_CONTROL classes have direct access * to ECA_CHAINSETUP's implementation. * * @author Kai Vehmanen */ class ECA_CHAINSETUP : public ECA_CHAINSETUP_POSITION { public: friend class ECA_ENGINE; friend class ECA_CONTROL; friend class ECA_CONTROL_BASE; friend class ECA_CONTROL_OBJECTS; friend class ECA_CHAINSETUP_PARSER; // ------------------------------------------------------------------- /** @name Public type definitions and constants */ /*@{*/ enum Buffering_mode { cs_bmode_auto, cs_bmode_nonrt, cs_bmode_rt, cs_bmode_rtlowlatency, cs_bmode_none }; enum Mix_mode { cs_mmode_avg, cs_mmode_sum }; enum Audio_dir { cs_dir_input, cs_dir_output }; typedef enum Buffering_mode Buffering_mode_t; typedef enum Mix_mode Mix_mode_t; static const string default_audio_format_const; static const string default_bmode_nonrt_const; static const string default_bmode_rt_const; static const string default_bmode_rtlowlatency_const; /*@}*/ // ------------------------------------------------------------------- /** @name Functions for init and cleanup */ /*@{*/ ECA_CHAINSETUP(void); ECA_CHAINSETUP(const vector& options); ECA_CHAINSETUP(const string& setup_file); virtual ~ECA_CHAINSETUP(void); /*@}*/ // ------------------------------------------------------------------- /** @name Functions for handling audio objects */ /*@{*/ void add_input(AUDIO_IO* aiod); void add_output(AUDIO_IO* aiod, bool truncate); void add_default_output(void); void remove_audio_input(const AUDIO_IO* aobj); void remove_audio_output(const AUDIO_IO* aobj); void attach_input_to_selected_chains(const AUDIO_IO* obj); void attach_output_to_selected_chains(const AUDIO_IO* obj); bool ok_audio_object(const AUDIO_IO* aobj) const; bool is_realtime_target_output(int output_id) const; vector audio_input_names(void) const; vector audio_output_names(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Functions for handling chains */ /*@{*/ void add_default_chain(void); void add_new_chains(const vector& newchains); void remove_chains(void); void select_chains(const vector& chainsarg) { selected_chainids = chainsarg; } void select_all_chains(void); void clear_chains(void); void rename_chain(const string& name); void toggle_chain_muting(void); void toggle_chain_bypass(void); const vector& selected_chains(void) const { return selected_chainids; } unsigned int first_selected_chain(void) const; vector chain_names(void) const; vector get_attached_chains_to_iodev(const string& filename) const; const CHAIN* get_chain_with_name(const string& name) const; int get_chain_index(const string& name) const; /*@}*/ // ------------------------------------------------------------------- /** @name Functions for handling MIDI-objects */ /*@{*/ void add_midi_device(MIDI_IO* mididev); void remove_midi_device(const string& name); void add_default_midi_device(void); /*@}*/ // ------------------------------------------------------------------- /** @name Functions for chain operators */ /*@{*/ void add_chain_operator(CHAIN_OPERATOR* cotmp); void add_controller(GENERIC_CONTROLLER* csrc); void set_target_to_controller(void); /*@}*/ // ------------------------------------------------------------------- /** @name Functions for configuration (default values, settings) */ /*@{*/ void toggle_precise_sample_rates(bool value) { precise_sample_rates_rep = value; } void toggle_ignore_xruns(bool v) { ignore_xruns_rep = v; } void set_output_openmode(int value) { output_openmode_rep = value; } void set_default_audio_format(ECA_AUDIO_FORMAT& value); void set_default_midi_device(const string& name) { default_midi_device_rep = name; } void set_buffering_mode(Buffering_mode_t value); void set_audio_io_manager_option(const string& mgrname, const string& optionstr); void set_mix_mode(Mix_mode_t value) { mix_mode_rep = value; } bool precise_sample_rates(void) const { return precise_sample_rates_rep; } bool ignore_xruns(void) const { return ignore_xruns_rep; } const ECA_AUDIO_FORMAT& default_audio_format(void) const; const string& default_midi_device(void) const { return default_midi_device_rep; } int output_openmode(void) const { return output_openmode_rep; } Buffering_mode_t buffering_mode(void) const { return buffering_mode_rep; } bool is_valid_for_connection(bool verbose) const; bool multitrack_mode(void) const { return multitrack_mode_rep; } long int multitrack_mode_offset(void) const { return multitrack_mode_offset_rep; } Mix_mode_t mix_mode(void) const { return mix_mode_rep; } /*@}*/ // ------------------------------------------------------------------- /** @name Functions for overriding current buffering mode parameters */ /*@{*/ void set_buffersize(long int value); void toggle_raised_priority(bool value); void set_sched_priority(int value); void toggle_double_buffering(bool value); void set_double_buffer_size(long int v); void toggle_max_buffers(bool v); long int buffersize(void) const; bool raised_priority(void) const; int get_sched_priority(void) const; bool double_buffering(void) const; long int double_buffer_size(void) const; bool max_buffers(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Functions that modify current state */ /*@{*/ void set_name(const string& str) { setup_name_rep = str; } void set_filename(const string& str) { setup_filename_rep = str; } void enable(void) throw(ECA_ERROR&); void disable(void); const string& name(void) const { return setup_name_rep; } const string& filename(void) const { return setup_filename_rep; } bool execute_edit(const ECA::chainsetup_edit_t& edit); /*@}*/ // ------------------------------------------------------------------- /** @name Functions implemented from ECA_SAMPLERATE_AWARE */ /*@{*/ virtual void set_samples_per_second(SAMPLE_SPECS::sample_rate_t v); /*@}*/ // ------------------------------------------------------------------- /** @name Functions implemented from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ // ------------------------------------------------------------------- /** @name Functions for observing current state */ /*@{*/ /** * Checks whether chainsetup is enabled (devices ready for use). */ bool is_enabled(void) const { return is_enabled_rep; } /** * Checks whether chainsetup is locked by ECA_ENGINE. * If locked, only a limited access to the chainsetup * data is allowed. */ bool is_locked(void) const { return is_locked_rep; } bool is_valid(void) const; bool has_realtime_objects(void) const; bool has_nonrealtime_objects(void) const; string options_to_string(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Functions for string->state conversions */ /*@{*/ /** * Returns the result of last call to interpret_option(), interpret_global_option() * or interpret_object_option(). * * @result true if options interpreted successfully, otherwise false */ bool interpret_result(void) const { return cparser_rep.interpret_result(); } const string& interpret_result_verbose(void) const { return cparser_rep.interpret_result_verbose(); } void interpret_option(const string& arg); void interpret_global_option(const string& arg); void interpret_object_option(const string& arg); void interpret_options(const vector& opts); /*@}*/ // ------------------------------------------------------------------- /** @name Functions for string<->state conversions */ /*@{*/ void save(void) throw(ECA_ERROR&); void save_to_file(const string& filename) throw(ECA_ERROR&); /*@}*/ // ------------------------------------------------------------------- private: /** @name Configuration data (settings and values) */ /*@{*/ ECA_CHAINSETUP_impl* impl_repp; ECA_CHAINSETUP_PARSER cparser_rep; bool precise_sample_rates_rep; bool ignore_xruns_rep; bool rtcaps_rep; int output_openmode_rep; long int double_buffer_size_rep; string default_midi_device_rep; /*@}*/ // ------------------------------------------------------------------- /** @name Current setup data (internal state, objects) */ /*@{*/ bool is_locked_rep; bool is_enabled_rep; bool multitrack_mode_rep; bool multitrack_mode_override_rep; bool memory_locked_rep; bool midi_server_needed_rep; /* FIXME: only needed by ECA_ENGINE */ int selected_chain_index_rep; int selected_cop_index_rep; int selected_cop_param_index_rep; int selected_ctrl_index_rep; int selected_ctrl_param_index_rep; int db_clients_rep; long int multitrack_mode_offset_rep; string setup_name_rep; string setup_filename_rep; vector selected_chainids; map loop_map; vector input_start_pos; vector output_start_pos; Buffering_mode_t buffering_mode_rep; Buffering_mode_t active_buffering_mode_rep; Mix_mode_t mix_mode_rep; vector inputs; vector inputs_direct_rep; vector outputs; vector outputs_direct_rep; vector aio_managers_rep; map aio_manager_option_map_rep; vector chains; vector midi_devices; AUDIO_IO_DB_SERVER* pserver_repp; MIDI_SERVER* midi_server_repp; ECA_ENGINE_DRIVER* engine_driver_repp; /*@}*/ // ------------------------------------------------------------------- /** @name Functions for handling audio objects */ /*@{*/ AUDIO_IO_MANAGER* get_audio_object_manager(AUDIO_IO* aio) const; AUDIO_IO_MANAGER* get_audio_object_type_manager(AUDIO_IO* aio) const; void register_engine_driver(AUDIO_IO_MANAGER* amgr); void register_audio_object_to_manager(AUDIO_IO* aio); void unregister_audio_object_from_manager(AUDIO_IO* aio); void propagate_audio_io_manager_options(void); AUDIO_IO* add_audio_object_helper(AUDIO_IO* aio); void remove_audio_object_proxy(AUDIO_IO* aio); void remove_audio_object_loop(const AUDIO_IO* aobj, AUDIO_IO* loop_aio, int dir); void remove_audio_object_impl(const AUDIO_IO* aobj, int dir, bool destroy); // ------------------------------------------------------------------- /** @name Functions for state<->string conversions */ /*@{*/ void load_from_file(const string& filename, vector& opts) const throw(ECA_ERROR&); /*@}*/ // ------------------------------------------------------------------- /** @name Functions for internal state changes */ /*@{*/ void select_active_buffering_mode(void); void enable_active_buffering_mode(void); void switch_to_direct_mode(void); void switch_to_direct_mode_helper(vector* objs, const vector& directobjs); void switch_to_db_mode(void); void switch_to_db_mode_helper(vector* objs, const vector& directobjs); void lock_all_memory(void); void unlock_all_memory(void); void set_defaults (void); int number_of_realtime_inputs(void) const; int number_of_realtime_outputs(void) const; int number_of_non_realtime_inputs(void) const; int number_of_non_realtime_outputs(void) const; int number_of_chain_operators(void) const; void toggle_locked_state(bool value) { is_locked_rep = value; } long int check_for_locked_buffersize(void) const; /*@}*/ // ------------------------------------------------------------------- /** @name Private helper functions */ /*@{*/ const ECA_CHAINSETUP_BUFPARAMS& active_buffering_parameters(void) const; const ECA_CHAINSETUP_BUFPARAMS& override_buffering_parameters(void) const; vector get_attached_chains_to_input(AUDIO_IO* aiod) const; vector get_attached_chains_to_output(AUDIO_IO* aiod) const; int number_of_attached_chains_to_input(AUDIO_IO* aiod) const; int number_of_attached_chains_to_output(AUDIO_IO* aiod) const; void add_chain_helper(const string& name); void enable_audio_object_helper(AUDIO_IO* aobj) const; void calculate_processing_length(void); /*@}*/ // ------------------------------------------------------------------- /** @name Static private helper functions */ /*@{*/ static bool ok_audio_object_helper(const AUDIO_IO* aobj, const vector& aobjs); static void check_object_samplerate(const AUDIO_IO* obj, SAMPLE_SPECS::sample_rate_t srate) throw(ECA_ERROR&); static string set_resource_helper(const ECA_RESOURCES& ecaresources, const string& tag, const string& alternative); static void audio_object_open_info(const AUDIO_IO* aio); /*@}*/ }; #endif ecasound-2.9.1/libecasound/eca-test-case.h0000644000076400007640000000303211141030171015317 00000000000000#ifndef INCLUDE_ECA_TEST_CASE_H #define INCLUDE_ECA_TEST_CASE_H #include #include /** * Macro definitions for subclasses * of ECA_TEST_CASE */ /** * Reports a failed assertion. * * @see ECA_TEST_CASE::report_failure * * @param x description, type 'const string&' */ #define ECA_TEST_FAILURE(x) \ do { report_failure(__FILE__, __LINE__, x); } while(0) /** * Abstract interface for implementing * test cases for component testing. * * @author Kai Vehmanen */ class ECA_TEST_CASE { public: /** @name Constructors and destructors */ /*@{*/ ECA_TEST_CASE(void); virtual ~ECA_TEST_CASE(void); /*@}*/ /** @name Public interface for running tests */ void run(void); void run(const std::string &name); /*@}*/ /** @name Public interface for queryng test results */ std::string name(void) const; bool success(void) const; const std::list& failures(void) const; /*@}*/ protected: /** @name Protected interface for reporting test failures */ void report_failure(const std::string& filename, int lineno, const std::string& description); /*@}*/ /** * @name Abtract virtual functions that need * to be defined by all subclasses. */ virtual std::string do_name(void) const = 0; virtual void do_run(void) = 0; virtual void do_run(const std::string& name); /*@}*/ private: void run_common_before(void); void run_common_after(void); std::list failures_rep; bool success_rep; }; #endif /* INCLUDE_ECA_TEST_CASE_H */ ecasound-2.9.1/libecasound/eca-logger-interface.cpp0000644000076400007640000001420511172721622017217 00000000000000// ------------------------------------------------------------------------ // eca-logger-interface.cpp: Logging subsystem interface // Copyright (C) 2002-2004,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 /* find() */ #include #include #include /* for getpid() */ #include /* --"-- */ #include #include #include #include #include #include "eca-version.h" #include "eca-logger-interface.h" using namespace std; const static int eca_l_i_default_log_history_len = 0; const static int eca_l_i_default_extlog_level = ECA_LOGGER::errors | ECA_LOGGER::info | ECA_LOGGER::subsystems | ECA_LOGGER::module_names | ECA_LOGGER::user_objects | ECA_LOGGER::system_objects | ECA_LOGGER::eiam_return_values; /** * Class constructor. Initializes log level to 'disabled'. */ ECA_LOGGER_INTERFACE::ECA_LOGGER_INTERFACE(void) : debug_value_rep(0), log_history_len_rep(eca_l_i_default_log_history_len), extlog_debug_level_rep(eca_l_i_default_extlog_level), extlog_file_repp(0) { char *extlog_dest = getenv("ECASOUND_LOGFILE"); char *extlog_loglevel = getenv("ECASOUND_LOGLEVEL"); if (extlog_dest) { if (extlog_loglevel) { extlog_debug_level_rep = atoi(extlog_loglevel); } extlog_file_repp = fopen(extlog_dest, "a"); if (extlog_file_repp) { time_t curtime; time(&curtime); fprintf(extlog_file_repp, "---------------------------------------------------------------------\n" "%sOpening logfile \"%s\" for ecasound-%s (logger=%p, pid=%d):\n", ctime(&curtime), extlog_dest, ecasound_library_version, this, getpid()); } else { std::cerr << "*** ERROR: Error in opening \"" << extlog_dest << "\". Check ECASOUND_LOGFILE and file permissions. ***\n"; } } } /** * Class destructor. */ ECA_LOGGER_INTERFACE::~ECA_LOGGER_INTERFACE(void) { if (extlog_file_repp != 0) { fprintf(extlog_file_repp, "Closing logfile (logger=%p, pid=%d).\n", this, getpid()); fclose(extlog_file_repp); } } /** * Issues a generic log message. */ void ECA_LOGGER_INTERFACE::msg(ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message) { std::string logmsg; /* step: output message with subclass implementation */ do_msg(level, module_name, log_message); /* step: store item to history * (note that we cannot archive EIAM return values as this * could create a loop when the backlog itself is printed) */ if (log_history_len_rep > 0 && level != ECA_LOGGER::eiam_return_values) { format_log_msg(&logmsg, level, module_name, log_message); log_history_rep.push_back(string("[") + ECA_LOGGER::level_to_string(level) + "] (" + ECA_LOGGER_INTERFACE::filter_module_name(module_name) + ") " + log_message); if (static_cast(log_history_rep.size()) > log_history_len_rep) { log_history_rep.pop_front(); DBC_CHECK(static_cast(log_history_rep.size()) == log_history_len_rep); } } /* step: conditionally output to external logfile */ if (extlog_file_repp != 0) { ECA_LOGGER::Msg_level_t extlevel = static_cast(extlog_debug_level_rep > 0 ? extlog_debug_level_rep : debug_value_rep); /* if message matches the request level mask, write it to log */ if (extlevel & level) { static unsigned long counter = 0; if (logmsg.size() == 0) format_log_msg(&logmsg, level, module_name, log_message); logmsg += " <" + kvu_numtostr(counter++) + ">\n"; fwrite(logmsg.c_str(), logmsg.size(), 1, extlog_file_repp); if (ferror(extlog_file_repp)) { std::cerr << "*** ERROR: Error in writing to ECASOUND_LOGFILE. Check free disk space. ***\n"; fclose(extlog_file_repp); extlog_file_repp = 0; } fflush(extlog_file_repp); } } } /** * Sets logging level to 'level' state to 'enabled'. */ void ECA_LOGGER_INTERFACE::set_log_level(ECA_LOGGER::Msg_level_t level, bool enabled) { if (enabled == true) { debug_value_rep |= level; } else { debug_value_rep &= ~level; } } /** * Flush all log messages. */ void ECA_LOGGER_INTERFACE::flush(void) { do_flush(); } /** * Disables logging. * * Note! Is equivalent to * 'set_log_level(ECA_LOGGER_INTERFACE::disabled)'. */ void ECA_LOGGER_INTERFACE::disable(void) { debug_value_rep = 0; } /** * Sets the log message history length. */ void ECA_LOGGER_INTERFACE::set_log_history_length(int len) { log_history_len_rep = len; } /** * Formats module name for logging purposes. * * Both "foobar.cpp" and "../src/foobar.cpp" return * the same formatted string "foobar". */ string ECA_LOGGER_INTERFACE::filter_module_name(const string& rawmodule) { string retval; size_t begin = rawmodule.rfind("/"); if (begin == string::npos) begin = 0; else /* skip the initial "/" */ ++begin; size_t end = rawmodule.rfind("."); if (end > begin) return string(rawmodule, begin, end - begin); return rawmodule; } void ECA_LOGGER_INTERFACE::format_log_msg(std::string *logmsg, ECA_LOGGER::Msg_level_t level, const std::string& module_name, const std::string& log_message) { *logmsg = string("[") + ECA_LOGGER::level_to_string(level) + "] (" + ECA_LOGGER_INTERFACE::filter_module_name(module_name) + ") " + log_message; } ecasound-2.9.1/libecasound/audioio-reverse.h0000644000076400007640000000474411032774266016041 00000000000000#ifndef INCLUDED_AUDIOIO_REVERSE_H #define INCLUDED_AUDIOIO_REVERSE_H #include #include #include #include "audioio-proxy.h" class SAMPLE_BUFFER; /** * A proxy class that reverts the child * object's data. * * Related design patterns: * - Proxy (GoF207 * * @author Kai Vehmanen */ class AUDIO_IO_REVERSE : public AUDIO_IO_PROXY { public: /** @name Public functions */ /*@{*/ AUDIO_IO_REVERSE (void); virtual ~AUDIO_IO_REVERSE(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return(string("Reverse => ") + child()->name()); } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual std::string parameter_names(void) const; virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ virtual AUDIO_IO_REVERSE* clone(void) const; virtual AUDIO_IO_REVERSE* new_expr(void) const { return(new AUDIO_IO_REVERSE()); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /* -- not reimplemented * virtual SAMPLE_SPECS::sample_pos_t position_in_samples(void) const { return(child_repp->position_in_samples()); } * virtual SAMPLE_SPECS::sample_pos_t length_in_samples(void) const { return(); } * virtual void set_length_in_samples(SAMPLE_SPECS::sample_pos_t pos); * virtual void set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos); */ /*@}*/ /** @name Reimplemented functions from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return(io_read); } virtual bool supports_seeking(void) const { return(true); } virtual bool finite_length_stream(void) const { return(true); } virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf) { child()->write_buffer(sbuf); } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual bool finished(void) const; /*@}*/ private: mutable std::vector params_rep; bool init_rep; bool finished_rep; SAMPLE_BUFFER* tempbuf_repp; static const int child_parameter_offset = 1; AUDIO_IO_REVERSE& operator=(const AUDIO_IO_REVERSE& x) { return *this; } AUDIO_IO_REVERSE (const AUDIO_IO_REVERSE& x) { } }; #endif ecasound-2.9.1/libecasound/libecasound_tester.cpp0000644000076400007640000000576311170171737017147 00000000000000// ------------------------------------------------------------------------ // libecasound_tester.cpp: Runs all tests registered to ECA_TEST_REPOSITORY // Copyright (C) 2002-2003,2009 Kai Vehmanen // // 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 #include #include /* POSIX: various signal functions */ #include /* POSIX: sleep() */ #include "eca-logger.h" #include "eca-test-repository.h" using namespace std; /** * See also 'ecasound/testsuite/eca_test1.cpp' */ int main(int argc, char *argv[]) { ECA_LOGGER::instance().set_log_level_bitmask(ECA_LOGGER::errors | ECA_LOGGER::info); /** * Uncomment to enable libecasound log messages */ //ECA_LOGGER::instance().set_log_level(ECA_LOGGER::user_objects, true); ECA_TEST_REPOSITORY& repo = ECA_TEST_REPOSITORY::instance(); #ifdef __FreeBSD__ { /* on FreeBSD, SIGFPEs are not ignored by default */ struct sigaction blockaction; blockaction.sa_flags = 0; blockaction.sa_handler = SIG_IGN; sigaction(SIGFPE, &blockaction, 0); } #endif cout << "-------------------------------------------------------------------------" << endl; cout << "libecasound_tester start:" << endl; cout << "-------------------------------------------------------------------------" << endl; if (argc > 1) /* note: run one test case */ repo.run(std::string(argv[1])); else /* note: run all test cases */ repo.run(); cout << "-------------------------------------------------------------------------" << endl; cout << "libecasound_tester summary:" << endl; cout << "-------------------------------------------------------------------------" << endl; cout << endl; if (repo.success() != true) { cout << repo.failures().size() << " failed test cases "; cout << "in ECA_TEST_REPOSITORY:" << endl << endl; const list& failures = repo.failures(); list::const_iterator q = failures.begin(); int n = 1; while(q != failures.end()) { cout << n++ << ". " << *q << endl; ++q; } return -1; } else { cout << "All tests succesful." << endl; } cout << endl; cout << "-------------------------------------------------------------------------"; cout << endl << endl; return 0; } ecasound-2.9.1/libecasound/linear-envelope.cpp0000644000076400007640000000405311034535034016336 00000000000000// ------------------------------------------------------------------------ // linear-envelope.cpp: Linear envelope // Copyright (C) 1999-2002,2005,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // This program is fre 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 #include #include #include "linear-envelope.h" #include "eca-logger.h" LINEAR_ENVELOPE::LINEAR_ENVELOPE(void) { } LINEAR_ENVELOPE::~LINEAR_ENVELOPE(void) { } CONTROLLER_SOURCE::parameter_t LINEAR_ENVELOPE::value(double pos) { parameter_t retval; /* note: position may go beyond stages_len_rep */ if (pos < stages_len_rep) { retval = (pos / stages_len_rep); } else retval = 1.0f; return retval; } void LINEAR_ENVELOPE::init(void) { MESSAGE_ITEM otemp; otemp << "Linear enveloped initialized; length "; otemp.setprecision(3); otemp << stages_len_rep; otemp << " seconds."; ECA_LOG_MSG(ECA_LOGGER::user_objects, otemp.to_string()); } void LINEAR_ENVELOPE::set_parameter(int param, CONTROLLER_SOURCE::parameter_t value) { switch (param) { case 1: stages_len_rep = value; break; } } CONTROLLER_SOURCE::parameter_t LINEAR_ENVELOPE::get_parameter(int param) const { switch (param) { case 1: return stages_len_rep; } return 0.0; } ecasound-2.9.1/libecasound/osc-gen-file.h0000644000076400007640000000202310664032032015157 00000000000000#ifndef INCLUDED_GENERIC_OSCILLATOR_FILE_H #define INCLUDED_GENERIC_OSCILLATOR_FILE_H #include "osc-gen.h" #include "eca-error.h" /** * Generic oscillator using preset envelopes. * Presets are read from an ascii configuration file. */ class GENERIC_OSCILLATOR_FILE : public GENERIC_OSCILLATOR { public: virtual std::string parameter_names(void) const { return("freq,mode,preset-number"); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; virtual std::string name(void) const { return("Generic oscillator (preset)"); } GENERIC_OSCILLATOR_FILE* clone(void) const { return new GENERIC_OSCILLATOR_FILE(*this); } GENERIC_OSCILLATOR_FILE* new_expr(void) const { return new GENERIC_OSCILLATOR_FILE(*this); } GENERIC_OSCILLATOR_FILE (double freq = 0.0, int preset_number = 0); virtual ~GENERIC_OSCILLATOR_FILE (void); protected: void parse_envelope(const std::string& str); private: int preset_rep; void get_oscillator_preset(int preset); }; #endif ecasound-2.9.1/libecasound/plugins/0000755000076400007640000000000012261520737014313 500000000000000ecasound-2.9.1/libecasound/plugins/audioio_jack_manager.cpp0000644000076400007640000016176012260763316021066 00000000000000// ------------------------------------------------------------------------ // audioio_jack_manager.cpp: Manager for JACK client objects // Copyright (C) 2001-2004,2008,2009,2011 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // References: // http://jackit.sourceforge.net/ // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include /* std::count() */ #include #include #include #include /* gettimeofday() */ #include /* ETIMEDOUT */ #include #include #include #include #include #include "audioio.h" #include "eca-engine.h" #include "eca-chainsetup.h" #include "eca-logger.h" #include /** * Enable and disable features */ /* Debug control flow */ // #define DEBUG_CFLOW /* Profile callback execution */ // #define PROFILE_CALLBACK_EXECUTION /** * Local macro definitions */ #ifdef DEBUG_CFLOW #define DEBUG_CFLOW_STATEMENT(x) (x) #else #define DEBUG_CFLOW_STATEMENT(x) ((void)0) #endif #ifdef PROFILE_CALLBACK_EXECUTION #define PROFILE_CE_STATEMENT(x) (x) static PROCEDURE_TIMER profile_callback_timer; #else #define PROFILE_CE_STATEMENT(x) ((void)0) #endif /** * Prototypes for static functions */ static int eca_jack_process_callback(jack_nframes_t nframes, void *arg); #if ECA_JACK_TRANSPORT_API >= 3 static int eca_jack_sync_callback(jack_transport_state_t state, jack_position_t *pos, void *arg); static void eca_jack_sync_start_seek_to(jack_transport_state_t state, jack_position_t *pos, void *arg); static void eca_jack_sync_start_live_seek_to(jack_transport_state_t state, jack_position_t *pos, void *arg); static void eca_jack_process_timebase_slave(jack_nframes_t nframes, void *arg); #endif static void eca_jack_process_engine_iteration(jack_nframes_t nframes, void *arg); static void eca_jack_process_mute(jack_nframes_t nframes, void* arg); #ifdef PROFILE_CALLBACK_EXECUTION static void eca_jack_process_profile_pre(void); static void eca_jack_process_profile_post(void); #endif static int eca_jack_bsize_cb(jack_nframes_t nframes, void *arg); static int eca_jack_srate_cb(jack_nframes_t nframes, void *arg); static void eca_jack_shutdown_cb(void *arg); static std::string eca_get_jack_port_item(const char **ports, int item); #include "audioio_jack_manager.h" using std::cerr; using std::endl; using std::list; using std::string; using std::vector; /** * Implementations of static functions */ /** * How many ecasound JACK manager instances * can run at the same time (affects connection * setup time in some situations). */ const int AUDIO_IO_JACK_MANAGER::instance_limit = 8; /** * Context help: * J = originates from JACK callback * E = ----- " ------- engine thread (exec()) * C = ----- " ------- control/client thread */ #if ECA_JACK_TRANSPORT_API >= 3 /** * JACK sync callback function. Called when someone has * issued a state change request. * * context: J-level-0 */ static int eca_jack_sync_callback(jack_transport_state_t state, jack_position_t *pos, void *arg) { // DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_SYNC: entering..."); AUDIO_IO_JACK_MANAGER* current = static_cast(arg); int result = 1; /* ready for rolling */ if (current->exit_request_rep == 1 || current->shutdown_request_rep == 1) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: after exit/shutdown!!!" << endl); return 0; } /* try to get the driver lock; if it fails or connection * is not fully establish, skip this processing cycle */ int ret = pthread_mutex_trylock(¤t->engine_mod_lock_rep); if (ret == 0) { SAMPLE_SPECS::sample_pos_t enginepos = current->engine_repp->current_position_in_samples(); /* 1. engine locked for editing, do not touch! */ // 2012/May: no longer needed /* 2. transport stopped */ if (state == JackTransportStopped) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: JACK stopped" << endl); /* 2.1 engine at correct place; report success */ if (enginepos == pos->frame) { result = 1; } /* 2.2 only start seek if engine is not already at correct place */ else if (current->jackslave_seekahead_target_rep == -1) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: stopped - starting seek to " << pos->frame << "." << endl); eca_jack_sync_start_seek_to(state, pos, arg); } result = 0; } /* 3. transport starting (or looping, all these states are fine to us, as is the case where state info is not available at all) */ else if (state == JackTransportStarting) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: JACK starting" << endl); /* 3.1 engine at correct position */ if (enginepos == pos->frame) { /* 3.1.1 engine ready for process callback; return positive */ if (current->engine_repp->is_prepared() && current->engine_repp->is_running()) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: JACK running; correct position, engine running\n"); result = 1; current->jackslave_seekahead_target_rep = -1; } /* 3.1.2 engine not ready for process callback; request start */ else { current->start_request_rep++; current->engine_repp->command(ECA_ENGINE::ep_start, 0.0f); result = 0; } } /* 3.2 engine at the wrong position but no seek target set; restart seek */ else if (current->jackslave_seekahead_target_rep == -1) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: starting - new seek to " << pos->frame << "." << endl); eca_jack_sync_start_seek_to(state, pos, arg); result = 0; } /* 3.3 engine at the wrong position; seek still ongoing */ else { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: still seeking, pos=" << pos->frame << ", enginepos=" << enginepos << "." << endl); if (pos->frame != static_cast(current->jackslave_seekahead_target_rep)) { eca_jack_sync_start_seek_to(state, pos, arg); } result = 0; } } /* 4. slow-start timeout elapsed; transport forced to rolling */ else { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: JACK running, forced, trying to catch up" << endl); eca_jack_sync_start_live_seek_to(state, pos, arg); } pthread_mutex_unlock(¤t->engine_mod_lock_rep); } else { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: couldn't get lock" << endl); result = 0; } return result; } #endif #if ECA_JACK_TRANSPORT_API >= 3 /** * Helper function to start seeking to a new position. * * context: J-level-1 */ static void eca_jack_sync_start_seek_to(jack_transport_state_t state, jack_position_t *pos, void *arg) { // DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_sync_start_seek_to(): entering..."); AUDIO_IO_JACK_MANAGER* current = static_cast(arg); SAMPLE_SPECS::sample_pos_t enginepos = current->engine_repp->current_position_in_samples(); /* prepare for the next start by seeking to the correct position */ if (enginepos != pos->frame) { current->jackslave_seekahead_target_rep = pos->frame; current->engine_repp->command(ECA_ENGINE::ep_setpos_samples, current->jackslave_seekahead_target_rep); DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_SYNC: seeking to " << pos->frame << endl); } current->engine_repp->command(ECA_ENGINE::ep_prepare, 0.0f); } #endif #if ECA_JACK_TRANSPORT_API >= 3 /** * Helper function to start forced (live-)seeking to a new * position. We have to be prepared to chase the timebase * master. * * context: J-level-1/2 */ static void eca_jack_sync_start_live_seek_to(jack_transport_state_t state, jack_position_t *pos, void *arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); SAMPLE_SPECS::sample_pos_t enginepos = current->engine_repp->current_position_in_samples(); if (current->is_running() != true) { /* transport rolling: engine not started; start it now */ if (current->engine_repp->status() != ECA_ENGINE::engine_status_finished && ((pos->frame <= current->engine_repp->connected_chainsetup()->length_in_samples()) || (current->engine_repp->is_finite_length() != true))) { /* conditions when we should start the engine * a. engine status not finished, AND... * a.1. transport position not beyond csetup length, OR... * a.2. csetup has infinite length */ if (current->engine_repp->is_prepared() == true && (enginepos == pos->frame)) { current->engine_repp->start_operation(); DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_FORCESYNC: Starting engine (direct)\n"); } else { current->start_request_rep++; current->engine_repp->command(ECA_ENGINE::ep_start, 0.0f); DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_FORCESYNC: Starting engine (cmdpipe)\n"); enginepos = -1; } } } else { DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_FORCESYNC: engine curpos '" << current->engine_repp->current_position_in_samples() << "' doesn't match JACK curpos '" << pos->frame << "'!" << endl); if ((pos->frame >= current->engine_repp->connected_chainsetup()->length_in_samples() && (current->engine_repp->is_finite_length() == true))) { DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_FORCESYNC: over max length" << endl); current->stop_request_rep++; current->engine_repp->command(ECA_ENGINE::ep_stop, 0.0f); } else if (current->jackslave_seekahead_target_rep == -1 || current->jackslave_seekahead_target_rep < static_cast(pos->frame + current->buffersize()) || current->jackslave_seekahead_target_rep - current->jackslave_seekahead_rep * current->buffersize() > static_cast(pos->frame + current->buffersize())) { /* note: we use seek-ahead to give time for the disk i/o subsystem to catch up for the next round, seek-ahead must be re-initialized if... a) seek-ahead target not set, b) we have missed the current seek-ahead target, or c) transport position has been rewinded (current seek-ahead target too far in the fututre) */ if (current->jackslave_seekahead_target_rep != -1) { /* previous seek has failed; try again with a longer look-ahead */ current->jackslave_seekahead_rep = (current->jackslave_seekahead_rep < (65536 / current->buffersize()) ? current->jackslave_seekahead_rep * 2 : (65536 / current->buffersize())); DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_FORCESYNC: seek-ahead request failed; increasing seek-ahead to " << current->jackslave_seekahead_rep << endl); } current->jackslave_seekahead_target_rep = pos->frame + current->jackslave_seekahead_rep * current->buffersize(); current->engine_repp->command(ECA_ENGINE::ep_setpos_live_samples, current->jackslave_seekahead_target_rep); DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_FORCESYNC: seek-ahead request sent; seeking to " << current->jackslave_seekahead_target_rep << endl); } else { /* engine is already seeking to a new pos */ DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_FORCESYNC: seek to new pos underway; " << pos->frame << " is transport-curpos." << endl); } } } #endif /** * Processes all registered JACK input and output ports. * This is the main callback function registered to * the JACK framework. * * context: J-level-0 */ static int eca_jack_process_callback(jack_nframes_t nframes, void *arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); PROFILE_CE_STATEMENT(eca_jack_process_profile_pre()); if (current->exit_request_rep == 1 || current->shutdown_request_rep == 1) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: after shutdown/exit!!!" << endl); if (current->exit_request_rep) eca_jack_process_mute(nframes, current); return 0; } if (current->engine_repp == 0) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: after engine destructor!!!" << endl); return 0; } /* try to get the driver lock; if it fails or connection * is not fully establish, skip this processing cycle */ int ret = pthread_mutex_trylock(¤t->engine_mod_lock_rep); if (ret == 0) { // DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: got lock" << endl); /* 1. transport control processing in "notransport" and "transport" mode */ if (current->mode_rep == AUDIO_IO_JACK_MANAGER::Transport_none || current->mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send) { /* execute one engine iteration */ if (current->is_running() == true) { eca_jack_process_engine_iteration(nframes, current); } else { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: not running, mute" << endl); eca_jack_process_mute(nframes, current); } } #if ECA_JACK_TRANSPORT_API >= 3 else { /* 2. transport control processing in "slave" mode */ if (current->mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive || current->mode_rep == AUDIO_IO_JACK_MANAGER::Transport_receive) { eca_jack_process_timebase_slave(nframes, arg); } else { /* never reached */ } } #endif pthread_mutex_unlock(¤t->engine_mod_lock_rep); // DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: released lock" << endl); } else { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: couldn't get lock; muting" << endl); eca_jack_process_mute(nframes, current); } PROFILE_CE_STATEMENT(eca_jack_process_profile_post()); return 0; } /** * Helper routine. Only called by eca_jack_process*() functions. * * context: J-level-1/ */ static void eca_jack_process_engine_iteration(jack_nframes_t nframes, void* arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); /* this is guaranteed by libjack */ DBC_CHECK(current->buffersize_rep == static_cast(nframes)); /* FIXME: remove me! */ if (current->buffersize_rep != static_cast(nframes)) { std::cerr << "JACK_MANAGER: invalid nframes! buffersize=" << current->buffersize_rep << ", nframes=" << nframes << std::endl; } if (current->engine_repp->status() != ECA_ENGINE::engine_status_finished) { /* 1. copy audio data from port input buffers to ecasound buffers */ for(size_t n = 0; n < current->inports_rep.size(); n++) { if (current->inports_rep[n]->cb_buffer != 0) { jack_default_audio_sample_t* in_cb_buffer = static_cast (jack_port_get_buffer(current->inports_rep[n]->jackport, nframes)); memcpy(current->inports_rep[n]->cb_buffer, in_cb_buffer, current->buffersize_rep * sizeof(jack_default_audio_sample_t)); } } // DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_PROCESS: engine_iter_in"); /* 2. execute one engine iteration */ current->engine_repp->engine_iteration(); // DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_PROCESS: engine_iter_out"); /* 3. copy data from ecasound buffers to port output buffers */ for(size_t n = 0; n < current->outports_rep.size(); n++) { if (current->outports_rep[n]->cb_buffer != 0) { jack_default_audio_sample_t* out_cb_buffer = static_cast (jack_port_get_buffer(current->outports_rep[n]->jackport, nframes)); memcpy(out_cb_buffer, current->outports_rep[n]->cb_buffer, current->buffersize_rep * sizeof(jack_default_audio_sample_t)); } } } else { /* 4. chainsetup finished, mute */ DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: chainsetup finished, muting\n"); eca_jack_process_mute(nframes, current); } /* 5. update engine status based on the last iteration */ current->engine_repp->update_engine_state(); } /** * Helper routine. Only called by eca_jack_process*() functions. * * context: J-level-1/2 */ static void eca_jack_process_mute(jack_nframes_t nframes, void* arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); for(size_t n = 0; n < current->outports_rep.size(); n++) { if (current->outports_rep[n]->cb_buffer != 0) { jack_default_audio_sample_t* out_cb_buffer = static_cast (jack_port_get_buffer(current->outports_rep[n]->jackport, nframes)); memset(out_cb_buffer, 0, current->buffersize_rep * sizeof(jack_default_audio_sample_t)); } } } #if ECA_JACK_TRANSPORT_API >= 3 /** * Helper routine. Only called by eca_jack_process_callback() function. * * context: J-level-1 */ static void eca_jack_process_timebase_slave(jack_nframes_t nframes, void *arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); jack_transport_state_t jackstate; jack_position_t jackpos; bool need_mute = true; jackstate = jack_transport_query(current->client_repp, &jackpos); /* 1. engine locked for editing, do not touch! */ // 2012/May: no longer needed /* 2. transport stopped or starting */ if (jackstate == JackTransportStopped) { // DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_process_timebase_slave(): JACK state stopped" << endl); ++current->j_stopped_rounds_rep; /* 2.1 transport stopped and no pending start requests */ if (current->is_running() == true && current->j_stopped_rounds_rep > 3) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_PROCESS: running, request stop" << endl); current->stop_request_rep++; current->engine_repp->command(ECA_ENGINE::ep_stop, 0.0f); } } /* 3. transport stopped or starting */ else if (jackstate == JackTransportStarting) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_process_timebase_slave(): JACK state starting" << endl); ++current->j_stopped_rounds_rep; } /* 4. transport rolling (or looping, both states are fine to us, as is the case where state info is not available at all) */ else { current->j_stopped_rounds_rep = 0; /* 4.1 engine not running for some odd reason; try a live-seek */ if (current->is_running() != true) { DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_process_timebase_slave(): not running!" << endl); eca_jack_sync_start_live_seek_to(jackstate, &jackpos, arg); } /* 4.2 engine running normally */ else { SAMPLE_SPECS::sample_pos_t enginepos = current->engine_repp->current_position_in_samples(); /* 4.2.1 engine at correct position, run the engine cycle */ if (enginepos == jackpos.frame) { if (current->jackslave_seekahead_target_rep != -1) { // report only on the first time DEBUG_CFLOW_STATEMENT(cerr << "eca_jack_process_timebase_slave(): JACK running; correct position\n"); } /* execute engine iteration */ eca_jack_process_engine_iteration(nframes, current); current->jackslave_seekahead_target_rep = -1; need_mute = false; } /* 4.2.2 engine at wrong position for some odd reason; try a live-seek */ else { DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_process_timebase_slave(): engine curpos '" << current->engine_repp->current_position_in_samples() << "' doesn't match JACK curpos '" << jackpos.frame << "'!" << endl); eca_jack_sync_start_live_seek_to(jackstate, &jackpos, arg); } } } if (need_mute == true) { eca_jack_process_mute(nframes, current); } } #endif #ifdef PROFILE_CALLBACK_EXECUTION static void eca_jack_process_profile_pre(void) { profile_callback_timer.start(); DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_PROCESS: entry ----> "); } static void eca_jack_process_profile_post(void) { profile_callback_timer.stop(); DEBUG_CFLOW_STATEMENT(cerr << endl << "eca_jack_PROCESS: process out" << endl); if (profile_callback_timer.last_duration_seconds() > 0.005f) { cerr << "(audioio-jack-manager) event " << profile_callback_timer.event_count(); cerr << ", process() took " << profile_callback_timer.last_duration_seconds() * 1000; cerr << " msecs." << endl; } else { if (profile_callback_timer.event_count() < 5) { cerr << "(audioio-jack-manager) event " << profile_callback_timer.event_count(); cerr << ", process() took " << profile_callback_timer.last_duration_seconds() * 1000; cerr << " msecs." << endl; } } } #endif /* PROFILE_CALLBACK_EXECUTION */ /** * Changes current sampling rate. Callback function registered * to the JACK framework. * * @param nframes new engine sample rate * @param arg pointer to a client supplied structure * * @return zero on success, non-zero on error */ static int eca_jack_srate_cb(jack_nframes_t nframes, void *arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); ECA_LOG_MSG(ECA_LOGGER::user_objects, "[callback] " + current->jackname_rep + ": setting srate to " + kvu_numtostr(nframes)); if (static_cast(nframes) != current->srate_rep) { current->shutdown_request_rep = true; ECA_LOG_MSG(ECA_LOGGER::info, "Unable to adapt to the new samplerate received from JACK, shutting down."); } return 0; } /** * Callback function that is called when the engine * buffersize changes. * * context: J-level-0 * * @param nframes new engine buffer size * @param arg pointer to a client supplied structure * * @return zero on success, non-zero on error */ static int eca_jack_bsize_cb(jack_nframes_t nframes, void *arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); ECA_LOG_MSG(ECA_LOGGER::user_objects, "[callback] " + current->jackname_rep + ": setting buffersize to " + kvu_numtostr(nframes)); if (static_cast(nframes) != current->buffersize()) { // FIXME: leads into a segfault...? current->shutdown_request_rep = true; ECA_LOG_MSG(ECA_LOGGER::info, "Unable to adapt to the new buffersize received from JACK, shutting down."); } return 0; } /** * Shuts down the callback context. Callback function registered * to the JACK framework. * * context: J-level-0 */ static void eca_jack_shutdown_cb(void *arg) { AUDIO_IO_JACK_MANAGER* current = static_cast(arg); ECA_LOG_MSG(ECA_LOGGER::user_objects, "" + current->jackname_rep + ": [callback] jackd shutdown, stopping processing"); current->shutdown_request_rep = true; } /** * Implementations of non-static functions * * context: E-level-0 */ AUDIO_IO_JACK_MANAGER::AUDIO_IO_JACK_MANAGER(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "constructor"); open_rep = false; activated_rep = false; open_clients_rep = 0; last_node_id_rep = 1; jackslave_seekahead_rep = 2; jackslave_seekahead_target_rep = -1; engine_repp = 0; jackname_rep = "ecasound"; pthread_cond_init(&exit_cond_rep, NULL); pthread_mutex_init(&exit_mutex_rep, NULL); pthread_mutex_init(&engine_mod_lock_rep, NULL); mode_rep = AUDIO_IO_JACK_MANAGER::Transport_invalid; shutdown_request_rep = false; cb_allocated_frames_rep = 0; buffersize_rep = 0; } /** * Class destructor. * * context: E-level-0 */ AUDIO_IO_JACK_MANAGER::~AUDIO_IO_JACK_MANAGER(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "destructor"); /* 1. close JACK connection */ if (is_open() == true) close_server_connection(); /* 2. clear input ports */ vector::iterator q = inports_rep.begin(); while(q != inports_rep.end()) { if ((*q)->cb_buffer != 0) { delete[] (*q)->cb_buffer; (*q)->cb_buffer = 0; } delete *q; ++q; } /* 3. clear output ports */ q = inports_rep.begin(); while(q != inports_rep.end()) { if ((*q)->cb_buffer != 0) { delete[] (*q)->cb_buffer; (*q)->cb_buffer = 0; } delete *q; ++q; } /* 4. clear objects */ list::iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { delete *p; ++p; } } /** * context: C-level-1 */ bool AUDIO_IO_JACK_MANAGER::is_managed_type(const AUDIO_IO* aobj) const { // --- DBC_REQUIRE(aobj != 0); // --- if (aobj->name() == "JACK interface") { DBC_CHECK(dynamic_cast(aobj) != 0); return(true); } return false; } /** * context: C-level-1 */ void AUDIO_IO_JACK_MANAGER::register_object(AUDIO_IO* aobj) { // --- DBC_REQUIRE(aobj != 0); DBC_REQUIRE(is_managed_type(aobj) == true); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "register object " + aobj->label()); AUDIO_IO_JACK* jobj = static_cast(aobj); eca_jack_node_t* tmp = new eca_jack_node_t; tmp->aobj = jobj; tmp->origptr = aobj; tmp->client_id = last_node_id_rep; node_list_rep.push_back(tmp); jobj->set_manager(this, tmp->client_id); ++last_node_id_rep; // --- DBC_ENSURE(is_managed_type(aobj) == true); // --- } /** * context: C-level-0 */ int AUDIO_IO_JACK_MANAGER::get_object_id(const AUDIO_IO* aobj) const { // --- DBC_REQUIRE(is_managed_type(aobj) == true); // --- list::const_iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { if ((*p)->origptr == aobj) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "found object id for aobj " + aobj->name() + ": " + kvu_numtostr((*p)->client_id)); return (*p)->client_id; } ++p; } return -1; } /** * context: C-level-0 */ list AUDIO_IO_JACK_MANAGER::get_object_list(void) const { list object_list; list::const_iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { object_list.push_back((*p)->client_id); ++p; } return object_list; } /** * Unregisters object previously registered with register_object() * from the manager. * * @param id unique identifier for managed objects; @see * get_object_id * * context: C-level-0 */ void AUDIO_IO_JACK_MANAGER::unregister_object(int id) { // --- DBC_DECLARE(unsigned int old_total_nodes = node_list_rep.size()); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "unregister object "); list::iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { if ((*p)->client_id == id) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "removing object " + (*p)->aobj->label()); (*p)->aobj->set_manager(0, -1); delete *p; node_list_rep.erase(p); break; } ++p; } // --- DBC_ENSURE(node_list_rep.size() == old_total_nodes - 1); DBC_DECLARE(list ol = get_object_list()); DBC_ENSURE(std::count(ol.begin(), ol.end(), id) == 0); // --- } void AUDIO_IO_JACK_MANAGER::set_transport_mode(enum Operation_mode mode, bool print_trace) { mode_rep = mode; if (print_trace == false) return; switch(mode) { case Transport_none: ECA_LOG_MSG(ECA_LOGGER::info, "JACK transport: send/receive disabled (mode: notransport)"); break; case Transport_receive: ECA_LOG_MSG(ECA_LOGGER::info, "JACK transport: slave, reacting to transport events (mode: recv)"); break; case Transport_send: ECA_LOG_MSG(ECA_LOGGER::info, "JACK transport: master, sending transport events (mode: send)"); break; case Transport_send_receive: ECA_LOG_MSG(ECA_LOGGER::info, "JACK transport: both sending and reacting to transport events (mode: sendrecv)"); break; case Transport_invalid: break; default: ; } } /** * context: E-level-0 */ void AUDIO_IO_JACK_MANAGER::set_parameter(int param, std::string value) { switch(param) { case 1: { jackname_rep = value; ECA_LOG_MSG(ECA_LOGGER::user_objects, "client name set to '" + value + "'."); break; } case 2: { #if ECA_JACK_TRANSPORT_API >= 3 if (value == "notransport" || value == "streaming") { set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_none, true); } else if (value == "send" || value == "master") { set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_send, true); } else if (value == "sendrecv" || value == "slave") { set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_send_receive, true); } else if (value == "recv") { set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_receive, true); } #else set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_none, false); if (value != "notransport") ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: JACK transport support disabled at build time, using 'notransport'."); #endif /* ECA_JACK_TRANSPORT_API */ break; } } } /** * context: E-level-0 */ std::string AUDIO_IO_JACK_MANAGER::get_parameter(int param) const { switch(param) { case 1: { return jackname_rep; } case 2: { switch(mode_rep) { case AUDIO_IO_JACK_MANAGER::Transport_none: return "notransport"; case AUDIO_IO_JACK_MANAGER::Transport_receive: return "recv"; case AUDIO_IO_JACK_MANAGER::Transport_send: return "send"; case AUDIO_IO_JACK_MANAGER::Transport_send_receive: return "sendrecv"; default: return "notransport"; } break; } } return ""; } /** * If transport is stopped, request JACK to seek to * Ecasond's current position. Otherwise let Ecasound seek * to JACK's position. */ void AUDIO_IO_JACK_MANAGER::initial_seek(void) { #if ECA_JACK_TRANSPORT_API >= 3 jack_transport_state_t jackstate; jack_position_t jackpos; jackstate = jack_transport_query(client_repp, &jackpos); if (jackstate == JackTransportStopped && (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive)) { ECA_LOG_MSG(ECA_LOGGER::info, "JACK transport: sending out initial locate to " + kvu_numtostr(engine_repp->current_position_in_seconds_exact(), 3) + "sec"); jack_transport_locate(client_repp, engine_repp->current_position_in_samples()); } #endif } #if ECA_JACK_TRANSPORT_API >= 3 static std::string priv_jack_transport_state_str(jack_transport_state_t state) { switch(state) { case JackTransportStopped: return "STOPPED"; case JackTransportRolling: return "ROLLING"; case JackTransportLooping: return "LOOPING"; case JackTransportStarting: return "STARTING"; default: ; } return std::string(); } static std::string priv_jack_transport_pos_str(jack_position_t *state) { if (state->frame_rate == 0) return std::string(); return kvu_numtostr(static_cast(state->frame) / state->frame_rate, 3) + "sec"; } #endif void AUDIO_IO_JACK_MANAGER::helper_print_transport_state(const std::string& when) const { #if ECA_JACK_TRANSPORT_API >= 3 jack_position_t jpos; jack_transport_state_t jstate; jstate = jack_transport_query(client_repp, &jpos); ECA_LOG_MSG(ECA_LOGGER::info, "JACK transport: at ecasound " + when + " JACK state is " + priv_jack_transport_state_str(jstate) + " (position " + priv_jack_transport_pos_str(&jpos) + ")"); #endif } void AUDIO_IO_JACK_MANAGER::exec_helper_setup_transport(void) { if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_invalid) { /* set default transport mode */ #if ECA_JACK_TRANSPORT_API >= 3 set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_send_receive, true); #else set_transport_mode(AUDIO_IO_JACK_MANAGER::Transport_none, false); #endif } if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_receive) helper_print_transport_state("start"); } void AUDIO_IO_JACK_MANAGER::exec_helper_clean_transport(void) { if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_receive) helper_print_transport_state("stop"); } /** * context: E-level-0 */ int AUDIO_IO_JACK_MANAGER::exec(ECA_ENGINE* engine, ECA_CHAINSETUP* csetup) { int result = 0; ECA_LOG_MSG(ECA_LOGGER::system_objects, "driver exec"); engine_repp = engine; engine->init_engine_state(); exec_helper_setup_transport(); exit_request_rep = false; stop_request_rep = 0; j_stopped_rounds_rep = 0; start_request_rep = 0; activate_server_connection(); if (is_connection_active() != true) { signal_exit(); } initial_seek(); while(true) { DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: wait for commands" << endl); engine_repp->wait_for_commands(); DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: wakes up; commands available" << endl); /* we must take the lock to ensure that * process callback does not run at the same time * * note: the RT-optimized command queue (VALUE_QUEUE_RT_C) is not * safe when accessed from more than 2 threads, but here it is ok * as we limit concurrent threads to two with engine_mod_lock_rep **/ SAMPLE_SPECS::sample_pos_t enginepos = engine_repp->current_position_in_samples(); pthread_mutex_lock(&engine_mod_lock_rep); engine_repp->check_command_queue(); if (exit_request_rep != true && enginepos != engine_repp->current_position_in_samples()) { /* seek requested */ #if ECA_JACK_TRANSPORT_API >= 3 if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive) { if (engine_repp->current_position_in_samples() != jackslave_seekahead_target_rep) { DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: seek requested to pos=" << engine_repp->current_position_in_samples() << "." << endl); jack_transport_locate(client_repp, engine_repp->current_position_in_samples()); } } #endif } pthread_mutex_unlock(&engine_mod_lock_rep); DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: check_commands finished" << endl); /* case 1: external exit request */ if (exit_request_rep == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "exit request in exec"); break; } /* case 2-i: engine finished and in batch mode -> exit */ if (engine_repp->status() == ECA_ENGINE::engine_status_finished && engine_repp->batch_mode() == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "batch finished in exec, exit"); break; } /* case 2-ii: engine error occured -> exit */ else if (engine_repp->status() == ECA_ENGINE::engine_status_error) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "engine error, exit"); break; } /* case 3: problems with jack callbacks -> exit */ if (shutdown_request_rep == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "problems with JACK callbacks"); result = -1; break; } } DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: out of exec" << endl); if (is_connection_active() == true) { deactivate_server_connection(); } exec_helper_clean_transport(); DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: deactivated" << endl); pthread_mutex_lock(&engine_mod_lock_rep); exit_request_rep = 0; engine_repp = 0; pthread_mutex_unlock(&engine_mod_lock_rep); /* signal exit() that we are done */ signal_exit(); DEBUG_CFLOW_STATEMENT(cerr << "jack_exec: exit" << endl); return result; } /** * Activate connection to the JACK server. * * context: E-level-0/3 * Can be called at the same time with * JACK callbacks, so proper locking * must be ensured (engine_mod_lock_rep taken * upon entry). * * @pre is_running() != true * @post is_running() == true * */ void AUDIO_IO_JACK_MANAGER::start(void) { // -- DBC_REQUIRE(is_running() != true); // -- ECA_LOG_MSG(ECA_LOGGER::system_objects, "driver start"); if (engine_repp->is_prepared() != true) engine_repp->prepare_operation(); engine_repp->start_operation(); #if ECA_JACK_TRANSPORT_API >= 3 if (start_request_rep > 0) { start_request_rep = 0; } else { if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive) { jack_transport_start(client_repp); } } j_stopped_rounds_rep = 0; #endif // -- DBC_ENSURE(is_running() == true); // -- } /** * Signals that driver should stop operation. * Once stopped, driver must not call * any ECA_ENGINE functions. * * context: E-level-0/3 * Caller must ensure that JACK process callback * does not run at the same time (engine_mod_lock_rep * taken upon entry). */ void AUDIO_IO_JACK_MANAGER::stop(bool drain) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "driver stop"); #if ECA_JACK_TRANSPORT_API >= 3 if (stop_request_rep > 0) { stop_request_rep = 0; } else { if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive) { jack_transport_stop(client_repp); } } #endif if (engine_repp->is_prepared() == true) engine_repp->stop_operation(drain); } /** * Activates connection to server. * * context: E-level-1 * * @pre is_connection_active() != true */ void AUDIO_IO_JACK_MANAGER::activate_server_connection(void) { // -- DBC_REQUIRE(is_connection_active() != true); // -- if (engine_repp->is_prepared() != true) engine_repp->prepare_operation(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "jack_activate()"); if (jack_activate (client_repp)) { ECA_LOG_MSG(ECA_LOGGER::info, "Error! Cannot active client!"); activated_rep = false; } else { connect_all_nodes(); /* update port-specific latency values */ engine_repp->update_cache_latency_values(); activated_rep = true; } } /** * Disconnects all connected ports and then * deactives the client. * * context: E-level-1 * Caller must ensure that JACK process callback * does not rung at the same time. * * @pre is_connection_active() == true * @post is_connection_active() != true */ void AUDIO_IO_JACK_MANAGER::deactivate_server_connection(void) { // -- DBC_REQUIRE(is_connection_active() == true); // -- if (shutdown_request_rep != true) { /* no need to disconnect as deactivate does that for us */ // disconnect_all_nodes(); ECA_LOG_MSG(ECA_LOGGER::system_objects, "jack_deactivate() "); if (jack_deactivate (client_repp)) { ECA_LOG_MSG(ECA_LOGGER::info, "Error! Cannot deactive client!"); } } if (engine_repp->is_prepared() == true) engine_repp->stop_operation(); activated_rep = false; signal_stop(); // -- DBC_ENSURE(is_connection_active() != true); // -- } /** * Signals that driver should stop operation * and return from its exec() method. * * context: E-level-0/3 * Can be called at the same time with * JACK callbacks, so proper locking * must be ensured (caller must hold * lock against the callbacks). */ void AUDIO_IO_JACK_MANAGER::exit(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "driver exit"); exit_request_rep = true; if (engine_repp->is_prepared() == true) engine_repp->stop_operation(); } /** * Returns a pointer to a 'eca_jack_node_t' structure * matching client 'client_id'. * * @pre list l = get_object_list(); std::count(l.begin(), l.end(), client_id) == 1 * @return non-zero pointer */ AUDIO_IO_JACK_MANAGER::eca_jack_node_t* AUDIO_IO_JACK_MANAGER::get_node(int client_id) { // -- DBC_DECLARE(list ol = get_object_list()); DBC_REQUIRE(std::count(ol.begin(), ol.end(), client_id) == 1); // -- eca_jack_node_t* node = 0; list::iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { if ((*p)->client_id == client_id) { node = *p; break; } ++p; } // -- DBC_ENSURE(node != 0); // -- return node; } /** * Sets up automatic port connection for client_id's port * 'portnum'. When jack client is activated, this port * is automatically connected to port 'portname'. The * direction of the connection is based on audio objects I/O mode * (@see AUDIO_IO::io_mode()). * * @pre list l = get_object_list(); std::count(l.begin(), l.end(), client_id) == 1 * @pre is_open() == true @ @pre portnum > 0 */ void AUDIO_IO_JACK_MANAGER::auto_connect_jack_port(int client_id, int portnum, const string& portname) { // --- DBC_DECLARE(list ol = get_object_list()); DBC_REQUIRE(std::count(ol.begin(), ol.end(), client_id) == 1); DBC_REQUIRE(is_open() == true); DBC_REQUIRE(portnum > 0); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "auto-connect jack ports for client " + kvu_numtostr(client_id)); eca_jack_node_t* node = get_node(client_id); list::const_iterator p = node->ports.begin(); int n = 1; while(p != node->ports.end()) { if (n == portnum) { (*p)->autoconnect_string = portname; break; } ++n; ++p; } } static std::string eca_get_jack_port_item(const char **ports, int item) { int n = 0; while(ports != 0 && ports[n] != 0) { if (n + 1 == item) return string(ports[n]); n++; } return string(""); } /** * Sets up automatic port connections to matching ports of * client 'dst'. * * @pre list l = get_object_list(); std::count(l.begin(), l.end(), client_id) == 1 * @pre is_open() == true @ @pre portnum > 0 */ void AUDIO_IO_JACK_MANAGER::auto_connect_jack_port_client(int client_id, const string& dst, int channels) { // --- DBC_DECLARE(list ol = get_object_list()); DBC_REQUIRE(std::count(ol.begin(), ol.end(), client_id) == 1); DBC_REQUIRE(is_open() == true); DBC_REQUIRE(channels > 0); // --- const char** ports; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Making autoconnection to ports matching: " + dst); eca_jack_node_t* node = get_node(client_id); list::const_iterator p = node->ports.begin(); int n = 1; while(p != node->ports.end()) { if (n <= channels) { ports = 0; if (node->aobj->io_mode() == AUDIO_IO::io_read) { ports = jack_get_ports (client_repp, dst.c_str(), NULL, JackPortIsOutput); } else { ports = jack_get_ports (client_repp, dst.c_str(), NULL, JackPortIsInput); } (*p)->autoconnect_string = eca_get_jack_port_item(ports, n); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Making autoconnection to terminal port: " + (*p)->autoconnect_string + ", channel " + kvu_numtostr(n)); if (ports != NULL) free(ports); } else { break; } ++n; ++p; } } /** * Returns the total latency for ports of client * 'client_id'. If client ports have different latency * values, the worst-case latency is reported. */ long int AUDIO_IO_JACK_MANAGER::client_latency(int client_id) { eca_jack_node_t* node = get_node(client_id); long int latency = -1; list::const_iterator p = node->ports.begin(); while(p != node->ports.end()) { if (latency == -1) { latency = (*p)->total_latency; } else { if (static_cast((*p)->total_latency) > latency) { ECA_LOG_MSG(ECA_LOGGER::info, "warning! port latencies don't match for client " + kvu_numtostr(client_id)); latency = (*p)->total_latency; } } ++p; } return latency; } /** * Registers new JACK port for client 'client_id'. The direction of * the port is based on audio objects I/O mode (@see * AUDIO_IO::io_mode()). If 'portname' is a non-empty string, * the port will be automatically connected to the 'portname' * port once JACK client is activated. * * The final port names are of the form 'clientname:portprefix_N', * where N is 1...max_port. * * @pre list l = get_object_list(); std::count(l.begin(), l.end(), client_id) == 1 * @pre is_open() == true */ void AUDIO_IO_JACK_MANAGER::register_jack_ports(int client_id, int ports, const string& portprefix) { // --- DBC_DECLARE(list ol = get_object_list()); DBC_REQUIRE(std::count(ol.begin(), ol.end(), client_id) == 1); DBC_REQUIRE(is_open() == true); DBC_DECLARE(unsigned int old_port_count_vectors = inports_rep.size() + outports_rep.size()); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "register jack ports for client " + kvu_numtostr(client_id)); eca_jack_node_t* node = get_node(client_id); for(int n = 0; n < ports; n++) { eca_jack_port_data_t* portdata = new eca_jack_port_data_t; portdata->jackport = 0; portdata->autoconnect_string = ""; portdata->total_latency = 0; portdata->cb_buffer = new jack_default_audio_sample_t [cb_allocated_frames_rep]; std::map::iterator it = port_numbers_rep.find(portprefix); if (it == port_numbers_rep.end()) { it = port_numbers_rep.insert(std::make_pair(portprefix, 0)).first; } string tport = portprefix + "_" + kvu_numtostr(++it->second); if (node->aobj->io_mode() == AUDIO_IO::io_read) { portdata->jackport = jack_port_register(client_repp, tport.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); inports_rep.push_back(portdata); } else { portdata->jackport = jack_port_register(client_repp, tport.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); outports_rep.push_back(portdata); } node->ports.push_back(portdata); } // --- DBC_ENSURE(inports_rep.size() + outports_rep.size() == old_port_count_vectors + ports); // --- } /** * Unregisters all JACK ports for client 'client_id'. * * @pre list l = get_object_list(); std::count(l.begin(), l.end(), client_id) == 1 * @pre is_open() == true * @post node->in_ports == 0 && node->out_ports == 0 */ void AUDIO_IO_JACK_MANAGER::unregister_jack_ports(int client_id) { // --- DBC_DECLARE(list ol = get_object_list()); DBC_REQUIRE(std::count(ol.begin(), ol.end(), client_id) == 1); DBC_REQUIRE(is_open() == true); DBC_DECLARE(unsigned int old_node_port_count = get_node(client_id)->ports.size()); DBC_DECLARE(unsigned int old_port_count_vectors = inports_rep.size() + outports_rep.size()); // --- ECA_LOG_MSG(ECA_LOGGER::system_objects, "unregister all jack ports for client " + kvu_numtostr(client_id)); eca_jack_node_t* node = get_node(client_id); list::iterator p = node->ports.begin(); while(p != node->ports.end()) { /* 1. unregister port from JACK */ if (open_rep == true && (*p)->jackport != 0) { jack_port_unregister(client_repp, (*p)->jackport); } /* 2. delete the port from inports and outports vectors */ vector::iterator q = inports_rep.begin(); while(q != inports_rep.end()) { if (*p == *q) { inports_rep.erase(q); break; } ++q; } q = outports_rep.begin(); while(q != outports_rep.end()) { if (*p == *q) { outports_rep.erase(q); break; } ++q; } /* 3. delete sub-structures */ delete[] (*p)->cb_buffer; (*p)->cb_buffer = 0; /* 4. delete the actual port_data object */ delete *p; ++p; } /* 5. clear the whole node port list */ node->ports.clear(); // --- DBC_ENSURE(node->ports.size() == 0); DBC_ENSURE(inports_rep.size() + outports_rep.size() == old_port_count_vectors - old_node_port_count); // --- } void AUDIO_IO_JACK_MANAGER::open(int client_id) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "open for client " + kvu_numtostr(client_id)); DBC_CHECK(shutdown_request_rep != true); /* only for the first client */ if (is_open() != true) { open_server_connection(); } ++open_clients_rep; } void AUDIO_IO_JACK_MANAGER::close(int client_id) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "close for client " + kvu_numtostr(client_id)); DBC_CHECK(open_clients_rep > 0); /* only for the last client */ if (open_clients_rep == 1) { if (is_open() == true) close_server_connection(); } else ECA_LOG_MSG(ECA_LOGGER::user_objects, "Not yet closing JACK server connection as there are " + kvu_numtostr(open_clients_rep - 1) + " clients still active."); --open_clients_rep; } /** * Returns current buffersize in sample frames. * Always returns 0 if manager is not connected. */ long int AUDIO_IO_JACK_MANAGER::buffersize(void) const { if (is_open() != true) return 0; return buffersize_rep; } bool AUDIO_IO_JACK_MANAGER::is_running(void) const { if (engine_repp != 0) { return engine_repp->is_running(); } return false; } /** * Returns the current JACK engine sample rate. * Always returns 0 if manager is not connected. */ SAMPLE_SPECS::sample_rate_t AUDIO_IO_JACK_MANAGER::samples_per_second(void) const { if (is_open() != true) return 0; return srate_rep; } /** * context: J-E-C-level-3 */ long int AUDIO_IO_JACK_MANAGER::read_samples(int client_id, void* target_buffer, long int samples) { // DEBUG_CFLOW_STATEMENT(cerr << endl << "read_samples:" << client_id); jack_default_audio_sample_t* ptr = static_cast(target_buffer); eca_jack_node_t* node = get_node(client_id); list::const_iterator p = node->ports.begin(); while(p != node->ports.end()) { if ((*p)->cb_buffer != 0) { memcpy(ptr, (*p)->cb_buffer, buffersize_rep * sizeof(jack_default_audio_sample_t)); ptr += buffersize_rep; } ++p; } return buffersize_rep; } /** * context: J-E-C-level-3 */ void AUDIO_IO_JACK_MANAGER::write_samples(int client_id, void* target_buffer, long int samples) { // DEBUG_CFLOW_STATEMENT(cerr << endl << "write_samples:" << client_id); size_t sample_size = sizeof(jack_default_audio_sample_t); long int writesamples = (samples <= buffersize_rep) ? samples : buffersize_rep; jack_default_audio_sample_t* ptr = static_cast(target_buffer); eca_jack_node_t* node = get_node(client_id); list::const_iterator p = node->ports.begin(); while(p != node->ports.end()) { if ((*p)->cb_buffer != 0) { /* note: cb_buffer points to jack_default_audio_sample_t* */ memcpy((*p)->cb_buffer, ptr, writesamples * sample_size); ptr += writesamples; memset((*p)->cb_buffer + writesamples, 0, (buffersize_rep - writesamples) * sample_size); } ++p; } } /** * Opens connection to the JACK server. Sets * is_open() to 'true' if connection is * successfully opened. * * @pre is_open() != true * * context: C-level-1 */ void AUDIO_IO_JACK_MANAGER::open_server_connection(void) { // -- DBC_REQUIRE(is_open() != true); // -- string client_name (jackname_rep); int n; for(n = 0; n < AUDIO_IO_JACK_MANAGER::instance_limit; n++) { client_repp = jack_client_open (client_name.c_str(), JackNullOption, NULL); if (client_repp != 0) break; client_name = jackname_rep + "_" + kvu_numtostr(n + 2); } if (n != AUDIO_IO_JACK_MANAGER::instance_limit) { srate_rep = static_cast(jack_get_sample_rate(client_repp)); /* FIXME: add better control of allocated memory */ cb_allocated_frames_rep = buffersize_rep = static_cast(jack_get_buffer_size(client_repp)); shutdown_request_rep = false; jackslave_seekahead_rep = 4096 / buffersize_rep + 1; /* set callbacks */ jack_set_process_callback(client_repp, eca_jack_process_callback, static_cast(this)); jack_set_sample_rate_callback(client_repp, eca_jack_srate_cb, static_cast(this)); jack_set_buffer_size_callback(client_repp, eca_jack_bsize_cb, static_cast(this)); jack_on_shutdown(client_repp, eca_jack_shutdown_cb, static_cast(this)); #if ECA_JACK_TRANSPORT_API >= 3 if (mode_rep == AUDIO_IO_JACK_MANAGER::Transport_receive || mode_rep == AUDIO_IO_JACK_MANAGER::Transport_send_receive) { jack_set_sync_callback(client_repp, eca_jack_sync_callback, static_cast(this)); } #endif open_rep = true; #ifdef PROFILE_CALLBACK_EXECUTION profile_callback_timer.set_lower_bound_seconds(0.001f); profile_callback_timer.set_upper_bound_seconds(0.005f); #endif ECA_LOG_MSG(ECA_LOGGER::user_objects, "Successfully opened JACK server connection."); } else { ECA_LOG_MSG(ECA_LOGGER::info, "Error! Cannot connect to JACK server!"); open_rep = false; } } /** * Closes connection to the JACK server. * * @pre is_open() == true * @post is_open() != true * * context: C-level-1 */ void AUDIO_IO_JACK_MANAGER::close_server_connection(void) { // -- DBC_REQUIRE(is_open() == true); // -- // FIXME: add proper unregistration // iterate over cids: unregister_jack_ports() jack_client_close (client_repp); shutdown_request_rep = false; open_rep = false; port_numbers_rep.clear(); ECA_LOG_MSG(ECA_LOGGER::user_objects, "Successfully closed JACK server connection."); #ifdef PROFILE_CALLBACK_EXECUTION cerr << profile_callback_timer.to_string() << endl; #endif // -- DBC_ENSURE(is_open() != true); DBC_REQUIRE(shutdown_request_rep != true); // -- } /** * Fetches total port latency information. * * context: E-level-5 */ void AUDIO_IO_JACK_MANAGER::get_total_port_latency(jack_client_t* client, eca_jack_port_data_t* port, int iomode) { jack_nframes_t latency = 0; #if ECA_JACK_FEATSET >= 1 jack_latency_range_t range; jack_port_get_latency_range(port->jackport, iomode == AUDIO_IO::io_read ? JackCaptureLatency : JackPlaybackLatency, &range); if (range.min != range.max) ECA_LOG_MSG(ECA_LOGGER::user_objects, "jack_port_get_latency_range mix=" + kvu_numtostr(range.min) + ", max=" + kvu_numtostr(range.max)); latency = range.min; #else latency = jack_port_get_total_latency(client, port->jackport); #endif port->total_latency = latency; ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total latency for port '" + string(jack_port_name(port->jackport)) + "' is " + kvu_numtostr(port->total_latency) + "."); } /** * Connects ports of node 'node'. * * @param node pointers to a node object * @param connect whether to connect (true) or disconnect (false) * * context: E-level-4 */ void AUDIO_IO_JACK_MANAGER::set_node_connection(eca_jack_node_t* node, bool connect) { list::iterator p = node->ports.begin(); while(p != node->ports.end()) { if ((*p)->cb_buffer != 0) { string ecaport = (*p)->autoconnect_string; if (ecaport.size() > 0) { string jackport (jack_port_name((*p)->jackport)); const string* fromport = &ecaport; const string* toport = &jackport; if (node->aobj->io_mode() != AUDIO_IO::io_read) { /* output object -> switch direction */ fromport = &jackport; toport = &ecaport; } if (connect == true) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "Connecting JACK port " + *fromport + " to " + *toport); if (jack_connect (client_repp, fromport->c_str(), toport->c_str())) { ECA_LOG_MSG(ECA_LOGGER::info, "Error! Cannot make connection " + *fromport + " -> " + *toport + "."); } else { AUDIO_IO_JACK_MANAGER::get_total_port_latency(client_repp, *p, node->aobj->io_mode()); } } else { ECA_LOG_MSG(ECA_LOGGER::system_objects, "jack_port_disconnect()"); /* don't call jack_disconnect() if engine has shut down */ if (jack_disconnect(client_repp, fromport->c_str(), toport->c_str())) { ECA_LOG_MSG(ECA_LOGGER::info, "Error! Cannot disconnect " + *fromport + " -> " + *toport + "."); } } } } ++p; } } /** * Connects ports of all registered nodes. * * @see set_node_connection() * * context: E-level-3 */ void AUDIO_IO_JACK_MANAGER::connect_all_nodes(void) { if (shutdown_request_rep != true) { list::iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { set_node_connection(*p, true); ++p; } } else { if (is_open() == true) close_server_connection(); } } /** * Disconnects all ports of registered nodes. * * @see set_node_connection() * * context: E-level-3 */ void AUDIO_IO_JACK_MANAGER::disconnect_all_nodes(void) { list::iterator p = node_list_rep.begin(); while(p != node_list_rep.end()) { set_node_connection(*p, false); ++p; } } /** * Signals that exec() has exited. * * @see wait_for_exit(); * * context: E-level-1 */ void AUDIO_IO_JACK_MANAGER::signal_exit(void) { pthread_mutex_lock(&exit_mutex_rep); pthread_cond_signal(&exit_cond_rep); pthread_mutex_unlock(&exit_mutex_rep); } /** * Waits until exec() has exited. * * context: not in use */ void AUDIO_IO_JACK_MANAGER::wait_for_exit(void) { int ret = kvu_pthread_timed_wait(&exit_mutex_rep, &exit_cond_rep, 5); ECA_LOG_MSG(ECA_LOGGER::info, kvu_pthread_timed_wait_result(ret, "(audioio_jack_manager) wait_for_exit")); } /** * Signals that client has stopped. * * @see wait_for_stop() * * context: E-level-2 */ void AUDIO_IO_JACK_MANAGER::signal_stop(void) { pthread_mutex_lock(&exit_mutex_rep); pthread_cond_signal(&exit_cond_rep); pthread_mutex_unlock(&exit_mutex_rep); } /** * Waits until client has stopped (no more callbacks). * * context: not in use */ void AUDIO_IO_JACK_MANAGER::wait_for_stop(void) { int ret = kvu_pthread_timed_wait(&stop_mutex_rep, &stop_cond_rep, 5); ECA_LOG_MSG(ECA_LOGGER::info, kvu_pthread_timed_wait_result(ret, "(audioio_jack_manager) wait_for_stop")); } ecasound-2.9.1/libecasound/plugins/Makefile.in0000644000076400007640000005525112261511325016301 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/libecasound/plugins/Makefile.am # Description: Audio I/O implementations that depend on external # libraries # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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 = libecasound/plugins DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libecasound_plugins_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__libecasound_plugins_la_SOURCES_DIST = audioio_dummy.cpp \ audioio_af.cpp audioio_alsa.cpp audioio_alsa_named.cpp \ audioio_arts.cpp audioio_jack.cpp audioio_jack_manager.cpp \ audioio_sndfile.cpp am__objects_1 = audioio_af.lo @ECA_AM_COMPILE_AUDIOFILE_TRUE@am__objects_2 = $(am__objects_1) am__objects_3 = audioio_alsa.lo audioio_alsa_named.lo @ECA_AM_COMPILE_ALSA_TRUE@am__objects_4 = $(am__objects_3) am__objects_5 = audioio_arts.lo @ECA_AM_COMPILE_ARTS_TRUE@am__objects_6 = $(am__objects_5) am__objects_7 = audioio_jack.lo audioio_jack_manager.lo @ECA_AM_COMPILE_JACK_TRUE@am__objects_8 = $(am__objects_7) am__objects_9 = audioio_sndfile.lo @ECA_AM_COMPILE_SNDFILE_TRUE@am__objects_10 = $(am__objects_9) am__objects_11 = $(am__objects_2) $(am__objects_4) $(am__objects_6) \ $(am__objects_8) $(am__objects_10) am_libecasound_plugins_la_OBJECTS = audioio_dummy.lo $(am__objects_11) libecasound_plugins_la_OBJECTS = $(am_libecasound_plugins_la_OBJECTS) @ECA_AM_DEBUG_MODE_FALSE@am_libecasound_plugins_la_rpath = am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libecasound_plugins_debug_la_DEPENDENCIES = $(am__DEPENDENCIES_2) am__libecasound_plugins_debug_la_SOURCES_DIST = audioio_dummy.cpp \ audioio_af.cpp audioio_alsa.cpp audioio_alsa_named.cpp \ audioio_arts.cpp audioio_jack.cpp audioio_jack_manager.cpp \ audioio_sndfile.cpp am__objects_13 = audioio_dummy.lo $(am__objects_11) am_libecasound_plugins_debug_la_OBJECTS = $(am__objects_13) libecasound_plugins_debug_la_OBJECTS = \ $(am_libecasound_plugins_debug_la_OBJECTS) @ECA_AM_DEBUG_MODE_TRUE@am_libecasound_plugins_debug_la_rpath = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libecasound_plugins_la_SOURCES) \ $(EXTRA_libecasound_plugins_la_SOURCES) \ $(libecasound_plugins_debug_la_SOURCES) \ $(EXTRA_libecasound_plugins_debug_la_SOURCES) DIST_SOURCES = $(am__libecasound_plugins_la_SOURCES_DIST) \ $(EXTRA_libecasound_plugins_la_SOURCES) \ $(am__libecasound_plugins_debug_la_SOURCES_DIST) \ $(EXTRA_libecasound_plugins_debug_la_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign # ---------------------------------------------------------------------- # defines # ---------------------------------------------------------------------- #common_clags = -DECA_ENABLE_AUDIOIO_PLUGINS all_arts_src = audioio_arts.cpp @ECA_AM_COMPILE_ARTS_TRUE@arts_src = $(all_arts_src) @ECA_AM_COMPILE_ARTS_FALSE@arts_target = @ECA_AM_COMPILE_ARTS_TRUE@arts_target = libaudioio_arts.la all_alsa_src = audioio_alsa.cpp audioio_alsa_named.cpp @ECA_AM_COMPILE_ALSA_TRUE@alsa_src = $(all_alsa_src) @ECA_AM_COMPILE_ALSA_FALSE@alsa_target = @ECA_AM_COMPILE_ALSA_TRUE@alsa_target = libaudioio_alsa.la \ @ECA_AM_COMPILE_ALSA_TRUE@ libaudioio_alsa_named.la all_af_src = audioio_af.cpp @ECA_AM_COMPILE_AUDIOFILE_TRUE@af_src = $(all_af_src) @ECA_AM_COMPILE_AUDIOFILE_FALSE@af_target = @ECA_AM_COMPILE_AUDIOFILE_TRUE@af_target = libaudioio_af.la all_sndfile_src = audioio_sndfile.cpp @ECA_AM_COMPILE_SNDFILE_TRUE@sndfile_src = $(all_sndfile_src) @ECA_AM_COMPILE_SNDFILE_FALSE@sndfile_target = @ECA_AM_COMPILE_SNDFILE_TRUE@sndfile_target = libaudioio_sndfile.la all_jack_src = audioio_jack.cpp audioio_jack_manager.cpp @ECA_AM_COMPILE_JACK_TRUE@jack_src = $(all_jack_src) @ECA_AM_COMPILE_JACK_FALSE@jack_target = @ECA_AM_COMPILE_JACK_TRUE@jack_target = libaudioio_jack.la INCLUDES = -I$(srcdir) \ -I$(top_srcdir) \ -I$(top_srcdir)/libecasound \ -I$(top_srcdir)/kvutils \ $(ECA_S_EXTRA_CPPFLAGS) #libdir = $(exec_prefix)/lib/libecasound@LIBECASOUND_VERSION@-plugins # ---------------------------------------------------------------------- # header files # ---------------------------------------------------------------------- plugin_includes = \ audioio_af.h \ audioio_alsa.h \ audioio_alsa_named.h \ audioio_arts.h \ audioio_jack.h \ audioio_jack_manager.h \ audioio_sndfile.h noinst_HEADERS = $(plugin_includes) @ECA_AM_DEBUG_MODE_FALSE@noinst_LTLIBRARIES = libecasound_plugins.la # ---------------------------------------------------------------------- # build targets and compiler options target defines # ---------------------------------------------------------------------- @ECA_AM_DEBUG_MODE_TRUE@noinst_LTLIBRARIES = libecasound_plugins_debug.la plugin_cond_sources = $(af_src) \ $(alsa_src) \ $(arts_src) \ $(jack_src) \ $(sndfile_src) plugin_all_sources = $(all_af_src) \ $(all_alsa_src) \ $(all_arts_src) \ $(all_jack_src) \ $(all_sndfile_src) # ---------------------------------------------------------------------- # source files # ---------------------------------------------------------------------- libecasound_plugins_la_SOURCES = audioio_dummy.cpp $(plugin_cond_sources) EXTRA_libecasound_plugins_la_SOURCES = $(plugin_all_sources) libecasound_plugins_la_LIBADD = $(ECA_S_EXTRA_LIBS) libecasound_plugins_la_LDFLAGS = -static libecasound_plugins_debug_la_SOURCES = $(libecasound_plugins_la_SOURCES) EXTRA_libecasound_plugins_debug_la_SOURCES = $(EXTRA_libecasound_plugins_la_SOURCES) libecasound_plugins_debug_la_LIBADD = $(libecasound_plugins_la_LIBADD) libecasound_plugins_debug_la_LDFLAGS = $(libecasound_plugins_la_LDFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libecasound/plugins/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign libecasound/plugins/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_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 libecasound_plugins.la: $(libecasound_plugins_la_OBJECTS) $(libecasound_plugins_la_DEPENDENCIES) $(CXXLINK) $(am_libecasound_plugins_la_rpath) $(libecasound_plugins_la_LDFLAGS) $(libecasound_plugins_la_OBJECTS) $(libecasound_plugins_la_LIBADD) $(LIBS) libecasound_plugins_debug.la: $(libecasound_plugins_debug_la_OBJECTS) $(libecasound_plugins_debug_la_DEPENDENCIES) $(CXXLINK) $(am_libecasound_plugins_debug_la_rpath) $(libecasound_plugins_debug_la_LDFLAGS) $(libecasound_plugins_debug_la_OBJECTS) $(libecasound_plugins_debug_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_af.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_alsa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_alsa_named.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_arts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_dummy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_jack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_jack_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audioio_sndfile.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: 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; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: 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) 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-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: 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-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES 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-exec \ install-exec-am install-info install-info-am install-man \ 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-info-am # ---------------------------------------------------------------------- # separate rules for compiling non-libtool plugins # ---------------------------------------------------------------------- # 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: ecasound-2.9.1/libecasound/plugins/audioio_dummy.cpp0000644000076400007640000000174610664032032017602 00000000000000// ------------------------------------------------------------------------ // audioio_dummy.cpp: Place-holder for libecasound_plugins. // Copyright (C) 2002,2007 Kai Vehmanen // 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 // ------------------------------------------------------------------------ int audioio_dummy_integer = 0; ecasound-2.9.1/libecasound/plugins/audioio_jack.cpp0000644000076400007640000002252611742532454017371 00000000000000// ------------------------------------------------------------------------ // audioio-jack.cpp: Interface to JACK audio framework // Copyright (C) 2001-2003,2008,2009,2011,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "audioio.h" #include "eca-version.h" #include "eca-logger.h" #include "samplebuffer.h" #include "audioio_jack.h" #include "audioio_jack_manager.h" #ifdef ECA_ENABLE_AUDIOIO_PLUGINS /* see eca-static-object-maps.cpp */ static const char* audio_io_keyword_const = "jack"; static const char* audio_io_keyword_regex_const = "(^jack$)|(^jack_alsa$)|(^jack_auto$)|(^jack_generic$)"; AUDIO_IO* audio_io_descriptor(void) { return new AUDIO_IO_JACK(); } const char* audio_io_keyword(void) {return audio_io_keyword_const; } const char* audio_io_keyword_regex(void){return audio_io_keyword_regex_const; } int audio_io_interface_version(void) { return ecasound_library_version_current; } #endif AUDIO_IO_JACK::AUDIO_IO_JACK (void) : jackmgr_rep(0), myid_rep(0), error_flag_rep(false) { ECA_LOG_MSG(ECA_LOGGER::functions, "constructor"); } AUDIO_IO_JACK::~AUDIO_IO_JACK(void) { if (is_open() == true && is_running()) stop(); if (is_open() == true) { close(); } } AUDIO_IO_MANAGER* AUDIO_IO_JACK::create_object_manager(void) const { return new AUDIO_IO_JACK_MANAGER(); } void AUDIO_IO_JACK::set_manager(AUDIO_IO_JACK_MANAGER* mgr, int id) { string mgrname = (mgr != 0 ? mgr->name() : "null"); ECA_LOG_MSG(ECA_LOGGER::system_objects, "setting manager to " + mgrname); jackmgr_rep = mgr; myid_rep = id; } void AUDIO_IO_JACK::open(void) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "open"); #ifdef WORDS_BIGENDIAN set_sample_format(ECA_AUDIO_FORMAT::sfmt_f32_be); #else set_sample_format(ECA_AUDIO_FORMAT::sfmt_f32_le); #endif toggle_interleaved_channels(false); if (jackmgr_rep != 0) { string my_in_portname ("in"), my_out_portname ("out"); if (label() == "jack" && params_rep.size() > 2 && params_rep[2].size() > 0) { my_in_portname = my_out_portname = params_rep[2]; } /* note: deprecated interface */ else if (label() == "jack_generic" && params_rep.size() > 1) { my_in_portname = my_out_portname = params_rep[1]; } jackmgr_rep->open(myid_rep); if (jackmgr_rep->is_open() != true) { /* unable to open connection to jackd, exit */ throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-JACK: Unable to open JACK-client")); } if (samples_per_second() != jackmgr_rep->samples_per_second()) { set_samples_per_second(jackmgr_rep->samples_per_second()); ECA_LOG_MSG(ECA_LOGGER::system_objects, "Note! Locking to jackd samplerate " + kvu_numtostr(samples_per_second())); } if (buffersize() != jackmgr_rep->buffersize()) { long int jackd_bsize = jackmgr_rep->buffersize(); jackmgr_rep->close(myid_rep); throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-JACK: Cannot connect open connection! Buffersize " + kvu_numtostr(buffersize()) + " differs from JACK server's buffersize of " + kvu_numtostr(jackd_bsize) + ".")); } /* - check whether channel count needs to be adjusted * (must be done before registering to manager) */ if (label() == "jack_multi") { /* if user has enumerated N JACK ports to connect to, make the ecasound * visible channel count at least N */ int jack_ports = static_cast(params_rep.size() - 1); if (channels() < jack_ports) set_channels(jack_ports); } if (io_mode() == AUDIO_IO::io_read) { jackmgr_rep->register_jack_ports(myid_rep, channels(), my_in_portname); } else { jackmgr_rep->register_jack_ports(myid_rep, channels(), my_out_portname); } /* - make automatic connections */ if (label() == "jack" && params_rep.size() > 1 && params_rep[1].size() > 0) { /* note: if 2nd param given, use it as the client to autoconnect to */ jackmgr_rep->auto_connect_jack_port_client(myid_rep, params_rep[1], channels()); } else if (label() == "jack_multi") { int i; for(i = 0; i < channels(); i++) { if (static_cast(params_rep.size()) > i + 1 && params_rep[i + 1].size() > 0) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "adding auto connection from " + my_out_portname + "_" + kvu_numtostr(i + 1) + " to " + params_rep[i + 1]); jackmgr_rep->auto_connect_jack_port(myid_rep, i + 1, params_rep[i + 1]); } } } else if (label() == "jack_alsa") { /* note: deprecated feature: 'alsa_pcm' is hidden in the port list returned by jack_get_ports(), but as you can still connect with the direct backend names, we have to keep this code around to be backward compatible */ string in_aconn_portprefix, out_aconn_portprefix; in_aconn_portprefix = "alsa_pcm:capture_"; out_aconn_portprefix = "alsa_pcm:playback_"; for(int n = 0; n < channels(); n++) { if (io_mode() == AUDIO_IO::io_read) { jackmgr_rep->auto_connect_jack_port(myid_rep, n + 1, in_aconn_portprefix + kvu_numtostr(n + 1)); } else { jackmgr_rep->auto_connect_jack_port(myid_rep, n + 1, out_aconn_portprefix + kvu_numtostr(n + 1)); } } } /* note: deprecated interface, plain "jack" should be used now */ else if (label() == "jack_auto" && params_rep.size() > 1 && params_rep[1].size() > 0) { jackmgr_rep->auto_connect_jack_port_client(myid_rep, params_rep[1], channels()); } } AUDIO_IO_DEVICE::open(); } void AUDIO_IO_JACK::close(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "close"); if (jackmgr_rep != 0) { jackmgr_rep->unregister_jack_ports(myid_rep); jackmgr_rep->close(myid_rep); } AUDIO_IO_DEVICE::close(); } bool AUDIO_IO_JACK::finished(void) const { if (is_open() != true || jackmgr_rep == 0 || jackmgr_rep->is_open() != true || error_flag_rep == true) return true; return false; } long int AUDIO_IO_JACK::read_samples(void* target_buffer, long int samples) { if (jackmgr_rep != 0) { DBC_CHECK(samples == jackmgr_rep->buffersize()); long int res = jackmgr_rep->read_samples(myid_rep, target_buffer, samples); return res; } return 0; } void AUDIO_IO_JACK::write_buffer(SAMPLE_BUFFER* sbuf) { /* note: this is reimplemented only to catch errors with unsupported * input streams (e.g. one produces by 'resample' object' */ if (sbuf->length_in_samples() > 0 && sbuf->length_in_samples() != jackmgr_rep->buffersize() && sbuf->event_tag_test(SAMPLE_BUFFER::tag_end_of_stream) != true) { error_flag_rep = true; ECA_LOG_MSG(ECA_LOGGER::errors, "ERROR: Variable size input buffers detected at JACK output, stopping processing. " "This can happen e.g. with a 'resample' input object."); } AUDIO_IO_DEVICE::write_buffer(sbuf); } void AUDIO_IO_JACK::write_samples(void* target_buffer, long int samples) { DBC_CHECK(samples <= jackmgr_rep->buffersize()); if (jackmgr_rep != 0) { jackmgr_rep->write_samples(myid_rep, target_buffer, samples); } } void AUDIO_IO_JACK::prepare(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "prepare / " + label()); error_flag_rep = false; AUDIO_IO_DEVICE::prepare(); } void AUDIO_IO_JACK::start(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "start / " + label()); AUDIO_IO_DEVICE::start(); } void AUDIO_IO_JACK::stop(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "stop / " + label()); AUDIO_IO_DEVICE::stop(); } long int AUDIO_IO_JACK::latency(void) const { return jackmgr_rep == 0 ? 0 : jackmgr_rep->client_latency(myid_rep); } std::string AUDIO_IO_JACK::parameter_names(void) const { if (label() == "jack_generic") return "label,portname"; else if (label() == "jack_auto") return "label,client"; else if (label() == "jack_multi") { string paramlist = "label"; int i; for(i = 0; i < channels(); i++) { paramlist += ",dstport" + kvu_numtostr(i + 1); } return paramlist; } /* jack */ return "jack,client,portprefix"; } void AUDIO_IO_JACK::set_parameter(int param, std::string value) { if (param > static_cast(params_rep.size())) params_rep.resize(param); params_rep[param - 1] = value; if (param == 1) { set_label(value); } } std::string AUDIO_IO_JACK::get_parameter(int param) const { if (param > 0 && param <= static_cast(params_rep.size())) return params_rep[param - 1]; return AUDIO_IO::get_parameter(param); } ecasound-2.9.1/libecasound/plugins/audioio_sndfile.h0000644000076400007640000000523111747220202017532 00000000000000#ifndef INCLUDED_AUDIOIO_SNDFILE_H #define INCLUDED_AUDIOIO_SNDFILE_H #include #include #include #include "samplebuffer.h" #include "audioio-buffered.h" #include "samplebuffer.h" #ifdef HAVE_CONFIG_H #include #endif /** * Interface to libsndfile library. * @author Kai Vehmanen */ class SNDFILE_INTERFACE : public AUDIO_IO_BUFFERED { public: /** @name Public functions */ /*@{*/ SNDFILE_INTERFACE (const string& name = ""); ~SNDFILE_INTERFACE(void); /*@}*/ /** @name Reimplemented functions from ECA_OBJECT */ /*@{*/ virtual string name(void) const { return "Libsndfile object"; } virtual string description(void) const { return "Libsndfile object. Supports all commona audio formats."; } /*@}*/ /** @name Reimplemented functions from DYNAMIC_PARAMETERS */ /*@{*/ virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; /*@}*/ /** @name Reimplemented functions from DYNAMIC_OBJECT */ /*@{*/ SNDFILE_INTERFACE* clone(void) const; SNDFILE_INTERFACE* new_expr(void) const { return new SNDFILE_INTERFACE(); } /*@}*/ /** @name Reimplemented functions from ECA_AUDIO_POSITION */ /*@{*/ virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); /*@}*/ /** @name Functions reimplemented from AUDIO_IO_BUFFERED */ /*@{*/ virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); /*@}*/ /** @name Functions reimplemented from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return io_read | io_write | io_readwrite; } virtual bool supports_seeking(void) const { return seek_supported_rep; } virtual string parameter_names(void) const { return "filename,opt_filename,format"; } virtual bool locked_audio_format(void) const { return true; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual bool finished(void) const; /*@}*/ /** @name Non-virtual functions */ /*@{*/ std::list supported_extensions(void) const; /*@}*/ private: std::string opt_filename_rep; std::string opt_format_rep; SNDFILE* snd_repp; long samples_read; bool finished_rep; bool closing_rep; bool seek_supported_rep; void open_parse_info(const SF_INFO* sfinfo) throw(AUDIO_IO::SETUP_ERROR&); int find_file_format(const std::string& filename); SNDFILE_INTERFACE& operator=(const SNDFILE_INTERFACE& x) { return *this; } }; #endif ecasound-2.9.1/libecasound/plugins/audioio_alsa.h0000644000076400007640000000642411560062544017041 00000000000000#ifndef INCLUDED_AUDIO_IO_ALSA_PCM_H #define INCLUDED_AUDIO_IO_ALSA_PCM_H #include #include #include #include #include #include #include #include "sample-specs.h" #include "samplebuffer.h" #include "audioio-device.h" #include using namespace std; /** * Class for handling ALSA pcm-devices (Advanced Linux Sound Architecture). */ class AUDIO_IO_ALSA_PCM : public AUDIO_IO_DEVICE { public: AUDIO_IO_ALSA_PCM (int card = 0, int device = 0, int subdevice = -1); virtual ~AUDIO_IO_ALSA_PCM(void); AUDIO_IO_ALSA_PCM* clone(void) const; AUDIO_IO_ALSA_PCM* new_expr(void) const { return new AUDIO_IO_ALSA_PCM(); } virtual string name(void) const { return("ALSA PCM device"); } virtual string description(void) const { return("ALSA PCM devices. Alsa-lib versions 0.9.0 and newer."); } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; /** @name Function reimplemented from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return(io_read | io_write); } virtual string parameter_names(void) const { return("label,card,device,subdevice"); } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); /*@}*/ /** @name Function reimplemented from AUDIO_IO_DEVICE */ /*@{*/ virtual void prepare(void); virtual void start(void); virtual void stop(bool drain = false); virtual long int delay(void) const; virtual long int latency(void) const { return(buffersize()); } virtual long int prefill_space(void) const { if (io_mode() != io_read) return(buffer_size_rep); else return(0); } /*@}*/ private: void open_device(void); void allocate_structs(void); void deallocate_structs(void); void set_audio_format_params(void); void fill_and_set_hw_params(void); void fill_and_set_sw_params(void); void print_pcm_info(void); void handle_xrun_capture(void); void handle_xrun_playback(void); private: snd_pcm_t *audio_fd_repp; snd_pcm_stream_t pcm_stream_rep; snd_pcm_format_t format_rep; snd_pcm_hw_params_t* pcm_hw_params_repp; snd_pcm_sw_params_t* pcm_sw_params_repp; snd_pcm_uframes_t period_size_rep; /**< current period size return by alsa-lib */ snd_pcm_uframes_t buffer_size_rep; /**< current buffer size return by alsa-lib */ int card_number_rep, device_number_rep, subdevice_number_rep; long underruns_rep, overruns_rep; unsigned char **nbufs_repp; string pcm_device_name_rep; static const string default_pcm_device_rep; bool using_plugin_rep; bool trigger_request_rep; protected: void set_pcm_device_name(const string& n); const string& pcm_device_name(void) const { return(pcm_device_name_rep); } private: AUDIO_IO_ALSA_PCM (const AUDIO_IO_ALSA_PCM& x) { } AUDIO_IO_ALSA_PCM& operator=(const AUDIO_IO_ALSA_PCM& x) { return *this; } }; #ifdef ECA_ENABLE_AUDIOIO_PLUGINS extern "C" { AUDIO_IO* audio_io_descriptor(void); int audio_io_interface_version(void); const char* audio_io_keyword(void); const char* audio_io_keyword_regex(void); }; #endif #endif /* INCLUDED_AUDIO_IO_ALSA_PCM_H */ ecasound-2.9.1/libecasound/plugins/audioio_arts.cpp0000644000076400007640000000715610664032032017421 00000000000000// ------------------------------------------------------------------------ // audioio-arts.cpp: Interface for communicating with aRts/MCOP. // Copyright (C) 2000,2002 Kai Vehmanen // // 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 "audioio-device.h" #include "eca-logger.h" #include "eca-version.h" extern "C" { #include } #include "audioio_arts.h" #ifdef ECA_ENABLE_AUDIOIO_PLUGINS static const char* audio_io_keyword_const = "arts"; static const char* audio_io_keyword_regex_const = "^arts$"; const char* audio_io_keyword(void){return(audio_io_keyword_const); } const char* audio_io_keyword_regex(void){return(audio_io_keyword_regex_const); } int audio_io_interface_version(void) { return(ecasound_library_version_current); } #endif int ARTS_INTERFACE::ref_rep = 0; ARTS_INTERFACE::ARTS_INTERFACE(const string& name) { set_label(name); } ARTS_INTERFACE::~ARTS_INTERFACE(void) { if (is_open() == true && is_running()) stop(); if (is_open() == true) { close(); } --ref_rep; if (ref_rep == 0) ::arts_free(); } ARTS_INTERFACE* ARTS_INTERFACE::clone(void) const { ARTS_INTERFACE* target = new ARTS_INTERFACE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return(target); } void ARTS_INTERFACE::open(void) throw(AUDIO_IO::SETUP_ERROR&) { if (ref_rep == 0) { int err = ::arts_init(); if (err < 0) { throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ARTS: unable to connect to aRts server: " + string(arts_error_text(err)))); } } ++ref_rep; if (io_mode() == io_read) { stream_rep = ::arts_record_stream(samples_per_second(), bits(), channels(), "ecasound-input"); } else if (io_mode() == io_write) { stream_rep = ::arts_play_stream(samples_per_second(), bits(), channels(), "ecasound-output"); } else { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-ARTS: Simultanious input/output not supported.")); } ::arts_stream_set(stream_rep, ARTS_P_BUFFER_SIZE, buffersize() * frame_size()); ::arts_stream_set(stream_rep, ARTS_P_BLOCKING, 1); samples_rep = 0; double total_latency = ::arts_stream_get(stream_rep, ARTS_P_TOTAL_LATENCY); latency_rep = static_cast(total_latency * samples_per_second() / 1000.0f); AUDIO_IO::open(); } void ARTS_INTERFACE::stop(void) { AUDIO_IO_DEVICE::stop(); } void ARTS_INTERFACE::close(void) { ::arts_close_stream(stream_rep); AUDIO_IO::close(); } void ARTS_INTERFACE::start(void) { AUDIO_IO_DEVICE::start(); } long int ARTS_INTERFACE::read_samples(void* target_buffer, long int samples) { long int res = ::arts_read(stream_rep, target_buffer, frame_size() * samples); if (res >= 0) { return(res / frame_size()); } else { return(0); } } void ARTS_INTERFACE::write_samples(void* target_buffer, long int samples) { ::arts_write(stream_rep, target_buffer, frame_size() * samples); } ecasound-2.9.1/libecasound/plugins/Makefile.am0000644000076400007640000000657310664032032016271 00000000000000# ---------------------------------------------------------------------- # File: ecasound/libecasound/plugins/Makefile.am # Description: Audio I/O implementations that depend on external # libraries # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- AUTOMAKE_OPTIONS = foreign # ---------------------------------------------------------------------- # defines # ---------------------------------------------------------------------- #common_clags = -DECA_ENABLE_AUDIOIO_PLUGINS all_arts_src = audioio_arts.cpp if ECA_AM_COMPILE_ARTS arts_src = $(all_arts_src) arts_target = libaudioio_arts.la else arts_target = endif all_alsa_src = audioio_alsa.cpp audioio_alsa_named.cpp if ECA_AM_COMPILE_ALSA alsa_src = $(all_alsa_src) alsa_target = libaudioio_alsa.la \ libaudioio_alsa_named.la else alsa_target = endif all_af_src = audioio_af.cpp if ECA_AM_COMPILE_AUDIOFILE af_src = $(all_af_src) af_target = libaudioio_af.la else af_target = endif all_sndfile_src = audioio_sndfile.cpp if ECA_AM_COMPILE_SNDFILE sndfile_src = $(all_sndfile_src) sndfile_target = libaudioio_sndfile.la else sndfile_target = endif all_jack_src = audioio_jack.cpp audioio_jack_manager.cpp if ECA_AM_COMPILE_JACK jack_src = $(all_jack_src) jack_target = libaudioio_jack.la else jack_target = endif INCLUDES = -I$(srcdir) \ -I$(top_srcdir) \ -I$(top_srcdir)/libecasound \ -I$(top_srcdir)/kvutils \ $(ECA_S_EXTRA_CPPFLAGS) #libdir = $(exec_prefix)/lib/libecasound@LIBECASOUND_VERSION@-plugins # ---------------------------------------------------------------------- # header files # ---------------------------------------------------------------------- plugin_includes = \ audioio_af.h \ audioio_alsa.h \ audioio_alsa_named.h \ audioio_arts.h \ audioio_jack.h \ audioio_jack_manager.h \ audioio_sndfile.h noinst_HEADERS = $(plugin_includes) # ---------------------------------------------------------------------- # build targets and compiler options target defines # ---------------------------------------------------------------------- if ECA_AM_DEBUG_MODE noinst_LTLIBRARIES = libecasound_plugins_debug.la else noinst_LTLIBRARIES = libecasound_plugins.la endif plugin_cond_sources = $(af_src) \ $(alsa_src) \ $(arts_src) \ $(jack_src) \ $(sndfile_src) plugin_all_sources = $(all_af_src) \ $(all_alsa_src) \ $(all_arts_src) \ $(all_jack_src) \ $(all_sndfile_src) # ---------------------------------------------------------------------- # source files # ---------------------------------------------------------------------- libecasound_plugins_la_SOURCES = audioio_dummy.cpp $(plugin_cond_sources) EXTRA_libecasound_plugins_la_SOURCES = $(plugin_all_sources) libecasound_plugins_la_LIBADD = $(ECA_S_EXTRA_LIBS) libecasound_plugins_la_LDFLAGS = -static libecasound_plugins_debug_la_SOURCES = $(libecasound_plugins_la_SOURCES) EXTRA_libecasound_plugins_debug_la_SOURCES = $(EXTRA_libecasound_plugins_la_SOURCES) libecasound_plugins_debug_la_LIBADD = $(libecasound_plugins_la_LIBADD) libecasound_plugins_debug_la_LDFLAGS = $(libecasound_plugins_la_LDFLAGS) # ---------------------------------------------------------------------- # separate rules for compiling non-libtool plugins # ---------------------------------------------------------------------- ecasound-2.9.1/libecasound/plugins/audioio_af.cpp0000644000076400007640000002063411141326077017040 00000000000000// ------------------------------------------------------------------------ // audioio-af.cpp: Interface to SGI audiofile library. // Copyright (C) 1999-2001,2004,2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // References: // http://www.68k.org/~michael/audiofile/ // // 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 #include #include #include #include #include #include #include #include #include #include "audioio_af.h" #include "samplebuffer.h" #include "eca-version.h" #include "eca-error.h" #include "eca-logger.h" #ifdef ECA_ENABLE_AUDIOIO_PLUGINS static const char* audio_io_keyword_const = "audiofile_aiff_au_snd"; static const char* audio_io_keyword_regex_const = "(aif*$)|(au$)|(snd$)"; const char* audio_io_keyword(void){return audio_io_keyword_const; } const char* audio_io_keyword_regex(void){return audio_io_keyword_regex_const; } int audio_io_interface_version(void) { return ecasound_library_version_current; } #endif using namespace std; AUDIOFILE_INTERFACE::AUDIOFILE_INTERFACE (const string& name) { finished_rep = false; set_label(name); } AUDIOFILE_INTERFACE::~AUDIOFILE_INTERFACE(void) { if (is_open() == true) { close(); } } AUDIOFILE_INTERFACE* AUDIOFILE_INTERFACE::clone(void) const { AUDIOFILE_INTERFACE* target = new AUDIOFILE_INTERFACE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIOFILE_INTERFACE::open(void) throw(AUDIO_IO::SETUP_ERROR&) { string real_filename = label(); if (real_filename == "audiofile") { real_filename = opt_filename_rep; } switch(io_mode()) { case io_read: { ECA_LOG_MSG(ECA_LOGGER::info, "Using audiofile library to open file \"" + real_filename + "\" for reading."); afhandle = ::afOpenFile(real_filename.c_str(), "r", NULL); if (afhandle == AF_NULL_FILEHANDLE) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-AF: Can't open file \"" + real_filename + "\" using libaudiofile.")); } else { set_samples_per_second((long int)::afGetRate(afhandle, AF_DEFAULT_TRACK)); set_channels(::afGetChannels(afhandle, AF_DEFAULT_TRACK)); int sample_format, sample_width; ::afGetSampleFormat(afhandle, AF_DEFAULT_TRACK, &sample_format, &sample_width); string format; switch(sample_format) { case AF_SAMPFMT_TWOSCOMP: { format = "s"; break; } case AF_SAMPFMT_UNSIGNED: { format = "u"; break; } case AF_SAMPFMT_FLOAT: { format = "f"; break; } case AF_SAMPFMT_DOUBLE: { format = "f"; break; } } format += kvu_numtostr(sample_width); // if (afGetByteOrder(afhandle, AF_DEFAULT_TRACK) == AF_BYTEORDER_BIGENDIAN) // format += "_be"; // else // format += "_le"; set_sample_format_string(format); set_length_in_samples(::afGetFrameCount(afhandle, AF_DEFAULT_TRACK)); } break; } case io_write: { ECA_LOG_MSG(ECA_LOGGER::info, "Using audiofile library to open file \"" + real_filename + "\" for writing."); AFfilesetup fsetup; fsetup = afNewFileSetup(); int file_format = -1; string teksti = real_filename; kvu_to_lowercase(teksti); if (strstr(teksti.c_str(),".aiffc") != 0) { file_format = AF_FILE_AIFFC; } else if (strstr(teksti.c_str(),".aifc") != 0) { file_format = AF_FILE_AIFFC; } else if (strstr(teksti.c_str(),".aiff") != 0) { file_format = AF_FILE_AIFF; } else if (strstr(teksti.c_str(),".aif") != 0) { file_format = AF_FILE_AIFF; } else if (strstr(teksti.c_str(),".au") != 0) { file_format = AF_FILE_NEXTSND; } else if (strstr(teksti.c_str(),".snd") != 0) { file_format = AF_FILE_NEXTSND; } else if (strstr(teksti.c_str(),".wav") != 0) { file_format = AF_FILE_WAVE; } else if (strstr(teksti.c_str(),".avr") != 0) { file_format = AF_FILE_AVR; } else { ECA_LOG_MSG(ECA_LOGGER::info, "Warning! Unknown audio format, using raw format instead."); file_format = AF_FILE_RAWDATA; } ::afInitFileFormat(fsetup, file_format); ::afInitChannels(fsetup, AF_DEFAULT_TRACK, channels()); if (format_string()[0] == 'u') ::afInitSampleFormat(fsetup, AF_DEFAULT_TRACK, AF_SAMPFMT_UNSIGNED, bits()); else if (format_string()[0] == 's') ::afInitSampleFormat(fsetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, bits()); else if (format_string()[0] == 'f') { if (bits() == 32) ::afInitSampleFormat(fsetup, AF_DEFAULT_TRACK, AF_SAMPFMT_FLOAT, bits()); else ::afInitSampleFormat(fsetup, AF_DEFAULT_TRACK, AF_SAMPFMT_DOUBLE, bits()); } ::afInitRate(fsetup, AF_DEFAULT_TRACK, static_cast(samples_per_second())); afhandle = ::afOpenFile(real_filename.c_str(), "w", fsetup); if (afhandle == AF_NULL_FILEHANDLE) throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-AF: Can't open file \"" + real_filename + "\" using libaudiofile.")); /* note: as seeking is not supported for outputs, we also reset * position to 0 at open() */ set_position_in_samples(0); break; } case io_readwrite: { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-AF: Simultaneous intput/ouput not supported.")); } } // -- // Get byteorder // -- // if (SAMPLE_BUFFER::is_system_littleendian) // afSetVirtualByteOrder(afhandle, AF_DEFAULT_TRACK, AF_BYTEORDER_LITTLEENDIAN); // else // afSetVirtualByteOrder(afhandle, AF_DEFAULT_TRACK, AF_BYTEORDER_BIGENDIAN); debug_print_type(); AUDIO_IO::open(); } void AUDIOFILE_INTERFACE::close(void) { AUDIO_IO::close(); ::afCloseFile(afhandle); } void AUDIOFILE_INTERFACE::debug_print_type(void) { int temp = ::afGetFileFormat(afhandle, 0); ECA_LOG_MSG(ECA_LOGGER::user_objects, "afFileformat: " + kvu_numtostr(temp) + "."); } bool AUDIOFILE_INTERFACE::finished(void) const { if (finished_rep == true || (io_mode() == io_read && out_position())) return true; return false; } long int AUDIOFILE_INTERFACE::read_samples(void* target_buffer, long int samples) { samples_read = ::afReadFrames(afhandle, AF_DEFAULT_TRACK, target_buffer, samples); finished_rep = (samples_read < samples) ? true : false; return samples_read; } void AUDIOFILE_INTERFACE::write_samples(void* target_buffer, long int samples) { ::afWriteFrames(afhandle, AF_DEFAULT_TRACK, target_buffer, samples); } SAMPLE_SPECS::sample_pos_t AUDIOFILE_INTERFACE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { AFframecount res; if (io_mode() == io_read) { finished_rep = false; res = ::afSeekFrame(afhandle, AF_DEFAULT_TRACK, pos); if (res != pos) { ECA_LOG_MSG(ECA_LOGGER::info, "invalid seek for file " + opt_filename_rep + " req was to " + kvu_numtostr(pos) + " result was " + kvu_numtostr(res)); if (res < 0) { res = afTellFrame(afhandle, AF_DEFAULT_TRACK); if (res >= 0) pos = res; else pos = position_in_samples(); } } } else { /* note: seeking is not supported for outputs by * libaudiofile */ if (pos != position_in_samples()) { ECA_LOG_MSG(ECA_LOGGER::errors, "libaudiofile does not support seeking for output files (" + opt_filename_rep + ")"); finished_rep = true; pos = 0; } } return pos; } void AUDIOFILE_INTERFACE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: opt_filename_rep = value; break; } } string AUDIOFILE_INTERFACE::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return opt_filename_rep; } return ""; } ecasound-2.9.1/libecasound/plugins/audioio_arts.h0000644000076400007640000000363610664032032017065 00000000000000#ifndef INCLUDED_AUDIOIO_ARTS_H #define INCLUDED_AUDIOIO_ARTS_H #include #include #include "sample-specs.h" #include "eca-version.h" typedef void *arts_stream_t; /** * Interface for communicating with aRts/MCOP. * @author Kai Vehmanen */ class ARTS_INTERFACE : public AUDIO_IO_DEVICE { public: string name(void) const { return("aRts client"); } string description(void) const { return("aRts client. Audio input and output using aRts server."); } /** @name Function reimplemented from AUDIO_IO */ /*@{*/ virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual int supported_io_modes(void) const { return(io_read | io_write); } virtual bool supports_nonblocking_mode(void) const { return(false); } virtual bool supports_seeking(void) const { return(false); } virtual bool locked_audio_format(void) const { return(false); } /*@}*/ /** @name Function reimplemented from AUDIO_IO_DEVICE */ /*@{*/ virtual void start(void); virtual void stop(void); virtual long int latency(void) const { return(latency_rep); } /*@}*/ ARTS_INTERFACE (const string& name = "arts"); ~ARTS_INTERFACE(void); ARTS_INTERFACE* clone(void) const; ARTS_INTERFACE* new_expr(void) const { return new ARTS_INTERFACE(); } private: ARTS_INTERFACE(const ARTS_INTERFACE& x) { } ARTS_INTERFACE& operator=(const ARTS_INTERFACE& x) { return *this; } arts_stream_t stream_rep; SAMPLE_SPECS::sample_pos_t samples_rep; long int latency_rep; static int ref_rep; }; #ifdef ECA_ENABLE_AUDIOIO_PLUGINS extern "C" { AUDIO_IO* audio_io_descriptor(void) { return(new ARTS_INTERFACE()); } int audio_io_interface_version(void); const char* audio_io_keyword(void); const char* audio_io_keyword_regex(void); }; #endif #endif ecasound-2.9.1/libecasound/plugins/audioio_sndfile.cpp0000644000076400007640000003300111747220073020067 00000000000000// ------------------------------------------------------------------------ // audioio_sndfile.cpp: Interface to the sndfile library. // Copyright (C) 2003-2004,2006-2007,2009,2012 Kai Vehmanen // Copyright (C) 2004 Jesse Chappell // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // References: // http://www.mega-nerd.com/libsndfile/ // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include "audioio_sndfile.h" #include "samplebuffer.h" #include "eca-version.h" #include "eca-error.h" #include "eca-logger.h" #ifdef WORDS_BIGENDIAN static const ECA_AUDIO_FORMAT::Sample_format audioio_sndfile_sfmt = ECA_AUDIO_FORMAT::sfmt_f32_be; #else static const ECA_AUDIO_FORMAT::Sample_format audioio_sndfile_sfmt = ECA_AUDIO_FORMAT::sfmt_f32_le; #endif using namespace std; SNDFILE_INTERFACE::SNDFILE_INTERFACE (const string& name) { finished_rep = false; snd_repp = 0; closing_rep = false; seek_supported_rep = true; set_label(name); } SNDFILE_INTERFACE::~SNDFILE_INTERFACE(void) { if (is_open() == true) { close(); } } SNDFILE_INTERFACE* SNDFILE_INTERFACE::clone(void) const { SNDFILE_INTERFACE* target = new SNDFILE_INTERFACE(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } /** * Parses the information given in 'sfinfo'. */ void SNDFILE_INTERFACE::open_parse_info(const SF_INFO* sfinfo) throw(AUDIO_IO::SETUP_ERROR&) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "audio file format: " + kvu_numtostr(sfinfo->format & SF_FORMAT_SUBMASK)); string format; if (sfinfo->seekable) seek_supported_rep = true; else seek_supported_rep = false; set_samples_per_second(static_cast(sfinfo->samplerate)); set_channels(sfinfo->channels); switch(sfinfo->format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: { format = "s8"; break; } case SF_FORMAT_PCM_U8: { format = "u8"; break; } case SF_FORMAT_PCM_16: { format = "s16"; break; } case SF_FORMAT_PCM_24: { format = "s24"; break; } case SF_FORMAT_PCM_32: { format = "s32"; break; } default: { /* SF_FORMAT_FLOAT */ format = "f32"; break; } } if (sfinfo->format & SF_ENDIAN_LITTLE) format += "_le"; else if (sfinfo->format & SF_ENDIAN_BIG) format += "_be"; set_sample_format_string(format); /* note: we have no way to find out whether frame count of * zero means an empty file, or that that the audio * format does not provide this information, so we * lean towards being cautious; see also finished() */ if (sfinfo->frames > 0) set_length_in_samples(sfinfo->frames); ECA_LOG_MSG(ECA_LOGGER::user_objects, string("file length (frames): ") + kvu_numtostr(sfinfo->frames)); } /** * Returns a list of support file extensions in lower-case. */ std::list SNDFILE_INTERFACE::supported_extensions(void) const { list exts; int i, count; SF_FORMAT_INFO format_info; sf_command (0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)); for (i = 0 ; i < count ; i++) { format_info.format = i; sf_command (0, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; exts.push_back(string(format_info.extension)); } return exts; } /** * Discovers a matching libsndfile file format for the filename * 'fname'. The filename extension is used to find a matching * format. * * @return sndfile major format identifier */ int SNDFILE_INTERFACE::find_file_format(const std::string& fname) { int file_format = -1, i, count; SF_FORMAT_INFO format_info; size_t pos = fname.rfind("."); string fext; if (pos != string::npos) { fext = string(fname, pos + 1); } ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Searching for fileformat matching extension '") + fext + "'."); sf_command (0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)); for (i = 0 ; i < count ; i++) { format_info.format = i; sf_command (0, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; if (fext == string(format_info.extension)) { file_format = format_info.format; ECA_LOG_MSG(ECA_LOGGER::user_objects, string("Found matching file format: ") + format_info.name + " (ext=." + fext + ")"); break; } } if (file_format < 0) { ECA_LOG_MSG(ECA_LOGGER::info, string("Warning! Unknown audio format extension '") + fext + "', using WAV format instead."); file_format = SF_FORMAT_WAV; } return file_format; } void SNDFILE_INTERFACE::open(void) throw(AUDIO_IO::SETUP_ERROR&) { SF_INFO sfinfo; string real_filename = label(); if (real_filename == "sndfile") { real_filename = opt_filename_rep; } string mod_filename = real_filename; if (!opt_format_rep.empty()) { mod_filename = opt_format_rep; } kvu_to_lowercase(mod_filename); // need to treat raw specially for read-only opening bool is_raw = false; if (strstr(mod_filename.c_str(),".raw") != 0) { is_raw = true; } if (io_mode() == io_read && !is_raw) { ECA_LOG_MSG(ECA_LOGGER::info, "Using libsndfile to open file \"" + real_filename + "\" for reading."); snd_repp = sf_open(real_filename.c_str(), SFM_READ, &sfinfo); if (snd_repp == NULL) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-SNDFILE: Can't open file \"" + real_filename + "\" for reading.")); } else { open_parse_info(&sfinfo); } } else { /* write or readwrite */ int file_format = -1; // note: support 1.0.0 formats by default, and others via // SF_FORMAT_GET_MAJOR file_format = find_file_format(mod_filename); if (format_string()[0] == 'u' && bits() == 8) file_format |= SF_FORMAT_PCM_S8; else if (format_string()[0] == 's') { if (bits() == 8) { file_format |= SF_FORMAT_PCM_S8; } else if (bits() == 16) { file_format |= SF_FORMAT_PCM_16; } else if (bits() == 24) { file_format |= SF_FORMAT_PCM_24; } else if (bits() == 32) { file_format |= SF_FORMAT_PCM_32; } else { file_format = 0; } } else if (format_string()[0] == 'f') { if (bits() == 32) { file_format |= SF_FORMAT_FLOAT; } else if (bits() == 64) { file_format |= SF_FORMAT_DOUBLE; } else { file_format = 0; } } else { file_format = 0; } if (file_format == 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-SNDFILE: Error! Unknown audio format requested.")); } // set endianess if (sample_endianess() == se_little) { file_format |= SF_ENDIAN_LITTLE; } else if (sample_endianess() == se_big) { file_format |= SF_ENDIAN_BIG; } /* set samplerate and channels */ sfinfo.samplerate = samples_per_second(); sfinfo.channels = channels(); sfinfo.format = file_format; if (io_mode() == io_write) { ECA_LOG_MSG(ECA_LOGGER::info, "Using libsndfile to open file \"" + real_filename + "\" for writing."); /* open the file */ snd_repp = sf_open(real_filename.c_str(), SFM_WRITE, &sfinfo); if (snd_repp == NULL) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-SNDFILE: Can't open file \"" + real_filename + "\" for writing.")); } } else if (io_mode() == io_read) { ECA_LOG_MSG(ECA_LOGGER::info, "Using libsndfile to open file \"" + real_filename + "\" for reading."); snd_repp = sf_open(real_filename.c_str(), SFM_READ, &sfinfo); if (snd_repp == NULL) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-SNDFILE: Can't open file \"" + real_filename + "\" for reading.")); } else { open_parse_info(&sfinfo); } } else { ECA_LOG_MSG(ECA_LOGGER::info, "Using libsndfile to open file \"" + real_filename + "\" for read/write."); DBC_CHECK(sf_format_check(&sfinfo)); /* io_readwrite */ snd_repp = sf_open(real_filename.c_str(), SFM_RDWR, &sfinfo); if (snd_repp == NULL) { /* if open fails, try with SFM_WRITE (formats like flac are not * supported in RDWR mode */ snd_repp = sf_open(real_filename.c_str(), SFM_WRITE, &sfinfo); if (snd_repp == NULL) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-SNDFILE: Can't open file \"" + real_filename + "\" for updating (read/write).")); } else { set_io_mode(io_write); open_parse_info(&sfinfo); } } else { open_parse_info(&sfinfo); } } } /* we need to reserve extra memory as we using 32bit * floats as the internal sample unit */ reserve_buffer_space((sizeof(float) * channels()) * buffersize()); AUDIO_IO::open(); } void SNDFILE_INTERFACE::close(void) { if (is_open() == true) { DBC_CHECK(closing_rep != true); if (snd_repp != 0 && closing_rep != true) { closing_rep = true; sf_close(snd_repp); snd_repp = 0; } } AUDIO_IO::close(); closing_rep = false; } bool SNDFILE_INTERFACE::finished(void) const { if (finished_rep == true || (length_set() == true && (io_mode() == io_read && out_position()))) return true; return false; } long int SNDFILE_INTERFACE::read_samples(void* target_buffer, long int samples) { // samples_read = sf_read_raw(snd_repp, target_buffer, frame_size() * samples); // samples_read /= frame_size(); samples_read = sf_readf_float(snd_repp, (float*)target_buffer, samples); finished_rep = (samples_read < samples) ? true : false; return samples_read; } void SNDFILE_INTERFACE::write_samples(void* target_buffer, long int samples) { //sf_write_raw(snd_repp, target_buffer, frame_size() * samples); sf_writef_float(snd_repp, (float*)target_buffer, samples); } void SNDFILE_INTERFACE::read_buffer(SAMPLE_BUFFER* sbuf) { // -------- DBC_REQUIRE(get_iobuf() != 0); DBC_REQUIRE(static_cast(get_iobuf_size()) >= buffersize() * frame_size()); // -------- /* note! modified from audioio-buffered.cpp */ DBC_CHECK(interleaved_channels() == true); /* in normal conditions this won't cause memory reallocs */ reserve_buffer_space((sizeof(float) * channels()) * buffersize()); sbuf->import_interleaved(get_iobuf(), read_samples(get_iobuf(), buffersize()), audioio_sndfile_sfmt, channels()); change_position_in_samples(sbuf->length_in_samples()); } void SNDFILE_INTERFACE::write_buffer(SAMPLE_BUFFER* sbuf) { // -------- DBC_REQUIRE(get_iobuf() != 0); DBC_REQUIRE(static_cast(get_iobuf_size()) >= buffersize() * frame_size()); // -------- /* note! modified from audioio-buffered.cpp */ DBC_CHECK(interleaved_channels() == true); /* in normal conditions this won't cause memory reallocs */ reserve_buffer_space((sizeof(float) * channels()) * buffersize()); set_buffersize(sbuf->length_in_samples()); sbuf->export_interleaved(get_iobuf(), audioio_sndfile_sfmt, channels()); write_samples(get_iobuf(), sbuf->length_in_samples()); change_position_in_samples(sbuf->length_in_samples()); extend_position(); } SAMPLE_SPECS::sample_pos_t SNDFILE_INTERFACE::seek_position(SAMPLE_SPECS::sample_pos_t pos) { finished_rep = false; sf_count_t res = sf_seek(snd_repp, pos, SEEK_SET); if (res != pos && length_set() == true && io_mode() == io_read && pos >= length_in_samples()) { pos = sf_seek(snd_repp, 0, SEEK_END); } else if (res != pos) { ECA_LOG_MSG(ECA_LOGGER::info, "invalid seek for file " + opt_filename_rep + ", req was to " + kvu_numtostr(pos) + ", result was " + kvu_numtostr(res)); if (res < 0) { res = sf_seek(snd_repp, 0, SEEK_CUR); DBC_CHECK(res >= 0); if (res >= 0) pos = res; else pos = position_in_samples(); } } return pos; } void SNDFILE_INTERFACE::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: opt_filename_rep = value; break; case 3: opt_format_rep = value; break; } } string SNDFILE_INTERFACE::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return opt_filename_rep; case 3: return opt_format_rep; } return ""; } ecasound-2.9.1/libecasound/plugins/audioio_alsa_named.h0000644000076400007640000000212210664032032020165 00000000000000#ifndef INCLUDED_AUDIO_IO_ALSA_PCM_NAMED_H #define INCLUDED_AUDIO_IO_ALSA_PCM_NAMED_H #include "audioio_alsa.h" /** * Class for handling named ALSA pcm-devices (Advanced Linux * Sound Architecture). */ class AUDIO_IO_ALSA_PCM_NAMED : public AUDIO_IO_ALSA_PCM { public: virtual string name(void) const { return("ALSA named PCM device"); } virtual string description(void) const { return("ALSA named PCM device. Library versions 0.6.x and newer."); } virtual string parameter_names(void) const { return("label,pcm_name"); } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; AUDIO_IO_ALSA_PCM_NAMED (void); virtual ~AUDIO_IO_ALSA_PCM_NAMED(void); AUDIO_IO_ALSA_PCM_NAMED* clone(void) const; AUDIO_IO_ALSA_PCM_NAMED* new_expr(void) const { return new AUDIO_IO_ALSA_PCM_NAMED(); } private: void print_status_debug(void); AUDIO_IO_ALSA_PCM_NAMED (const AUDIO_IO_ALSA_PCM_NAMED& x) { } AUDIO_IO_ALSA_PCM_NAMED& operator=(const AUDIO_IO_ALSA_PCM_NAMED& x) { return *this; } }; #endif /* INCLUDED_AUDIO_IO_ALSA_PCM_NAMED */ ecasound-2.9.1/libecasound/plugins/audioio_af.h0000644000076400007640000000400111141323334016464 00000000000000#ifndef INCLUDED_AUDIOIO_AF_H #define INCLUDED_AUDIOIO_AF_H #include #include #include "samplebuffer.h" #include "audioio-buffered.h" #include "samplebuffer.h" #ifdef HAVE_CONFIG_H #include #endif /** * Interface to SGI audiofile library. * @author Kai Vehmanen */ class AUDIOFILE_INTERFACE : public AUDIO_IO_BUFFERED { std::string opt_filename_rep; long samples_read; bool finished_rep; AFfilehandle afhandle; AUDIOFILE_INTERFACE& operator=(const AUDIOFILE_INTERFACE& x) { return *this; } void debug_print_type(void); public: virtual string name(void) const { return "SGI libaudiofile object"; } virtual string description(void) const { return "SGI libaudiofile object. Supports AIFF (.aiff, .aifc, .aif) and Sun/NeXT audio files (.au, .snd)."; } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; virtual int supported_io_modes(void) const { return (io_read | io_write); } virtual bool supports_seeking(void) const { return (io_mode() == io_read); } virtual string parameter_names(void) const { return "filename,opt_filename"; } virtual bool locked_audio_format(void) const { return true; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual bool finished(void) const; virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); AUDIOFILE_INTERFACE* clone(void) const; AUDIOFILE_INTERFACE* new_expr(void) const { return new AUDIOFILE_INTERFACE(); } AUDIOFILE_INTERFACE (const string& name = ""); ~AUDIOFILE_INTERFACE(void); }; #ifdef ECA_ENABLE_AUDIOIO_PLUGINS extern "C" { AUDIO_IO* audio_io_descriptor(void) { return(new AUDIOFILE_INTERFACE()); } int audio_io_interface_version(void); const char* audio_io_keyword(void); const char* audio_io_keyword_regex(void); }; #endif #endif ecasound-2.9.1/libecasound/plugins/audioio_jack_manager.h0000644000076400007640000001470311560614025020517 00000000000000#ifndef INCLUDED_AUDIOIO_JACK_MANAGER_H #define INCLUDED_AUDIOIO_JACK_MANAGER_H #include #include #include #include #include #include #include "sample-specs.h" #include "dynamic-object.h" #include "audioio-manager.h" #include "eca-engine-driver.h" #include "audioio_jack.h" class AUDIO_IO; using std::list; using std::string; using std::vector; /** * Manager class for JACK client objects. * * Related design patterns: * - Mediator (GoF273) * * @author Kai Vehmanen */ class AUDIO_IO_JACK_MANAGER : public AUDIO_IO_MANAGER, public ECA_ENGINE_DRIVER { public: friend int eca_jack_process_callback(jack_nframes_t nframes, void *arg); #if ECA_JACK_TRANSPORT_API >= 3 friend int eca_jack_sync_callback(jack_transport_state_t state, jack_position_t *pos, void *arg); friend void eca_jack_sync_start_seek_to(jack_transport_state_t state, jack_position_t *pos, void *arg); friend void eca_jack_sync_start_live_seek_to(jack_transport_state_t state, jack_position_t *pos, void *arg); #endif friend void eca_jack_process_engine_iteration(jack_nframes_t nframes, void *arg); friend void eca_jack_process_mute(jack_nframes_t nframes, void *arg); friend void eca_jack_process_timebase_slave(jack_nframes_t nframes, void *arg); friend int eca_jack_bsize_cb(jack_nframes_t nframes, void *arg); friend int eca_jack_srate_cb(jack_nframes_t nframes, void *arg); friend void eca_jack_shutdown_cb(void *arg); static const int instance_limit; public: typedef struct eca_jack_port_data { jack_port_t* jackport; string autoconnect_string; jack_nframes_t total_latency; jack_default_audio_sample_t* cb_buffer; } eca_jack_port_data_t; typedef struct eca_jack_node { AUDIO_IO_JACK* aobj; AUDIO_IO* origptr; list ports; int client_id; } eca_jack_node_t; private: typedef enum Operation_mode { Transport_none, Transport_receive, Transport_send, Transport_send_receive, Transport_invalid } Operation_mode_t; public: /** @name Constructors */ /*@{*/ AUDIO_IO_JACK_MANAGER(void); virtual ~AUDIO_IO_JACK_MANAGER(void); /*@}*/ /** @name Functions reimplemented from AUDIO_IO_MANAGER */ /*@{*/ virtual bool is_managed_type(const AUDIO_IO* aobj) const; virtual void register_object(AUDIO_IO* aobj); virtual int get_object_id(const AUDIO_IO* aobj) const; virtual list get_object_list(void) const; virtual void unregister_object(int id); /*@}*/ /** @name Functions reimplemented from ECA_OBJECT */ /*@{*/ virtual string name(void) const { return("jack"); } virtual string description(void) const { return("JACK object manager"); } /*@}*/ /** @name Function reimplemented from DYNAMIC_PARAMETERS */ /*@{*/ virtual std::string parameter_names(void) const { return("clientname,mode"); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** @name Function reimplemented from DYNAMIC_OBJECT */ /*@{*/ AUDIO_IO_JACK_MANAGER* clone(void) const { return new_expr(); } AUDIO_IO_JACK_MANAGER* new_expr(void) const { return new AUDIO_IO_JACK_MANAGER(); } /*@}*/ /** @name Functions reimplemented from ECA_ENGINE_DRIVER */ /*@{*/ virtual int exec(ECA_ENGINE* engine, ECA_CHAINSETUP* csetup); virtual void start(void); virtual void stop(bool drain); virtual void exit(void); /*@}*/ /** @name Public API for JACK clients */ /*@{*/ void register_jack_ports(int client_id, int ports, const string& portprefix); void unregister_jack_ports(int client_id); void auto_connect_jack_port(int client_id, int portnum, const string& portname); void auto_connect_jack_port_client(int client_id, const string& dst, int channels); long int client_latency(int client_id); void open(int client_id); void close(int client_id); long int read_samples(int client_id, void* target_buffer, long int samples); void write_samples(int client_id, void* target_buffer, long int samples); bool is_open(void) const { return(open_rep); } bool is_connection_active(void) const { return(activated_rep); } bool is_running(void) const; long int buffersize(void) const; SAMPLE_SPECS::sample_rate_t samples_per_second(void) const; /*@}*/ private: static void get_total_port_latency(jack_client_t* client, eca_jack_port_data_t* ports, int mode); void open_server_connection(void); void close_server_connection(void); void initial_seek(void); void exec_helper_setup_transport(void); void exec_helper_clean_transport(void); void set_transport_mode(enum Operation_mode mode, bool print_trace); void helper_print_transport_state(const std::string& when) const; void activate_server_connection(void); void deactivate_server_connection(void); void set_node_connection(eca_jack_node_t* node, bool connect); void connect_all_nodes(void); void disconnect_all_nodes(void); eca_jack_node_t* get_node(int client_id); void wait_for_exit(void); void signal_exit(void); void wait_for_stop(void); void signal_stop(void); pthread_cond_t exit_cond_rep; pthread_mutex_t exit_mutex_rep; pthread_cond_t stop_cond_rep; pthread_mutex_t stop_mutex_rep; pthread_mutex_t engine_mod_lock_rep; Operation_mode_t mode_rep; bool open_rep; /**< connection established to the JACK server */ bool activated_rep; /**< JACK connection activated */ bool shutdown_request_rep; /**< jack->engine pending shutdown request */ bool exit_request_rep; /**< engine->engine exit request */ int open_clients_rep; /** number of active client nodes */ int last_node_id_rep; int start_request_rep; /**< number of jack->engine start requests pending */ int stop_request_rep; /**< number of jack->engine stop requests pending */ int j_stopped_rounds_rep; /**< number of iterations that JACK state has been stopped; accessed only from proces thread */ list node_list_rep; vector inports_rep; vector outports_rep; std::map port_numbers_rep; /** highest port number used for each prefix */ int jackslave_seekahead_rep; long int jackslave_seekahead_target_rep; ECA_ENGINE* engine_repp; jack_client_t *client_repp; string jackname_rep; /**< client name */ SAMPLE_SPECS::sample_rate_t srate_rep; long int buffersize_rep; long int cb_allocated_frames_rep; }; #endif ecasound-2.9.1/libecasound/plugins/audioio_alsa_named.cpp0000644000076400007640000000465710664032032020537 00000000000000// ------------------------------------------------------------------------ // audioio_alsa_named.cpp: ALSA 0.9.x named PCM-device input/output. // Copyright (C) 2001-2002 Kai Vehmanen // 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 #include #include #include #include #include "audioio_alsa_named.h" #include "eca-error.h" #include "eca-logger.h" #include "eca-version.h" #ifdef ECA_ENABLE_AUDIOIO_PLUGINS static const char* audio_io_keyword_const = "alsa_09"; static const char* audio_io_keyword_regex_const = "^alsa_09$"; const char* audio_io_keyword(void){return(audio_io_keyword_const); } const char* audio_io_keyword_regex(void){return(audio_io_keyword_regex_const); } AUDIO_IO* audio_io_descriptor(void) { return(new AUDIO_IO_ALSA_PCM_NAMED()); } int audio_io_interface_version(void) { return(ecasound_library_version_current); } #endif AUDIO_IO_ALSA_PCM_NAMED::AUDIO_IO_ALSA_PCM_NAMED (void) { set_pcm_device_name(""); } AUDIO_IO_ALSA_PCM_NAMED::~AUDIO_IO_ALSA_PCM_NAMED(void) { } AUDIO_IO_ALSA_PCM_NAMED* AUDIO_IO_ALSA_PCM_NAMED::clone(void) const { AUDIO_IO_ALSA_PCM_NAMED* target = new AUDIO_IO_ALSA_PCM_NAMED(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return(target); } void AUDIO_IO_ALSA_PCM_NAMED::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); break; case 2: set_pcm_device_name(value); break; } } string AUDIO_IO_ALSA_PCM_NAMED::get_parameter(int param) const { switch (param) { case 1: return(label()); case 2: return(pcm_device_name()); } return(""); } ecasound-2.9.1/libecasound/plugins/audioio_jack.h0000644000076400007640000000442111161464275017030 00000000000000#ifndef INCLUDED_AUDIOIO_JACK_H #define INCLUDED_AUDIOIO_JACK_H #include #include #include "audioio-device.h" #include "sample-specs.h" class AUDIO_IO_MANAGER; class AUDIO_IO_JACK_MANAGER; /** * Interface to JACK audio framework. * * @author Kai Vehmanen */ class AUDIO_IO_JACK : public AUDIO_IO_DEVICE { public: virtual std::string name(void) const { return "JACK interface"; } virtual std::string description(void) const { return name(); } virtual std::string parameter_names(void) const; AUDIO_IO_JACK (void); ~AUDIO_IO_JACK(void); virtual bool variable_params(void) const { return true; } virtual void set_parameter(int param, string value); virtual string get_parameter(int param) const; /** @name Function reimplemented from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return io_read | io_write; } virtual bool locked_audio_format(void) const { return true; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void close(void); virtual bool finished(void) const; virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual long int read_samples(void* target_buffer, long int samples); virtual void write_samples(void* target_buffer, long int samples); virtual AUDIO_IO_MANAGER* create_object_manager(void) const; void set_manager(AUDIO_IO_JACK_MANAGER* mgr, int id); /*@}*/ /** @name Function reimplemented from AUDIO_IO_DEVICE */ /*@{*/ virtual void prepare(void); virtual void start(void); virtual void stop(void); virtual long int latency(void) const; virtual long int prefill_space(void) const { return 0; } /*@}*/ AUDIO_IO_JACK* clone(void) const { return new AUDIO_IO_JACK(*this); } AUDIO_IO_JACK* new_expr(void) const { return new AUDIO_IO_JACK(); } private: AUDIO_IO_JACK_MANAGER* jackmgr_rep; int myid_rep; bool error_flag_rep; std::vector params_rep; SAMPLE_SPECS::sample_pos_t curpos_rep; private: AUDIO_IO_JACK (const AUDIO_IO_JACK& x) { } AUDIO_IO_JACK& operator=(const AUDIO_IO_JACK& x) { return *this; } }; #ifdef ECA_ENABLE_AUDIOIO_PLUGINS extern "C" { AUDIO_IO* audio_io_descriptor(void); int audio_io_interface_version(void); const char* audio_io_keyword(void); const char* audio_io_keyword_regex(void); }; #endif #endif ecasound-2.9.1/libecasound/plugins/audioio_alsa.cpp0000644000076400007640000005367112260762753017411 00000000000000// ------------------------------------------------------------------------ // audioio-alsa.cpp: ALSA 0.9.x PCM input and output. // Copyright (C) 1999-2004,2008 Kai Vehmanen // Copyright (C) 2001,2002 Jeremy Hall // // Attributes: // eca-style-version: 3 // // References: // http://alsa-project.org/ // // 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 #include #include #include #include #include #include #define MY_SND_LIB_VERSION(maj,min,sub) \ ((maj<<16)| (min<<8)| sub) /* error if alsa-lib older than 0.9.0, use old API if 0.9.0->0.9.8, otherwise do nothing */ #if SND_LIB_MAJOR < 1 && SND_LIB_MINOR == 9 #if SND_LIB_SUBMINOR > 0 || SND_LIB_EXTRAVER >= 100004 #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #else #error "Unable to compile ALSA-support. Alsa-lib version 0.9.0rc4 or newer is required!" #endif #endif #include /* Linux-kernel specific errnos */ #ifndef ESTRPIPE #define ESTRPIPE 86 #endif #include #include #include #include #include #include "samplebuffer.h" #include "audioio-device.h" #include "audioio_alsa.h" #include "eca-version.h" #include "eca-error.h" #include "eca-logger.h" using std::cerr; using std::endl; #ifndef timersub #define timersub(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) #endif const string AUDIO_IO_ALSA_PCM::default_pcm_device_rep = "default"; AUDIO_IO_ALSA_PCM::AUDIO_IO_ALSA_PCM (int card, int device, int subdevice) : AUDIO_IO_DEVICE() { // ECA_LOG_MSG(ECA_LOGGER::system_objects, "construct"); card_number_rep = card; device_number_rep = device; subdevice_number_rep = subdevice; trigger_request_rep = false; overruns_rep = underruns_rep = 0; nbufs_repp = 0; allocate_structs(); } AUDIO_IO_ALSA_PCM::~AUDIO_IO_ALSA_PCM(void) { if (is_open() == true && is_running()) stop(); if (is_open() == true) { close(); } if (io_mode() != io_read) { if (underruns_rep != 0) { cerr << "WARNING! While writing to ALSA-pcm device "; cerr << "C" << card_number_rep << "D" << device_number_rep; cerr << ", there were " << underruns_rep << " underruns.\n"; } } else { if (overruns_rep != 0) { cerr << "WARNING! While reading from ALSA-pcm device "; cerr << "C" << card_number_rep << "D" << device_number_rep; cerr << ", there were " << overruns_rep << " overruns.\n"; } } if (nbufs_repp != 0) delete nbufs_repp; deallocate_structs(); } AUDIO_IO_ALSA_PCM* AUDIO_IO_ALSA_PCM::clone(void) const { AUDIO_IO_ALSA_PCM* target = new AUDIO_IO_ALSA_PCM(); for(int n = 0; n < number_of_params(); n++) { target->set_parameter(n + 1, get_parameter(n + 1)); } return target; } void AUDIO_IO_ALSA_PCM::allocate_structs(void) { int err = snd_pcm_hw_params_malloc(&pcm_hw_params_repp); DBC_CHECK(!err); err = snd_pcm_sw_params_malloc(&pcm_sw_params_repp); DBC_CHECK(!err); } void AUDIO_IO_ALSA_PCM::deallocate_structs(void) { snd_pcm_hw_params_free(pcm_hw_params_repp); snd_pcm_sw_params_free(pcm_sw_params_repp); } void AUDIO_IO_ALSA_PCM::open_device(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "open"); // ------------------------------------------------------------------- // Device name initialization string device_name = pcm_device_name(); // ------------------------------------------------------------------- // Open devices int err; if (io_mode() == io_read) { pcm_stream_rep = SND_PCM_STREAM_CAPTURE; err = snd_pcm_open(&audio_fd_repp, (char*)device_name.c_str(), pcm_stream_rep, SND_PCM_NONBLOCK); if (err < 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-ALSA: Unable to open ALSA--device for capture; error: " + string(snd_strerror(err)))); } } else if (io_mode() == io_write) { pcm_stream_rep = SND_PCM_STREAM_PLAYBACK; err = snd_pcm_open(&audio_fd_repp, (char*)device_name.c_str(), pcm_stream_rep, SND_PCM_NONBLOCK); if (err < 0) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-ALSA: Unable to open ALSA-device for playback; error: " + string(snd_strerror(err)))); } } else if (io_mode() == io_readwrite) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-ALSA: Simultaneous input/output not supported.")); } // ------------------------------------------------------------------- // enables blocking mode snd_pcm_nonblock(audio_fd_repp, 0); } void AUDIO_IO_ALSA_PCM::set_audio_format_params(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "set_audio_format_params"); format_rep = SND_PCM_FORMAT_LAST; switch(sample_format()) { case ECA_AUDIO_FORMAT::sfmt_u8: { format_rep = SND_PCM_FORMAT_U8; break; } case ECA_AUDIO_FORMAT::sfmt_s8: { format_rep = SND_PCM_FORMAT_S8; break; } case ECA_AUDIO_FORMAT::sfmt_s16_le: { format_rep = SND_PCM_FORMAT_S16_LE; break; } case ECA_AUDIO_FORMAT::sfmt_s16_be: { format_rep = SND_PCM_FORMAT_S16_BE; break; } case ECA_AUDIO_FORMAT::sfmt_s24_le: { format_rep = SND_PCM_FORMAT_S24_3LE; break; } case ECA_AUDIO_FORMAT::sfmt_s24_be: { format_rep = SND_PCM_FORMAT_S24_3BE; break; } case ECA_AUDIO_FORMAT::sfmt_s32_le: { format_rep = SND_PCM_FORMAT_S32_LE; break; } case ECA_AUDIO_FORMAT::sfmt_s32_be: { format_rep = SND_PCM_FORMAT_S32_BE; break; } default: { throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-ALSA: Error when setting audio format not supported (1)")); } } } void AUDIO_IO_ALSA_PCM::print_pcm_info(void) { } void AUDIO_IO_ALSA_PCM::fill_and_set_hw_params(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "fill_and_set_hw_params"); /* 1. create one param combination */ int err = snd_pcm_hw_params_any(audio_fd_repp, pcm_hw_params_repp); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up hwparams/any: " + string(snd_strerror(err)))); /* 2. set interleaving mode */ if (interleaved_channels() == true) ECA_LOG_MSG(ECA_LOGGER::user_objects, "Using interleaved stream format."); else ECA_LOG_MSG(ECA_LOGGER::user_objects, "Using noninterleaved stream format."); if (interleaved_channels() == true) err = snd_pcm_hw_params_set_access(audio_fd_repp, pcm_hw_params_repp, SND_PCM_ACCESS_RW_INTERLEAVED); else err = snd_pcm_hw_params_set_access(audio_fd_repp, pcm_hw_params_repp, SND_PCM_ACCESS_RW_NONINTERLEAVED); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up hwparams/access: " + string(snd_strerror(err)))); /* 3. set sample format */ err = snd_pcm_hw_params_set_format(audio_fd_repp, pcm_hw_params_repp, format_rep); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::sample_format, "AUDIOIO-ALSA: Audio format not supported.")); /* 4. set channel count */ err = snd_pcm_hw_params_set_channels(audio_fd_repp, pcm_hw_params_repp, channels()); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::channels, "AUDIOIO-ALSA: Channel count " + kvu_numtostr(channels()) + " is out of range!")); /* 5. set sampling rate */ unsigned int uivalue = samples_per_second(); err = snd_pcm_hw_params_set_rate_near(audio_fd_repp, pcm_hw_params_repp, &uivalue, 0); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::sample_rate, "AUDIOIO-ALSA: Sample rate " + kvu_numtostr(samples_per_second()) + " is out of range!")); /* 6. create buffers for noninterleaved i/o */ if (interleaved_channels() != true) { if (nbufs_repp == 0) nbufs_repp = new unsigned char* [channels()]; } snd_pcm_uframes_t fvalue = buffersize(); /* 7. sets period size (period = one fragment) */ err = snd_pcm_hw_params_set_period_size_near(audio_fd_repp, pcm_hw_params_repp, &fvalue, 0); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::buffersize, "AUDIOIO-ALSA: buffersize " + kvu_numtostr(buffersize()) + " is out of range!")); /* 8. sets buffer size */ if (max_buffers() == true) { snd_pcm_uframes_t bufferreq = buffersize() * 1024; err = snd_pcm_hw_params_set_buffer_size_near(audio_fd_repp, pcm_hw_params_repp, &bufferreq); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up hwparams/btime (1): " + string(snd_strerror(err)))); } else { snd_pcm_uframes_t bufferreq = buffersize() * 3; err = snd_pcm_hw_params_set_buffer_size_near(audio_fd_repp, pcm_hw_params_repp, &bufferreq); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up hwparams/btime (2): " + string(snd_strerror(err)))); } /* 9. print debug information */ snd_pcm_hw_params_get_period_time(pcm_hw_params_repp, &uivalue, 0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "period time set to " + kvu_numtostr(uivalue) + " usecs."); snd_pcm_hw_params_get_period_size(pcm_hw_params_repp, &period_size_rep, 0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "period time set to " + kvu_numtostr(period_size_rep) + " frames."); if (period_size_rep != static_cast(buffersize())) { ECA_LOG_MSG(ECA_LOGGER::info, "Warning! Period-size differs from current client buffersize."); } snd_pcm_hw_params_get_buffer_time(pcm_hw_params_repp, &uivalue, 0); ECA_LOG_MSG(ECA_LOGGER::system_objects, "buffer time set to " + kvu_numtostr(uivalue) + " usecs."); snd_pcm_hw_params_get_buffer_size(pcm_hw_params_repp, &buffer_size_rep); ECA_LOG_MSG(ECA_LOGGER::system_objects, "buffer time set to " + kvu_numtostr(buffer_size_rep) + " frames."); ECA_LOG_MSG(ECA_LOGGER::system_objects, "total latency is " + kvu_numtostr(latency()) + " frames."); /* 9. all set, now active hw params */ err = snd_pcm_hw_params(audio_fd_repp, pcm_hw_params_repp); if (err < 0) { throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up hwparams: " + string(snd_strerror(err)))); } } void AUDIO_IO_ALSA_PCM::fill_and_set_sw_params(void) { ECA_LOG_MSG(ECA_LOGGER::system_objects, "fill_and_set_sw_params"); /* 1. get current params */ snd_pcm_sw_params_current(audio_fd_repp, pcm_sw_params_repp); /* 2. set start threshold (should be big enough so that processing won't start until a explicit snd_pcm_start() is issued */ int err = snd_pcm_sw_params_set_start_threshold(audio_fd_repp, pcm_sw_params_repp, buffer_size_rep * 2); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up pcm_sw_params/start_threshold: " + string(snd_strerror(err)))); #if SND_LIB_VERSION <= MY_SND_LIB_VERSION(1,0,15) /* note: deprecated in alsa-lib-1.0.16 (2008/Feb) */ /* 3. set align to one frame (like the OSS-emulation layer) */ err = snd_pcm_sw_params_set_xfer_align(audio_fd_repp, pcm_sw_params_repp, 1); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up pcm_sw_params_repp/xfer_align: " + string(snd_strerror(err)))); #endif /* 4. activate params */ err = snd_pcm_sw_params(audio_fd_repp, pcm_sw_params_repp); if (err < 0) throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-ALSA: Error when setting up pcm_sw_params_repp: " + string(snd_strerror(err)))); } void AUDIO_IO_ALSA_PCM::open(void) throw(AUDIO_IO::SETUP_ERROR&) { open_device(); set_audio_format_params(); fill_and_set_hw_params(); print_pcm_info(); fill_and_set_sw_params(); AUDIO_IO_DEVICE::open(); } void AUDIO_IO_ALSA_PCM::stop(bool drain) { if (drain == true && io_mode() != io_read) { /* * The sw-params combination: * "silence-threshold==0 && silence-size>=boundary" * ... is a API special case to request silencing all * processed frames. This will ensure no stale data is * played out at the end of drain. */ snd_pcm_uframes_t boundary; snd_pcm_sw_params_get_boundary(pcm_sw_params_repp, &boundary); snd_pcm_sw_params_set_silence_threshold(audio_fd_repp, pcm_sw_params_repp, 0); snd_pcm_sw_params_set_silence_size(audio_fd_repp, pcm_sw_params_repp, boundary); snd_pcm_sw_params(audio_fd_repp, pcm_sw_params_repp); ECA_LOG_MSG(ECA_LOGGER::user_objects, "drain - start / " + label()); snd_pcm_drain(audio_fd_repp); /* blocking */ ECA_LOG_MSG(ECA_LOGGER::user_objects, "drain complete / " + label()); } else { snd_pcm_drop(audio_fd_repp); /* non-blocking */ } ECA_LOG_MSG(ECA_LOGGER::user_objects, "stop - " + label() + "."); AUDIO_IO_DEVICE::stop(); } void AUDIO_IO_ALSA_PCM::close(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "close - " + label() + "."); if (is_prepared() == true && is_running() == true) stop(); snd_pcm_close(audio_fd_repp); AUDIO_IO_DEVICE::close(); } void AUDIO_IO_ALSA_PCM::prepare(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "prepare - " + label() + "."); int err = snd_pcm_prepare(audio_fd_repp); if (err < 0) ECA_LOG_MSG(ECA_LOGGER::info, "Error when preparing stream: " + string(snd_strerror(err))); AUDIO_IO_DEVICE::prepare(); } void AUDIO_IO_ALSA_PCM::start(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "start - " + label() + "."); snd_pcm_start(audio_fd_repp); AUDIO_IO_DEVICE::start(); } long int AUDIO_IO_ALSA_PCM::read_samples(void* target_buffer, long int samples) { // -- DBC_REQUIRE(samples <= buffersize()); // -- long int realsamples = 0; if (interleaved_channels() == true) { realsamples = snd_pcm_readi(audio_fd_repp, target_buffer, buffersize()); if (realsamples < 0) { /* Note! ALSA versions <=0.9.1 sometimes return -EIO in xrun-state; * EPIPE=xrun, ESTRPIPE=xrun) */ if (realsamples == -EPIPE || realsamples == -ESTRPIPE || realsamples == -EIO) { if (ignore_xruns() == true) { handle_xrun_capture(); realsamples = snd_pcm_readi(audio_fd_repp, target_buffer, buffersize()); if (realsamples < 0) realsamples = 0; } else { cerr << "ALSA: Overrun! Stopping operation!" << endl; stop(); close(); } } else { cerr << "ALSA: Read error (" << realsamples << ")! Stopping operation." << endl; stop(); close(); } } } else { unsigned char* ptr_to_channel = reinterpret_cast(target_buffer); for (int channel = 0; channel < channels(); channel++) { nbufs_repp[channel] = ptr_to_channel; ptr_to_channel += samples * sample_size(); } realsamples = snd_pcm_readn(audio_fd_repp, reinterpret_cast(target_buffer), buffersize()); if (realsamples < 0) { /* Note! ALSA versions <=0.9.1 sometimes return -EIO in xrun-state; * EPIPE=xrun, ESTRPIPE=xrun) */ if (realsamples == -EPIPE || realsamples == -ESTRPIPE || realsamples == -EIO) { if (ignore_xruns() == true) { handle_xrun_capture(); realsamples = snd_pcm_readn(audio_fd_repp, reinterpret_cast(target_buffer), buffersize()); if (realsamples < 0) realsamples = 0; } else { cerr << "ALSA: Overrun! Stopping operation!" << endl; stop(); close(); } } else { cerr << "ALSA: Read error! Stopping operation." << endl; stop(); close(); } } } return realsamples; } void AUDIO_IO_ALSA_PCM::handle_xrun_capture(void) { snd_pcm_status_t *status; snd_pcm_status_alloca(&status); int res = snd_pcm_status(audio_fd_repp, status); if (res >= 0) { snd_pcm_state_t state = snd_pcm_status_get_state(status); if (state == SND_PCM_STATE_XRUN) { struct timeval now, diff, tstamp; gettimeofday(&now, 0); snd_pcm_status_get_trigger_tstamp(status, &tstamp); timersub(&now, &tstamp, &diff); cerr << "WARNING: ALSA recording overrun, some audio samples were lost!" << " Break was at least " << kvu_numtostr(diff.tv_sec * 1000 + diff.tv_usec / 1000.0) << " ms long." << endl; overruns_rep++; stop(); prepare(); start(); } else if (state == SND_PCM_STATE_SUSPENDED) { cerr << "ALSA: Device suspended! Stopping operation!" << endl; stop(); close(); } else { cerr << "ALSA: Unknown device state '" << static_cast(state) << "'" << endl; } } else { ECA_LOG_MSG(ECA_LOGGER::info, "snd_pcm_status() failed!"); } } void AUDIO_IO_ALSA_PCM::write_samples(void* target_buffer, long int samples) { if (trigger_request_rep == true) { trigger_request_rep = false; start(); } if (interleaved_channels() == true) { long int count = snd_pcm_writei(audio_fd_repp, target_buffer, samples); if (count < 0) { /* Note! ALSA versions <=0.9.1 sometimes return -EIO in xrun-state; * EPIPE=xrun, ESTRPIPE=xrun) */ DBC_CHECK(count != -EINTR); if (count == -EPIPE || count == -EIO || count == -ESTRPIPE) { if (ignore_xruns() == true) { handle_xrun_playback(); if (snd_pcm_writei(audio_fd_repp, target_buffer, samples) < 0) cerr << "ALSA: playback xrun handling failed!" << endl; trigger_request_rep = true; } else { cerr << "ALSA: Overrun! Stopping operation!" << endl; stop(); close(); } } else { cerr << "ALSA: Write error! Stopping operation (" << count << ")." << endl; stop(); close(); } } } else { unsigned char* ptr_to_channel = reinterpret_cast(target_buffer); for (int channel = 0; channel < channels(); channel++) { nbufs_repp[channel] = ptr_to_channel; // cerr << "Pointer to channel " << channel << ": " << reinterpret_cast(nbufs_repp[channel]) << endl; ptr_to_channel += samples * sample_size(); // cerr << "Advancing pointer count by " << samples * sample_size() << " to " << reinterpret_cast(ptr_to_channel) << endl; } long int count = snd_pcm_writen(audio_fd_repp, reinterpret_cast(nbufs_repp), samples); if (count < 0) { /* Note! ALSA versions <=0.9.1 sometimes return -EIO in xrun-state; * EPIPE=xrun, ESTRPIPE=xrun) */ DBC_CHECK(count != -EINTR); if (count == -EPIPE || count == -EIO || count == -ESTRPIPE) { if (ignore_xruns() == true) { handle_xrun_playback(); snd_pcm_writen(audio_fd_repp, reinterpret_cast(nbufs_repp), samples); trigger_request_rep = true; } else { cerr << "ALSA: Overrun! Stopping operation!" << endl; stop(); close(); } } else { cerr << "ALSA: Write error! Stopping operation." << endl; stop(); close(); } } } } void AUDIO_IO_ALSA_PCM::handle_xrun_playback(void) { snd_pcm_status_t *status; snd_pcm_status_alloca(&status); int res = snd_pcm_status(audio_fd_repp, status); if (res >= 0) { snd_pcm_state_t state = snd_pcm_status_get_state(status); if (state == SND_PCM_STATE_XRUN) { struct timeval now, diff, tstamp; gettimeofday(&now, 0); snd_pcm_status_get_trigger_tstamp(status, &tstamp); timersub(&now, &tstamp, &diff); cerr << "WARNING: ALSA playback underrun, glitches in audio playback possible!" << " Break was at least " << kvu_numtostr(diff.tv_sec * 1000 + diff.tv_usec / 1000.0) << " ms long." << endl; underruns_rep++; stop(); prepare(); trigger_request_rep = true; } else if (state == SND_PCM_STATE_SUSPENDED) { cerr << "ALSA: Device suspended! Stopping operation!" << endl; stop(); close(); } else { cerr << "ALSA: Unknown device state '" << static_cast(state) << "'" << endl; } } else { ECA_LOG_MSG(ECA_LOGGER::info, "snd_pcm_status() failed!"); } } long int AUDIO_IO_ALSA_PCM::delay(void) const { snd_pcm_sframes_t delay = 0; if (is_running() == true) { if (snd_pcm_delay(audio_fd_repp, &delay) != 0) { delay = 0; } } return static_cast(delay); } void AUDIO_IO_ALSA_PCM::set_parameter(int param, string value) { switch (param) { case 1: set_label(value); if (label().find("alsaplugin") != string::npos) { using_plugin_rep = true; } break; case 2: card_number_rep = atoi(value.c_str()); break; case 3: device_number_rep = atoi(value.c_str()); break; case 4: subdevice_number_rep = atoi(value.c_str()); break; } if (using_plugin_rep) pcm_device_name_rep = string("plughw:") + kvu_numtostr(card_number_rep) + "," + kvu_numtostr(device_number_rep) + "," + kvu_numtostr(subdevice_number_rep); else pcm_device_name_rep = string("hw:") + kvu_numtostr(card_number_rep) + "," + kvu_numtostr(device_number_rep) + "," + kvu_numtostr(subdevice_number_rep); } string AUDIO_IO_ALSA_PCM::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return kvu_numtostr(card_number_rep); case 3: return kvu_numtostr(device_number_rep); case 4: return kvu_numtostr(subdevice_number_rep); } return ""; } void AUDIO_IO_ALSA_PCM::set_pcm_device_name(const string& n) { if (n.size() > 0) pcm_device_name_rep = n; else pcm_device_name_rep = default_pcm_device_rep; } ecasound-2.9.1/libecasound/generic-controller.h0000644000076400007640000000431711034750421016515 00000000000000#ifndef INCLUDED_GENERIC_CONTROLLER_H #define INCLUDED_GENERIC_CONTROLLER_H #include "ctrl-source.h" #include "eca-operator.h" /** * Generic controller class that connects controller sources * to objects supporting dynamic parameter control (classes * which inherit DYNAMIC_PARAMETERS). * * Related design patterns: * - Decorator (GoF175) */ class GENERIC_CONTROLLER : public CONTROLLER_SOURCE { public: /** @name Constructors and destructors */ /*@{*/ GENERIC_CONTROLLER(CONTROLLER_SOURCE* source, OPERATOR* dobj = 0, int param_id = 0, double range_low = 0.0, double range_high = 0.0); GENERIC_CONTROLLER* clone(void) const { return(0); } GENERIC_CONTROLLER* new_expr(void) const { return(new GENERIC_CONTROLLER(0)); } /*@}*/ /** @name Public functions reimplemented from CONTROLLER_SOURCE */ /*@{*/ virtual void init(void); /** * Returns the current value, scale it and * applies it to target objects. * * @pre is_valid() == true */ virtual parameter_t value(double pos_secs); virtual void set_initial_value(parameter_t arg) { } /*@}*/ /** @name Public functions reimplemented from ECA_OBJECT */ /*@{*/ virtual std::string name(void) const { return(source == 0 ? string("") : source->name()); } /*@}*/ /** @name Public functions reimplemented from DYNAMIC_PARAMETERS */ /*@{*/ virtual bool variable_params(void) const { return true; } virtual std::string parameter_names(void) const { return("param-id,range-low,range-high," + source->parameter_names()); } virtual void set_parameter(int param, parameter_t value); virtual parameter_t get_parameter(int param) const; /*@}*/ /** @name Public functions */ /*@{*/ bool is_valid(void) const { return(target != 0 && source != 0); } std::string status(void) const; void assign_target(OPERATOR* obj); void assign_source(CONTROLLER_SOURCE* obj); CONTROLLER_SOURCE* source_pointer(void) const { return(source); } OPERATOR* target_pointer(void) const { return(target); } /*@}*/ private: OPERATOR* target; CONTROLLER_SOURCE* source; bool init_called_rep; int param_id_rep; double rangelow_rep, rangehigh_rep; double last_value_pos_rep; }; #endif ecasound-2.9.1/libecasound/eca-audio-time.cpp0000644000076400007640000001443011034137670016040 00000000000000// ------------------------------------------------------------------------ // eca-audio-time.cpp: Generic class for representing time in audio // environment. // Copyright (C) 2000,2007,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include "eca-audio-time.h" /** * FIXME notes (last update 2008-03-09) * * - Add variant that allows specifying both sample position and * sampling rate to set_time_string(). E.g. "1234@44100sa" or * something similar. */ using SAMPLE_SPECS::sample_pos_t; using SAMPLE_SPECS::sample_rate_t; ECA_AUDIO_TIME::ECA_AUDIO_TIME(sample_pos_t samples, sample_rate_t sample_rate) { set_samples_per_second(sample_rate); set_samples(samples); rate_set_rep = true; } ECA_AUDIO_TIME::ECA_AUDIO_TIME(double time_in_seconds) : samples_rep(0), sample_rate_rep(ECA_AUDIO_TIME::invalid_srate), rate_set_rep(false) { set_seconds(time_in_seconds); rate_set_rep = true; } ECA_AUDIO_TIME::ECA_AUDIO_TIME(format_type type, const std::string& time) : samples_rep(0), sample_rate_rep(ECA_AUDIO_TIME::invalid_srate), rate_set_rep(false) { set(type, time); } ECA_AUDIO_TIME::ECA_AUDIO_TIME(const std::string& time) : samples_rep(0), sample_rate_rep(ECA_AUDIO_TIME::invalid_srate), rate_set_rep(false) { set_time_string(time); } ECA_AUDIO_TIME::ECA_AUDIO_TIME(void) : samples_rep(0), sample_rate_rep(ECA_AUDIO_TIME::invalid_srate), rate_set_rep(false) { } /** * Sets time based on 'type', 'time' and 'srate'. * * @param sample_rate a value of zero will be ignored. */ void ECA_AUDIO_TIME::set(format_type type, const std::string& time) { switch(type) { /* FIXME: not implemented! */ case format_hour_min_sec: { DBC_CHECK(false); break; } /* FIXME: not implemented! */ case format_min_sec: { DBC_CHECK(false); break; } case format_seconds: { double seconds = atof(time.c_str()); set_seconds(seconds); break; } case format_samples: { samples_rep = atol(time.c_str()); break; } default: { } } } /** * Sets time expressed in seconds. Additionally sample_rate is given * to express the timing accuracy. * * @param sample_rate a value of zero will be ignored. */ void ECA_AUDIO_TIME::set_seconds(double seconds) { if (sample_rate_rep == ECA_AUDIO_TIME::invalid_srate) { sample_rate_rep = ECA_AUDIO_TIME::default_srate; rate_set_rep = true; } samples_rep = static_cast(seconds * sample_rate_rep); } /** * Sets time based on string 'time'. Additionally sample_rate is given * to express the timing accuracy. * * The time string is by default interpreted as seconds (need not * be an integer but can be given as a decimal number, e.g. "1.05"). * However, if the string contains an integer number and has a postfix * of "sa" (e.g. "44100sa"), it is interpreted as time expressed as * samples (in case of a multichannel stream, time in sample frames). * * @param sample_rate a value of zero will be ignored. */ void ECA_AUDIO_TIME::set_time_string(const std::string& time) { if (time.size() > 2 && time.find("sa") != std::string::npos) ECA_AUDIO_TIME::set(format_samples, std::string(time, 0, time.size() - 2)); else ECA_AUDIO_TIME::set(format_seconds, time); } /** * Sets the sample count. * * Note, this can change the value of seconds(). */ void ECA_AUDIO_TIME::set_samples(SAMPLE_SPECS::sample_pos_t samples) { samples_rep = samples; } /** * Sets samples per second. Additionally sample_rate is given * to express the timing accuracy. * * Note, this can change the value of seconds(). */ void ECA_AUDIO_TIME::set_samples_per_second(SAMPLE_SPECS::sample_rate_t srate) { if (srate > 0) { sample_rate_rep = srate; rate_set_rep = true; } else { rate_set_rep = false; sample_rate_rep = ECA_AUDIO_TIME::invalid_srate; } } /** * Sets samples per second. * * Note, if sampling rate has been set earlier, this function * does NOT change the value of seconds() like * set_samples_per_second() potentially does. */ void ECA_AUDIO_TIME::set_samples_per_second_keeptime(sample_rate_t srate) { if (srate > 0 && sample_rate_rep != srate) { if (rate_set_rep == true) { /* only needed if sampling rate has been set */ double time_secs = seconds(); set_samples_per_second(srate); set_seconds(time_secs); } else { set_samples_per_second(srate); } } } void ECA_AUDIO_TIME::mark_as_invalid(void) { set_samples_per_second(ECA_AUDIO_TIME::invalid_srate); } std::string ECA_AUDIO_TIME::to_string(format_type type) const { /* FIXME: not implemented */ switch(type) { case format_hour_min_sec: { return ""; } case format_min_sec: { return ""; } case format_seconds: { return kvu_numtostr(seconds(), 6); } case format_samples: { return kvu_numtostr(samples_rep); } default: { } } return ""; } double ECA_AUDIO_TIME::seconds(void) const { if (rate_set_rep != true) { sample_rate_rep = ECA_AUDIO_TIME::default_srate; rate_set_rep = true; } return static_cast(samples_rep) / sample_rate_rep; } SAMPLE_SPECS::sample_rate_t ECA_AUDIO_TIME::samples_per_second(void) const { return sample_rate_rep; } SAMPLE_SPECS::sample_pos_t ECA_AUDIO_TIME::samples(void) const { return samples_rep; } bool ECA_AUDIO_TIME::valid(void) const { return rate_set_rep; } ecasound-2.9.1/libecasound/samplebuffer_test.h0000644000076400007640000000716611167613223016444 00000000000000// ------------------------------------------------------------------------ // samplebuffer_test.h: Unit test for SAMPLE_BUFFER // Copyright (C) 2009 Kai Vehmanen // // 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 #include #include "kvu_dbc.h" #include "kvu_inttypes.h" #include "samplebuffer.h" #include "samplebuffer_functions.h" #include "eca-test-case.h" using namespace std; /** * Unit test for SAMPLE_BUFFER */ class SAMPLE_BUFFER_TEST : public ECA_TEST_CASE { protected: virtual string do_name(void) const { return("SAMPLE_BUFFER"); } virtual void do_run(void); public: virtual ~SAMPLE_BUFFER_TEST(void) { } private: }; void SAMPLE_BUFFER_TEST::do_run(void) { const int bufsize = 1024; const int channels = 12; const SAMPLE_BUFFER::sample_t multiplier = 100.1f; std::fprintf(stdout, "%s: tests for SAMPLE_BUFFER class\n", __FILE__); /* case: multiply_by */ { std::fprintf(stdout, "%s: multiply_by\n", __FILE__); SAMPLE_BUFFER sbuf_orig (bufsize, channels); SAMPLE_BUFFER sbuf_ref (bufsize, channels); SAMPLE_BUFFER sbuf_test (bufsize, channels); SAMPLE_BUFFER_FUNCTIONS::fill_with_random_samples(&sbuf_orig); sbuf_test.copy_all_content(sbuf_orig); sbuf_ref.copy_all_content(sbuf_orig); sbuf_test.multiply_by(multiplier); sbuf_ref.multiply_by_ref(multiplier); if (SAMPLE_BUFFER_FUNCTIONS::is_almost_equal(sbuf_ref, sbuf_test) != true) { ECA_TEST_FAILURE("optimized multiple_by"); } } /* case: copy_all_content */ { std::fprintf(stdout, "%s: copy_all_content\n", __FILE__); SAMPLE_BUFFER sbuf_orig (bufsize, channels); SAMPLE_BUFFER sbuf_ref (bufsize, channels); SAMPLE_BUFFER sbuf_test (bufsize, channels); SAMPLE_BUFFER_FUNCTIONS::fill_with_random_samples(&sbuf_orig); /* note: copy_all_content should modify the destination * channel and sample counts to match those of * the source object. */ sbuf_test.number_of_channels(0); sbuf_test.length_in_samples(1); sbuf_test.copy_all_content(sbuf_orig); sbuf_ref.copy_matching_channels(sbuf_orig); if (SAMPLE_BUFFER_FUNCTIONS::is_almost_equal(sbuf_ref, sbuf_test) != true) { ECA_TEST_FAILURE("copy_all_content"); } } /* case: multiply_by */ { std::fprintf(stdout, "%s: add_matching_channels\n", __FILE__); SAMPLE_BUFFER sbuf_orig (bufsize, channels); SAMPLE_BUFFER sbuf_ref (bufsize, channels); SAMPLE_BUFFER sbuf_test (bufsize, channels); SAMPLE_BUFFER_FUNCTIONS::fill_with_random_samples(&sbuf_orig); sbuf_test.copy_all_content(sbuf_orig); sbuf_ref.copy_all_content(sbuf_orig); sbuf_test.add_matching_channels(sbuf_orig); sbuf_ref.add_matching_channels_ref(sbuf_orig); if (SAMPLE_BUFFER_FUNCTIONS::is_almost_equal(sbuf_ref, sbuf_test) != true) { ECA_TEST_FAILURE("optimized add_matching_channels"); } } } ecasound-2.9.1/libecasound/eca-chainsetup-bufparams.h0000644000076400007640000000347210664032032017567 00000000000000#ifndef INCLUDED_ECA_CHAINSETUP_BUFPARAMS_H #define INCLUDED_ECA_CHAINSETUP_BUFPARAMS_H #include using std::string; class ECA_CHAINSETUP_BUFPARAMS { public: ECA_CHAINSETUP_BUFPARAMS(void); void set_all(const std::string& paramstring); void set_buffersize(long int value); void toggle_raised_priority(bool value); void set_sched_priority(int prio); void toggle_double_buffering(bool value); void set_double_buffer_size(long int v); void toggle_max_buffers(bool v); bool are_all_set(void) const; int number_of_set(void) const; long int buffersize(void) const { return(buffersize_rep); } bool raised_priority(void) const { return(raisedpriority_rep); } int get_sched_priority(void) const { return(sched_priority_rep); } bool double_buffering(void) const { return(double_buffering_rep); } long int double_buffer_size(void) const { return(double_buffer_size_rep); } bool max_buffers(void) const { return(max_buffers_rep); } bool is_set_buffersize(void) const { return(set_buffersize_rep); } bool is_set_raised_priority(void) const { return(set_raisedpriority_rep); } bool is_set_sched_priority(void) const { return(set_sched_priority_rep); } bool is_set_double_buffering(void) const { return(set_double_buffering_rep); } bool is_set_double_buffer_size(void) const { return(set_double_buffer_size_rep); } bool is_set_max_buffers(void) const { return(set_max_buffers_rep); } std::string to_string(void) const; private: long int buffersize_rep; bool raisedpriority_rep; int sched_priority_rep; bool double_buffering_rep; long int double_buffer_size_rep; bool max_buffers_rep; bool set_buffersize_rep; bool set_raisedpriority_rep; bool set_sched_priority_rep; bool set_double_buffering_rep; bool set_double_buffer_size_rep; bool set_max_buffers_rep; }; #endif ecasound-2.9.1/libecasound/eca-audio-position.cpp0000644000076400007640000001164211032774503016750 00000000000000// ------------------------------------------------------------------------ // eca-audio-position.cpp: Base class for representing position and length // of a audio stream. // Copyright (C) 1999-2002,2007,2008 Kai Vehmanen // // Attributes: // eca-style-version: 3 (see Ecasound Programmer's Guide) // // 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 #include /* ceil() */ #include #include "eca-audio-position.h" ECA_AUDIO_POSITION::ECA_AUDIO_POSITION(void) { length_set_rep = false; position_in_samples_rep = 0; length_in_samples_rep = 0; } ECA_AUDIO_POSITION::~ECA_AUDIO_POSITION(void) { } SAMPLE_SPECS::sample_pos_t ECA_AUDIO_POSITION::length_in_samples(void) const { return length_in_samples_rep; } int ECA_AUDIO_POSITION::length_in_seconds(void) const { DBC_CHECK(samples_per_second() != 0); return (int)ceil((double)length_in_samples() / (double)samples_per_second()); } double ECA_AUDIO_POSITION::length_in_seconds_exact(void) const { DBC_CHECK(samples_per_second() != 0); return (double)length_in_samples() / (double)samples_per_second(); } void ECA_AUDIO_POSITION::set_length_in_samples(SAMPLE_SPECS::sample_pos_t pos) { length_in_samples_rep = pos; length_set_rep = true; } void ECA_AUDIO_POSITION::set_length_in_seconds(int pos_in_seconds) { DBC_CHECK(samples_per_second() != 0); set_length_in_seconds((double)pos_in_seconds); } void ECA_AUDIO_POSITION::set_length_in_seconds(double pos_in_seconds) { DBC_CHECK(samples_per_second() != 0); set_length_in_samples(static_cast(pos_in_seconds * samples_per_second())); } SAMPLE_SPECS::sample_pos_t ECA_AUDIO_POSITION::position_in_samples(void) const { return position_in_samples_rep; } int ECA_AUDIO_POSITION::position_in_seconds(void) const { DBC_CHECK(samples_per_second() != 0); return (int)ceil((double)position_in_samples() / (double)samples_per_second()); } double ECA_AUDIO_POSITION::position_in_seconds_exact(void) const { DBC_CHECK(samples_per_second() != 0); return (double)position_in_samples() / (double)samples_per_second(); } void ECA_AUDIO_POSITION::set_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { position_in_samples_rep = pos; if (position_in_samples_rep < 0) { position_in_samples_rep = 0; } } void ECA_AUDIO_POSITION::change_position_in_samples(SAMPLE_SPECS::sample_pos_t pos) { position_in_samples_rep += pos; } void ECA_AUDIO_POSITION::change_position_in_seconds(double pos_in_seconds) { DBC_CHECK(samples_per_second() != 0); change_position_in_samples(static_cast(pos_in_seconds * samples_per_second())); } void ECA_AUDIO_POSITION::set_position_in_seconds(int pos_in_seconds) { DBC_CHECK(samples_per_second() != 0); set_position_in_seconds((double)pos_in_seconds); } void ECA_AUDIO_POSITION::set_position_in_seconds(double pos_in_seconds) { DBC_CHECK(samples_per_second() != 0); set_position_in_samples(static_cast(pos_in_seconds * samples_per_second())); } void ECA_AUDIO_POSITION::seek_first(void) { seek_position_in_samples(0); } void ECA_AUDIO_POSITION::seek_last(void) { seek_position_in_samples(length_in_samples()); } void ECA_AUDIO_POSITION::seek_position_in_samples(SAMPLE_SPECS::sample_pos_t pos_in_samples) { SAMPLE_SPECS::sample_pos_t res = seek_position(pos_in_samples); set_position_in_samples(res); } void ECA_AUDIO_POSITION::seek_position_in_samples_advance(SAMPLE_SPECS::sample_pos_t pos) { seek_position_in_samples(position_in_samples() + pos); } void ECA_AUDIO_POSITION::seek_position_in_seconds(double pos_in_seconds) { DBC_CHECK(samples_per_second() != 0); seek_position_in_samples(static_cast(pos_in_seconds * samples_per_second())); } void ECA_AUDIO_POSITION::set_samples_per_second(SAMPLE_SPECS::sample_rate_t new_value) { double ratio (new_value); ratio /= samples_per_second(); set_position_in_samples(static_cast(position_in_samples() * ratio)); if (length_set() == true) { set_length_in_samples(static_cast(length_in_samples() * ratio)); } ECA_SAMPLERATE_AWARE::set_samples_per_second(new_value); } ecasound-2.9.1/libecasound/midiio-raw.cpp0000644000076400007640000000550110664032032015307 00000000000000// ------------------------------------------------------------------------ // midiio-raw.cpp: Input and output of raw MIDI streams using standard // UNIX file operations. // Copyright (C) 2000,2005 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include "midiio-raw.h" #include "eca-logger.h" MIDI_IO_RAW::MIDI_IO_RAW(const std::string& name) { label("rawmidi"); device_name_rep = name; } MIDI_IO_RAW::~MIDI_IO_RAW(void) { if (is_open()) close(); } void MIDI_IO_RAW::open(void) { int flags = 0; switch(io_mode()) { case io_read: { flags = O_RDONLY; break; } case io_write: { flags = O_WRONLY; break; } case io_readwrite: { flags = O_RDWR; break; } } if (nonblocking_mode() == true) flags |= O_NONBLOCK; ECA_LOG_MSG(ECA_LOGGER::system_objects, "Opening midi device \"" + device_name_rep + "\"."); fd_rep = ::open(device_name_rep.c_str(), flags); if (fd_rep < 0) { toggle_open_state(false); } else { toggle_open_state(true); } finished_rep = false; } void MIDI_IO_RAW::close(void) { ::close(fd_rep); toggle_open_state(false); } bool MIDI_IO_RAW::finished(void) const { return finished_rep; } long int MIDI_IO_RAW::read_bytes(void* target_buffer, long int bytes) { /* note: ignore bytes, already read one byte at a time */ long int res = ::read(fd_rep, target_buffer, 1); if (res >= 0) return res; finished_rep = true; return 0; } long int MIDI_IO_RAW::write_bytes(void* target_buffer, long int bytes) { long int res = ::write(fd_rep, target_buffer, bytes); if (res >= 0) return res; finished_rep = true; return 0; } void MIDI_IO_RAW::set_parameter(int param, std::string value) { switch (param) { case 1: label(value); break; case 2: device_name_rep = value; break; } } std::string MIDI_IO_RAW::get_parameter(int param) const { switch (param) { case 1: return label(); case 2: return device_name_rep; } return ""; } ecasound-2.9.1/libecasound/audioio-loop.h0000644000076400007640000000364511501246164015326 00000000000000#ifndef INCLUDED_AUDIOIO_LOOP_DEVICE_H #define INCLUDED_AUDIOIO_LOOP_DEVICE_H #include #include #include "audioio.h" #include "samplebuffer.h" /** * Audio object that routes data from inputs to outputs */ class LOOP_DEVICE : public AUDIO_IO { public: LOOP_DEVICE(std::string tag); LOOP_DEVICE(void) { } virtual ~LOOP_DEVICE(void); virtual LOOP_DEVICE* clone(void) const; virtual LOOP_DEVICE* new_expr(void) const { return new LOOP_DEVICE(); } virtual std::string name(void) const { return("Internal loop device"); } virtual std::string description(void) const { return("Loop device that routes data from output to input."); } /** @name Function reimplemented from AUDIO_IO */ /*@{*/ virtual int supported_io_modes(void) const { return io_read | io_write; } virtual bool locked_audio_format(void) const { return true; } virtual void open(void) throw(AUDIO_IO::SETUP_ERROR&); virtual void set_buffersize(long int samples) { }; virtual long int buffersize(void) const { return(0); }; virtual void read_buffer(SAMPLE_BUFFER* sbuf); virtual void write_buffer(SAMPLE_BUFFER* sbuf); virtual bool finished(void) const; virtual SAMPLE_SPECS::sample_pos_t seek_position(SAMPLE_SPECS::sample_pos_t pos); virtual std::string parameter_names(void) const { return("label,id_number"); } virtual void set_parameter(int param, std::string value); virtual std::string get_parameter(int param) const; /*@}*/ /** * Register a new input client */ void register_input(void) { ++registered_inputs_rep; } /** * Register a new output client */ void register_output(void) { ++registered_outputs_rep; } const std::string& tag(void) const { return(tag_rep); } private: std::string tag_rep; int writes_rep; int registered_inputs_rep; int registered_outputs_rep; int empty_rounds_rep; bool finished_rep; bool filled_rep; SAMPLE_BUFFER sbuf; }; #endif ecasound-2.9.1/libecasound/audioio-timidity.cpp0000644000076400007640000001074611137153043016542 00000000000000// ------------------------------------------------------------------------ // audioio-timidity.cpp: Interface class for Timidity++ input. // Copyright (C) 2000,2002,2004-2006,2008,2009 Kai Vehmanen // // 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 #include /* stat() */ #include /* stat() */ #include #include "audioio-timidity.h" #include "eca-logger.h" string TIMIDITY_INTERFACE::default_timidity_cmd = "timidity -Or1S -id -s %s -o - %f"; void TIMIDITY_INTERFACE::set_timidity_cmd(const std::string& value) { TIMIDITY_INTERFACE::default_timidity_cmd = value; } TIMIDITY_INTERFACE::TIMIDITY_INTERFACE(const std::string& name) : triggered_rep(false), finished_rep(false) { } TIMIDITY_INTERFACE::~TIMIDITY_INTERFACE(void) { clean_child(true); if (is_open() == true) { close(); } } void TIMIDITY_INTERFACE::open(void) throw (AUDIO_IO::SETUP_ERROR &) { std::string urlprefix; struct stat buf; int ret = ::stat(label().c_str(), &buf); if (ret != 0) { size_t offset = label().find_first_of("://"); if (offset == std::string::npos) { throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-TIMIDITY: Can't open file " + label() + ".")); } else { urlprefix = std::string(label(), 0, offset); ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-timidity) Found url; protocol '" + urlprefix + "'."); } } /* decoder supports: s16 samples, 2 channels, srate configurable no support for: endianess (use native) */ set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16); set_channels(2); triggered_rep = false; finished_rep = false; AUDIO_IO::open(); } void TIMIDITY_INTERFACE::close(void) { if (pid_of_child() > 0) { if (io_mode() == io_read) { kill_timidity(); } } AUDIO_IO::close(); } long int TIMIDITY_INTERFACE::read_samples(void* target_buffer, long int samples) { if (triggered_rep != true) { ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context"); triggered_rep = true; fork_timidity(); } bytes_read_rep = std::fread(target_buffer, 1, frame_size() * samples, f1_rep); if (bytes_read_rep < samples * frame_size() || bytes_read_rep == 0) { if (position_in_samples() == 0) ECA_LOG_MSG(ECA_LOGGER::info, "Can't start process \"" + TIMIDITY_INTERFACE::default_timidity_cmd + "\". Please check your ~/.ecasound/ecasoundrc."); finished_rep = true; triggered_rep = false; } else finished_rep = false; return(bytes_read_rep / frame_size()); } void TIMIDITY_INTERFACE::kill_timidity(void) { ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-timidity) Cleaning Timidity++-child with pid=" + kvu_numtostr(pid_of_child()) + "."); clean_child(); triggered_rep = false; } void TIMIDITY_INTERFACE::fork_timidity(void) { set_fork_command(TIMIDITY_INTERFACE::default_timidity_cmd); set_fork_file_name(label()); set_fork_bits(bits()); set_fork_channels(channels()); set_fork_sample_rate(samples_per_second()); fork_child_for_read(); if (child_fork_succeeded() == true) { /* NOTE: the file description will be closed by * AUDIO_IO_FORKED_STREAM::clean_child() */ filedes_rep = file_descriptor(); f1_rep = fdopen(filedes_rep, "r"); /* not part of */ if (f1_rep == 0) { finished_rep = true; triggered_rep = false; } } if (wait_for_child() != true) { finished_rep = true; triggered_rep = false; } } void TIMIDITY_INTERFACE::start_io(void) { if (triggered_rep != true) { if (io_mode() == io_read) fork_timidity(); triggered_rep = true; } } void TIMIDITY_INTERFACE::stop_io(void) { if (triggered_rep == true) { if (io_mode() == io_read) clean_child(true); triggered_rep = false; } } ecasound-2.9.1/config.h.in0000644000076400007640000001670712261511345012313 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* disable all use of shared libs */ #undef ECA_ALL_STATIC /* enable ALSA support */ #undef ECA_COMPILE_ALSA /* enable aRts support */ #undef ECA_COMPILE_ARTS /* enable libaudiofile support */ #undef ECA_COMPILE_AUDIOFILE /* enable JACK support */ #undef ECA_COMPILE_JACK /* enable OSS audio input/output */ #undef ECA_COMPILE_OSS /* enable libsamplerate support */ #undef ECA_COMPILE_SAMPLERATE /* enable libsndfile support */ #undef ECA_COMPILE_SNDFILE /* debugging mode build */ #undef ECA_DEBUG_MODE /* disable all effects */ #undef ECA_DISABLE_EFFECTS /* disable use of OSS trigger API */ #undef ECA_DISABLE_OSS_TRIGGER /* enable experimental features */ #undef ECA_FEELING_EXPERIMENTAL /* ecasound specific versioning of JACK interface features */ #undef ECA_JACK_FEATSET /* version of JACK transport API to use */ #undef ECA_JACK_TRANSPORT_API /* enable ecasound curses console interface */ #undef ECA_PLATFORM_CURSES /* Ecasound configure script prefix */ #undef ECA_PREFIX /* use ncurses.h for curses interface */ #undef ECA_USE_CURSES_H /* use C++ std namespace */ #undef ECA_USE_CXX_STD_NAMESPACE /* Use liblilv for LV2 support */ #undef ECA_USE_LIBLILV /* Use liblo for OSC support */ #undef ECA_USE_LIBLO /* Use liboil */ #undef ECA_USE_LIBOIL /* use curses.h for curses interface */ #undef ECA_USE_NCURSES_H /* ncurses headers are installed in ncurses subdir */ #undef ECA_USE_NCURSES_NCURSES_H /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the header file. */ #undef HAVE_EXECINFO_H /* Define to 1 if you have the `execvp' function. */ #undef HAVE_EXECVP /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the header file. */ #undef HAVE_FEATURES_H /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LADSPA_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mlockall' function. */ #undef HAVE_MLOCKALL /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define to 1 if you have the `munlockall' function. */ #undef HAVE_MUNLOCKALL /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP /* Define to 1 if you have the `pause' function. */ #undef HAVE_PAUSE /* Define to 1 if you have the `posix_memalign' function. */ #undef HAVE_POSIX_MEMALIGN /* Define to 1 if you have the `pthread_getschedparam' function. */ #undef HAVE_PTHREAD_GETSCHEDPARAM /* Define to 1 if you have the `pthread_kill' function. */ #undef HAVE_PTHREAD_KILL /* Define to 1 if you have the `pthread_mutexattr_init' function. */ #undef HAVE_PTHREAD_MUTEXATTR_INIT /* Define to 1 if you have the `pthread_self' function. */ #undef HAVE_PTHREAD_SELF /* Define to 1 if you have the `pthread_setschedparam' function. */ #undef HAVE_PTHREAD_SETSCHEDPARAM /* Define to 1 if you have the `pthread_sigmask' function. */ #undef HAVE_PTHREAD_SIGMASK /* Define to 1 if you have the header file. */ #undef HAVE_REGEX_H /* Define to 1 if you have the `sched_getparam' function. */ #undef HAVE_SCHED_GETPARAM /* Define to 1 if you have the `sched_getscheduler' function. */ #undef HAVE_SCHED_GETSCHEDULER /* Define to 1 if you have the `sched_get_priority_max' function. */ #undef HAVE_SCHED_GET_PRIORITY_MAX /* Define to 1 if you have the header file. */ #undef HAVE_SCHED_H /* Define to 1 if you have the `sched_setscheduler' function. */ #undef HAVE_SCHED_SETSCHEDULER /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H /* Define to 1 if you have the `sigprocmask' function. */ #undef HAVE_SIGPROCMASK /* Define to 1 if you have the `sigwait' function. */ #undef HAVE_SIGWAIT /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP /* libecasoundc interface version */ #undef LIBECASOUNDC_VERSION /* libecasound interface version */ #undef LIBECASOUND_VERSION /* libecasound interface age */ #undef LIBECASOUND_VERSION_AGE /* libkvutils interface version */ #undef LIBKVUTILS_VERSION /* libkvutils interface age */ #undef LIBKVUTILS_VERSION_AGE /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Version number of package */ #undef VERSION /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Define to `unsigned int' if does not define. */ #undef size_t ecasound-2.9.1/rubyecasound/0000755000076400007640000000000012261520737013045 500000000000000ecasound-2.9.1/rubyecasound/Makefile.in0000644000076400007640000003773012261511325015035 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/pyecasound/Makefile.am # Description: Ruby implmentation of the Ecasound Control Interface # License: LGPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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 = rubyecasound DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign EXTRA_DIST = README \ ecasound.rb \ stresstest.rb # ---------------------------------------------------------------------- # defines # ---------------------------------------------------------------------- @ECA_AM_RUBYECASOUND_INSTALL_TRUE@rubyecasound_install_list1 = $(srcdir)/ecasound.rb @ECA_AM_RUBYECASOUND_INSTALL_TRUE@rubyecasound_uninstall_list1 = $(DESTDIR)$(ECA_S_RUBY_SITEDIR)/ecasound.rb @ECA_AM_RUBYECASOUND_INSTALL_TRUE@TESTS = stresstest.rb all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign rubyecasound/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign rubyecasound/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list='$(TESTS)'; \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ ;; \ *) \ echo "PASS: $$tst"; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ *) \ failed=`expr $$failed + 1`; \ echo "FAIL: $$tst"; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ echo "SKIP: $$tst"; \ fi; \ done; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="All $$all tests passed"; \ else \ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all tests failed"; \ else \ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ skipped="($$skip tests were not run)"; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ echo "$$dashes"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: 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) 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-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am uninstall-local .PHONY: all all-am check check-TESTS check-am clean clean-generic \ clean-libtool clean-local distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-exec-hook install-info install-info-am \ install-man install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am uninstall-info-am \ uninstall-local # ---------------------------------------------------------------------- # hooks # ---------------------------------------------------------------------- # unit test requires "ecasound.rb" in the build directory stresstest.rb: ecasound.rb-STAMP ecasound.rb-STAMP: $(srcdir)/ecasound.rb if test ! -e ecasound.rb ; then $(LN_S) $(srcdir)/ecasound.rb . ; fi touch ecasound.rb-STAMP @ECA_AM_RUBYECASOUND_INSTALL_TRUE@install-exec-hook: $(rubyecasound_install_list1) $(rubyecasound_install_list2) @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ $(INSTALL) -d $(DESTDIR)$(ECA_S_RUBY_SITEDIR) @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ $(INSTALL) $(rubyecasound_install_list1) $(rubyecasound_install_list2) $(DESTDIR)$(ECA_S_RUBY_SITEDIR)/ @ECA_AM_RUBYECASOUND_INSTALL_FALSE@install-exec-hook: @ECA_AM_RUBYECASOUND_INSTALL_TRUE@uninstall-local: @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ rm -f $(rubyecasound_uninstall_list1) $(rubyecasound_uninstall_list2) @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ rmdir $(DESTDIR)$(ECA_S_RUBY_SITEDIR) || echo "Skipping non-empty directory" @ECA_AM_RUBYECASOUND_INSTALL_FALSE@uninstall-local: clean-local: rm -vf ecasound.rb-STAMP # 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: ecasound-2.9.1/rubyecasound/Makefile.am0000644000076400007640000000327511172656140015026 00000000000000# ---------------------------------------------------------------------- # File: ecasound/pyecasound/Makefile.am # Description: Ruby implmentation of the Ecasound Control Interface # License: LGPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- AUTOMAKE_OPTIONS = foreign EXTRA_DIST = README \ ecasound.rb \ stresstest.rb # ---------------------------------------------------------------------- # defines # ---------------------------------------------------------------------- if ECA_AM_RUBYECASOUND_INSTALL rubyecasound_install_list1 = $(srcdir)/ecasound.rb rubyecasound_uninstall_list1 = $(DESTDIR)$(ECA_S_RUBY_SITEDIR)/ecasound.rb endif if ECA_AM_RUBYECASOUND_INSTALL TESTS = stresstest.rb endif # ---------------------------------------------------------------------- # hooks # ---------------------------------------------------------------------- # unit test requires "ecasound.rb" in the build directory stresstest.rb: ecasound.rb-STAMP ecasound.rb-STAMP: $(srcdir)/ecasound.rb if test ! -e ecasound.rb ; then $(LN_S) $(srcdir)/ecasound.rb . ; fi touch ecasound.rb-STAMP if ECA_AM_RUBYECASOUND_INSTALL install-exec-hook: $(rubyecasound_install_list1) $(rubyecasound_install_list2) $(INSTALL) -d $(DESTDIR)$(ECA_S_RUBY_SITEDIR) $(INSTALL) $(rubyecasound_install_list1) $(rubyecasound_install_list2) $(DESTDIR)$(ECA_S_RUBY_SITEDIR)/ else install-exec-hook: endif if ECA_AM_RUBYECASOUND_INSTALL uninstall-local: rm -f $(rubyecasound_uninstall_list1) $(rubyecasound_uninstall_list2) rmdir $(DESTDIR)$(ECA_S_RUBY_SITEDIR) || echo "Skipping non-empty directory" else uninstall-local: endif clean-local: rm -vf ecasound.rb-STAMPecasound-2.9.1/rubyecasound/stresstest.rb0000755000076400007640000000563212260762753015553 00000000000000#!/usr/bin/env ruby # ----------------------------------------------------------------------- # Runs a stress test using the ruby-ecasound ControlInterface # Jan Weil # Adapted from original code for ecacontrol.py/pyecasound: # Copyright (C) 2003 Kai Vehmanen # Licensed under GPL. See the file 'COPYING' for more information. # ----------------------------------------------------------------------- if test(?x, "../ecasound/ecasound_debug") ENV['ECASOUND'] = "../ecasound/ecasound_debug" end if test(?x, "../ecasound/ecasound") ENV['ECASOUND'] = "../ecasound/ecasound" end # workaround to support both ruby >=1.9 (current dir not # in $LOAD_PATH) and older ruby versions require File.expand_path('.', "ecasound") # --- # configuration variables # run for how many seconds runlen = 5 # debug level (0, 1, 2) debuglevel = 2 # if above tests fail, the default ecasound binary # will be used # main program e = Ecasound::ControlInterface.new() result = 0 e.command("cs-add play_chainsetup") e.command("c-add 1st_chain") e.command("ai-add rtnull") e.command("ao-add null") e.command("cop-add -ezx:1,0.0") e.command("ctrl-add -kos:2,-1,1,300,0") e.command("cop-add -efl:300") e.command("cop-add -evp") e.command("cop-select 3") e.command("copp-select 1") e.command("cs-connect") e.command("start") total_cmds = 0 curpos = 0 # not a block var! copp = 0 puts "Test1" while true curpos = e.command("get-position") break if curpos > runlen copp = e.command("copp-get") if debuglevel == 2 #print curpos, e.last_float() #if curpos == None: # curpos = 0.0 $stderr << "#{curpos} #{copp}\r" # sys.stderr.write('%6.2f %6.4f\r' % (curpos,e.last_float())) else $stderr << '.' if debuglevel == 1 end total_cmds += 2 end $stderr << "\nprocessing speed: #{total_cmds / runlen} cmds/second.\n" if debuglevel == 2 $stderr << "\n" if debuglevel > 0 e.command("stop") e.command("cs-disconnect") # Test 2 puts "Test2" e.command("cs-remove") e.command("cs-add play_chainsetup") e.command("c-add 1st_chain") e.command("ai-add rtnull") e.command("ao-add null") e.command("cop-add -ezx:1,0.0") e.command("ctrl-add -kos:2,-1,1,300,0") e.command("cop-add -efl:300") e.command("cop-add -evp") e.command("cop-select 3") e.command("copp-select 1") e.command("cs-connect") e.command("start") total_cmds = 0 curpos = 0 # not a block var! copp = 0 while true curpos = e.command("get-position") break if curpos > runlen e.command("copp-get") # some commands that return a lot # of return data e.command("cop-register") e.command("aio-register") e.command("int-cmd-list") total_cmds = total_cmds + 4 $stderr << '.' if debuglevel > 0 end e.command("stop") e.command("cs-disconnect") $stderr << "\nprocessing speed: #{total_cmds / runlen} cmds/second.\n" if debuglevel == 2 $stderr << "\n" if debuglevel > 0 e.command("quit") exit(result) ecasound-2.9.1/rubyecasound/README0000644000076400007640000000063312260765643013655 00000000000000 ecasound-ruby ------------- This is the first part of an ecasound module for Ruby. It was written with Ruby 1.8.0 but it should also work with Ruby 1.6.8. (Someone to prove this?) documentation ------------- See the Ecasound Control Interface (ECI) Guide and related documents: dist package: ecasound/Documentation/ web.........: http://nosignal.fi/ecasound Have fun, Jan Weil ecasound-2.9.1/rubyecasound/ecasound.rb0000644000076400007640000001204610664032032015105 00000000000000# This is a native implementation of Ecasound's control interface for Ruby. # Copyright (C) 2003 - 2004 Jan Weil # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 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 # --------------------------------------------------------------------------- =begin = ruby-ecasound Example: require "ecasound" eci = Ecasound::ControlInterface.new(ecasound_args) ecasound-response = eci.command("iam-command-here") ... TODO: Is there a chance that the ecasound process gets zombified? =end require "timeout" require "thread" class File def self::which(prog, path=ENV['PATH']) path.split(File::PATH_SEPARATOR).each do |dir| f = File::join(dir, prog) if File::executable?(f) && ! File::directory?(f) return f end end end end # File class VersionString < String attr_reader :numbers def initialize(str) if str.split(".").length() != 3 raise("Versioning scheme must be major.minor.micro") end super(str) @numbers = [] str.split(".").each {|s| @numbers.push(s.to_i())} end def <=>(other) numbers.each_index do |i| if numbers[i] < other.numbers[i] return -1 elsif numbers[i] > other.numbers[i] return 1 elsif i < 2 next end end return 0 end end # VersionString module Ecasound REQUIRED_VERSION = VersionString.new("2.2.0") TIMEOUT = 15 # seconds before sync is called 'lost' class EcasoundError < RuntimeError; end class EcasoundCommandError < EcasoundError attr_accessor :command, :error def initialize(command, error) @command = command @error = error end end class ControlInterface @@ecasound = ENV['ECASOUND'] || File::which("ecasound") if not File::executable?(@@ecasound.to_s) raise("ecasound executable not found") else @@version = VersionString.new(`#{@@ecasound} --version`.split("\n")[0][/\d\.\d\.\d/]) if @@version < REQUIRED_VERSION raise("ecasound version #{REQUIRED_VERSION} or newer required, found: #{@@version}") end end def initialize(args = nil) @mutex = Mutex.new() @ecapipe = IO.popen("-", "r+") # fork! if @ecapipe.nil? # child $stderr.reopen(open("/dev/null", "w")) exec("#{@@ecasound} #{args.to_s} -c -D -d:256 ") else @ecapipe.sync = true # parent command("int-output-mode-wellformed") end end def cleanup() @ecapipe.close() end def command(cmd) @mutex.synchronize do cmd.strip!() #puts "command: #{cmd}" @ecapipe.write(cmd + "\n") # ugly hack but the process gets stuck otherwise -kvehmanen if cmd == "quit" return nil end response = "" begin # TimeoutError is raised unless response is complete timeout(TIMEOUT) do loop do response += read() break if response =~ /256 ([0-9]{1,5}) (\-|i|li|f|s|S|e)\r\n(.*)\r\n\r\n/m end end rescue TimeoutError raise(EcasoundError, "lost synchronisation to ecasound subprocess\nlast command was: '#{cmd}'") end content = $3[0, $1.to_i()] #puts "type: '#{$2}'" #puts "length: #{$1}" #puts "content: #{content}" case $2 when "e" raise(EcasoundCommandError.new(cmd, content)) when "-" return nil when "s" return content when "S" return content.split(",") when "f" return content.to_f() when "i", "li" return content.to_i() else raise(EcasoundError, "parsing of ecasound's output produced an unknown return type") end end end private def read() buffer = "" while select([@ecapipe], nil, nil, 0) buffer += @ecapipe.read(1) || "" end return buffer end end # ControlInterface end # Ecasound:: ecasound-2.9.1/kvutils/0000755000076400007640000000000012261520736012042 500000000000000ecasound-2.9.1/kvutils/kvu_procedure_timer.h0000644000076400007640000000371311747045406016220 00000000000000// -*- mode: C++; -*- #ifndef INCLUDED_KVU_PROCEDURE_TIMER #define INCLUDED_KVU_PROCEDURE_TIMER #include #include #include /** * Procedure timer. Meant for timing and gathering statistics of * repeating events. * * @author Kai Vehmanen */ class PROCEDURE_TIMER { public: void set_upper_bound(const struct timeval *); void set_upper_bound_seconds(double secs); void set_lower_bound(const struct timeval *); void set_lower_bound_seconds(double secs); void start(void); void start(const struct timespec *t) { start_rep = *t; } void stop(void); void stop(const struct timespec *t) { now_rep = *t; stop_helper(); } void reset(void); long int events_over_upper_bound(void) const; long int events_under_lower_bound(void) const; long int event_count(void) const; double max_duration_seconds(void) const; double min_duration_seconds(void) const; double average_duration_seconds(void) const; double last_duration_seconds(void) const; const struct timespec* min_duration(void) const; const struct timespec* max_duration(void) const; std::string to_string(void) const; PROCEDURE_TIMER(int id = 0); ~PROCEDURE_TIMER(void); private: PROCEDURE_TIMER(const PROCEDURE_TIMER& x) { } PROCEDURE_TIMER& operator=(const PROCEDURE_TIMER& x) { return *this; } void stop_helper(void); bool less_than(const struct timespec *i, const struct timespec *ii) const; void subtract(struct timespec *i, const struct timespec *ii) const; double to_seconds(const struct timeval *i) const; double to_seconds(const struct timespec *i) const; struct timespec start_rep; struct timespec now_rep; struct timespec min_event_rep; struct timespec max_event_rep; struct timespec lower_bound_rep; struct timespec upper_bound_rep; double event_time_total_rep; double last_duration_rep; long int events_rep; long int events_over_bound_rep; long int events_under_bound_rep; std::string idstr_rep; }; #endif ecasound-2.9.1/kvutils/Makefile.in0000644000076400007640000006230412261511324014025 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/kvutils/Makefile.am # Description: Misc. utility routines (library created by Kai Vehmanen) # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ check_PROGRAMS = $(am__EXEEXT_1) subdir = kvutils DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in COPYING ChangeLog INSTALL ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libkvutils_la_LIBADD = am__objects_1 = kvu_dbc.lo kvu_debug.lo kvu_com_line.lo kvu_fd_io.lo \ kvu_locks.lo kvu_message_item.lo kvu_numtostr.lo \ kvu_procedure_timer.lo kvu_rtcaps.lo \ kvu_temporary_file_directory.lo kvu_threads.lo kvu_utils.lo \ kvu_timestamp.lo kvu_value_queue.lo am__objects_2 = am_libkvutils_la_OBJECTS = $(am__objects_1) $(am__objects_2) libkvutils_la_OBJECTS = $(am_libkvutils_la_OBJECTS) @ECA_AM_DEBUG_MODE_FALSE@am_libkvutils_la_rpath = -rpath $(libdir) libkvutils_debug_la_LIBADD = am__objects_3 = $(am__objects_1) $(am__objects_2) am_libkvutils_debug_la_OBJECTS = $(am__objects_3) libkvutils_debug_la_OBJECTS = $(am_libkvutils_debug_la_OBJECTS) @ECA_AM_DEBUG_MODE_TRUE@am_libkvutils_debug_la_rpath = -rpath \ @ECA_AM_DEBUG_MODE_TRUE@ $(libdir) am__EXEEXT_1 = libkvutils_tester$(EXEEXT) am_libkvutils_tester_OBJECTS = libkvutils_tester.$(OBJEXT) libkvutils_tester_OBJECTS = $(am_libkvutils_tester_OBJECTS) @ECA_AM_DEBUG_MODE_FALSE@am__DEPENDENCIES_1 = libkvutils.la @ECA_AM_DEBUG_MODE_TRUE@am__DEPENDENCIES_1 = libkvutils_debug.la libkvutils_tester_DEPENDENCIES = $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libkvutils_la_SOURCES) $(libkvutils_debug_la_SOURCES) \ $(libkvutils_tester_SOURCES) DIST_SOURCES = $(libkvutils_la_SOURCES) $(libkvutils_debug_la_SOURCES) \ $(libkvutils_tester_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign @ECA_AM_DEBUG_MODE_FALSE@lib_LTLIBRARIES = libkvutils.la # --- # Makefile.am for building libkvutils.a # --- @ECA_AM_DEBUG_MODE_TRUE@lib_LTLIBRARIES = libkvutils_debug.la TESTS = libkvutils_tester INCLUDES = $(ECA_S_EXTRA_CPPFLAGS) kvutil_sources = kvu_dbc.cpp \ kvu_debug.cpp \ kvu_com_line.cpp \ kvu_fd_io.cpp \ kvu_locks.cpp \ kvu_message_item.cpp \ kvu_numtostr.cpp \ kvu_procedure_timer.cpp \ kvu_rtcaps.cpp \ kvu_temporary_file_directory.cpp \ kvu_threads.cpp \ kvu_utils.cpp \ kvu_timestamp.cpp \ kvu_value_queue.cpp kvutil_headers = kvu_dbc.h \ kvu_debug.h \ kvu_definition_by_contract.h \ kvu_com_line.h \ kvu_fd_io.h \ kvu_inttypes.h \ kvu_locks.h \ kvu_message_item.h \ kvu_message_queue.h \ kvu_numtostr.h \ kvu_object_queue.h \ kvu_procedure_timer.h \ kvu_rtcaps.h \ kvu_temporary_file_directory.h \ kvu_threads.h \ kvu_utils.h \ kvu_timestamp.h \ kvu_value_queue.h libkvutils_la_SOURCES = $(kvutil_sources) $(kvutil_headers) libkvutils_la_LDFLAGS = -version-info @LIBKVUTILS_VERSION@:0:@LIBKVUTILS_VERSION_AGE@ -static libkvutils_debug_la_SOURCES = $(libkvutils_la_SOURCES) libkvutils_debug_la_LDFLAGS = $(libkvutils_la_LDFLAGS) libkvutils_tester_SOURCES = libkvutils_tester.cpp libkvutils_tester_LDFLAGS = -static libkvutils_tester_LDADD = $(lib_LTLIBRARIES) noinst_HEADERS = $(kvutil_headers) all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign kvutils/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign kvutils/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_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 libkvutils.la: $(libkvutils_la_OBJECTS) $(libkvutils_la_DEPENDENCIES) $(CXXLINK) $(am_libkvutils_la_rpath) $(libkvutils_la_LDFLAGS) $(libkvutils_la_OBJECTS) $(libkvutils_la_LIBADD) $(LIBS) libkvutils_debug.la: $(libkvutils_debug_la_OBJECTS) $(libkvutils_debug_la_DEPENDENCIES) $(CXXLINK) $(am_libkvutils_debug_la_rpath) $(libkvutils_debug_la_LDFLAGS) $(libkvutils_debug_la_OBJECTS) $(libkvutils_debug_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done libkvutils_tester$(EXEEXT): $(libkvutils_tester_OBJECTS) $(libkvutils_tester_DEPENDENCIES) @rm -f libkvutils_tester$(EXEEXT) $(CXXLINK) $(libkvutils_tester_LDFLAGS) $(libkvutils_tester_OBJECTS) $(libkvutils_tester_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_com_line.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_dbc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_fd_io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_locks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_message_item.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_numtostr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_procedure_timer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_rtcaps.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_temporary_file_directory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_threads.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_timestamp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kvu_value_queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkvutils_tester.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: 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; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list='$(TESTS)'; \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ ;; \ *) \ echo "PASS: $$tst"; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ *) \ failed=`expr $$failed + 1`; \ echo "FAIL: $$tst"; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ echo "SKIP: $$tst"; \ fi; \ done; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="All $$all tests passed"; \ else \ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all tests failed"; \ else \ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ skipped="($$skip tests were not run)"; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ echo "$$dashes"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)"; 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) 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-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-exec-am: install-libLTLIBRARIES install-info: install-info-am install-man: 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-info-am uninstall-libLTLIBRARIES \ uninstall-local .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool 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-data-local install-exec \ install-exec-am install-info install-info-am \ install-libLTLIBRARIES install-man 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-info-am \ uninstall-libLTLIBRARIES uninstall-local # --------------------------------------------------------------------- # Install targets install-data-local: $(INSTALL) -d $(DESTDIR)$(includedir)/kvutils cd $(srcdir) ; cp $(kvutil_headers) $(DESTDIR)$(includedir)/kvutils # --------------------------------------------------------------------- # Uninstall targets uninstall-local: cd $(DESTDIR)$(includedir)/kvutils && \ rm -f $(kvutil_headers) rmdir $(DESTDIR)$(includedir)/kvutils || echo "Skipping non-empty directory" # 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: ecasound-2.9.1/kvutils/kvu_temporary_file_directory.cpp0000644000076400007640000001370310664032032020454 00000000000000// ------------------------------------------------------------------------ // kvu_temporary_file_directory.cpp: Provides services for allocating and // reserving secure, temporary // directories. // Copyright (C) 2001,2004 Kai Vehmanen // // 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 /* getenv() */ #include /* mkdir() */ #include /* getuid(), geteuid(), mkdir(), lstat() */ #include /* mkdir() */ #include /* getuid(), geteuid(), mkdir(), lstat(), getpid() */ #include /* errno */ #include "kvu_numtostr.h" #include "kvu_temporary_file_directory.h" /** * Constructor. */ TEMPORARY_FILE_DIRECTORY::TEMPORARY_FILE_DIRECTORY(void) : valid_rep(false) { } /** * Constructor that reserves a new directory. */ TEMPORARY_FILE_DIRECTORY::TEMPORARY_FILE_DIRECTORY(const std::string& dir) : valid_rep(false) { reserve_directory(dir); } /** * Reserves a new directory. In addition to argument 'dir', * UNIX environment variables TMPDIR, TMP are used when * physically creating the directory. If these variables are * not defined, default "/tmp" is used. */ void TEMPORARY_FILE_DIRECTORY::reserve_directory(const std::string& dir) { if (is_valid() == true) { release_directory(); } tdir_rep = get_directory_prefix() + "/" + dir; /* FIXME: add 'unlink(tdir_rep.c_str());' ? */ int result = mkdir(tdir_rep.c_str(), 0700); if (result == 0 || errno == EEXIST) { check_validity(); if (is_valid() != true) { release_directory(); } } else { /* FIXME: should we try something else here? for instance * selecting 'dir+string(n+1)'? */ // cerr << "(kvutils) " << "mkdir(" << tdir_rep << ") failed" << endl; valid_rep = false; } } /** * Releases the directory. The physical directory * is removed. For this to succeed, all created * temporary files must first be removed. */ void TEMPORARY_FILE_DIRECTORY::release_directory(void) { rmdir(tdir_rep.c_str()); valid_rep = false; } /** * Destructor. Releases the directory. */ TEMPORARY_FILE_DIRECTORY::~TEMPORARY_FILE_DIRECTORY(void) { if (is_valid() == true) { release_directory(); } } void TEMPORARY_FILE_DIRECTORY::check_validity(void) { struct stat statbuf; valid_rep = true; lstat(tdir_rep.c_str(), &statbuf); if (statbuf.st_uid != geteuid()) { valid_rep = false; // cerr << "(kvutils) " << "st_uid doesn't match." << endl; } // kaiv, 10.10.2001 - removed as unnecessary // if (statbuf.st_gid != getegid()) { // valid_rep = false; // cerr << "(kvutils) " << "st_gid doesn't match." << endl; // } if (!S_ISDIR(statbuf.st_mode)) { valid_rep = false; // cerr << "(kvutils) " << "st_mode - not a directory." << endl; } if (S_ISLNK(statbuf.st_mode)) { valid_rep = false; // cerr << "(kvutils) " << "st_mode - a symbolic link." << endl; } if ((statbuf.st_mode & S_IRWXG) > 0) { valid_rep = false; // cerr << "(kvutils) " << "st_mode - group has access." << endl; } if ((statbuf.st_mode & S_IRWXO) > 0) { valid_rep = false; // cerr << "(kvutils) " << "st_mode - others have access." << endl; } } /** * Sets a new directory prefix (for instance "/tmp"). The new * setting will take effect when the reserve_directory() is issued. */ void TEMPORARY_FILE_DIRECTORY::set_directory_prefix(const std::string& dir) { dirprefix_rep = dir; } std::string TEMPORARY_FILE_DIRECTORY::get_directory_prefix(void) const { if (dirprefix_rep.size() > 0) { return(dirprefix_rep); } std::string tmpname ("/tmp"); if ((getuid() == geteuid()) && (getgid() == getegid())) { char* tmpdir_p = NULL; tmpdir_p = getenv("TMPDIR"); if (tmpdir_p != NULL) { if (tmpdir_p != NULL) tmpname = std::string(tmpdir_p); } else { tmpdir_p = getenv("TMP"); if (tmpdir_p != NULL) tmpname = std::string(tmpdir_p); } } return(tmpname); } /** * Returns the whole path of the reserved directory. */ std::string TEMPORARY_FILE_DIRECTORY::get_reserved_directory(void) const { if (is_valid() == true) return(tdir_rep); return(""); } /** * Returns a new unique name with prefix 'prefix'. Notice * that files won't be opened or removed, only a filename * is generated. Returns an empty string if directory is not * in valid state, or an error has occured. */ std::string TEMPORARY_FILE_DIRECTORY::create_filename(const std::string& prefix, const std::string& postfix) { std::string fname (tdir_rep + "/" + prefix + "-" + kvu_numtostr(getpid()) + "-"); struct stat statbuf; for(int n = 0; n < TEMPORARY_FILE_DIRECTORY::max_temp_files; n++) { if (is_valid() != true) break; std::string temp = fname + kvu_numtostr(tmp_index_rep) + postfix; if (tmp_index_rep > TEMPORARY_FILE_DIRECTORY::max_temp_files) tmp_index_rep = 0; ++tmp_index_rep; int res = lstat(temp.c_str(), &statbuf); if (res == -1 && errno == ENOENT) { // cerr << "(kvutils) Creating temp file " << temp << "." << endl; return(temp); } } return(""); } /** * Whether directory is ready for use. */ bool TEMPORARY_FILE_DIRECTORY::is_valid(void) const { return(valid_rep); } ecasound-2.9.1/kvutils/kvu_debug.cpp0000644000076400007640000000444311162771361014447 00000000000000// ------------------------------------------------------------------------ // kvu_debug.cpp: Debug helper functions // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ // References // - glibc manual (section "33.1 Backtraces" // http://www.gnu.org/software/libc/manual/html_node/index.html#toc_Debugging-Support #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_FEATURES_H #include #endif using namespace std; /* backtrace is an GNU glibc extension and it was * first added to glibc 2.1 */ #if defined(__GLIBC_PREREQ) #if __GLIBC_PREREQ(2,1) && defined(HAVE_EXECINFO_H) #include #include #include void kvu_print_backtrace_stderr(void) { const int NUM_STACK_FRAMES = 10; void *array[NUM_STACK_FRAMES]; size_t size; char **strings; size_t i; size = backtrace (array, NUM_STACK_FRAMES); strings = backtrace_symbols (array, size); cerr << "-----------------------------------------------------------------------" << endl << "Function call backtrace (" << size << " frames):" << endl; for (i = 0; i < size; i++) cerr << " " << i << ": " << strings[i] << endl; free (strings); cerr << "-----------------------------------------------------------------------" << endl; } #endif #else /* non-glibc case */ void kvu_print_backtrace_stderr(void) { cout << "ERROR (kvu_print_backtrace_stderr): backtrace printing only supported with glibc" << endl; } #endif ecasound-2.9.1/kvutils/kvu_locks.h0000644000076400007640000000307110664032032014124 00000000000000// -*- mode: C++; -*- #ifndef INCLUDED_KVU_LOCKS_H #define INCLUDED_KVU_LOCKS_H #include /** * Atomic access to single integer values. Implementation * may be based on direct atomic operations or traditional * locking, depending on the underlying platform. * * On supported platforms, atomicity is guaranteed for * both single- and multiprocessor concurrency. Ordering of * concurrent reads and writes is however not guaranteed. * * Note! Atomic test-and-modify operations are not provided. */ class ATOMIC_INTEGER { public: /** * Returns the stored integer value. * * Non-blocking. */ int get(void) const; /** * Sets the integer value to 'value'. * * Non-blocking. Atomic on most platforms. * * Atomic without limitations on most platforms. On some * platforms (e.g. sparc64 and armv6), writes from multiple * threads are unsafe. */ void set(int value); ATOMIC_INTEGER(int value = 0); ~ATOMIC_INTEGER(void); private: volatile int value_rep; ATOMIC_INTEGER& operator=(const ATOMIC_INTEGER& v); ATOMIC_INTEGER(const ATOMIC_INTEGER& v); }; /** * A simple guarded lock wrapper for pthread_mutex_lock * and pthread_mutex_unlock. Lock is acquired * upon object creating and released during destruction. */ class KVU_GUARD_LOCK { public: KVU_GUARD_LOCK(pthread_mutex_t* lock_arg); ~KVU_GUARD_LOCK(void); private: pthread_mutex_t* lock_repp; KVU_GUARD_LOCK(void) {} KVU_GUARD_LOCK(const KVU_GUARD_LOCK&) {} KVU_GUARD_LOCK& operator=(const KVU_GUARD_LOCK&) { return *this; } }; #endif ecasound-2.9.1/kvutils/kvu_temporary_file_directory.h0000644000076400007640000000167010664032032020121 00000000000000// -*- mode: C++; -*- #ifndef INCLUDED_TEMPORARY_FILE_DIRECTORY #define INCLUDED_TEMPORARY_FILE_DIRECTORY #include /** * Provides services for allocating and reserving * secure, temporary directories. * * @author Kai Vehmanen */ class TEMPORARY_FILE_DIRECTORY { public: static const int max_temp_files = 512; TEMPORARY_FILE_DIRECTORY(void); TEMPORARY_FILE_DIRECTORY(const std::string& dir); ~TEMPORARY_FILE_DIRECTORY(void); void set_directory_prefix(const std::string& dir); void reserve_directory(const std::string& nspace); void release_directory(void); std::string get_directory_prefix(void) const; std::string get_reserved_directory(void) const; std::string create_filename(const std::string& prefix, const std::string& postfix); bool is_valid(void) const; private: void check_validity(void); std::string tdir_rep; std::string dirprefix_rep; int tmp_index_rep; bool valid_rep; }; #endif ecasound-2.9.1/kvutils/kvu_value_queue.h0000644000076400007640000000543311170346720015342 00000000000000// -*- mode: C++; -*- #ifndef INCLUDE_KVU_VALUE_QUEUE_H #define INCLUDE_KVU_VALUE_QUEUE_H #include #include #include #include /* ANSI C++: size_t */ /** * A thread-safe queue implementation for int-double * value pairs. * @author Kai Vehmanen */ class VALUE_QUEUE { private: mutable pthread_mutex_t lock_rep; // mutex ensuring exclusive access to buffer mutable pthread_cond_t cond_rep; std::pair empty_rep; std::deque > cmds_rep; public: /** * Adds a new item to the end of the queue. */ void push_back(int key, double value); /** * Removes the first item. * * require: * is_empty() == false */ void pop_front(void); /** * Returns the first item. * * require: * is_empty() == false */ const std::pair& front(void); /** * Blocks until 'is_empty() != true'. 'timeout_sec' and * 'timeout_usec' specify the upper time limit for blocking. */ void poll(int timeout_sec, long int timeout_usec); /** * Is queue empty? * * require: * is_empty() == false */ bool is_empty(void) const; VALUE_QUEUE(void); }; /** * A queue implementation for int-double value pairs, optimized for * two thread scenarios, and specifically cases in which the consumer * thread is potentially run with higher static priority. * * All the consumer operations are real-time safe, i.e. they have * bounded execution time. Bounded execution is guaranteed until queue * size reaches bounded_execution_queue_size_limit() items. Once this * limit is reached, consumer operation is switched to blocking behaviour. * This is done to avoid live-locks between the two threads. * * Note that this implementation is not thread-safe if the producer * thread is run with higher static priority or if more than two * threads access the same queue object. * * For a definition of static priority, see man sched_setscheduler(2). * See libkvutils_tester.cpp:kvu_test_4() for an example of how to * use this class. * * @author Kai Vehmanen */ class VALUE_QUEUE_RT_C { public: void push_back(int key, double value); void pop_front(void); const std::pair* front(void); const std::pair* invalid_item(void) const { return &invalid_rep; } void poll(int timeout_sec, long int timeout_usec); bool is_empty(void) const; size_t bounded_execution_queue_size_limit(void) const; VALUE_QUEUE_RT_C(int bounded_exec_max_size = -1); private: mutable pthread_mutex_t lock_rep; // mutex ensuring exclusive access to buffer mutable pthread_cond_t cond_rep; size_t bounded_exec_max_size_rep; size_t pending_pops_rep; std::pair invalid_rep; std::deque > cmds_rep; }; #endif ecasound-2.9.1/kvutils/kvu_procedure_timer.cpp0000644000076400007640000001463011747046505016554 00000000000000// ------------------------------------------------------------------------ // kvu_procedure_timer.cpp: Procedure timer. Meant for timing and gathering // statistics of repeating events. // Copyright (C) 2000,2004,2012 Kai Vehmanen // // 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 #include /* floor() */ #include "kvu_numtostr.h" #include "kvu_procedure_timer.h" #include PROCEDURE_TIMER::PROCEDURE_TIMER(int id) { reset(); idstr_rep = "Timer-" + kvu_numtostr(id); } PROCEDURE_TIMER::~PROCEDURE_TIMER(void) { } bool PROCEDURE_TIMER::less_than(const struct timespec *i, const struct timespec *ii) const { bool result = false; if (i->tv_sec < ii->tv_sec) result = true; if (i->tv_sec == ii->tv_sec) { result = false; if (i->tv_nsec < ii->tv_nsec) result = true; } return result; } void PROCEDURE_TIMER::subtract(struct timespec *i, const struct timespec *ii) const { i->tv_nsec -= ii->tv_nsec; if (i->tv_nsec < 0) { i->tv_nsec += 1000000000; i->tv_sec -= 1; } i->tv_sec -= ii->tv_sec; } double PROCEDURE_TIMER::to_seconds(const struct timeval *i) const { return(i->tv_sec + static_cast(i->tv_usec) / 1000000.0); } double PROCEDURE_TIMER::to_seconds(const struct timespec *i) const { return(i->tv_sec + static_cast(i->tv_nsec) / 1000000000.0); } void PROCEDURE_TIMER::set_upper_bound(const struct timeval *p) { upper_bound_rep.tv_sec = p->tv_sec; upper_bound_rep.tv_nsec = p->tv_usec * 1000; } void PROCEDURE_TIMER::set_upper_bound_seconds(double secs) { struct timeval buf; buf.tv_sec = static_cast(floor(secs)); buf.tv_usec = static_cast(1000000.0f * (secs - static_cast(buf.tv_sec))); set_upper_bound(&buf); } void PROCEDURE_TIMER::set_lower_bound(const struct timeval *p) { lower_bound_rep.tv_sec = p->tv_sec; lower_bound_rep.tv_nsec = p->tv_usec * 1000; } void PROCEDURE_TIMER::set_lower_bound_seconds(double secs) { struct timeval buf; buf.tv_sec = static_cast(floor(secs)); buf.tv_usec = static_cast(1000000.0f * (secs - static_cast(buf.tv_sec))); set_lower_bound(&buf); } static void priv_gettime(struct timespec *dst) { #if HAVE_CLOCK_GETTIME #if defined CLOCK_MONOTONIC clock_gettime(CLOCK_MONOTONIC, dst); #else clock_gettime(CLOCK_REALTIME, dst); #endif #else struct timeval tmp; gettimeofday(&tmp, 0); dst->tv_sec = tmp.tv_sec; dst->tv_nsec = tmp.tv_usec * 1000; #endif } void PROCEDURE_TIMER::start(void) { priv_gettime(&start_rep); } void PROCEDURE_TIMER::stop(void) { priv_gettime(&now_rep); stop_helper(); } /** * Do heavy operations in a non-inlined helper * functions for stop(). * * This is especially useful for the inlined stop() * variant. */ void PROCEDURE_TIMER::stop_helper(void) { subtract(&now_rep, &start_rep); last_duration_rep = to_seconds(&now_rep); // cerr << idstr_rep << ": " << kvu_numtostr(length, 16) << " secs." << endl; events_rep++; event_time_total_rep += last_duration_rep; if (events_rep == 1) memcpy(&min_event_rep, &now_rep, sizeof(struct timeval)); if (less_than(&now_rep, &min_event_rep)) memcpy(&min_event_rep, &now_rep, sizeof(struct timeval)); if (less_than(&max_event_rep, &now_rep)) memcpy(&max_event_rep, &now_rep, sizeof(struct timeval)); if (less_than(&now_rep, &lower_bound_rep)) events_under_bound_rep++; if (less_than(&upper_bound_rep, &now_rep)) events_over_bound_rep++; } void PROCEDURE_TIMER::reset(void) { events_over_bound_rep = 0; events_under_bound_rep = 0; events_rep = 0; event_time_total_rep = 0.0f; last_duration_rep = 0.0f; memset(&now_rep, 0, sizeof(struct timeval)); memset(&start_rep, 0, sizeof(struct timeval)); memset(&min_event_rep, 0, sizeof(struct timeval)); memset(&max_event_rep, 0, sizeof(struct timeval)); memset(&lower_bound_rep, 0, sizeof(struct timeval)); memset(&upper_bound_rep, 0, sizeof(struct timeval)); } long int PROCEDURE_TIMER::events_over_upper_bound(void) const { return(events_over_bound_rep); } long int PROCEDURE_TIMER::events_under_lower_bound(void) const { return(events_under_bound_rep); } long int PROCEDURE_TIMER::event_count(void) const { return(events_rep); } double PROCEDURE_TIMER::max_duration_seconds(void) const { return(to_seconds(&max_event_rep)); } double PROCEDURE_TIMER::min_duration_seconds(void) const { return(to_seconds(&min_event_rep)); } double PROCEDURE_TIMER::average_duration_seconds(void) const { return(event_time_total_rep / event_count()); } double PROCEDURE_TIMER::last_duration_seconds(void) const { return(last_duration_rep); } const struct timespec* PROCEDURE_TIMER::min_duration(void) const { return(&max_event_rep); } const struct timespec* PROCEDURE_TIMER::max_duration(void) const { return(&min_event_rep); } static std::string priv_s2us(double sec) { return kvu_numtostr(sec * 1000000.0, 6); } std::string PROCEDURE_TIMER::to_string(void) const { std::string res; res = idstr_rep + ":\n"; res += "Number of events: " + kvu_numtostr(event_count()) + "\n"; res += "Events over bound: " + kvu_numtostr(events_over_upper_bound()); res += " (" + kvu_numtostr(to_seconds(&upper_bound_rep), 8) + "sec)\n"; res += "Events under bound: " + kvu_numtostr(events_under_lower_bound()); res += " (" + kvu_numtostr(to_seconds(&lower_bound_rep), 8) + "sec)\n"; res += "Min duration, us: " + priv_s2us(min_duration_seconds()) + "\n"; res += "Max duration, us: " + priv_s2us(max_duration_seconds()) + "\n"; res += "Average duration, us: " + priv_s2us(average_duration_seconds()) + "\n"; res += "Duration of last event, us: " + priv_s2us(last_duration_rep) + "\n"; return(res); } ecasound-2.9.1/kvutils/COPYING0000644000076400007640000004310510664032032013010 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ecasound-2.9.1/kvutils/kvu_message_item.h0000644000076400007640000000351610664032032015457 00000000000000// -*- mode: C++; -*- #ifndef INCLUDED_KVU_MESSAGE_ITEM_H #define INCLUDED_KVU_MESSAGE_ITEM_H #include /** * A simple version of C++ stringstream */ class MESSAGE_ITEM { std::string stringtemp; int flo_prec; public: MESSAGE_ITEM(void) { flo_prec = 2; } void setprecision (int prec) { flo_prec = prec; } const std::string& to_string(void) const { return(stringtemp); } MESSAGE_ITEM& operator<< (std::string& c) { stringtemp = stringtemp + c; return (*this); } MESSAGE_ITEM& operator<< (const std::string& c) { stringtemp = stringtemp + c; return (*this); } MESSAGE_ITEM& operator<< (char c); MESSAGE_ITEM& operator<< (unsigned char c) { return (*this) << (char)c; } MESSAGE_ITEM& operator<< (signed char c) { return (*this) << (char)c; } MESSAGE_ITEM& operator<< (const char *s) { stringtemp = stringtemp + std::string(s); return (*this); } MESSAGE_ITEM& operator<< (const unsigned char *s) { return (*this) << (const char*)s; } MESSAGE_ITEM& operator<< (const signed char *s) { return (*this) << (const char*)s; } MESSAGE_ITEM& operator<< (const void *p); MESSAGE_ITEM& operator<< (int n); MESSAGE_ITEM& operator<< (unsigned int n); MESSAGE_ITEM& operator<< (long int n); MESSAGE_ITEM& operator<< (unsigned long n); #if defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE || defined _LARGEFILE_SOURCE || defined __GNUC__ MESSAGE_ITEM& operator<< (long long int n); MESSAGE_ITEM& operator<< (unsigned long long int n); #endif MESSAGE_ITEM& operator<< (short n) {return operator<<((int)n);} MESSAGE_ITEM& operator<< (unsigned short n) {return operator<<((unsigned int)n);} MESSAGE_ITEM& operator<< (bool b) { return operator<<((int)b); } MESSAGE_ITEM& operator<< (double n); MESSAGE_ITEM& operator<< (float n) { return operator<<((double)n); } }; #endif ecasound-2.9.1/kvutils/kvu_dbc.cpp0000644000076400007640000000261111163013321014066 00000000000000/************************************************************************** * dbc.h: A barebones design-by-contract framework for C and C++ * Copyright (C) 2009 Kai Vehmanen * * 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 **************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "kvu_dbc.h" #include "kvu_debug.h" #ifdef ENABLE_DBC #include void kvu_dbc_report_failure(const char *action, const char* expr, const char* file, const char* func, int lineno) { #ifndef NDEBUG kvu_print_backtrace_stderr(); #endif std::fprintf(stderr, "Warning: type %s soft-assert '%s' failed at\n -> %s:%d [%s]\n", action, expr, file, lineno, func); } #endif ecasound-2.9.1/kvutils/kvu_fd_io.h0000644000076400007640000000036610664032032014075 00000000000000#ifndef INCLUDED_KVU_FD_IO_H #define INCLUDED_KVU_FD_IO_H ssize_t kvu_fd_read(int fd, void *buf, size_t count, int timeout); ssize_t kvu_fd_write(int fd, const void *buf, size_t count, int timeout); int kvu_fd_wait(int fd, int timeout); #endif ecasound-2.9.1/kvutils/kvu_timestamp.cpp0000644000076400007640000000601011353705625015356 00000000000000// ------------------------------------------------------------------------ // kvu_timestamp.cpp: Monotonic timestamps // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif /* note: code assumes timespect struct to be defined in * time.h (i.e. SUSv2 or later) */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include #if HAVE_CLOCK_GETTIME /* IMPLEMENTATION: clock_gettime() */ /* *********************************/ int kvu_clock_is_monotonic(void) { int res = -1; #if defined CLOCK_MONOTONIC struct timespec tp; res = clock_getres(CLOCK_MONOTONIC, &tp); #endif if (res == 0) return 1; return 0; } int kvu_clock_getres(struct timespec *dst) { struct timespec tp; int res = -1; #if defined CLOCK_MONOTONIC res = clock_getres(CLOCK_MONOTONIC, &tp); #endif if (res < 0) res = clock_getres(CLOCK_REALTIME, &tp); if (res == 0) { dst->tv_sec = tp.tv_sec; dst->tv_sec = tp.tv_nsec; } return res; } int kvu_clock_gettime(struct timespec *dst) { struct timespec tp; int res = -1; #if defined CLOCK_MONOTONIC res = clock_gettime(CLOCK_MONOTONIC, &tp); #endif if (res < 0) res = clock_gettime(CLOCK_REALTIME, &tp); if (res == 0) { dst->tv_sec = tp.tv_sec; dst->tv_nsec = tp.tv_nsec; } return res; } #elif HAVE_GETTIMEOFDAY /* IMPLEMENTATION: gettimeofday() */ /* ********************************/ int kvu_clock_is_monotonic(void) { return 0; } int kvu_clock_getres(struct timespec *arg) { /* note: an estimate, actual resolution may * be worse */ arg->tv_sec = 0; arg->tv_nsec = 1000; return 0; } int kvu_clock_gettime(struct timespec *arg) { struct timeval tmp; int res = gettimeofday(&tmp, NULL); if (res == 0) { arg->tv_sec = tmp.tv_sec; arg->tv_nsec = tmp.tv_usec * 1000; } return res; } #else /* IMPLEMENTATION: fallback / no-op */ /* **********************************/ int kvu_clock_is_monotonic(void) { DBC_NEVER_REACHED(); return 0; } int kvu_clock_getres(struct timespec *res) { DBC_NEVER_REACHED(); return -1; } int kvu_clock_gettime(struct timespec *tp) { DBC_NEVER_REACHED(); return -1; } #endif ecasound-2.9.1/kvutils/kvu_value_queue.cpp0000644000076400007640000001717211337741251015703 00000000000000// ------------------------------------------------------------------------ // kvu_value_queue.cpp: A thread-safe way to transmit int-double pairs. // Copyright (C) 1999,2004 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 #include #include #include #include #include #include #include "kvu_dbc.h" #include "kvu_value_queue.h" /* --------------------------------------------------------------------- * Options */ // #define VERBOSE /* --------------------------------------------------------------------- * Test util macros */ #ifdef VERBOSE #define KVU_NOTE_S(x) do { printf("%s:%d - %s\n", __FILE__, __LINE__, x); fflush(stdout); } while(0) #define KVU_NOTE_SD(x, y) do { printf("%s:%d - %s=%d\n", __FILE__, __LINE__, x, y); fflush(stdout); } while(0) #else #define KVU_NOTE_S(x) ((void) 0) #define KVU_NOTE_SD(x, y) ((void) 0) #endif /* --------------------------------------------------------------------- * Definitions */ using namespace std; VALUE_QUEUE::VALUE_QUEUE(void) { pthread_mutex_init(&lock_rep, NULL); pthread_cond_init(&cond_rep, NULL); empty_rep = pair(0, 0.0f); } void VALUE_QUEUE::push_back(int key, double value) { pthread_mutex_lock(&lock_rep); cmds_rep.push_back(pair(key, value)); pthread_cond_broadcast(&cond_rep); pthread_mutex_unlock(&lock_rep); } void VALUE_QUEUE::pop_front(void) { // -------- DBC_REQUIRE(is_empty() == false); // -------- pthread_mutex_lock(&lock_rep); cmds_rep.pop_front(); pthread_mutex_unlock(&lock_rep); } const pair& VALUE_QUEUE::front(void) { // -------- DBC_REQUIRE(is_empty() == false); // -------- pthread_mutex_lock(&lock_rep); const pair& s = cmds_rep.front(); pthread_mutex_unlock(&lock_rep); return s; } void VALUE_QUEUE::poll(int timeout_sec, long int timeout_usec) { struct timeval now; struct timespec timeout; int retcode; pthread_mutex_lock(&lock_rep); gettimeofday(&now, 0); timeout.tv_sec = now.tv_sec + timeout_sec; timeout.tv_nsec = now.tv_usec * 1000 + timeout_usec * 1000; retcode = 0; while (cmds_rep.empty() == true && retcode != ETIMEDOUT) { retcode = pthread_cond_timedwait(&cond_rep, &lock_rep, &timeout); } pthread_mutex_unlock(&lock_rep); return; } bool VALUE_QUEUE::is_empty(void) const { pthread_mutex_lock(&lock_rep); bool result = cmds_rep.empty(); pthread_mutex_unlock(&lock_rep); return result; } /************************************************************************/ /** * Default for maximum size of the queue for operation in * bounded execution time mode. */ static const size_t kvqr_bound_exec_max_size_const = 1024; /** * Class constructor. * * @param * * Execution note: not bounded (may block, may allocate memory) */ VALUE_QUEUE_RT_C::VALUE_QUEUE_RT_C(int bounded_exec_max_size) : pending_pops_rep(0) { pthread_mutex_init(&lock_rep, NULL); pthread_cond_init(&cond_rep, NULL); if (bounded_exec_max_size == -1) bounded_exec_max_size_rep = kvqr_bound_exec_max_size_const; else bounded_exec_max_size_rep = static_cast(bounded_exec_max_size); } /** * Adds a new item to the end of the queue. * * Execution note: non-realtime (may block, may allocate memory) */ void VALUE_QUEUE_RT_C::push_back(int key, double value) { pthread_mutex_lock(&lock_rep); cmds_rep.push_back(pair(key, value)); KVU_NOTE_SD("pushback-when-size=", cmds_rep.size()); pthread_cond_broadcast(&cond_rep); pthread_mutex_unlock(&lock_rep); } /** * Removes the first item. * * Execution note: bounded * * @pre is_empty() != true */ void VALUE_QUEUE_RT_C::pop_front(void) { int ret = pthread_mutex_trylock(&lock_rep); if (ret == 0) { cmds_rep.pop_front(); pthread_mutex_unlock(&lock_rep); } else { /* could not remove item, add to pending pops */ if (pending_pops_rep != cmds_rep.size()) { ++pending_pops_rep; KVU_NOTE_SD("add-pending-pop=", pending_pops_rep); } } } /** * Returns the first item. * * Execution note: bounded * * @pre is_empty() != true * @return returns VALUE_QUEUE_RT_C::invalid_item() if temporarily * unable to access the queue */ const pair* VALUE_QUEUE_RT_C::front(void) { pair* s = &invalid_rep; int ret = pthread_mutex_trylock(&lock_rep); if (ret != 0 && cmds_rep.size() >= bounded_execution_queue_size_limit()) { /* queue has grown beyond the rt-safe maximum size, * change to non-bounded mode to force synchronization * between the producer and consumer threads */ KVU_NOTE_SD("queue-limit-when-size=", cmds_rep.size()); ret = pthread_mutex_lock(&lock_rep); } if (ret == 0) { /* now that we have the lock, we can safely process * any pending pop requests */ DBC_CHECK(cmds_rep.size() >= pending_pops_rep); while(pending_pops_rep > 0 && cmds_rep.size() > 0) { cmds_rep.pop_front(); --pending_pops_rep; KVU_NOTE_SD("dec-pending-pop=", pending_pops_rep); } KVU_NOTE_SD("front-when-size=", cmds_rep.size()); s = &cmds_rep.front(); pthread_mutex_unlock(&lock_rep); } return s; } /** * Blocks until 'is_empty() != true'. 'timeout_sec' and * 'timeout_usec' specify the upper time limit for blocking. * * Execution: not bounded (may block, may allocate memory) * * @pre is_empty() != true */ void VALUE_QUEUE_RT_C::poll(int timeout_sec, long int timeout_usec) { struct timeval now; struct timespec timeout; int retcode; pthread_mutex_lock(&lock_rep); gettimeofday(&now, 0); timeout.tv_sec = now.tv_sec + timeout_sec; timeout.tv_nsec = now.tv_usec * 1000 + timeout_usec * 1000; retcode = 0; while (cmds_rep.empty() == true && retcode != ETIMEDOUT) { KVU_NOTE_S("poll-in"); retcode = pthread_cond_timedwait(&cond_rep, &lock_rep, &timeout); KVU_NOTE_S("poll-out"); } pthread_mutex_unlock(&lock_rep); return; } /** * Is queue empty? * * Execution note: bounded (may block, may allocate memory) */ bool VALUE_QUEUE_RT_C::is_empty(void) const { size_t size = 0; int ret = pthread_mutex_trylock(&lock_rep); if (ret != 0 && cmds_rep.size() >= bounded_execution_queue_size_limit()) { /* queue has grown beyond the rt-safe maximum size, * change to non-bounded mode to force synchronization * between the producer and consumer threads */ KVU_NOTE_SD("queue-limit-when-size=", cmds_rep.size()); ret = pthread_mutex_lock(&lock_rep); } if (ret == 0) { size = cmds_rep.size(); DBC_CHECK(size - pending_pops_rep >= 0); pthread_mutex_unlock(&lock_rep); } return (size - pending_pops_rep) == 0; } size_t VALUE_QUEUE_RT_C::bounded_execution_queue_size_limit(void) const { return bounded_exec_max_size_rep; } /************************************************************************/ ecasound-2.9.1/kvutils/kvu_utils.h0000644000076400007640000000422510664032032014153 00000000000000// -*- mode: C++; -*- #ifndef INCLUDED_KVU_UTILS_H #define INCLUDED_KVU_UTILS_H #include #include bool kvu_string_icmp(const std::string& a, const std::string& b); std::string kvu_string_regex_meta_escape(const std::string& arg); std::string kvu_string_shell_meta_escape(const std::string& arg); void kvu_string_strip_outer_quotes(std::string* input, const std::string::value_type quote_char); std::vector kvu_string_to_tokens(const std::string& s); std::vector kvu_string_to_tokens_quoted(const std::string& s); std::vector kvu_string_to_vector(const std::string& str, const std::string::value_type separator); std::vector kvu_string_to_int_vector(const std::string& str, const std::string::value_type separator); std::string kvu_string_search_and_replace(const std::string& a, const std::string::value_type from, const std::string::value_type to); std::string kvu_string_search_and_replace(const std::string& str, const std::string& from, const std::string& to); std::vector kvu_vector_search_and_replace(const std::vector& str_vector, const std::string& from, const std::string& to); std::string kvu_vector_to_string(const std::vector& str, const std::string& separator); std::string kvu_remove_trailing_spaces(const std::string& a); std::string kvu_remove_preceding_spaces(const std::string& a); std::string kvu_remove_surrounding_spaces(const std::string& a); std::string kvu_convert_to_uppercase(const std::string& a); std::string kvu_convert_to_lowercase(const std::string& a); void kvu_to_uppercase(std::string& a); void kvu_to_lowercase(std::string& a); std::string kvu_get_argument_number(int number, const std::string& arg); std::vector kvu_get_arguments(const std::string& arg); int kvu_get_number_of_arguments(const std::string& arg); std::string kvu_get_argument_prefix(const std::string& argument); void kvu_print_time_stamp(void); int kvu_sleep(long int seconds, long int nanoseconds); /** * Obsolete functions. */ /*@{*/ std::vector kvu_string_to_words(const std::string& s); /*@}*/ #endif ecasound-2.9.1/kvutils/kvu_numtostr.h0000644000076400007640000000150310664032032014702 00000000000000#ifndef INCLUDED_KVU_NUMTOSTR_H #define INCLUDED_KVU_NUMTOSTR_H #include std::string kvu_numtostr(char c); std::string kvu_numtostr(unsigned char c); std::string kvu_numtostr(signed char c); std::string kvu_numtostr(const void *p); std::string kvu_numtostr(int n); std::string kvu_numtostr(unsigned int n); std::string kvu_numtostr(long int n); std::string kvu_numtostr(unsigned long int n); #if defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE || defined _LARGEFILE_SOURCE || defined __GNUC__ std::string kvu_numtostr(long long int n); std::string kvu_numtostr(unsigned long long int n); #endif std::string kvu_numtostr(short n); std::string kvu_numtostr(unsigned short n); std::string kvu_numtostr(bool b); std::string kvu_numtostr(double n, int flo_prec = 2); std::string kvu_numtostr(float n, int flo_prec = 2); #endif ecasound-2.9.1/kvutils/kvu_com_line.h0000644000076400007640000000353210664032032014600 00000000000000// -*- mode: C++; -*- #ifndef INCLUDED_KVU_COM_LINE_H #define INCLUDED_KVU_COM_LINE_H #include #include /** * Class representation of command line arguments */ class COMMAND_LINE { private: std::vector cparams; mutable std::vector::size_type current_rep; public: /** * Number of elements */ std::string::size_type size() const { return(cparams.size()); } /** * Sets the first argument active. This is usually program's * name. */ void begin(void) const { current_rep = 0; } /** * Moves to the next argument. */ void next(void) const { ++current_rep; } /** * Moves to the previous argument. */ void previous(void) const { --current_rep; } /** * Returns true if we've past the last argument. */ bool end(void) const { if (current_rep >= cparams.size()) return(true); else return (false); } /** * Returns the current argument * * require: * end() == false */ const std::string& current(void) const { return(cparams[current_rep]); } /** * Is '-option' is among the arguments? * * ensure: * current() == old current() */ bool has(char option) const; /** * Is '-option' is among the arguments? */ bool has(const std::string& option) const; /** * Make sure that all option tokens start with a '-' sign */ void combine(void); /** * Static version of combine */ static std::vector combine(const std::vector& source); /** * Adds 'argu' to the arguments. */ void push_back(const std::string& argu); COMMAND_LINE(int argc, char *argv[]); COMMAND_LINE(const std::vector& params); COMMAND_LINE(void); }; #endif ecasound-2.9.1/kvutils/libkvutils_tester.cpp0000644000076400007640000003752111260600675016253 00000000000000// ------------------------------------------------------------------------ // libkvutils_tester.cpp: Runs a set of libkvutils unit tests. // Copyright (C) 2002-2004,2009 Kai Vehmanen // // Attributes: // eca-style-version: 2 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include /* ANSI-C: size_t */ #include /* for AIX */ #include /* ANSI-C: clock() */ #include "kvu_dbc.h" #include "kvu_locks.h" #include "kvu_numtostr.h" #include "kvu_rtcaps.h" #include "kvu_timestamp.h" #include "kvu_utils.h" #include "kvu_value_queue.h" #include "kvu_message_queue.h" using namespace std; /* --------------------------------------------------------------------- * Options */ #define VERBOSE /* --------------------------------------------------------------------- * Test util macros */ #ifdef VERBOSE #define ECA_TEST_ENTRY() do { printf("\n%s:%d - Test started\n", __KVU_FUNCTION, __LINE__); } while(0) #define ECA_TEST_SUCCESS() do { printf("%s:%d - Test passed\n", __KVU_FUNCTION, __LINE__); return 0; } while(0) #define ECA_TEST_FAIL(x,y) do { printf("\n%s:%d - Test failed: \"%s\"\n", __KVU_FUNCTION, __LINE__, y); return x; } while(0) #define ECA_TEST_NOTE(x) do { printf("%s:%d - %s\n", __KVU_FUNCTION, __LINE__, x); fflush(stdout); } while(0) #else #define ECA_TEST_ENTRY() ((void) 0) #define ECA_TEST_SUCCESS() return 0 #define ECA_TEST_FAIL(x,y) return x #define ECA_TEST_NOTE(x) ((void) 0) #endif /* --------------------------------------------------------------------- * Type definitions */ typedef int (*kvu_test_t)(void); /* --------------------------------------------------------------------- * Test case declarations */ static int kvu_test_1(void); static int kvu_test_2(void); static int kvu_test_3(void); static int kvu_test_4(void); static int kvu_test_5_timestamp(void); static int kvu_test_6_msgqueue(void); static kvu_test_t kvu_funcs[] = { kvu_test_1, /* kvu_locks.h: ATOMIC_INTEGER */ kvu_test_2, /* kvu_utils.h: string handling */ kvu_test_3, /* kvu_utils.h: float2str */ kvu_test_4, /* kvu_value_queue.h */ kvu_test_5_timestamp, /* kvu_timestamp.h */ kvu_test_6_msgqueue, /* kvu_message_queue.h */ NULL }; /* --------------------------------------------------------------------- * Funtion definitions */ int main(int argc, char *argv[]) { int n, failed = 0; if (argc > 1) { /* run just a single test */ size_t m = std::atoi(argv[1]); if (m > 0 && m < (sizeof(kvu_funcs) / sizeof(kvu_test_t))) { if (kvu_funcs[m - 1]() != 0) { ++failed; } } } else { /* run all tests */ for(n = 0; kvu_funcs[n] != NULL; n++) { int ret = kvu_funcs[n](); if (ret != 0) { ++failed; } } } return failed; } #define KVU_TEST_1_ROUNDS 5 // #define KVU_TEST_1_ROUNDS 60 static void* kvu_test_1_helper(void* ptr) { ATOMIC_INTEGER* i = (ATOMIC_INTEGER*)ptr; int stop_after = KVU_TEST_1_ROUNDS * CLOCKS_PER_SEC / 5; clock_t prev, now = clock(); for(int n = 0, m = 0; n < stop_after;) { // if (!(m & 0xffff)) fprintf(stderr, "S"); ++m; int j = i->get(); if (j < 0) { ++j; i->set(j); } j = i->get(); if (j > 0) { ECA_TEST_FAIL((void*)1, "kvu_test_1_helper access error (1)"); } if (j < -1) { ECA_TEST_FAIL((void*)1, "kvu_test_1_helper access error (2)"); } prev = now; now = clock(); if (prev > now) n += prev - now; else n += now - prev; } return 0; } /** * Tests the ATOMIC_INTEGER class defined * in kvu_locks.h. */ static int kvu_test_1(void) { ECA_TEST_ENTRY(); ATOMIC_INTEGER i (0); pthread_t thread; pthread_create(&thread, NULL, kvu_test_1_helper, (void*)&i); int stop_after = KVU_TEST_1_ROUNDS * CLOCKS_PER_SEC; clock_t prev, now = clock(); for(int n = 0, m = 0; n < stop_after;) { // if (!(m & 0xffff)) fprintf(stderr, "M"); ++m; int j = i.get(); if (j < 0) { ++j; i.set(j); } else { --j; i.set(j); } j = i.get(); if (j > 0) { ECA_TEST_FAIL(1, "kvu_test_1 access error (3)"); } if (j < -1) { ECA_TEST_FAIL(1, "kvu_test_1 access error (4)"); } prev = now; now = clock(); if (prev > now) n += prev - now; else n += now - prev; } ECA_TEST_SUCCESS(); } /** * Tests the string handling functions defined * in kvu_utils.h. */ static int kvu_test_2(void) { ECA_TEST_ENTRY(); /* string comparison: */ if (kvu_string_icmp(" foo ", " fOo ") != true) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_icmp"); } /* vectorization: */ vector vec = kvu_string_to_tokens(" a foo string "); if (vec.size() != 3) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens (1)"); } if (vec[2] != "string") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens (2)"); } vec = kvu_string_to_tokens_quoted("a foo\\ string"); if (vec.size() != 2) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens_quoted (1)"); } if (vec[1] != "foo string") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens_quoted (2)"); } vec = kvu_string_to_tokens_quoted("another\\ foo \"with substring\" \\\\slashes"); if (vec.size() != 3) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens_quoted (3)"); } if (vec[1] != "\"with substring\"") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens_quoted (4)"); } if (vec[2] != "\\slashes") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_to_tokens_quoted (5)"); } /* de-vectorization: */ vector test; test.push_back(" foo"); test.push_back("bar "); if (kvu_vector_to_string(test, "") != " foobar ") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_vector_to_string (1)"); } /* argument string parsing: */ const string test_arg1 ("-efoobarsouNd:arg1,arg2,arg3,long\\,arg\\:4,arg5,\"arg,6,comma1,comma2\""); if (kvu_get_argument_prefix(test_arg1) != "efoobarsouNd") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_argument_prefix"); } if (kvu_get_argument_number(5, test_arg1) != "arg5") { // fprintf(stderr, "vec2: '%s'.\n", kvu_get_argument_number(5, test_arg1).c_str()); ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_argument_number (1)"); } if (kvu_get_argument_number(6, test_arg1) != "arg,6,comma1,comma2") { fprintf(stderr, "vec2: '%s'.\n", kvu_get_argument_number(6, test_arg1).c_str()); ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_argument_number (2)"); } /* request for non-existant arg should return an empty string */ if (kvu_get_argument_number(7, test_arg1) != "") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_argument_number (3)"); } vec = kvu_get_arguments(test_arg1); if (vec.size() != 6) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_arguments (1)"); } if (vec[2] != "arg3" || vec[0] != "arg1" || vec[3] != "long,arg:4") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_arguments (2)"); } if (kvu_get_number_of_arguments(test_arg1) != 6) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_number_of_arguments"); } const string test_arg2 ("-e:\"\\arg1,arg2,arg3"); if (kvu_get_number_of_arguments(test_arg2) != 3) { ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_number_of_arguments (arg2-2)"); } if (kvu_get_argument_number(1, test_arg2) != "\"\\arg1") { fprintf(stderr, "vec2: '%s'.\n", kvu_get_argument_number(1, test_arg2).c_str()); ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_argument_number (arg2-1)"); } if (kvu_get_number_of_arguments("-f:,,") != 3) ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_number_of_arguments (empty args)"); if (kvu_get_number_of_arguments("-f:a,") != 2) ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_number_of_arguments (valid+null)"); if (kvu_get_number_of_arguments("-f:,a") != 2) ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_number_of_arguments (null+valid)"); if (kvu_get_number_of_arguments("-f:") != 0) ECA_TEST_FAIL(1, "kvu_test_2 kvu_get_number_of_arguments (no args)"); /* search and replace: */ if (kvu_string_search_and_replace("foo bar", 'f', 'b') != "boo bar") { ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_search_and_replace"); } /* meta-char espacing: */ if (kvu_string_shell_meta_escape("foo\"bar") != "foo\\\"bar") ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_meta_escape"); if (kvu_string_shell_meta_escape("foo'bar") != "foo\\'bar") ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_meta_escape"); if (kvu_string_shell_meta_escape("foo|bar") != "foo\\|bar") ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_meta_escape"); if (kvu_string_shell_meta_escape("foo&bar&&&") != "foo\\&bar\\&\\&\\&") ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_meta_escape"); if (kvu_string_shell_meta_escape("foo bar ") != "foo\\ bar\\ ") ECA_TEST_FAIL(1, "kvu_test_2 kvu_string_meta_escape"); ECA_TEST_SUCCESS(); } /** * Tests the floating point to text conversion functions defined * in kvu_numtostr.h. */ static int kvu_test_3(void) { ECA_TEST_ENTRY(); /* 17 digits after decimal point */ double foo = 0.12345678912345678; string foostr = kvu_numtostr(foo, 17); if (foostr != "0.12345678912345678") { // fprintf(stderr, "foo=%.17lf, res=%s.\n", foo, foostr.c_str()); ECA_TEST_FAIL(1, "kvu_test_3 kvu_numtostr double"); } /* 8 digits after decimal point */ float bar = 0.12345678; string barstr = kvu_numtostr(bar, 8); if (barstr != "0.12345678") { // fprintf(stderr, "bar=%.8f, res=%s.\n", bar, barstr.c_str()); ECA_TEST_FAIL(1, "kvu_test_3 kvu_numtostr float"); } ECA_TEST_SUCCESS(); } static const int kvu_test_4_iterations_const = 16384; static int kvu_test_4_retval = 0; static void* kvu_test_4_helper(void* ptr); /** * Tests the VALUE_QUEUE_RT_C class implementation. */ static int kvu_test_4(void) { ECA_TEST_ENTRY(); /* guarantee bounded execution time only upto 16 items */ VALUE_QUEUE_RT_C rqueue (16); ECA_TEST_NOTE("start-test"); pthread_t thread; pthread_create(&thread, NULL, kvu_test_4_helper, (void*)&rqueue); kvu_sleep(1, 0); ECA_TEST_NOTE("start-item-push"); for(int iter = 0; iter < kvu_test_4_iterations_const; iter++) { // fprintf(stderr, "%s:%d push.\n", __FUNCTION__, __LINE__); rqueue.push_back(iter, 1.0f); // kvu_sleep(1, 0); } void *res_ptr = 0; pthread_join(thread, (void**)&res_ptr); if (*(int*)res_ptr != 0) { ECA_TEST_FAIL(1, "kvu_test_4 slave-thread-failed"); } ECA_TEST_NOTE("end-test."); ECA_TEST_SUCCESS(); } /** * The real-time consumer thread used in testing VALUE_QUEUE_RT_C. */ static void* kvu_test_4_helper(void* ptr) { VALUE_QUEUE_RT_C *rqueue = (VALUE_QUEUE_RT_C*)ptr; kvu_test_4_retval = 0; ECA_TEST_NOTE("start-thread."); int res = kvu_set_thread_scheduling(SCHED_FIFO, 1); if (res == 0) { ECA_TEST_NOTE("schedfifo-scheduling-enabled"); } else { ECA_TEST_NOTE("schedfifo-scheduling-disabled"); } int last_received_v = 0; for(int received = 0; received < kvu_test_4_iterations_const; ) { if (rqueue->is_empty() != true) { const pair* ref = rqueue->front(); if (ref != rqueue->invalid_item()) { // fprintf(stderr, "%s:%d front-success.\n", __FUNCTION__, __LINE__); ++received; last_received_v = ref->first + 1; if (received != last_received_v) { ECA_TEST_NOTE("queue-sync-error"); kvu_test_4_retval = -1; } rqueue->pop_front(); } else { ECA_TEST_NOTE("corner-case-queue-busy"); } } } if (last_received_v != kvu_test_4_iterations_const) { ECA_TEST_NOTE("end-of-queue-sync-error"); kvu_test_4_retval = -1; } ECA_TEST_NOTE("exit-thread"); pthread_exit(&kvu_test_4_retval); /* never reached */ return 0; } /** * Tests the kvu_timestamp.h interface */ static int kvu_test_5_timestamp(void) { ECA_TEST_ENTRY(); struct timespec stamp; int res; int monotonic = kvu_clock_is_monotonic(); double start, now, prev, end; res = kvu_clock_gettime(&stamp); if (res) ECA_TEST_FAIL(1, "kvu_test_5-1 clock_gettime failed"); start = kvu_timespec_seconds(&stamp); end = start + 3.0; now = prev = start; ECA_TEST_NOTE("3s timer loop starts"); while (now < end) { /* 5ms sleeps */ kvu_sleep(0, 5000000); res = kvu_clock_gettime(&stamp); if (res) ECA_TEST_FAIL(1, "kvu_test_5-2 clock_gettime failed"); now = kvu_timespec_seconds(&stamp); #ifdef VERY_VERBOSE fprintf(stderr, "now=%.09f delta=%.09f end=%.03f\n", now - start, now - prev, end - start); #endif if (now < prev) { if (monotonic) ECA_TEST_FAIL(1, "kvu_test_5-3 clock goes backwards"); else ECA_TEST_NOTE("kvu_test_5 - clock went backwards"); } prev = now; } ECA_TEST_SUCCESS(); } /* note: around 50ms per iteration */ static const int kvu_test_6_iterations_const = 100; static int kvu_test_6_retval = 0; static void* kvu_test_6_helper(void* ptr); /** * Tests the MESSAGE_QUEUE_RT_C class implementation. */ static int kvu_test_6_msgqueue(void) { ECA_TEST_ENTRY(); std::srand(std::time(0)); /* guarantee bounded execution time only upto 16 items */ MESSAGE_QUEUE_RT_C rqueue (16); ECA_TEST_NOTE("start-test"); pthread_t thread; pthread_create(&thread, NULL, kvu_test_6_helper, (void*)&rqueue); kvu_sleep(1, 0); ECA_TEST_NOTE("start-item-push"); for(int iter = 0; iter < kvu_test_6_iterations_const; iter++) { // fprintf(stderr, "%s:%d push.\n", __FUNCTION__, __LINE__); std::string msg = kvu_numtostr(iter + 1); //std::fprintf(stdout, "%s:%d pushed '%s'\n", __FUNCTION__, __LINE__, msg.c_str()); rqueue.push_back(msg); int sleep_ns = std::rand() % 100; kvu_sleep(0, sleep_ns * 1000000); /* [0,100]ms */ } void *res_ptr = 0; pthread_join(thread, (void**)&res_ptr); if (*(int*)res_ptr != 0) { ECA_TEST_FAIL(1, "kvu_test_6 slave-thread-failed"); } ECA_TEST_NOTE("end-test."); ECA_TEST_SUCCESS(); } /** * The real-time consumer thread. */ static void* kvu_test_6_helper(void* ptr) { MESSAGE_QUEUE_RT_C *rqueue = static_cast*>(ptr); kvu_test_6_retval = 0; ECA_TEST_NOTE("start-thread."); int res = kvu_set_thread_scheduling(SCHED_FIFO, 1); if (res == 0) { ECA_TEST_NOTE("schedfifo-scheduling-enabled"); } else { ECA_TEST_NOTE("schedfifo-scheduling-disabled"); } std::string last_received_v; for(int received = 0; received < kvu_test_6_iterations_const; ) { int sleep_ns = std::rand() % 100; kvu_sleep(0, sleep_ns * 1000000); /* [0,100]ms */ if (rqueue->is_empty() != true) { std::string ref; int popres = rqueue->pop_front(&ref); if (popres > 0) { // std::fprintf(stdout, "%s:%d popped '%s'\n", __FUNCTION__, __LINE__, ref.c_str()); ++received; if (last_received_v == ref) { ECA_TEST_NOTE("queue-sync-error"); kvu_test_6_retval = -1; break; } last_received_v = ref; } else { ECA_TEST_NOTE("corner-case-queue-busy"); } } } if (std::atoi(last_received_v.c_str()) != kvu_test_6_iterations_const) { // std::fprintf(stdout, "%s:%d last item '%s'\n", __FUNCTION__, __LINE__, last_received_v.c_str()); ECA_TEST_NOTE("end-of-queue-sync-error"); kvu_test_6_retval = -1; } ECA_TEST_NOTE("exit-thread"); pthread_exit(&kvu_test_6_retval); /* never reached */ return 0; } ecasound-2.9.1/kvutils/kvu_rtcaps.h0000644000076400007640000000040511162527470014314 00000000000000#ifndef INCLUDED_KVU_RTCAPS_H #define INCLUDED_KVU_RTCAPS_H bool kvu_check_for_sched_fifo(void); bool kvu_check_for_sched_rr(void); bool kvu_check_for_mlockall(void); int kvu_set_thread_scheduling(int policy, int priority); #endif /* INCLUDED_KVU_RTCAPS_H */ ecasound-2.9.1/kvutils/kvu_threads.cpp0000644000076400007640000001022412260762753015012 00000000000000// ------------------------------------------------------------------------ // kvu_threads.cpp: Various pthread related helper functions. // Copyright (C) 2002,2004,2012 Kai Vehmanen // // 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 /* clock_gettime() */ #include /* gettimeofday() */ #include /* ETIMEDOUT */ #include "kvu_threads.h" using std::string; /** * A variant of the standard pthread_mutex_lock. This routine is * originally from Quasimodo CVS-tree, from the libpbd library, Written * by Paul Davis. This version of the routine adds a second * argument, 'spinlimit' which specifies the number of loops spent * spinning, before blocking with the standard pthread_mutex_lock() call. */ int kvu_pthread_mutex_spinlock (pthread_mutex_t *mp, long int spinlimit) { int err = EBUSY; unsigned int i; i = spinlimit; while (i > 0 && ((err = pthread_mutex_trylock (mp)) == EBUSY)) i--; if (err == EBUSY) { err = pthread_mutex_lock (mp); } return err; } /** * Waits for condition to occur. * * Note: this model of condition waiting is inherently racy and * must be only used in specific cases (not a general solution). * The main problem is that the condition is not checked with * mutex held before going into pthread_cond_timedwait(), so a * condition change may be missed. * * @return 0 on success, * -ETIMEDOUT if timeout occured, * other nonzero value on other errors */ int kvu_pthread_timed_wait(pthread_mutex_t* mutex, pthread_cond_t* cond, long int seconds) { struct timeval now; gettimeofday(&now, 0); struct timespec sleepcount; sleepcount.tv_sec = now.tv_sec + seconds; sleepcount.tv_nsec = now.tv_usec * 1000; int ret = 0; /* note: timing race possible here, if condition has already been * signaled at this point, thus the sleepcount is mandatory */ pthread_mutex_lock(mutex); ret = pthread_cond_timedwait(cond, mutex, &sleepcount); pthread_mutex_unlock(mutex); return(ret); } /** * Returns a string explaning the error code * returned by kvu_pthread_timed_wait(). */ string kvu_pthread_timed_wait_result(int result, const string& prefix) { if (result != 0) { if (result == -ETIMEDOUT) return(prefix + " failed; timeout"); else return(prefix + " failed"); } return(prefix + " ok"); } /** * Fills absolute timeout struct out for pthread_cond_timedwait() that * results in 'seconds' of relative timeout. * * @arg seconds timeout in seconds (must be positive) * @out out pointer to output timeout struct * @out mononic true if CLOCK_MONOTONIC should be used (condition * attribute set to MONOTONIC using pthread_condattr_setclock(MONOTONIC); * otherwise using CLOCK_REALTIME (system time) */ int kvu_pthread_cond_timeout(int seconds, struct timespec *out, bool monotonic = false) { // FIXME: needs to be implemented using MONOTONIC clock_gettime() // and setting on the clock int res = 0; if (monotonic) { #if defined CLOCK_MONOTONIC res = clock_gettime(CLOCK_MONOTONIC, out); out->tv_sec += seconds; #else res = -1; #endif } else { #if defined(CLOCK_REALTIME) res = clock_gettime(CLOCK_REALTIME, out); out->tv_sec += seconds; #else struct timeval tv; res = gettimeofday(&tv, NULL); out->tv_sec = tv.tv_sec + seconds; out->tv_nsec = tv.tv_usec * 1000; #endif } return res; } ecasound-2.9.1/kvutils/kvu_locks.cpp0000644000076400007640000000430410664032032014457 00000000000000// ------------------------------------------------------------------------ // kvu_locks.cpp: Various lock related helper functions. // Copyright (C) 2000-2002,2006 Kai Vehmanen // // 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 /* ANSI-C: sig_atomic_t */ #include /* POSIX: threading */ #include "kvu_dbc.h" #include "kvu_locks.h" /* NOTE: This implementation is currenly a dummy one. The primary * reason to use ATOMIC_OINT() is to mark all code segments * where atomic read/write access is required. * * Tested platforms: * - IA32 single- and multi-processor cases * * Platforms that should be atomic w.r.t. read/writes: * - Alpha * - ARM-v4 (ARM9) and older * - IA64 * - MIPS * - PowerPC * - SH * - S390 * - SPARC64 * - X86-64 * * Platforms that where writes from multiple threads do _NOT_ work: * - ARM-v6 (ARM11) and up * - SPARC32 * * References: * - architecture manuals * - Linux kernel and glibc sources */ ATOMIC_INTEGER::ATOMIC_INTEGER(int value) { value_rep = value; } ATOMIC_INTEGER::~ATOMIC_INTEGER(void) { } int ATOMIC_INTEGER::get(void) const { return value_rep; } void ATOMIC_INTEGER::set(int value) { value_rep = value; } KVU_GUARD_LOCK::KVU_GUARD_LOCK(pthread_mutex_t* lock_arg) { lock_repp = lock_arg; DBC_CHECK(pthread_mutex_lock(lock_repp) == 0); } KVU_GUARD_LOCK::~KVU_GUARD_LOCK(void) { DBC_CHECK(pthread_mutex_unlock(lock_repp) == 0); } ecasound-2.9.1/kvutils/ChangeLog0000644000076400007640000001406511762640701013542 000000000000002012-06-03 Kai Vehmanen * library interface version 10:0:0 frozen 2012-05-27 Kai Vehmanen * kvu_message_queue.h (MESSAGE_QUEUE_RT_C): Added peek_front() method. 2012-04-28 Kai Vehmanen * kvu_procedure_timer.h: Public API modified to use struct timespec (instead of struct timeval). * library interface version to 10:0:0 2012-04-17 Kai Vehmanen * kvu_threads.cpp (kvu_pthread_cond_timeout): Added. * library interface version to 10:0:6 2009-10-17 Kai Vehmanen * library interface version 9:0:5 frozen (2.7.0 release) 2009-04-12 Kai Vehmanen * kvu_message_queue.h: file added. 2009-03-27 Kai Vehmanen * kvu_timestamp.h: New interface. 2009-03-21 Kai Vehmanen * kvu_dbc.h: Added DBC_NEVER_REACHED macro. * kvu_debug.h: File added. * library version changed to 9:0:5 2006-12-06 Kai Vehmanen * library interface version 8 frozen (2.4.5 release) * library version changed to 8:0:4 * kvu_utils.cpp (kvu_string_strip_outer_quotes): Added. 2005-03-12 Kai Vehmanen * library interface version 7 frozen (2.4.0 release) 2004-12-15 Kai Vehmanen * kvu_utils.cpp (kvu_string_regex_meta_escape): Added. * kvu_utils.cpp (kvu_string_search_and_replace): Added. 2004-12-14 Kai Vehmanen * kvu_value_queue.h (VALUE_QUEUE_RT_C): Added. 2004-12-12 Kai Vehmanen * kvu_utils.h (kvu_vector_search_and_replace): Added. * kvu_utils.h (kvu_string_shell_meta_escape): Added. * library version changed to 7:0:3 2003-08-29 Kai Vehmanen * library interface version 6 frozen 2003-05-29 Kai Vehmanen * kvu_rtcaps.h (kvu_set_thread_scheduling): added * library version changed to 6:0:2 2003-02-13 Kai Vehmanen * kvu_inttypes.h: file added * library version changed to 5:0:1 2003-01-07 Kai Vehmanen * library interface version 4 frozen 2002-11-05 Kai Vehmanen * kvu_locks.h: removed dependency to asm/atomic.h * kvu_locks.h (add,sub,increment,decrement): removed 2002-10-16 Kai Vehmanen * NOTE: from now on, the library version presents the public API version number, not the ABI version. * removed interface version from library base name * library version changed to 4:0:0 2002-06-29 Kai Vehmanen * kvu_fd_io.h: file added 2002-06-28 Kai Vehmanen * kvu_com_line.h (COMMAND_LINE): iterators functions to const members * kvu_com_line.h (COMMAND_LINE): added constructor that takes 'void' as its argument 2002-04-29 Kai Vehmanen * kvu_locks.h (KVU_GUARD_LOCK): class added 2002-04-28 Kai Vehmanen * all files renamed to have a 'kvu_' prefix * 'kvu_' prefix added to all free operators 2002-04-25 Kai Vehmanen * library version number added to library name; current name is libkvutils3 2002-04-19 Kai Vehmanen * kvutils.h (kvu_sleep): added 2002-02-27 Kai Vehmanen * threads.h (all): added * locks.h (pthread_mutex_spinlock): moved to threads.h 2002-02-26 Kai Vehmanen * library version changed to 3:0:0 (change in binary-level API) * procedure_timer.h (last_duration_seconds): added 2001-12-22 Kai Vehmanen * kvutils.h (string_to_words): marked obsolete - not removed from the library * kvutils.h (string_to_tokens): replaces string_to_words() * kvutils.h (string_to_tokens_quoted): added 2001-11-29 Kai Vehmanen * message_item.h (< * procudure_timer.h (set_upper_bound_seconds, set_lower_bound_seconds): added 2001-10-09 Kai Vehmanen * locks.h (all): made function member of ATOMIC_INTEGER non-inlined to better hide the actual implementation 2001-10-03 Kai Vehmanen * dbc.h (DBC_DECLARE): added * kvurtcaps.h (all): added 2001-08-19 Kai Vehmanen * library version changed to 3:0:1 * dbc.h (all): added, makes definition_by_contract.h obsolete 2001-04-27 Kai Vehmanen * library interface version 2 frozen 2001-04-23 Kai Vehmanen * kvutils.h (string_to_int_vector): added 2001-03-22 Kai Vehmanen * temporary_file_directory.h (all): added 2001-02-19 Kai Vehmanen * value_queue.h (poll): added 2000-11-18 Kai Vehmanen * procedure_timer.h (all): added 2000-11-16 Kai Vehmanen * locks.h (read): renamed to 'get' * locks.h (write): renamed to 'set' * locks.h (add, subtract, increment, decrement): added 2000-10-17 Kai Vehmanen * object_queue.h (all): few member functions renamed, pthread locking changes * command_queue.h (all): removed as obsolete * locks.h (pthread_mutex_spinlock): added 2000-09-30 Kai Vehmanen * definition_by_contract.h (all): lots of changes in the public interface * library version changed to 2:0:0 2000-04-11 Kai Vehmanen * kvutils.h (print_time_stamp): added * library version changed to 1:0:0 2000-03-24 Kai Vehmanen * com_line.h (combine): a new overloaded version 2000-03-21 Kai Vehmanen * object_queue.h: added * changes in all interfaces * library version set to 0:0:0 (current:revision:age) ----------------------------------------------------------------------- ecasound-2.9.1/kvutils/INSTALL0000644000076400007640000001722710664032032013014 00000000000000Basic Installation ================== These are generic installation instructions. 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, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). 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 at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' 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. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. 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. 4. Type `make install' to install the programs and any data files and documentation. 5. 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. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure 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 must use a version of `make' that supports the `VPATH' variable, such as 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 `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have 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. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' 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. 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'. Optional Features ================= 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. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM 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 host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ 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. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--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. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. ecasound-2.9.1/kvutils/kvu_object_queue.h0000644000076400007640000000604410664032032015466 00000000000000// ------------------------------------------------------------------------ // object_queue.cpp: Thread-safe way to transmit generic objects (FIFO). // Copyright (C) 1999-2000 Kai Vehmanen // // 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 INCLUDED_OBJECT_QUEUE_H #define INCLUDED_OBJECT_QUEUE_H #include #include /** * Thread-safe way to transmit generic objects (FIFO-queue). */ template class OBJECT_QUEUE { private: deque cmds_rep; mutable pthread_mutex_t lock_rep; public: /** * Inserts 'obj' into the queue. If some other process is * accessing the queue, this call will block. */ void push_back(const T& obj) { pthread_mutex_lock(&lock_rep); cmds_rep.push_back(obj); pthread_mutex_unlock(&lock_rep); } /** * Pops the first item. If some other process is * accessing the queue, this call will block. */ void pop_front(void) { pthread_mutex_lock(&lock_rep); cmds_rep.pop_front(); pthread_mutex_unlock(&lock_rep); } /** * Returns the first item. If some other process is * accessing the queue, this call will block. */ T front(void) const { T temporary; pthread_mutex_lock(&lock_rep); if (cmds_rep.size() > 0) { temporary = cmds_rep.front(); } pthread_mutex_unlock(&lock_rep); return(temporary); } /** * Returns true if the queue is empty. Unlike other calls, * this call will not block if some other process is * accessing the queue. In this case, the returned result * will be 'true' even if the queue wasn't empty. */ bool is_empty(void) const { if (pthread_mutex_trylock(&lock_rep) != 0) return(true); bool temp = true; if (cmds_rep.size() > 0) temp = false; pthread_mutex_unlock(&lock_rep); return(temp); } /** * Clears the queue. If some other process is * accessing the queue, this call will block. */ void clear(void) { pthread_mutex_lock(&lock_rep); while (cmds_repsize() > 0) cmds_rep.pop_front(); pthread_mutex_unlock(&lock_rep); } OBJECT_QUEUE(void) { pthread_mutex_init(&lock_rep, NULL); } ~OBJECT_QUEUE(void) { pthread_mutex_destroy(&lock_rep); } }; #endif ecasound-2.9.1/kvutils/kvu_com_line.cpp0000644000076400007640000000556610664032032015144 00000000000000// ------------------------------------------------------------------------ // kvu_com_line.cpp: A wrapper class for parsing command line arguments // Copyright (C) 1999,2002 Kai Vehmanen // // 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 #include #include #include "kvu_com_line.h" using namespace std; COMMAND_LINE::COMMAND_LINE(void) { current_rep = 0; } COMMAND_LINE::COMMAND_LINE(int argc, char *argv[]) { current_rep = 0; for(int t = 0; t < argc; t++) { cparams.push_back(argv[t]); } } COMMAND_LINE::COMMAND_LINE(const vector& params) { cparams = params; } void COMMAND_LINE::push_back(const string& argu) { cparams.push_back(argu); } bool COMMAND_LINE::has(char option) const { vector::size_type savepos = current_rep; current_rep = 0; while (current_rep < cparams.size()) { if (cparams[current_rep].size() > 1) { if (cparams[current_rep].at(0) == '-' && cparams[current_rep].at(1) == option) { current_rep = savepos; return(true); } } ++current_rep; } current_rep = savepos; return(false); } bool COMMAND_LINE::has(const string& option) const { vector::size_type savepos = current_rep; current_rep = 0; while (current_rep < cparams.size()) { if (cparams[current_rep] == option) { current_rep = savepos; return(true); } ++current_rep; } current_rep = savepos; return(false); } void COMMAND_LINE::combine(void) { cparams = combine(cparams); } vector COMMAND_LINE::combine(const vector& source) { vector result; string first; vector::const_iterator p = source.begin(); while(p != source.end()) { if (p->size() == 0) { ++p; continue; } if ((*p)[0] == '-') { if (find(p->begin(), p->end(), ':') == p->end()) { first = *p; ++p; if (p == source.end()) { result.push_back(first); break; } if ((*p)[0] != '-') { first += ":" + *p; result.push_back(first); } else { --p; result.push_back(first); } } else result.push_back(*p); } else result.push_back(*p); ++p; } return(result); } ecasound-2.9.1/kvutils/Makefile.am0000644000076400007640000000427211172655365014032 00000000000000# ---------------------------------------------------------------------- # File: ecasound/kvutils/Makefile.am # Description: Misc. utility routines (library created by Kai Vehmanen) # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- AUTOMAKE_OPTIONS = foreign # --- # Makefile.am for building libkvutils.a # --- if ECA_AM_DEBUG_MODE lib_LTLIBRARIES = libkvutils_debug.la else lib_LTLIBRARIES = libkvutils.la endif TESTS = libkvutils_tester check_PROGRAMS = $(TESTS) INCLUDES = $(ECA_S_EXTRA_CPPFLAGS) kvutil_sources = kvu_dbc.cpp \ kvu_debug.cpp \ kvu_com_line.cpp \ kvu_fd_io.cpp \ kvu_locks.cpp \ kvu_message_item.cpp \ kvu_numtostr.cpp \ kvu_procedure_timer.cpp \ kvu_rtcaps.cpp \ kvu_temporary_file_directory.cpp \ kvu_threads.cpp \ kvu_utils.cpp \ kvu_timestamp.cpp \ kvu_value_queue.cpp kvutil_headers = kvu_dbc.h \ kvu_debug.h \ kvu_definition_by_contract.h \ kvu_com_line.h \ kvu_fd_io.h \ kvu_inttypes.h \ kvu_locks.h \ kvu_message_item.h \ kvu_message_queue.h \ kvu_numtostr.h \ kvu_object_queue.h \ kvu_procedure_timer.h \ kvu_rtcaps.h \ kvu_temporary_file_directory.h \ kvu_threads.h \ kvu_utils.h \ kvu_timestamp.h \ kvu_value_queue.h libkvutils_la_SOURCES = $(kvutil_sources) $(kvutil_headers) libkvutils_la_LDFLAGS = -version-info @LIBKVUTILS_VERSION@:0:@LIBKVUTILS_VERSION_AGE@ -static libkvutils_debug_la_SOURCES = $(libkvutils_la_SOURCES) libkvutils_debug_la_LDFLAGS = $(libkvutils_la_LDFLAGS) libkvutils_tester_SOURCES = libkvutils_tester.cpp libkvutils_tester_LDFLAGS = -static libkvutils_tester_LDADD = $(lib_LTLIBRARIES) noinst_HEADERS = $(kvutil_headers) # --------------------------------------------------------------------- # Install targets install-data-local: $(INSTALL) -d $(DESTDIR)$(includedir)/kvutils cd $(srcdir) ; cp $(kvutil_headers) $(DESTDIR)$(includedir)/kvutils # --------------------------------------------------------------------- # Uninstall targets uninstall-local: cd $(DESTDIR)$(includedir)/kvutils && \ rm -f $(kvutil_headers) rmdir $(DESTDIR)$(includedir)/kvutils || echo "Skipping non-empty directory" ecasound-2.9.1/kvutils/kvu_utils.cpp0000644000076400007640000004004511140167675014522 00000000000000// ------------------------------------------------------------------------ // kvu_utils.cpp: Miscellaneous helper routines // Copyright (C) 1999-2004,2009 Kai Vehmanen // // Attributes: // eca-style-version: 2 // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include /* find() */ #include /* atoi() */ #include #include #include #if HAVE_LOCALE_H #include /* setlocale */ #endif #include /* nanosleep() */ #include /* gettimeofday() */ #include /* usleep() */ #include /* isspace(), toupper() */ #include "kvu_dbc.h" #include "kvu_utils.h" using namespace std; static string::const_iterator kvu_priv_find_next_instance(const string& arg, const string::const_iterator& curpos, const string::value_type value); static void kvu_priv_strip_escapes(string* const input, const string& escaped_char); /** * Returns a string where all regex metachars in 'arg' * have been quoted using a backslash. * * Reference: man regex(7) */ string kvu_string_regex_meta_escape(const string& arg) { string result; /* regex metachar set: ^.[]$()|*+?{}\ */ string::const_iterator p = arg.begin(); while(p != arg.end()) { if (*p == '^') result += "\\^"; else if (*p == '.') result += "\\."; else if (*p == '[') result += "\\["; else if (*p == ']') result += "\\]"; else if (*p == '$') result += "\\$"; else if (*p == '(') result += "\\("; else if (*p == ')') result += "\\)"; else if (*p == '|') result += "\\|"; else if (*p == '*') result += "\\*"; else if (*p == '+') result += "\\+"; else if (*p == '?') result += "\\?"; else if (*p == '{') result += "\\{"; else if (*p == '}') result += "\\}"; else if (*p == '\\') result += "\\\\"; else result += *p; ++p; } return result; } /** * Returns a string where all meta characters in 'arg' * have been quoted using a backslash. * * Reference: man sh(1), man bash(1) */ string kvu_string_shell_meta_escape(const string& arg) { string result; string::const_iterator p = arg.begin(); while(p != arg.end()) { if (*p == '"') result += "\\\""; else if (*p == '\'') result += "\\\'"; else if (*p == ' ') result += "\\ "; else if (*p == '|') result += "\\|"; else if (*p == '&') result += "\\&"; else if (*p == ';') result += "\\;"; else if (*p == '(') result += "\\("; else if (*p == ')') result += "\\)"; else if (*p == '<') result += "\\<"; else if (*p == '>') result += "\\>"; else result += *p; ++p; } return result; } /** * Converts a string to a vector of strings (words). * Whitespace is used as the separator. * * Note! This function is obsolete, use @see string_to_tokens() * instead. */ vector kvu_string_to_words(const string& s) { return kvu_string_to_tokens(s); } /** * Converts a string to a vector of token strings. * Whitespace is used as the separator. */ vector kvu_string_to_tokens(const string& s) { vector vec; string stmp = ""; for(string::const_iterator p = s.begin(); p != s.end(); p++) { if (isspace(*p) == 0) stmp += *p; else { if (stmp == "") continue; vec.push_back(stmp); stmp = ""; } } if (stmp.size() > 0) vec.push_back(stmp); return vec; } /** * Converts a string to a vector of token strings. * Whitespace is used as the token separator. * * Unlike string_to_tokens(), quotes can be used to mark * groups of words as tokens (e.g. "this is one token"). * The tokens are not removed from the string. * Single-quotes (') are not supported. * * It's also possible to add individual whitespace * characted by escaping them with a backclash (e.g. * 'this\ is\ one\ token\ '). Escaped characters are * not considered as possible separators. */ vector kvu_string_to_tokens_quoted(const string& s) { vector vec; string stmp; bool quoteflag = false; for(string::const_iterator p = s.begin(); p != s.end(); p++) { if (*p == '\"') { quoteflag = !quoteflag; stmp += *p; } else if (*p == '\\') { p++; if (p == s.end()) break; stmp += *p; } else if (isspace(*p) == 0 || quoteflag == true) { stmp += *p; } else { /* note: token ready, add to vector if length is non-zero */ if (stmp.size() == 0) continue; vec.push_back(stmp); stmp = ""; DBC_CHECK(stmp.size() == 0); } } if (stmp.size() > 0) vec.push_back(stmp); return vec; } /** * Converts a string to a vector of strings. * * @param str string to be converted * @param separator character to be used for separating items */ vector kvu_string_to_vector(const string& str, const string::value_type separator) { vector vec; string stmp = ""; for(string::const_iterator p = str.begin(); p != str.end(); p++) { if (*p != separator) stmp += *p; else { if (stmp == "") continue; vec.push_back(stmp); stmp = ""; } } if (stmp.size() > 0) vec.push_back(stmp); return vec; } /** * Converts a string to a vector of integers. * * @param str string to be converted * @param separator character to be used for separating items */ vector kvu_string_to_int_vector(const string& str, const string::value_type separator) { vector vec; string stmp = ""; for(string::const_iterator p = str.begin(); p != str.end(); p++) { if (*p != separator) stmp += *p; else { if (stmp == "") continue; vec.push_back(atoi(stmp.c_str())); stmp = ""; } } if (stmp.size() > 0) vec.push_back(atoi(stmp.c_str())); return vec; } /** * Return a modified copy of vector 'str_vector' where 'from' has * been replaced with 'to' in all items. */ vector kvu_vector_search_and_replace(const vector& str_vector, const string& from, const string& to) { vector vstmp; vector::const_iterator p = str_vector.begin(); while(p != str_vector.end()) { vstmp.push_back(kvu_string_search_and_replace(*p, from, to)); ++p; } return vstmp; } /** * Converts a vector of strings to a single string. * * @param str vector of strings to be converted * @param separator string that is inserted between items */ string kvu_vector_to_string(const vector& str, const string& separator) { string stmp; vector::const_iterator p = str.begin(); while(p != str.end()) { stmp += *p; ++p; if (p != str.end()) stmp += separator; } return stmp; } /** * Return a new string, where all 'from' characters are * replaced with 'to' characters. */ string kvu_string_search_and_replace(const string& str, const string::value_type from, const string::value_type to) { string stmp (str); for(vector::size_type p = 0; p < str.size(); p++) { if (str[p] == from) stmp[p] = to; else stmp[p] = str[p]; } return stmp; } /** * Return a new string, where all 'from' characters are * replaced with 'to' characters. */ string kvu_string_search_and_replace(const string& str, const string& from, const string& to) { string tmp (str); size_t pos = 0; while((pos = tmp.find(from, pos)) != string::npos) { tmp.replace(pos, from.size(), to); pos += (to.size() > from.size() ? to.size() : from.size()); } return tmp; } /** * Case-insensitive string compare. Ignores preceding and * trailing white space. */ bool kvu_string_icmp(const string& first, const string& second) { string a = first; string b = second; a = kvu_remove_trailing_spaces(a); a = kvu_remove_preceding_spaces(a); a = kvu_convert_to_uppercase(a); b = kvu_remove_trailing_spaces(b); b = kvu_remove_preceding_spaces(b); b = kvu_convert_to_uppercase(b); return a == b; } /** * Removes all trailing white space */ string kvu_remove_trailing_spaces(const string& a) { string r = ""; string::const_reverse_iterator p; for(p = a.rbegin(); p != a.rend(); p++) { if (*p != ' ') break; } for(; p != a.rend(); p++) { r = *p + r; } return r; } /** * Removes all preciding white space */ string kvu_remove_preceding_spaces(const string& a) { string r = ""; string::const_iterator p; for(p = a.begin(); p != a.end(); p++) { if (*p != ' ') break; } for(; p != a.end(); p++) { r += *p; } return r; } /** * Removes all surrounding white spaces */ string kvu_remove_surrounding_spaces(const string& a) { string::const_iterator p,q; for(p = a.begin(); p != a.end() && *p == ' '; p++); for(q = (a.end() - 1); q != a.begin() && *q == ' '; q--); return string(p,q + 1); } /** * Converts string to uppercase using toupper(int) */ string kvu_convert_to_uppercase(const string& a) { string r = a; for(string::iterator p = r.begin(); p != r.end(); p++) *p = toupper(*p); return r; } /** * Converts string to lowercase using tolower(int) */ string kvu_convert_to_lowercase(const string& a) { string r = a; for(string::iterator p = r.begin(); p != r.end(); p++) *p = tolower(*p); return r; } /** * Converts string to uppercase using toupper(int) * Modifies the parameter object. */ void kvu_to_uppercase(string& a) { string::iterator p = a.begin(); while(p != a.end()) { *p = toupper(*p); ++p; } } /** * Converts string to lowercase using tolower(int) * Modifies the parameter object. */ void kvu_to_lowercase(string& a) { string::iterator p = a.begin(); while(p != a.end()) { *p = tolower(*p); ++p; } } /** * Finds the next instance of character 'value' and returns its * position. * * All backslash escaped instances of 'value' ("\") * are ignored in the search. Also instance of 'value' within * a pair of double quotes are ignored. * * Note that general backlash escaping is not supported, i.e. * "\" is not interpreted as "". * * @return position of next 'value' or arg.end() if not found */ static string::const_iterator kvu_priv_find_next_instance(const string& arg, const string::const_iterator& start, const string::value_type value) { string::const_iterator curpos = start, ret = arg.end(), nextquote = arg.end(); while(curpos != arg.end()) { ret = find(curpos, arg.end(), value); nextquote = find(curpos, arg.end(), '"'); if (nextquote < ret) { /* step: ignore quoted part of the input string */ nextquote = find(nextquote + 1, arg.end(), '"'); if (nextquote != arg.end()) { curpos = nextquote + 1; ret = find(curpos, arg.end(), value); } } if (ret != arg.end() && ret != arg.begin()) { string::const_iterator prev = ret - 1; if ((*prev) == '\\') { curpos = ret + 1; continue; } } break; } return ret; } /** * Returns the nth argument from a formatted string * * @param number the argument number * @param argu a formatted string: "something:arg1,arg2,...,argn" * * require: * number >= 1 */ string kvu_get_argument_number(int number, const string& arg) { string result; vector temp = kvu_get_arguments(arg); if (static_cast(temp.size()) >= number) { result = temp[number - 1]; } return result; } /** * Converts all backslash-commas into commas and returns * the result. * * @pre escaped_char.size() == 1 */ static void kvu_priv_strip_escapes(string* const input, const string& escaped_char) { size_t pos; while((pos = input->find(string("\\") + escaped_char)) != string::npos) { input->replace(pos, 2, escaped_char); } } /** * Strips the outer quotes of type 'quote_char' from the string. * The string is only modified if the the string starts with, * and ends to, a character matching 'quote_char'. * * @pre escaped_char.size() == 1 */ void kvu_string_strip_outer_quotes(string* input, const std::string::value_type quote_char) { if (input->size() >= 2 && *input->begin() == quote_char && *(input->end() - 1) == quote_char) *input = std::string(input->begin() + 1, input->end() - 1); } /** * Returns number of arguments in formatted string 'arg'. */ int kvu_get_number_of_arguments(const string& arg) { return kvu_get_arguments(arg).size(); } /** * Returns a vector of all arguments from a formatted string * * Note: forces locale to "POSIX" as decimal separate must be * be period (.) in order to argument separation to work * * @param argu a formatted string: "something:arg1,arg2,...,argn" */ vector kvu_get_arguments(const string& argu) { vector resvec; char* locale_save; string::const_iterator b = kvu_priv_find_next_instance(argu, argu.begin(), ':'); string::const_iterator e; if (b == argu.end()) { if (argu.size() > 0) b = argu.begin(); else return resvec; } else ++b; #if HAVE_SETLOCALE locale_save = setlocale (LC_NUMERIC, "POSIX"); #else locale_save = NULL; #endif for(; b != argu.end();) { e = kvu_priv_find_next_instance(argu, b, ','); string target = string(b, e); /* strip backslash-commas (and leave the commas in place) */ kvu_priv_strip_escapes(&target, ","); kvu_priv_strip_escapes(&target, ":"); kvu_string_strip_outer_quotes(&target, '"'); resvec.push_back(target); if (e == argu.end()) break; b = e; ++b; /* special case in which last argument is empty */ if (b == argu.end() && *e == ',') resvec.push_back(""); } #if HAVE_SETLOCALE /* restore original locale */ if (locale_save) setlocale (LC_NUMERIC, locale_save); #endif return resvec; } /** * Get the prefix part of a string argument * @param argument format used is -prefix:arg1, arg2, ..., argN * * require: * argu.find('-') != string::npos * * ensure: * result.size() >= 0 */ string kvu_get_argument_prefix(const string& argu) { // -------- DBC_REQUIRE(argu.find('-') != string::npos); // -------- string::const_iterator b = find(argu.begin(), argu.end(), '-'); string::const_iterator e = find(argu.begin(), argu.end(), ':'); if (b != argu.end()) { ++b; if (b != argu.end()) { return string(b,e); } } return ""; } /** * Prints a time stamp to stderr */ void kvu_print_time_stamp(void) { // -- // not thread-safe! // -- static bool first = true; static struct timeval last; struct timeval current; if (first) { ::gettimeofday(&last, 0); first = false; } ::gettimeofday(¤t, 0); cerr << "(timestamp) " << current.tv_sec << "sec, " << current.tv_usec << "msec."; long delta = current.tv_usec; delta -= last.tv_usec; delta += (current.tv_sec - last.tv_sec) * 1000000; cerr << " Delta " << delta << "msec." << endl; last.tv_sec = current.tv_sec; last.tv_usec = current.tv_usec; } /** * Put the calling execution context to sleeps for * 'seconds.nanosecods'. * * Note! If available, implemented using nanosleep(). * * @return 0 on success, non-zero if sleep was * interrupted for some reason */ int kvu_sleep(long int seconds, long int nanoseconds) { int ret = 0; #if defined(HAVE_NANOSLEEP) && !defined(__CYGWIN__) struct timespec len; len.tv_sec = static_cast(seconds); len.tv_nsec = nanoseconds; ret = nanosleep(&len, NULL); #elif HAVE_USLEEP ret = usleep(seconds * 1000000 + nanoseconds / 1000); #else cerr << "(libkvutils) kvutils:: warning! neither nanosleep() or usleep() found!" << endl; #endif return ret; } ecasound-2.9.1/kvutils/kvu_rtcaps.cpp0000644000076400007640000001073711261213043014644 00000000000000// ------------------------------------------------------------------------ // kvu_rtcaps.h: Routines for utilizing POSIX RT extensions. // Copyright (C) 2001-2003,2009 Kai Vehmanen // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include /* getpid(), _POSIX_MEMLOCK */ #ifdef HAVE_SCHED_H #include #endif #ifdef HAVE_SYS_MMAN_H #include /* mlockall(), munlockall() */ #endif #include #include "kvu_rtcaps.h" static bool kvu_check_for_sched_sub(int policy); bool kvu_check_for_sched_sub(int policy) { bool result = false; #ifdef HAVE_SCHED_GETPARAM int curpid = getpid(); /* store old scheduling params */ struct sched_param prev_sparam; int ret = sched_getparam(curpid, &prev_sparam); if (ret == 0) { int prev_prio = prev_sparam.sched_priority; int prev_policy = sched_getscheduler(0); if (prev_policy >= 0) { /* get maximum priority for the tested policy */ int min_prio = sched_get_priority_min(policy); if (min_prio >= 0) { struct sched_param sparam; sparam.sched_priority = min_prio; /* try to change scheduling according the new params */ int ret = sched_setscheduler(curpid, policy, &sparam); if (ret == 0) { /* test succeeded, restore old settings */ result = true; sparam.sched_priority = prev_prio; sched_setscheduler(curpid, prev_policy, &sparam); } } } } #else /* HAVE_SCHED_GETPARAM */ std::cerr << "(libkvutils) kvu_rtcaps: warning! sched_getparam() not supported" << std::endl; #endif return(result); } /** * Checks whether current process has privileges * to set scheduler to SCHED_FIFO. */ bool kvu_check_for_sched_fifo(void) { #ifdef HAVE_SCHED_H return(kvu_check_for_sched_sub(SCHED_FIFO)); #else std::cerr << "(libkvutils) kvu_rtcaps: warning! sched.h not available" << std::endl; #endif } /** * Checks whether current process has privileges * to set scheduler to SCHED_RR. */ bool kvu_check_for_sched_rr(void) { #ifdef HAVE_SCHED_H return(kvu_check_for_sched_sub(SCHED_RR)); #else std::cerr << "(libkvutils) kvu_rtcaps: warning! sched.h not available" << std::endl; #endif } /** * Checks whether mlockall() call is available * and whether current process has privileges * to execute it. * * Note! Function issues an munlockall() call, * which will free all previously locked * memory areas for this process. */ bool kvu_check_for_mlockall(void) { bool result = false; #if defined(_POSIX_MEMLOCK) && defined(HAVE_MLOCKALL) && defined(HAVE_MUNLOCKALL) /* unistd.h */ int ret = mlockall(MCL_CURRENT); if (ret == 0) { result = true; munlockall(); } #else std::cerr << "(libkvutils) kvu_rtcaps: warning! POSIX_MEMLOCK not supported" << std::endl; #endif return(result); } /** * Sets the scheduler settings for calling thread. * If thread specific scheduler API (pthread_setscheduler, etc) * is not available, function will fall back to process level * functions (sched_setscheduler). * * @param policy SCHED_OTHER, SCHED_FIFO, SCHED_RR (see sched_setscheduler(2)) * @param priority value between 0 and 99 (see sched_setscheduler(2)) * * @return Zero on success, non-zero on error. */ int kvu_set_thread_scheduling(int policy, int priority) { int ret = 0; #if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_PTHREAD_SELF) struct sched_param sparam; sparam.sched_priority = priority; ret = pthread_setschedparam(pthread_self(), policy, &sparam); #elif defined(HAVE_SCHED_SETSCHEDULER) struct sched_param sparam; sparam.sched_priority = priority; ret = sched_setscheduler(0, policy, &sparam); #else std::cerr << "(libkvutils) kvu_rtcaps: warning! unable to set scheduler settings" << std::endl; #endif return ret; } ecasound-2.9.1/kvutils/kvu_definition_by_contract.h0000644000076400007640000000550210664032032017531 00000000000000// ------------------------------------------------------------------------ // definition_by_contract.h: Tools for simulating design-by-contract // Copyright (C) 1999-2000 Kai Vehmanen // // 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 INCLUDED_DEFINITION_BY_CONTRACT_H #define INCLUDED_DEFINITION_BY_CONTRACT_H /** * Exception that is thrown when some contract fails * * Note! Obsolete - not used anymore * * @author Kai Vehmanen */ class DBC_EXCEPTION { public: const char* type_repp; const char* file_repp; const char* expression_repp; int line_rep; DBC_EXCEPTION(const char* type, const char* expr, const char* file, int line) : type_repp(type), file_repp(file), expression_repp(expr), line_rep(line) { } }; /** * Tool for simulating programming/design-by-contract in C++ * classes. Features include routine preconditions, postconditions * and virtual class invariants. Checks are only performed, when * ENABLE_DBC is defined. * * Note! Obsolete - not used anymore * * @author Kai Vehmanen */ class DEFINITION_BY_CONTRACT { #ifdef ENABLE_DBC protected: inline void require(bool expr, const char* expr_str, const char* file, int line) const { check_invariant(file, line); if (!expr) throw(DBC_EXCEPTION("require", expr_str, file, line)); } inline void ensure(bool expr, const char* expr_str, const char* file, int line) const { if (!expr) throw(DBC_EXCEPTION("ensure", expr_str, file, line)); check_invariant(file, line); } inline void check_invariant(const char* file, int line) const { if (!class_invariant()) throw(DBC_EXCEPTION("class invariant", "", file, line)); } virtual bool class_invariant(void) const { return(true); } public: virtual ~DEFINITION_BY_CONTRACT(void) { } #define REQUIRE(expr) \ (expr) ? static_cast(0) : (require (false,#expr,__FILE__, __LINE__)) #define ENSURE(expr) \ (expr) ? static_cast(0) : (ensure (false,#expr,__FILE__, __LINE__)) #else // --> DBC DISABLED public: #define REQUIRE(expr) ((void) 0) #define ENSURE(expr) ((void) 0) #endif // <-- DBC DISABLED }; #endif ecasound-2.9.1/kvutils/kvu_dbc.h0000644000076400007640000000700111353657560013555 00000000000000/************************************************************************** * dbc.h: A barebones design-by-contract framework for C and C++ * Copyright (C) 2001,2002,2009 Kai Vehmanen * * 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 INCLUDED_DBC_H #define INCLUDED_DBC_H #ifdef ENABLE_DBC #include void kvu_dbc_report_failure(const char *action, const char* expr, const char* file, const char* func, int lineno); /** * Declare a boolean precondition assertion. A warning is emitted * if expr is false. */ #define DBC_REQUIRE(expr) \ (expr) ? (void)(0) : kvu_dbc_report_failure("DBC_REQUIRE", #expr, __FILE__, __KVU_FUNCTION, __LINE__) /** * Declare a boolean postcondition assertion. A warning is emitted * if expr is false. */ #define DBC_ENSURE(expr) \ (expr) ? (void)(0) : kvu_dbc_report_failure("DBC_ENSURE", #expr, __FILE__, __KVU_FUNCTION, __LINE__) /** * Declare a boolean invariant assertion. A warning is emitted * if expr is false. */ #define DBC_CHECK(expr) \ (expr) ? (void)(0) : kvu_dbc_report_failure("DBC_CHECK", #expr, __FILE__, __KVU_FUNCTION, __LINE__) /** * Emits warning if macro is ever executed. */ #define DBC_NEVER_REACHED(expr) \ kvu_dbc_report_failure("DBC_NEVER_REACHED", NULL, __FILE__, __KVU_FUNCTION, __LINE__) /** * A helper macro for declaring variables, etc that will be * only defined when ENABLE_DBC is enabled. */ #define DBC_DECLARE(expr) expr #else /* DBC DISABLED --> */ /* When ENABLE_DBC is not defined, the macros expand to no-op statements */ #define DBC_REQUIRE(expr) ((void) 0) #define DBC_ENSURE(expr) ((void) 0) #define DBC_CHECK(expr) ((void) 0) #define DBC_NEVER_REACHED(x) ((void) 0) #define DBC_DECLARE(expr) ((void) 0) #endif /* <-- DBC DISABLED */ /* Adapted from glibc 2.9 assert.h (LGPL 2.1) Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__' which contains the name of the function currently being defined. This is broken in G++ before version 2.6. C9x has a similar variable called __func__, but prefer the GCC one since it demangles C++ function names. */ #undef __KVU_FUNCTION #if defined HAVE_FEATURES_H # include #endif #if defined __GNUC_PREREQ /* 1. gcc pretty-printer */ # if __GNUC_PREREQ(2, 6) # define __KVU_FUNCTION __PRETTY_FUNCTION__ # endif #elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L /* 2. check for C99 (not defined at all in C90, nor in C++1998) */ # define __KVU_FUNCTION __func__ #elif defined __GNUC__ && __GNUC__ >= 2 /* 3. as per http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html */ # define __KVU_FUNCTION __FUNCTION__ #else /* 4. not supported */ # define __KVU_FUNCTION "__func__" #endif #endif /* INCLUDED_DBC_H */ ecasound-2.9.1/kvutils/kvu_message_queue.h0000644000076400007640000001427111760467520015661 00000000000000// ------------------------------------------------------------------------ // kvu_message_queue.cpp: Special purpose queue data for RT msg passsing // Copyright (C) 2009,2012 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 INCLUDE_KVU_MESSAGE_QUEUE_H #define INCLUDE_KVU_MESSAGE_QUEUE_H #include #include #include #include #include "kvu_timestamp.h" /** * Default for maximum size of the queue for operation in * bounded execution time mode. */ static const size_t msg_queue_rt_max_size_const = 1024; /** * A queue implementation for sending generic messages between * threads. * * All the consumer operations are real-time safe, i.e. they have * bounded execution time. However, the bounded execution is * guaranteed only until queue size reaches max_rt_size() items. * * Once queue size reached max_rt_size(), consumer operation is * switched to blocking behaviour. This is done as a safety * measure in real-time use. * * @author Kai Vehmanen */ template class MESSAGE_QUEUE_RT_C { public: /** * Class constructor. * * @param max_rt_size Change queue behaviour to be non-determistic * if the number of queued messaes reaches this * limit. This can be used as a safety measure * real-time applications. * * Execution note: may block, may allocate memory */ MESSAGE_QUEUE_RT_C(int max_rt_size = -1) : pending_pops_rep(0) { pthread_mutex_init(&lock_rep, NULL); pthread_cond_init(&cond_rep, NULL); if (max_rt_size == -1) max_rt_size_rep = msg_queue_rt_max_size_const; else max_rt_size_rep = static_cast(max_rt_size); } /** * Adds a new item to the end of the queue. * * Execution note: may block, may allocate memory */ void push_back(const T& arg) { pthread_mutex_lock(&lock_rep); msgs_rep.push_back(arg); pthread_cond_broadcast(&cond_rep); pthread_mutex_unlock(&lock_rep); } /** * Fetches, and removes, the front item in the queue. * If the queue is empty, an error is returned. * * Execution note: rt-safe, does not block * * @return 1 on success, -1 if busy, 0 if empty */ int pop_front(T* front_msg) { int res = 1; int lockres = pthread_mutex_trylock(&lock_rep); if (lockres == 0) { if (msgs_rep.size() > 0) { if (front_msg != 0) *front_msg = msgs_rep.front(); msgs_rep.pop_front(); } else { res = 0; } pthread_mutex_unlock(&lock_rep); } else { res = -1; } return res; } /** * Fetches but does not remove the front item in the queue. * If the queue is empty, an error is returned. * * Execution note: rt-safe, does not block * * @return 1 on success, -1 if busy, 0 if empty */ int peek_front(T* front_msg) { int res = 1; int lockres = pthread_mutex_trylock(&lock_rep); if (lockres == 0) { if (msgs_rep.size() > 0) { if (front_msg != 0) *front_msg = msgs_rep.front(); } else { res = 0; } pthread_mutex_unlock(&lock_rep); } else { res = -1; } return res; } /** * Clears the queue * * Execution note: may block */ void clear(void) { pthread_mutex_lock(&lock_rep); msgs_rep.clear(); pthread_cond_broadcast(&cond_rep); pthread_mutex_unlock(&lock_rep); } /** * Blocks until 'is_empty() != true'. 'timeout_sec' and * 'timeout_usec' specify the upper time limit for blocking. * * Execution: may block, may allocate memory * * @pre is_empty() != true */ void poll(int timeout_sec, long int timeout_usec) { struct timeval nowtmp; struct timespec now, timeout; int retcode = 0; gettimeofday(&nowtmp, NULL); now.tv_sec = nowtmp.tv_sec; now.tv_nsec = nowtmp.tv_usec * 1000; timeout.tv_sec = timeout_sec; timeout.tv_nsec = timeout_usec * 1000; kvu_timespec_add(&now, &timeout, &timeout); pthread_mutex_lock(&lock_rep); while (msgs_rep.empty() == true && retcode != ETIMEDOUT) { retcode = pthread_cond_timedwait(&cond_rep, &lock_rep, &timeout); } pthread_mutex_unlock(&lock_rep); return; } /** * Is queue empty? * * Execution note: rt-safe if queue size within 'max_rt_size' */ bool is_empty(void) const { bool emptyres = false; int ret = pthread_mutex_trylock(&lock_rep); /* note: msgs_rep.size() is accessed without holding * a lock, but that's safe as in the worst case * caller blocks unnecessarily */ if (ret != 0 && msgs_rep.size() >= max_rt_size_rep) { /* note: queue has grown beyond the rt-safe maximum size, * change to non-bounded mode to force synchronization * between the producer and consumer threads */ ret = pthread_mutex_lock(&lock_rep); } if (ret == 0) { emptyres = (msgs_rep.size() == 0); pthread_mutex_unlock(&lock_rep); } return emptyres; } size_t max_rt_size(void) const { return max_rt_size_rep; } private: mutable pthread_mutex_t lock_rep; // mutex ensuring exclusive access to buffer mutable pthread_cond_t cond_rep; size_t max_rt_size_rep; // only modified in constructor size_t pending_pops_rep; T invalid_rep; // only modified in constructor std::deque msgs_rep; }; #endif /* INCLUDE_KVU_MESSAGE_QUEUE_H */ ecasound-2.9.1/kvutils/kvu_debug.h0000644000076400007640000000211011163011476014074 00000000000000// ------------------------------------------------------------------------ // kvu_debug.h: Debug helper functions // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 INCLUDED_KVU_DEBUG_H #define INCLUDED_KVU_DEBUG_H void kvu_print_backtrace_stderr(void); #endif ecasound-2.9.1/kvutils/kvu_fd_io.cpp0000644000076400007640000000643110664032032014427 00000000000000// ------------------------------------------------------------------------ // kvu_fd_io.cpp: Helper functions for reading from, writing to and // waiting on UNIX file descriptors. // // Copyright (C) 2002 Kai Vehmanen // // 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 /* POSIX: read()/write() */ #include /* XPG4-UNIX: poll() */ #include "kvu_fd_io.h" /** * Attempts to read up to 'count' bytes from file descriptor 'fd' * into the buffer starting at 'buf'. If no data is available * for reading, up to 'timeout' milliseconds will be waited. * A negative value means infinite timeout. */ ssize_t kvu_fd_read(int fd, void *buf, size_t count, int timeout) { int nfds = 1; struct pollfd ufds; ssize_t rescount = 0; ufds.fd = fd; ufds.events = POLLIN | POLLPRI; ufds.revents = 0; int ret = poll(&ufds, nfds, timeout); if (ret > 0) { if (ufds.revents & POLLIN || ufds.revents & POLLPRI) { rescount = ::read(fd, buf, count); } } else if (ret == 0) { /* timeout */ rescount = -1; } return(rescount); } /** * Attempts to write up to 'count' bytes to file descriptor 'fd' * from the buffer starting at 'buf'. If no space is available * for writing, up to 'timeout' milliseconds will be waited. * A negative value means infinite timeout. */ ssize_t kvu_fd_write(int fd, const void *buf, size_t count, int timeout) { int nfds = 1; struct pollfd ufds; ssize_t rescount = 0; ufds.fd = fd; ufds.events = POLLOUT; ufds.revents = 0; int ret = poll(&ufds, nfds, timeout); if (ret > 0) { if (ufds.revents & POLLOUT) { rescount = ::write(fd, buf, count); } } else if (ret == 0) { /* timeout */ rescount = -1; } return(rescount); } /** * Blocks until state of file descriptor 'fd' * changes. State changes include 'fd' becoming * readable, writing or an error condition. * A maximum of 'timeout' milliseconds will be * waited. A negative value means infinite timeout. * * @return returns 1 for success, 0 for timeout * and -1 on error */ int kvu_fd_wait(int fd, int timeout) { int nfds = 1; struct pollfd ufds; ufds.fd = fd; ufds.events = POLLIN | POLLPRI | POLLOUT; ufds.revents = 0; int ret = poll(&ufds, nfds, timeout); if (ret > 0) { if (ufds.revents & POLLERR || ufds.revents & POLLHUP || ufds.revents & POLLNVAL) { /* error */ return(-1); } else { /* success */ return(1); } } else if (ret == 0) { /* timeout */ return(0); } /* error */ return(-1); } ecasound-2.9.1/kvutils/kvu_threads.h0000644000076400007640000000263511743344147014464 00000000000000// ------------------------------------------------------------------------ // kvu_threads.h: Various pthread related helper functions. // Copyright (C) 2002,2004,2012 Kai Vehmanen // // 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 // ------------------------------------------------------------------------ // -*- mode: C++; -*- #ifndef INCLUDED_KVU_THREADS_H #define INCLUDED_KVU_THREADS_H #include #include int kvu_pthread_mutex_spinlock (pthread_mutex_t *mp, long int spinlimit); int kvu_pthread_timed_wait(pthread_mutex_t* mutex, pthread_cond_t* cond, long int seconds); std::string kvu_pthread_timed_wait_result(int result, const std::string& prefix); int kvu_pthread_cond_timeout(int seconds, struct timespec *out, bool monotonic); #endif ecasound-2.9.1/kvutils/kvu_message_item.cpp0000644000076400007640000000531510664032032016011 00000000000000// ------------------------------------------------------------------------ // kvu_message_item.cpp: A simple version of C++ stringstream // Copyright (C) 1999,2001,2004 Kai Vehmanen // // 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 #include "kvu_message_item.h" MESSAGE_ITEM& MESSAGE_ITEM::operator<< (char c) { char temp[2]; temp[0] = c; temp[1] = 0; stringtemp += std::string(temp); return (*this); } MESSAGE_ITEM& MESSAGE_ITEM::operator<< (int n) { char ctmp[12]; snprintf(ctmp, 12, "%d",n); ctmp[11] = 0; stringtemp += std::string(ctmp); return (*this); } MESSAGE_ITEM& MESSAGE_ITEM::operator<< (const void *p) { char ctmp[12]; snprintf(ctmp, 12, "%p",p); ctmp[11] = 0; stringtemp += std::string(ctmp); return (*this); } MESSAGE_ITEM& MESSAGE_ITEM::operator<< (unsigned int n) { char ctmp[12]; snprintf(ctmp, 12, "%u",n); ctmp[11] = 0; stringtemp += std::string(ctmp); return (*this); } MESSAGE_ITEM& MESSAGE_ITEM::operator<< (long int n) { char ctmp[12]; snprintf(ctmp, 12, "%ld",n); ctmp[11] = 0; stringtemp += std::string(ctmp); return (*this); } MESSAGE_ITEM& MESSAGE_ITEM::operator<< (unsigned long int n) { char ctmp[12]; snprintf(ctmp, 12, "%lu",n); ctmp[11] = 0; stringtemp += std::string(ctmp); return (*this); } #if defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE || defined _LARGEFILE_SOURCE || defined __GNUC__ MESSAGE_ITEM& MESSAGE_ITEM::operator<< (long long int n) { char ctmp[24]; snprintf(ctmp, 24, "%lli", n); ctmp[23] = 0; stringtemp += std::string(ctmp); return (*this); } MESSAGE_ITEM& MESSAGE_ITEM::operator<< (unsigned long long int n) { char ctmp[24]; snprintf(ctmp, 24, "%llu", n); ctmp[23] = 0; stringtemp += std::string(ctmp); return (*this); } #endif MESSAGE_ITEM& MESSAGE_ITEM::operator<< (double n) { char ctmp[32]; snprintf(ctmp, 12, "%.*f",flo_prec, n); ctmp[31] = 0; stringtemp += std::string(ctmp); return (*this); } ecasound-2.9.1/kvutils/kvu_timestamp.h0000644000076400007640000000700511170401640015013 00000000000000// ------------------------------------------------------------------------ // kvu_timestamp.h: Monotonic timestamps // Copyright (C) 2009 Kai Vehmanen // // Attributes: // eca-style-version: 3 // // 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 INCLUDED_KVU_TIMESTAMP_H #define INCLUDED_KVU_TIMESTAMP_H #include /** * Returns non-zero if clock is monotonic. * * See POSIX 'CLOCK_MONOTONIC' */ int kvu_clock_is_monotonic(void); /** * Finds the resolution (precision) of the clock * source. * * See POSIX clock_getres(). */ int kvu_clock_getres(struct kvu_timespec *res); /** * Retrieves a timestamp * * See POSIX clock_gettime() */ int kvu_clock_gettime(struct timespec *tp); /** * Returns the timestamp as seconds */ static inline double kvu_timespec_seconds(struct timespec *tp) { return tp->tv_sec + (static_cast(tp->tv_nsec) / 1000000000.0); } /** * Adapted from macro definitions in glibc's sys/time.h (LGPL 2.1) */ static inline void kvu_timespec_clear(struct timespec *tvp) { tvp->tv_sec = tvp->tv_nsec = 0; } static inline void kvu_timespec_assign(struct timespec *x, const struct timespec *y) { x->tv_sec = y->tv_sec; x->tv_nsec = y->tv_nsec; } /** * result = a + b * * Adapted from macro definitions in glibc's sys/time.h (LGPL 2.1) */ static inline void kvu_timespec_add(const struct timespec *a, const struct timespec *b, struct timespec *result) { (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; if ((result)->tv_nsec >= 1000000000) { ++(result)->tv_sec; (result)->tv_nsec -= 1000000000; } } /** * Returns 'a < b' * * Adapted from macro definitions in glibc's sys/time.h (LGPL 2.1) */ static inline int kvu_timespec_cmp_lt(const struct timespec *a, const struct timespec *b) { return (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_nsec < (b)->tv_nsec) : ((a)->tv_sec < (b)->tv_sec)); } /** * Returns 'a > b' * * Adapted from macro definitions in glibc's sys/time.h (LGPL 2.1) */ static inline int kvu_timespec_cmp_gt(const struct timespec *a, const struct timespec *b) { return (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_nsec > (b)->tv_nsec) : ((a)->tv_sec > (b)->tv_sec)); } /** * result = a - b * * Adapted from macro definitions in glibc's sys/time.h (LGPL 2.1) */ static inline void kvu_timespec_sub(const struct timespec *a, const struct timespec *b, struct timespec *result) { (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; if ((result)->tv_nsec < 0) { --(result)->tv_sec; (result)->tv_nsec += 1000000000; } } \ #endif /* INCLUDED_KVU_TIMESTAMP_H */ ecasound-2.9.1/kvutils/kvu_numtostr.cpp0000644000076400007640000000523010664032032015236 00000000000000// ------------------------------------------------------------------------ // kvu_numtostr.cpp: Routines for converting string objects to numbers. // Copyright (C) 1999,2001 Kai Vehmanen // // 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 #include #include "kvu_numtostr.h" std::string kvu_numtostr (unsigned char c) { return kvu_numtostr((int)c); } std::string kvu_numtostr (signed char c) { return kvu_numtostr((int)c); } std::string kvu_numtostr (bool b) { return kvu_numtostr((int)b); } std::string kvu_numtostr(unsigned short i) { return kvu_numtostr((int)i); } std::string kvu_numtostr (float n, int flo_prec) { return kvu_numtostr(static_cast(n), flo_prec); } std::string kvu_numtostr (int n) { char ctmp[12]; snprintf(ctmp, 12, "%d",n); ctmp[11] = 0; return(std::string(ctmp)); } std::string kvu_numtostr (const void *p) { char ctmp[12]; snprintf(ctmp, 12, "%p",p); ctmp[11] = 0; return(std::string(ctmp)); } std::string kvu_numtostr (unsigned int n) { char ctmp[12]; snprintf(ctmp, 12, "%u",n); ctmp[11] = 0; return(std::string(ctmp)); } std::string kvu_numtostr (long int n) { char ctmp[12]; snprintf(ctmp, 12, "%ld",n); ctmp[11] = 0; return(std::string(ctmp)); } std::string kvu_numtostr (unsigned long int n) { char ctmp[12]; snprintf(ctmp, 12, "%lu",n); ctmp[11] = 0; return(std::string(ctmp)); } #if defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE || defined _LARGEFILE_SOURCE || defined __GNUC__ std::string kvu_numtostr (long long int n) { char ctmp[24]; snprintf(ctmp, 24, "%lli", n); ctmp[23] = 0; return (std::string(ctmp)); } std::string kvu_numtostr (unsigned long long int n) { char ctmp[24]; snprintf(ctmp, 24, "%llu", n); ctmp[23] = 0; return (std::string(ctmp)); } #endif std::string kvu_numtostr (double n, int flo_prec) { char ctmp[32]; snprintf(ctmp, 32, "%.*f",flo_prec, n); ctmp[31] = 0; return(std::string(ctmp)); } ecasound-2.9.1/kvutils/README0000644000076400007640000000136412260766017012651 00000000000000======================================================================= *** kvutils README file *** ======================================================================= Kvutils is a simple utility library. As it is not meant for general use, there is no public documentation available. Using kvutils in other projects is not supported by the author. Kvutils is freely distributable according to the terms of the GNU General Public License (see the file 'COPYING'). For more info about projects in which kvutils library is used, see . Copyright (C) 1997-2002 Kai Vehmanen ======================================================================= ecasound-2.9.1/kvutils/kvu_inttypes.h0000644000076400007640000000350110664032032014666 00000000000000/************************************************************************** * kvu_inttypes.h: Ensure that C99 guaranteed length integer types are * defined in the current environment * Copyright (C) 2003 Kai Vehmanen * * 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 INCLUDED_KVU_INTTYPES_H #define INCLUDED_KVU_INTTYPES_H #ifdef HAVE_CONFIG_H #include #endif /* 1. stdint.h: the C99 standard */ #ifdef HAVE_STDINT_H #include #else /* 2.1 inttypes.h: C99 and Single Unix Specification v2 */ #if HAVE_INTTYPES_H #include /* 2.2 sys/types.h: POSIX */ #elif HAVE_SYS_TYPES_H #include /* Cygwin32 doesn't define all types */ #ifdef __CYGWIN__ typedef u_int8_t uint8_t; typedef u_int16_t uint16_t; typedef u_int32_t uint32_t; #endif /* 2.3 fallback to x86 defaults */ #else typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int int16_t; typedef unsigned short int uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; #endif /* 2.x */ #endif /* 1.x */ #endif /* INCLUDED_KVU_INTTYPES_H */ ecasound-2.9.1/ecatools/0000755000076400007640000000000012261520737012153 500000000000000ecasound-2.9.1/ecatools/Makefile.in0000644000076400007640000007132112261511324014134 00000000000000# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 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@ # ---------------------------------------------------------------------- # File: ecasound/ecatools/Makefile.am # Description: Utility applications built on Ecasound libraries # License: GPL (see ecasound/{AUTHORS,COPYING}) # ---------------------------------------------------------------------- srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ 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@ @ECA_AM_DEBUG_MODE_FALSE@bin_PROGRAMS = ecaconvert$(EXEEXT) \ @ECA_AM_DEBUG_MODE_FALSE@ ecafixdc$(EXEEXT) ecalength$(EXEEXT) \ @ECA_AM_DEBUG_MODE_FALSE@ ecanormalize$(EXEEXT) \ @ECA_AM_DEBUG_MODE_FALSE@ ecaplay$(EXEEXT) \ @ECA_AM_DEBUG_MODE_FALSE@ ecasignalview$(EXEEXT) @ECA_AM_DEBUG_MODE_TRUE@bin_PROGRAMS = ecaconvert_debug$(EXEEXT) \ @ECA_AM_DEBUG_MODE_TRUE@ ecafixdc_debug$(EXEEXT) \ @ECA_AM_DEBUG_MODE_TRUE@ ecalength_debug$(EXEEXT) \ @ECA_AM_DEBUG_MODE_TRUE@ ecanormalize_debug$(EXEEXT) \ @ECA_AM_DEBUG_MODE_TRUE@ ecaplay_debug$(EXEEXT) \ @ECA_AM_DEBUG_MODE_TRUE@ ecasignalview_debug$(EXEEXT) subdir = ecatools DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.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 = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) am_ecaconvert_OBJECTS = ecaconvert.$(OBJEXT) ecicpp_helpers.$(OBJEXT) ecaconvert_OBJECTS = $(am_ecaconvert_OBJECTS) @ECA_AM_DEBUG_MODE_FALSE@am__DEPENDENCIES_1 = $(top_builddir)/libecasoundc/libecasoundc.la @ECA_AM_DEBUG_MODE_TRUE@am__DEPENDENCIES_1 = $(top_builddir)/libecasoundc/libecasoundc_debug.la @ECA_AM_DEBUG_MODE_FALSE@am__DEPENDENCIES_2 = $(top_builddir)/kvutils/libkvutils.la @ECA_AM_DEBUG_MODE_TRUE@am__DEPENDENCIES_2 = $(top_builddir)/kvutils/libkvutils_debug.la ecaconvert_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) am__objects_1 = ecaconvert.$(OBJEXT) ecicpp_helpers.$(OBJEXT) am_ecaconvert_debug_OBJECTS = $(am__objects_1) ecaconvert_debug_OBJECTS = $(am_ecaconvert_debug_OBJECTS) am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) ecaconvert_debug_DEPENDENCIES = $(am__DEPENDENCIES_3) am_ecafixdc_OBJECTS = ecafixdc.$(OBJEXT) ecicpp_helpers.$(OBJEXT) ecafixdc_OBJECTS = $(am_ecafixdc_OBJECTS) ecafixdc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) am__objects_2 = ecafixdc.$(OBJEXT) ecicpp_helpers.$(OBJEXT) am_ecafixdc_debug_OBJECTS = $(am__objects_2) ecafixdc_debug_OBJECTS = $(am_ecafixdc_debug_OBJECTS) ecafixdc_debug_DEPENDENCIES = $(am__DEPENDENCIES_3) am_ecalength_OBJECTS = ecalength.$(OBJEXT) ecalength_OBJECTS = $(am_ecalength_OBJECTS) ecalength_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_3 = ecalength.$(OBJEXT) am_ecalength_debug_OBJECTS = $(am__objects_3) ecalength_debug_OBJECTS = $(am_ecalength_debug_OBJECTS) am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) ecalength_debug_DEPENDENCIES = $(am__DEPENDENCIES_4) am_ecanormalize_OBJECTS = ecanormalize.$(OBJEXT) \ ecicpp_helpers.$(OBJEXT) ecanormalize_OBJECTS = $(am_ecanormalize_OBJECTS) ecanormalize_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) am__objects_4 = ecanormalize.$(OBJEXT) ecicpp_helpers.$(OBJEXT) am_ecanormalize_debug_OBJECTS = $(am__objects_4) ecanormalize_debug_OBJECTS = $(am_ecanormalize_debug_OBJECTS) ecanormalize_debug_DEPENDENCIES = $(am__DEPENDENCIES_3) am_ecaplay_OBJECTS = ecaplay.$(OBJEXT) ecaplay_OBJECTS = $(am_ecaplay_OBJECTS) ecaplay_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_5 = ecaplay.$(OBJEXT) am_ecaplay_debug_OBJECTS = $(am__objects_5) ecaplay_debug_OBJECTS = $(am_ecaplay_debug_OBJECTS) ecaplay_debug_DEPENDENCIES = $(am__DEPENDENCIES_4) am_ecasignalview_OBJECTS = ecasignalview.$(OBJEXT) \ ecicpp_helpers.$(OBJEXT) ecasignalview_OBJECTS = $(am_ecasignalview_OBJECTS) am__DEPENDENCIES_5 = ecasignalview_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_5) am__objects_6 = ecasignalview.$(OBJEXT) ecicpp_helpers.$(OBJEXT) am_ecasignalview_debug_OBJECTS = $(am__objects_6) ecasignalview_debug_OBJECTS = $(am_ecasignalview_debug_OBJECTS) am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_5) ecasignalview_debug_DEPENDENCIES = $(am__DEPENDENCIES_6) binSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(bin_SCRIPTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(ecaconvert_SOURCES) $(ecaconvert_debug_SOURCES) \ $(ecafixdc_SOURCES) $(ecafixdc_debug_SOURCES) \ $(ecalength_SOURCES) $(ecalength_debug_SOURCES) \ $(ecanormalize_SOURCES) $(ecanormalize_debug_SOURCES) \ $(ecaplay_SOURCES) $(ecaplay_debug_SOURCES) \ $(ecasignalview_SOURCES) $(ecasignalview_debug_SOURCES) DIST_SOURCES = $(ecaconvert_SOURCES) $(ecaconvert_debug_SOURCES) \ $(ecafixdc_SOURCES) $(ecafixdc_debug_SOURCES) \ $(ecalength_SOURCES) $(ecalength_debug_SOURCES) \ $(ecanormalize_SOURCES) $(ecanormalize_debug_SOURCES) \ $(ecaplay_SOURCES) $(ecaplay_debug_SOURCES) \ $(ecasignalview_SOURCES) $(ecasignalview_debug_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ ARTSC_CONFIG = @ARTSC_CONFIG@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECA_AM_ALL_STATIC_FALSE = @ECA_AM_ALL_STATIC_FALSE@ ECA_AM_ALL_STATIC_TRUE = @ECA_AM_ALL_STATIC_TRUE@ ECA_AM_COMPILE_ALSA_FALSE = @ECA_AM_COMPILE_ALSA_FALSE@ ECA_AM_COMPILE_ALSA_TRUE = @ECA_AM_COMPILE_ALSA_TRUE@ ECA_AM_COMPILE_ARTS_FALSE = @ECA_AM_COMPILE_ARTS_FALSE@ ECA_AM_COMPILE_ARTS_TRUE = @ECA_AM_COMPILE_ARTS_TRUE@ ECA_AM_COMPILE_AUDIOFILE_FALSE = @ECA_AM_COMPILE_AUDIOFILE_FALSE@ ECA_AM_COMPILE_AUDIOFILE_TRUE = @ECA_AM_COMPILE_AUDIOFILE_TRUE@ ECA_AM_COMPILE_JACK_FALSE = @ECA_AM_COMPILE_JACK_FALSE@ ECA_AM_COMPILE_JACK_TRUE = @ECA_AM_COMPILE_JACK_TRUE@ ECA_AM_COMPILE_OSS_FALSE = @ECA_AM_COMPILE_OSS_FALSE@ ECA_AM_COMPILE_OSS_TRUE = @ECA_AM_COMPILE_OSS_TRUE@ ECA_AM_COMPILE_SAMPLERATE_FALSE = @ECA_AM_COMPILE_SAMPLERATE_FALSE@ ECA_AM_COMPILE_SAMPLERATE_TRUE = @ECA_AM_COMPILE_SAMPLERATE_TRUE@ ECA_AM_COMPILE_SNDFILE_FALSE = @ECA_AM_COMPILE_SNDFILE_FALSE@ ECA_AM_COMPILE_SNDFILE_TRUE = @ECA_AM_COMPILE_SNDFILE_TRUE@ ECA_AM_DEBUG_MODE_FALSE = @ECA_AM_DEBUG_MODE_FALSE@ ECA_AM_DEBUG_MODE_TRUE = @ECA_AM_DEBUG_MODE_TRUE@ ECA_AM_DISABLE_EFFECTS_FALSE = @ECA_AM_DISABLE_EFFECTS_FALSE@ ECA_AM_DISABLE_EFFECTS_TRUE = @ECA_AM_DISABLE_EFFECTS_TRUE@ ECA_AM_FEELING_EXPERIMENTAL_FALSE = @ECA_AM_FEELING_EXPERIMENTAL_FALSE@ ECA_AM_FEELING_EXPERIMENTAL_TRUE = @ECA_AM_FEELING_EXPERIMENTAL_TRUE@ ECA_AM_KVUTILS_INSTALLED_FALSE = @ECA_AM_KVUTILS_INSTALLED_FALSE@ ECA_AM_KVUTILS_INSTALLED_TRUE = @ECA_AM_KVUTILS_INSTALLED_TRUE@ ECA_AM_PYECASOUND_CEXT_FALSE = @ECA_AM_PYECASOUND_CEXT_FALSE@ ECA_AM_PYECASOUND_CEXT_TRUE = @ECA_AM_PYECASOUND_CEXT_TRUE@ ECA_AM_PYECASOUND_INSTALL_FALSE = @ECA_AM_PYECASOUND_INSTALL_FALSE@ ECA_AM_PYECASOUND_INSTALL_TRUE = @ECA_AM_PYECASOUND_INSTALL_TRUE@ ECA_AM_RUBYECASOUND_INSTALL_FALSE = @ECA_AM_RUBYECASOUND_INSTALL_FALSE@ ECA_AM_RUBYECASOUND_INSTALL_TRUE = @ECA_AM_RUBYECASOUND_INSTALL_TRUE@ ECA_AM_SYSTEM_READLINE_FALSE = @ECA_AM_SYSTEM_READLINE_FALSE@ ECA_AM_SYSTEM_READLINE_TRUE = @ECA_AM_SYSTEM_READLINE_TRUE@ ECA_AM_USE_NCURSES_FALSE = @ECA_AM_USE_NCURSES_FALSE@ ECA_AM_USE_NCURSES_TRUE = @ECA_AM_USE_NCURSES_TRUE@ ECA_AM_USE_TERMCAP_FALSE = @ECA_AM_USE_TERMCAP_FALSE@ ECA_AM_USE_TERMCAP_TRUE = @ECA_AM_USE_TERMCAP_TRUE@ ECA_S_EXTRA_CPPFLAGS = @ECA_S_EXTRA_CPPFLAGS@ ECA_S_EXTRA_LIBS = @ECA_S_EXTRA_LIBS@ ECA_S_JACK_INCLUDES = @ECA_S_JACK_INCLUDES@ ECA_S_JACK_LIBS = @ECA_S_JACK_LIBS@ ECA_S_PREFIX = @ECA_S_PREFIX@ ECA_S_PYTHON_DLMODULES = @ECA_S_PYTHON_DLMODULES@ ECA_S_PYTHON_INCLUDES = @ECA_S_PYTHON_INCLUDES@ ECA_S_PYTHON_MODULES = @ECA_S_PYTHON_MODULES@ ECA_S_READLINE_INCLUDES = @ECA_S_READLINE_INCLUDES@ ECA_S_READLINE_LIBS = @ECA_S_READLINE_LIBS@ ECA_S_RUBY_SITEDIR = @ECA_S_RUBY_SITEDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBECASOUNDC_VERSION = @LIBECASOUNDC_VERSION@ LIBECASOUNDC_VERSION_AGE = @LIBECASOUNDC_VERSION_AGE@ LIBECASOUND_VERSION = @LIBECASOUND_VERSION@ LIBECASOUND_VERSION_AGE = @LIBECASOUND_VERSION_AGE@ LIBKVUTILS_VERSION = @LIBKVUTILS_VERSION@ LIBKVUTILS_VERSION_AGE = @LIBKVUTILS_VERSION_AGE@ LIBLILV_CFLAGS = @LIBLILV_CFLAGS@ LIBLILV_LIBS = @LIBLILV_LIBS@ LIBLO_CFLAGS = @LIBLO_CFLAGS@ LIBLO_LIBS = @LIBLO_LIBS@ LIBOBJS = @LIBOBJS@ LIBOIL_CFLAGS = @LIBOIL_CFLAGS@ LIBOIL_LIBS = @LIBOIL_LIBS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ 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@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHONPATH = @PYTHONPATH@ RANLIB = @RANLIB@ RUBYPATH = @RUBYPATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ 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@ 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@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ EXTRA_DIST = ecasound.el ecamonitor @ECA_AM_DEBUG_MODE_FALSE@libkvutils_path = $(top_builddir)/kvutils/libkvutils.la @ECA_AM_DEBUG_MODE_TRUE@libkvutils_path = $(top_builddir)/kvutils/libkvutils_debug.la @ECA_AM_DEBUG_MODE_FALSE@libecasoundc_path = $(top_builddir)/libecasoundc/libecasoundc.la @ECA_AM_DEBUG_MODE_TRUE@libecasoundc_path = $(top_builddir)/libecasoundc/libecasoundc_debug.la @ECA_AM_USE_NCURSES_TRUE@ncurses_library = -lncurses @ECA_AM_USE_TERMCAP_TRUE@termcap_library = -ltermcap INCLUDES = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/kvutils -I$(top_srcdir)/libecasound -I$(top_srcdir)/libecasoundc bin_SCRIPTS = ecamonitor # -- noinst_HEADERS = ecicpp_helpers.h ecaconvert_SOURCES = ecaconvert.cpp ecicpp_helpers.cpp ecaconvert_LDADD = $(libecasoundc_path) $(libkvutils_path) ecafixdc_SOURCES = ecafixdc.cpp ecicpp_helpers.cpp ecafixdc_LDADD = $(libecasoundc_path) $(libkvutils_path) ecalength_SOURCES = ecalength.c ecalength_LDADD = $(libecasoundc_path) ecanormalize_SOURCES = ecanormalize.cpp ecicpp_helpers.cpp ecanormalize_LDADD = $(libecasoundc_path) $(libkvutils_path) ecaplay_SOURCES = ecaplay.c ecaplay_LDADD = $(libecasoundc_path) ecasignalview_SOURCES = ecasignalview.cpp ecicpp_helpers.cpp ecasignalview_LDADD = $(libecasoundc_path) $(libkvutils_path) $(termcap_library) $(ncurses_library) # -- ecaconvert_debug_SOURCES = $(ecaconvert_SOURCES) ecaconvert_debug_LDADD = $(ecaconvert_LDADD) ecafixdc_debug_SOURCES = $(ecafixdc_SOURCES) ecafixdc_debug_LDADD = $(ecafixdc_LDADD) ecalength_debug_SOURCES = $(ecalength_SOURCES) ecalength_debug_LDADD = $(ecalength_LDADD) ecanormalize_debug_SOURCES = $(ecanormalize_SOURCES) ecanormalize_debug_LDADD = $(ecanormalize_LDADD) ecanormalize_debug_LDFLAGS = $(ecanormalize_LDFLAGS) ecaplay_debug_SOURCES = $(ecaplay_SOURCES) ecaplay_debug_LDADD = $(ecaplay_LDADD) ecasignalview_debug_SOURCES = $(ecasignalview_SOURCES) ecasignalview_debug_LDADD = $(ecasignalview_LDADD) all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ecatools/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign ecatools/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done ecaconvert$(EXEEXT): $(ecaconvert_OBJECTS) $(ecaconvert_DEPENDENCIES) @rm -f ecaconvert$(EXEEXT) $(CXXLINK) $(ecaconvert_LDFLAGS) $(ecaconvert_OBJECTS) $(ecaconvert_LDADD) $(LIBS) ecaconvert_debug$(EXEEXT): $(ecaconvert_debug_OBJECTS) $(ecaconvert_debug_DEPENDENCIES) @rm -f ecaconvert_debug$(EXEEXT) $(CXXLINK) $(ecaconvert_debug_LDFLAGS) $(ecaconvert_debug_OBJECTS) $(ecaconvert_debug_LDADD) $(LIBS) ecafixdc$(EXEEXT): $(ecafixdc_OBJECTS) $(ecafixdc_DEPENDENCIES) @rm -f ecafixdc$(EXEEXT) $(CXXLINK) $(ecafixdc_LDFLAGS) $(ecafixdc_OBJECTS) $(ecafixdc_LDADD) $(LIBS) ecafixdc_debug$(EXEEXT): $(ecafixdc_debug_OBJECTS) $(ecafixdc_debug_DEPENDENCIES) @rm -f ecafixdc_debug$(EXEEXT) $(CXXLINK) $(ecafixdc_debug_LDFLAGS) $(ecafixdc_debug_OBJECTS) $(ecafixdc_debug_LDADD) $(LIBS) ecalength$(EXEEXT): $(ecalength_OBJECTS) $(ecalength_DEPENDENCIES) @rm -f ecalength$(EXEEXT) $(LINK) $(ecalength_LDFLAGS) $(ecalength_OBJECTS) $(ecalength_LDADD) $(LIBS) ecalength_debug$(EXEEXT): $(ecalength_debug_OBJECTS) $(ecalength_debug_DEPENDENCIES) @rm -f ecalength_debug$(EXEEXT) $(LINK) $(ecalength_debug_LDFLAGS) $(ecalength_debug_OBJECTS) $(ecalength_debug_LDADD) $(LIBS) ecanormalize$(EXEEXT): $(ecanormalize_OBJECTS) $(ecanormalize_DEPENDENCIES) @rm -f ecanormalize$(EXEEXT) $(CXXLINK) $(ecanormalize_LDFLAGS) $(ecanormalize_OBJECTS) $(ecanormalize_LDADD) $(LIBS) ecanormalize_debug$(EXEEXT): $(ecanormalize_debug_OBJECTS) $(ecanormalize_debug_DEPENDENCIES) @rm -f ecanormalize_debug$(EXEEXT) $(CXXLINK) $(ecanormalize_debug_LDFLAGS) $(ecanormalize_debug_OBJECTS) $(ecanormalize_debug_LDADD) $(LIBS) ecaplay$(EXEEXT): $(ecaplay_OBJECTS) $(ecaplay_DEPENDENCIES) @rm -f ecaplay$(EXEEXT) $(LINK) $(ecaplay_LDFLAGS) $(ecaplay_OBJECTS) $(ecaplay_LDADD) $(LIBS) ecaplay_debug$(EXEEXT): $(ecaplay_debug_OBJECTS) $(ecaplay_debug_DEPENDENCIES) @rm -f ecaplay_debug$(EXEEXT) $(LINK) $(ecaplay_debug_LDFLAGS) $(ecaplay_debug_OBJECTS) $(ecaplay_debug_LDADD) $(LIBS) ecasignalview$(EXEEXT): $(ecasignalview_OBJECTS) $(ecasignalview_DEPENDENCIES) @rm -f ecasignalview$(EXEEXT) $(CXXLINK) $(ecasignalview_LDFLAGS) $(ecasignalview_OBJECTS) $(ecasignalview_LDADD) $(LIBS) ecasignalview_debug$(EXEEXT): $(ecasignalview_debug_OBJECTS) $(ecasignalview_debug_DEPENDENCIES) @rm -f ecasignalview_debug$(EXEEXT) $(CXXLINK) $(ecasignalview_debug_LDFLAGS) $(ecasignalview_debug_OBJECTS) $(ecasignalview_debug_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" @list='$(bin_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ else :; fi; \ done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecaconvert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecafixdc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecalength.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecanormalize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecaplay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecasignalview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecicpp_helpers.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @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@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @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@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @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 $@ $< .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: 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; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && 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)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 $(PROGRAMS) $(SCRIPTS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; 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) 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-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS install-info: install-info-am install-man: 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-binPROGRAMS uninstall-binSCRIPTS \ uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-binSCRIPTS install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man 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-binPROGRAMS \ uninstall-binSCRIPTS uninstall-info-am # -- # special targets with dependency tracking ecainstall: $(MAKE) -C $(srcdir)/../libecasound -q 2>/dev/null || make -C $(srcdir)/../libecasound $(MAKE) -C $(srcdir)/../kvutils -q 2>/dev/null || make -C $(srcdir)/../kvutils $(MAKE) install # 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: ecasound-2.9.1/ecatools/ecasignalview.cpp0000644000076400007640000004117411143666651015433 00000000000000// ------------------------------------------------------------------------ // ecasignalview.cpp: A simple command-line tools for monitoring // signal amplitude. // Copyright (C) 1999-2005,2007,2008 Kai Vehmanen // Copyright (C) 2005 Jeffrey Cunningham // // 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 // ------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include /* POSIX: select() */ #include /* POSIX: timeval struct */ #include #include #include #include #include "ecicpp_helpers.h" #ifdef HAVE_TERMIOS_H /* see: http://www.opengroup.org/onlinepubs/007908799/xsh/termios.h.html */ #include #endif #if defined(ECA_USE_NCURSES_H) || defined(ECA_USE_NCURSES_NCURSES_H) || defined(ECA_USE_CURSES_H) #define ECASV_USE_CURSES 1 #ifdef ECA_USE_NCURSES_H #include #include /* for setupterm() */ #elif ECA_USE_NCURSES_NCURSES_H #include #include /* for setupterm() */ #else #include #include /* for setupterm() */ #endif #endif /* ECA_*CURSES_H */ #include /** * Import namespaces */ using namespace std; /** * Type definitions */ struct ecasv_channel_stats { double last_peak; double drawn_peak; double max_peak; long int clipped_samples; vector avg_peak; // jkc: addition int avg_peak_ptr; // jkc: addition double avg_peak_val; // jkc: addition }; /** * Function declarations */ int main(int argc, char *argv[]); void ecasv_parse_command_line(ECA_CONTROL_INTERFACE* cop, int argc, char *argv[]); void ecasv_fill_defaults(void); std::string ecasv_cop_to_string(ECA_CONTROL_INTERFACE* cop); void ecasv_output_init(void); void ecasv_output_cleanup(void); int ecasv_print_vu_meters(ECA_CONTROL_INTERFACE* eci, std::vector* chstats); void ecasv_update_chstats(std::vector* chstats, int ch, double value); void ecasv_create_bar(double value, int barlen, unsigned char* barbuf); void ecasv_print_usage(void); void ecasv_signal_handler(int signum); void reset_stats_fcn(vector* chstats); // jkc: addition float dB(float v) { return 10.0*log10(v*v); } // jkc: addition void ecasv_set_buffered(void); void ecasv_set_unbuffered(void); int ecasv_kbhit(); /** * Static global variables */ static const string ecatools_signalview_version = "20051112-10"; static bool ecasv_log_display_mode = false; // jkc: addition static const double ecasv_clipped_threshold_const = 1.0f - 1.0f / 16384.0f; static const int ecasv_bar_length_const = 32; static const int ecasv_header_height_const = 9; static const long int ecasv_rate_default_const = 50; static const long int ecasv_buffersize_default_const = 128; static unsigned char ecasv_bar_buffer[ecasv_bar_length_const + 1] = { 0 }; static bool ecasv_enable_debug, ecasv_enable_cumulative_mode; static long int ecasv_buffersize, ecasv_rate_msec; static string ecasv_input, ecasv_output, ecasv_format_string; static int ecasv_chcount = 0; static ECA_CONTROL_INTERFACE* ecasv_eci_repp = 0; static sig_atomic_t done = 0; static sig_atomic_t reset_stats = 0; static int avg_peak_buffer_sz=100; // jkc: addition #ifdef HAVE_TERMIOS_H struct termios old_term, new_term; #endif /** * Function definitions */ int main(int argc, char *argv[]) { int res; struct sigaction es_handler; es_handler.sa_handler = ecasv_signal_handler; sigemptyset(&es_handler.sa_mask); es_handler.sa_flags = 0; sigaction(SIGTERM, &es_handler, 0); sigaction(SIGINT, &es_handler, 0); sigaction(SIGQUIT, &es_handler, 0); sigaction(SIGABRT, &es_handler, 0); sigaction(SIGHUP, &es_handler, 0); struct sigaction ign_handler; ign_handler.sa_handler = SIG_IGN; sigemptyset(&ign_handler.sa_mask); ign_handler.sa_flags = 0; /* ignore the following signals */ sigaction(SIGPIPE, &ign_handler, 0); sigaction(SIGFPE, &ign_handler, 0); ECA_CONTROL_INTERFACE eci; eci.command("cs-add default"); eci.command("c-add default"); /* set engine buffersize */ eci.command("cs-set-param -b:" + kvu_numtostr(ecasv_buffersize)); /* in case JACK is used, do not send nor receive transport events */ eci.command("cs-set-param -G:jack,ecasignalview,notransport"); /* note: might change the cs options (-G, -z, etc) */ ecasv_parse_command_line(&eci,argc,argv); if (ecasv_format_string.size() > 0) { eci.command("cs-set-audio-format " + ecasv_format_string); } string format; if (ecicpp_add_input(&eci, ecasv_input, &format) < 0) return -1; cout << "Using audio format -f:" << format << "\n"; ecasv_chcount = ecicpp_format_channels(format); cout << "Setting up " << ecasv_chcount << " separate channels for analysis." << endl; if (ecicpp_add_output(&eci, ecasv_output, format) < 0) return -1; ecasv_eci_repp = &eci; vector chstats; eci.command("cop-add -evp"); eci.command("cop-add -ev"); if (ecasv_enable_cumulative_mode == true) { eci.command("cop-set 2,1,1"); } eci.command("cop-select 1"); if (ecicpp_connect_chainsetup(&eci, "default") < 0) { return -1; } int secs = 0, msecs = ecasv_rate_msec; while(msecs > 999) { ++secs; msecs -= 1000; } ecasv_output_init(); eci.command("start"); int chr=0; // jkc: addition int rv=0; // jkc: addition while(! done ) { kvu_sleep(secs, msecs * 1000000); res = ecasv_print_vu_meters(&eci, &chstats); if (res < 0) break; #if defined(ECASV_USE_CURSES) // jkc: addition until noted if (ecasv_kbhit()) { /* note: getch() is a curses.h function */ switch (chr=getch()) { case 'q': case 27: /* Esc */ case 'Q': done=true; break; case ' ': reset_stats_fcn(&chstats); break; } } // jkc: end of addition #endif } ecasv_output_cleanup(); #ifdef ECASV_USE_CURSES endwin(); #endif return rv; } void ecasv_parse_command_line(ECA_CONTROL_INTERFACE *eci, int argc, char *argv[]) { COMMAND_LINE cline = COMMAND_LINE (argc, argv); if (cline.size() == 0 || cline.has("--version") || cline.has("--help") || cline.has("-h")) { ecasv_print_usage(); exit(1); } ecasv_enable_debug = false; ecasv_enable_cumulative_mode = false; ecasv_rate_msec = 0; ecasv_buffersize = 0; cline.begin(); cline.next(); // 1st argument while (cline.end() != true) { string arg = cline.current(); if (arg.size() > 0) { if (arg[0] != '-') { if (ecasv_input == "") ecasv_input = arg; else if (ecasv_output == "") ecasv_output = arg; } else { string prefix = kvu_get_argument_prefix(arg); if (prefix == "b") ecasv_buffersize = atol(kvu_get_argument_number(1, arg).c_str()); if (prefix == "c") ecasv_enable_cumulative_mode = true; if (prefix == "d") ecasv_enable_debug = true; if (prefix == "f") ecasv_format_string = string(arg.begin() + 3, arg.end()); if (prefix == "I") ecasv_log_display_mode = false; // jkc: addition if (prefix == "L") ecasv_log_display_mode = true; // jkc: addition if (prefix == "r") ecasv_rate_msec = atol(kvu_get_argument_number(1, arg).c_str()); if (prefix == "G" || prefix == "B" || (prefix.size() > 0 && prefix[0] == 'M') || prefix == "r" || prefix == "z") { eci->command("cs-option " + arg); } } } cline.next(); } ecasv_fill_defaults(); } void ecasv_fill_defaults(void) { // ECA_RESOURCES ecarc; if (ecasv_input.size() == 0) ecasv_input = "/dev/dsp"; if (ecasv_output.size() == 0) ecasv_output = "null"; if (ecasv_buffersize == 0) ecasv_buffersize = ecasv_buffersize_default_const; if (ecasv_rate_msec == 0) ecasv_rate_msec = ecasv_rate_default_const; if (ecasv_format_string.size() == 0) ecasv_format_string = "s16_le,2,44100,i"; // ecarc.resource("default-audio-format"); } string ecasv_cop_to_string(ECA_CONTROL_INTERFACE* eci) { eci->command("cop-status"); return(eci->last_string()); } void ecasv_output_init(void) { #ifdef ECASV_USE_CURSES initscr(); erase(); int r=0; // jkc: added r for row indexing here and below mvprintw(r++, 0, "ecasignalview v%s (%s) -- (C) K.Vehmanen, J.Cunningham", ecatools_signalview_version.c_str(), VERSION); //mvprintw(r++, 0, "* (C) 1999-2005 Kai Vehmanen, Jeff Cunningham *\n"); //mvprintw(r++, 0, "******************************************************\n\n"); ++r; mvprintw(r++, 2, "Input/output: \"%s\" => \"%s\"", ecasv_input.c_str(),ecasv_output.c_str()); double avg_length = (double)ecasv_rate_msec * avg_peak_buffer_sz; mvprintw(r++, 2, "Settings: %s refresh=%ldms bsize=%ld avg-length=%.0fms", ecasv_format_string.c_str(), ecasv_rate_msec, ecasv_buffersize, avg_length); /* mvprintw(r++, 0, "refresh rate = %ld (msec), buffer size = %ld, " "avg-length = %.0f (msec)", ecasv_rate_msec, ecasv_buffersize, avg_length); */ ++r; const char* bar="------------------------------------------------------------------------------\n"; mvprintw(r++, 0, bar); mvprintw(r, 0, "channel"); if (ecasv_log_display_mode) mvprintw(r++,38, "%s avg-peak dB max-peak dB clipped\n", ecasv_bar_buffer); else mvprintw(r++,38, "%s avg-peak max-peak clipped\n", ecasv_bar_buffer); mvprintw(r++, 0, bar); memset(ecasv_bar_buffer, ' ', ecasv_bar_length_const - 4); ecasv_bar_buffer[ecasv_bar_length_const - 4] = 0; mvprintw(r + ecasv_chcount + 3, 0, "Press spacebar to reset stats"); // jkc: addition move(r + ecasv_chcount - 2, 0); // 13 + 12 refresh(); #endif } void ecasv_output_cleanup(void) { #ifdef ECASV_USE_CURSES endwin(); #endif // FIXME: should be enabled #if 0 if (ecasv_eci_repp != 0) { cout << endl << endl << endl; ecasv_eci_repp->command("cop-status"); } #endif } // jkc: addition of reset_stats function void reset_stats_fcn(vector* chstats) { #ifdef ECASV_USE_CURSES vector::iterator s=chstats->begin(); while (s!=chstats->end()) { s->last_peak=0; s->max_peak=0; s->drawn_peak=0; s->clipped_samples=0; s++; } #endif } // jkc: end of addition int ecasv_print_vu_meters(ECA_CONTROL_INTERFACE* eci, vector* chstats) { int result = 0; /* check wheter to reset peaks */ if (reset_stats) { reset_stats = 0; for(int n = 0; n < ecasv_chcount; n++) { (*chstats)[n].max_peak = 0; (*chstats)[n].clipped_samples = 0; } } #ifdef ECASV_USE_CURSES for(int n = 0; n < ecasv_chcount; n++) { eci->command("copp-select " + kvu_numtostr(n + 1)); eci->command("copp-get"); if (eci->error()) { result = -1; break; } double value = eci->last_float(); ecasv_update_chstats(chstats, n, value); ecasv_create_bar((*chstats)[n].drawn_peak, ecasv_bar_length_const, ecasv_bar_buffer); // jkc: commented out following two lines and substituted what follows until noted // mvprintw(ecasv_header_height_const+n, 0, "Ch-%02d: %s| %.5f %ld\n", // n + 1, ecasv_bar_buffer, (*chstats)[n].max_peak, (*chstats)[n].clipped_samples); // Calculate average peak value if (ecasv_log_display_mode) mvprintw(ecasv_header_height_const+n, 0, "Ch-%02d: %s %.2f %.2f %ld\n", n+1, ecasv_bar_buffer, dB((*chstats)[n].avg_peak_val), dB((*chstats)[n].max_peak), (*chstats)[n].clipped_samples); else mvprintw(ecasv_header_height_const+n, 0, "Ch-%02d: %s %.5f %.5f %ld\n", n+1, ecasv_bar_buffer, (*chstats)[n].avg_peak_val, (*chstats)[n].max_peak, (*chstats)[n].clipped_samples); // jkc: end of substitution } move(ecasv_header_height_const + 2 + ecasv_chcount, 0); refresh(); #else cout << ecasv_cop_to_string(eci) << endl; #endif return result; } void ecasv_update_chstats(vector* chstats, int ch, double value) { /* 1. in case a new channel is encoutered */ if (static_cast(chstats->size()) <= ch) { chstats->resize(ch + 1); // jkc: added until noted (*chstats)[ch].last_peak=0; (*chstats)[ch].drawn_peak=0; (*chstats)[ch].max_peak=0; (*chstats)[ch].clipped_samples=0; (*chstats)[ch].avg_peak.resize(avg_peak_buffer_sz,0); (*chstats)[ch].avg_peak_ptr=0; // jkc: end of additions } /* 2. update last_peak and drawn_peak */ (*chstats)[ch].last_peak = value; if ((*chstats)[ch].last_peak < (*chstats)[ch].drawn_peak) { (*chstats)[ch].drawn_peak *= ((*chstats)[ch].last_peak / (*chstats)[ch].drawn_peak); } else { (*chstats)[ch].drawn_peak = (*chstats)[ch].last_peak; } /* 3. update max_peak */ if (value > (*chstats)[ch].max_peak) { (*chstats)[ch].max_peak = value; } /* 4. update clipped_samples counter */ if (value > ecasv_clipped_threshold_const) { (*chstats)[ch].clipped_samples++; } // jkc: added until noted /* 5. update running average vector */ (*chstats)[ch].avg_peak[(*chstats)[ch].avg_peak_ptr] = value; (*chstats)[ch].avg_peak_ptr = ((*chstats)[ch].avg_peak_ptr == avg_peak_buffer_sz-1)? 0 : (*chstats)[ch].avg_peak_ptr+1; vector::iterator p=(*chstats)[ch].avg_peak.begin(); (*chstats)[ch].avg_peak_val=0; while (p!=(*chstats)[ch].avg_peak.end()) { (*chstats)[ch].avg_peak_val+=*p++; } (*chstats)[ch].avg_peak_val/=avg_peak_buffer_sz; // jkc; end of addition } void ecasv_create_bar(double value, int barlen, unsigned char* barbuf) { int curlen = static_cast(rint(((value / 1.0f) * barlen))); for(int n = 0; n < barlen; n++) { if (n <= curlen) barbuf[n] = '*'; else barbuf[n] = ' '; } } /** * Sets terminal to unbuffered mode (no echo, * non-canonical input). -jkc */ void ecasv_set_unbuffered(void) { #ifdef HAVE_TERMIOS_H tcgetattr( STDIN_FILENO, &old_term ); new_term = old_term; new_term.c_lflag &= ~( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSANOW, &new_term ); #endif } /** * Sets terminal to buffered mode -jkc */ void ecasv_set_buffered(void) { #ifdef HAVE_TERMIOS_H tcsetattr( STDIN_FILENO, TCSANOW, &old_term ); #endif } /** * Reads a character from the terminal console. -jkc */ int ecasv_kbhit(void) { int result; fd_set set; struct timeval tv; FD_ZERO(&set); FD_SET(STDIN_FILENO,&set); /* watch stdin */ tv.tv_sec = 0; tv.tv_usec = 0; /* don't wait */ /* quick peek at the input, to see if anything is there */ ecasv_set_unbuffered(); result = select( STDIN_FILENO+1,&set,NULL,NULL,&tv); ecasv_set_buffered(); return result == 1; } void ecasv_print_usage(void) { cerr << "****************************************************************************\n"; cerr << "* ecasignalview, v" << ecatools_signalview_version << " (" << VERSION << ")\n"; cerr << "* Copyright 1999-2005 Kai Vehmanen, Jeffrey Cunningham\n"; cerr << "* Licensed under the terms of the GNU General Public License\n"; cerr << "****************************************************************************\n"; cerr << "\nUSAGE: ecasignalview [options] [input] [output] \n"; cerr << "\nOptions:\n"; cerr << "\t-b:buffersize\n"; // cerr << "\t\t-c (cumulative mode)\n"; cerr << "\t-d (debug mode)\n"; cerr << "\t-f:bits,channels,samplerate\n"; cerr << "\t-r:refresh_msec\n\n"; cerr << "\t-I (linear-scale)\n"; cerr << "\t-L (logarithmic-scale)\n"; } void ecasv_signal_handler(int signum) { if (signum == SIGHUP) { reset_stats = 1; } else { cerr << "Interrupted... cleaning up.\n"; done=1; } } ecasound-2.9.1/ecatools/ecasound.el0000644000076400007640000024303011753025057014220 00000000000000;;; ecasound.el --- Interactive and programmatic interface to Ecasound ;; Copyright (C) 2001, 2002, 2003 Mario Lang ;; Author: Mario Lang ;; Keywords: audio, ecasound, eci, comint, process, pcomplete ;; Version: 0.8.3 ;; This file 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, or (at your option) ;; any later version. ;; This file 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 GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; This file implements several aspects of ecasound use: ;; ;; * A derived-major-mode, from comint mode for an inferior ecasound ;; process (ecasound-aim-mode). Complete with context sensitive ;; completion and interactive features to control the current process ;; using ECI. ;; ;; * Ecasound Control Interface (ECI) library for programmatic control ;; of a Ecasound process. This allows you to write Ecasound batch ;; jobs in Emacs-Lisp with Lisp functions and return values. Have a ;; look at eci-example and ecasound-normalize. ;; ;; * ecasound-ewf-mode, a mode for editing .ewf files. ;; ;; ;; Usage: ;; ;; You need at least ecasound 2.2.0 for this file to work properly. ;; ;; Put ecasound.el in your load-path and require it in your .emacs. ;; Set `ecasound-program' to the path to your ecasound executable. ;; ;; (setq load-path (cons "/home/user/elisp") ;; (require 'ecasound) ;; (setq ecasound-program "/home/user/bin/ecasound" ;; eci-program "/home/user/bin/ecasound") ;; ;; To set ecasound startup options use ;; ;; M-x ecasound-customize-startup RET ;; ;; Then use M-x ecasound RET to invoke an inferior ecasound process. ;; ;; For programmatic use of the ECI API, have a look at `eci-init', ;; `eci-command' and in general the eci-* namespace. ;; ;; Compatibility: ;; ;; This file is only tested with GNU Emacs 21. I've invested some minimal ;; efforts to get it working with XEmacs. However, XEmacs support ;; might be broken in some areas. Since I personally very seldomly ;; use XEmacs, I am happy about suggestions and patches. ;; ;; Todo: ;; ;; * Find a better way to do status info fetching... ;; * Add more conditions to the menu. ;; * Use map-xxx-list data in the ecasound-copp widget. This means we ;; need to merge cop-status and map-cop-list data somehow or have ;; the cop-editor fetch hints from map-cop/ladpsa/preset-list. ;; * Make `ecasound-signalview' faster, and allow to invoke it on already ;; opened sessions. ;; * Fix the case where ecasound sends output *after* the prompt. ;; This is tricky! Fixed for internal parsing, probably will leave ;; like that for interactive use, not worth the trouble... ;; * Copy documentation for ECI commands into eci-* docstrings and menu ;; :help keywords. ;; * Expand the menu. ;;; History: ;; ;; Version: 0.8.3 ;; ;; * ecasound-cli-arg:value-to-internal: Use `widget-get' instead of ;; (car (last elt)) to extract :value from :args which makes code compatible ;; to XEmacs. ;; * ecasound-cli-arg:value-to-external: Use `widget-get' instead of ;; `widget-apply' to fetch :arg-format. Makes XEmacs happy. ;; * Add "-D" to the default `ecasound-arguments'. This fixes a problem ;; with the TERM variable which only appeared in XEmacs and is a reasonable ;; default anyway. ;; * Fix `ecasound-output-filter' when "-D" is used as argument on startup. ;; * Add `comint-strip-ctrl-m' to `comint-output-filter-functions' when ;; we are running XEmacs. ;; * `defeci' cs-set-position. Bound to "M-c M-s s" and in ;; `ecasound-iam-cs-menu'. ;; * Add some more docstrings. ;; * New interactive functions `ecasound-set-mark' and `ecasound-goto-mark' ;; which implement the position marker system discussed on ecasound-list. ;; Bound to C-c C-SPC and C-c C-j respectively. ;; * New user variable `ecasound-daemon-host' which defaults to "localhost". ;; * Record the daemon port in a buffer local variable `ecasound-daemon-port' ;; and therefore allow temporarily binding `ecasound-arguments' to something ;; different via e.g. `let' before invoking `ecasound'. ;; * Fix regexp in `eci-input-filter' to be XEmacs compatible. ;; ;; Version: 0.8.2 ;; ;; * Added quite some missing docstrings. ;; * New variable `ecasound-last-command-alist'. Use that to do fancy stuff ;; to certain commands return values. ;; * New variable `ecasound-type-alist'. Normally you should not need to ;; change this, but it's nice to have it configurable. ;; * New function `eci-is-valid-p'. Rationale is that nil as return ;; value of a ECI command should indicate an error. So this function ;; with a -p suffix to use as a predicate. ;; * New variable `ecasound-parent' holds the parent buffer in a daemon buffer. ;; * New variables ecasound-timer-flag&interval. ;; * Renamed `eci-output-filter' to `ecasound-output-filter'. ;; * New variable ecasound-mode|header-line-format. ;; * `ecasound-cop-edit' now uses cop-set instead of ;; cop-select+copp-select+copp-set to update values. ;; * Fixed multiple-argument handling. They are separated with ',', not ;; with a space. ;; * New variable ecasound-sending-command, used to prevent the background ;; timer from coliding with other ECI requests. ;; ;; Version: 0.8.1 ;; ;; * Make ai|ao|cs-forward|rewind use ai|ao|cs-selected in the prompt ;; string of the interactive spec. ;; * New keymaps ecasound-audioin|audioout-map. ;; Now you can be very quick: ;; M-x ecasound RET M-i a