Mercurial > hg > sonic-annotator
changeset 248:c8e5fcddf8be
Merge
author | Chris Cannam |
---|---|
date | Fri, 18 Mar 2016 15:15:55 +0000 |
parents | 5eadb3b687bb (current diff) 4307b34f86c0 (diff) |
children | 85ab36c3b7d8 |
files | runner.pro |
diffstat | 45 files changed, 981 insertions(+), 259 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgsubstate Fri Mar 18 15:15:37 2016 +0000 +++ b/.hgsubstate Fri Mar 18 15:15:55 2016 +0000 @@ -1,4 +1,4 @@ d16f0fd6db6104d87882bc43788a3bb1b0f8c528 dataquay -55ece8862b6d3a54aad271a53f9c1615e5d3bcf8 sv-dependency-builds -c8e291700c0eaa10c064dbf732ba0e72efa1f8a7 svcore -632d90c185ecc8655f7a85ba58dc568351449dfd vamp-plugin-sdk +1e4f338ae482429a7ab9bdd0825242042354152f sv-dependency-builds +0ad516dc5d8d1eac370c7f43eeb7775919e0f2e9 svcore +55de53d7c777008997721bb43051a67c3b3772d2 vamp-plugin-sdk
--- a/.hgtags Fri Mar 18 15:15:37 2016 +0000 +++ b/.hgtags Fri Mar 18 15:15:55 2016 +0000 @@ -14,3 +14,4 @@ 5fe1f2efd40779acbdccc4c91a53693bd61f6d9b sonic-annotator-1.0 766268a32378f8e9e4fdfd3c78c3d43d482976ca sonic-annotator-1.1 f35bbb3e4d41caf3ca1be5576ed8ef6ef7c23e34 sonic-annotator-1.2 +710f4885f901c7b6617cfa4f1d9b3ff6a431affb sonic-annotator-1.3
--- a/CHANGELOG Fri Mar 18 15:15:37 2016 +0000 +++ b/CHANGELOG Fri Mar 18 15:15:55 2016 +0000 @@ -1,3 +1,25 @@ + +Changes in Sonic Annotator 1.4 since the previous release 1.3: + +Front-end changes: + + - Better error reporting, especially for invalid transform files + and transform-not-found + + - Avoid crashing out when a single plugin (that is not being used) + can't be loaded because of e.g. an undefined symbol + +Bug fixes: + + - Fix (with test) horrible crash with --multiplex option + + - Fix erroneous quantization to 16 bits for coded file types of + greater bit depth + + - Fix multiple outputs when requesting both summary and non-summary + for the same output + + Changes in Sonic Annotator 1.3 since the previous release 1.2: Back-end (feature writer) changes:
--- a/acinclude.m4 Fri Mar 18 15:15:37 2016 +0000 +++ b/acinclude.m4 Fri Mar 18 15:15:55 2016 +0000 @@ -69,6 +69,9 @@ AC_CHECK_PROG(QMAKE, qmake-qt5, $QTDIR/bin/qmake-qt5,,$QTDIR/bin/) fi if test x$QMAKE = x ; then + AC_CHECK_PROG(QMAKE, qt5-qmake, $QTDIR/bin/qt5-qmake,,$QTDIR/bin/) +fi +if test x$QMAKE = x ; then AC_CHECK_PROG(QMAKE, qmake, $QTDIR/bin/qmake,,$QTDIR/bin/) fi if test x$QMAKE = x ; then @@ -78,6 +81,9 @@ AC_CHECK_PROG(QMAKE, qmake-qt5, qmake-qt5,,$PATH) fi if test x$QMAKE = x ; then + AC_CHECK_PROG(QMAKE, qt5-qmake, qt5-qmake,,$PATH) +fi +if test x$QMAKE = x ; then AC_CHECK_PROG(QMAKE, qmake, qmake,,$PATH) fi if test x$QMAKE = x ; then @@ -112,3 +118,146 @@ ]) +# From autoconf archive: + +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXXFLAGS to enable support. +# +# The first argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The second argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline C++11 support is required and that the macro +# should error out if no mode with that support is found. If specified +# 'optional', then configuration proceeds regardless, after defining +# HAVE_CXX11 if and only if a supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> +# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> +# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> +# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + struct Base { + virtual void f() {} + }; + struct Child : public Base { + virtual void f() override {} + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c); + + auto d = a; + auto l = [](){}; +]]) + +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl + m4_if([$1], [], [], + [$1], [ext], [], + [$1], [noext], [], + [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl + m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], + [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], + [$2], [optional], [ax_cxx_compile_cxx11_required=false], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++11 features by default, + ax_cv_cxx_compile_cxx11, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [ax_cv_cxx_compile_cxx11=yes], + [ax_cv_cxx_compile_cxx11=no])]) + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + m4_if([$1], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++11 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$1], [ext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) + fi + else + if test x$ac_success = xno; then + HAVE_CXX11=0 + AC_MSG_NOTICE([No compiler with C++11 support was found]) + else + HAVE_CXX11=1 + AC_DEFINE(HAVE_CXX11,1, + [define if the compiler supports basic C++11 syntax]) + fi + + AC_SUBST(HAVE_CXX11) + fi +]) +
--- a/configure Fri Mar 18 15:15:37 2016 +0000 +++ b/configure Fri Mar 18 15:15:55 2016 +0000 @@ -1,8 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Sonic Annotator 1.2. -# -# Report bugs to <cannam@all-day-breakfast.com>. +# Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -266,8 +264,7 @@ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: cannam@all-day-breakfast.com about your system, + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." @@ -578,13 +575,14 @@ MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='Sonic Annotator' -PACKAGE_TARNAME='sonic-annotator' -PACKAGE_VERSION='1.2' -PACKAGE_STRING='Sonic Annotator 1.2' -PACKAGE_BUGREPORT='cannam@all-day-breakfast.com' -PACKAGE_URL='' - +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="Sonic Annotator" ac_unique_file="runner/main.cpp" # Factoring default headers for most tests. ac_includes_default="\ @@ -667,6 +665,7 @@ EGREP GREP CXXCPP +HAVE_CXX11 MKDIR_P INSTALL_DATA INSTALL_SCRIPT @@ -805,7 +804,7 @@ localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1305,7 +1304,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Sonic Annotator 1.2 to adapt to many kinds of systems. +\`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1353,7 +1352,7 @@ --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/sonic-annotator] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1365,9 +1364,7 @@ fi if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of Sonic Annotator 1.2:";; - esac + cat <<\_ACEOF Optional Features: @@ -1432,7 +1429,7 @@ Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to <cannam@all-day-breakfast.com>. +Report bugs to the package provider. _ACEOF ac_status=$? fi @@ -1495,7 +1492,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Sonic Annotator configure 1.2 +configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1734,10 +1731,6 @@ $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ------------------------------------------- ## -## Report this to cannam@all-day-breakfast.com ## -## ------------------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 @@ -1835,7 +1828,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Sonic Annotator $as_me 1.2, which was +It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3419,6 +3412,146 @@ $as_echo "$MKDIR_P" >&6; } +# We are daringly making use of C++11 now + + ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if ${ax_cv_cxx_compile_cxx11+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + struct Base { + virtual void f() {} + }; + struct Child : public Base { + virtual void f() override {} + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c); + + auto d = a; + auto l = [](){}; + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + + + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + struct Base { + virtual void f() {} + }; + struct Child : public Base { + virtual void f() override {} + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c); + + auto d = a; + auto l = [](){}; + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXXFLAGS="$ac_save_CXXFLAGS" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + else + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + fi + ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' @@ -3966,6 +4099,45 @@ fi if test x$QMAKE = x ; then + # Extract the first word of "qt5-qmake", so it can be a program name with args. +set dummy qt5-qmake; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_QMAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$QMAKE"; then + ac_cv_prog_QMAKE="$QMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $QTDIR/bin/ +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_QMAKE="$QTDIR/bin/qt5-qmake" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +QMAKE=$ac_cv_prog_QMAKE +if test -n "$QMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $QMAKE" >&5 +$as_echo "$QMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test x$QMAKE = x ; then # Extract the first word of "qmake", so it can be a program name with args. set dummy qmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -4083,6 +4255,45 @@ fi if test x$QMAKE = x ; then + # Extract the first word of "qt5-qmake", so it can be a program name with args. +set dummy qt5-qmake; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_QMAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$QMAKE"; then + ac_cv_prog_QMAKE="$QMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_QMAKE="qt5-qmake" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +QMAKE=$ac_cv_prog_QMAKE +if test -n "$QMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $QMAKE" >&5 +$as_echo "$QMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test x$QMAKE = x ; then # Extract the first word of "qmake", so it can be a program name with args. set dummy qmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -6231,7 +6442,7 @@ subdirs="$subdirs svcore" -ac_config_files="$ac_config_files config.pri version.h" +ac_config_files="$ac_config_files config.pri" cat >confcache <<\_ACEOF @@ -6776,7 +6987,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Sonic Annotator $as_me 1.2, which was +This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6823,13 +7034,13 @@ Configuration files: $config_files -Report bugs to <cannam@all-day-breakfast.com>." +Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Sonic Annotator config.status 1.2 +config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -6942,7 +7153,6 @@ do case $ac_config_target in "config.pri") CONFIG_FILES="$CONFIG_FILES config.pri" ;; - "version.h") CONFIG_FILES="$CONFIG_FILES version.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac
--- a/configure.ac Fri Mar 18 15:15:37 2016 +0000 +++ b/configure.ac Fri Mar 18 15:15:55 2016 +0000 @@ -1,5 +1,5 @@ -AC_INIT([Sonic Annotator], [1.2], cannam@all-day-breakfast.com) +AC_INIT([Sonic Annotator], [], cannam@all-day-breakfast.com) AC_CONFIG_SRCDIR(runner/main.cpp) @@ -25,6 +25,9 @@ AC_PROG_INSTALL AC_PROG_MKDIR_P +# We are daringly making use of C++11 now +AX_CXX_COMPILE_STDCXX_11(noext) + AC_HEADER_STDC # These are the flags Autoconf guesses for us; we use them later if @@ -108,7 +111,7 @@ AC_SUBST(QMAKE_CONFIG) AC_CONFIG_SUBDIRS([svcore]) -AC_CONFIG_FILES([config.pri version.h]) +AC_CONFIG_FILES([config.pri]) AC_OUTPUT
--- a/runner.pro Fri Mar 18 15:15:37 2016 +0000 +++ b/runner.pro Fri Mar 18 15:15:55 2016 +0000 @@ -1,5 +1,7 @@ TEMPLATE = app +INCLUDEPATH += vamp-plugin-sdk + win32-g++ { INCLUDEPATH += sv-dependency-builds/win32-mingw/include LIBS += -Lsv-dependency-builds/win32-mingw/lib @@ -22,7 +24,7 @@ CONFIG += release DEFINES += NDEBUG BUILD_RELEASE NO_TIMING - DEFINES += HAVE_BZ2 HAVE_FFTW3 HAVE_FFTW3F HAVE_SNDFILE HAVE_SAMPLERATE HAVE_VAMP HAVE_VAMPHOSTSDK HAVE_DATAQUAY HAVE_MAD HAVE_ID3TAG + DEFINES += HAVE_BZ2 HAVE_FFTW3 HAVE_FFTW3F HAVE_SNDFILE HAVE_SAMPLERATE HAVE_DATAQUAY HAVE_MAD HAVE_ID3TAG LIBS += -lbz2 -lfftw3 -lfftw3f -lsndfile -lFLAC -logg -lvorbis -lvorbisenc -lvorbisfile -logg -lmad -lid3tag -lsamplerate -lz -lsord-0 -lserd-0 @@ -49,11 +51,7 @@ # look for win32 features win32-x-g++:QMAKE_LFLAGS += -Wl,-subsystem,console -# If you have compiled your Vamp plugin SDK with FFTW (using its -# HAVE_FFTW3 flag), you can define the same flag here to ensure the -# program saves and restores FFTW wisdom in its configuration properly -# -DEFINES += HAVE_FFTW3 +DEFINES += HAVE_FFTW3 HAVE_VAMP HAVE_VAMPHOSTSDK TARGET = sonic-annotator @@ -81,7 +79,7 @@ LIBS = $$MY_LIBS $$LIBS -#PRE_TARGETDEPS += svcore/libsvcore.a +PRE_TARGETDEPS += svcore/libsvcore.a HEADERS += \ vamp-plugin-sdk/vamp-hostsdk/PluginBase.h \ @@ -113,6 +111,7 @@ vamp-plugin-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp \ vamp-plugin-sdk/src/vamp-hostsdk/PluginWrapper.cpp \ vamp-plugin-sdk/src/vamp-hostsdk/RealTime.cpp \ + vamp-plugin-sdk/src/vamp-hostsdk/Files.cpp \ runner/main.cpp \ runner/DefaultFeatureWriter.cpp \ runner/FeatureExtractionManager.cpp \
--- a/runner/FeatureExtractionManager.cpp Fri Mar 18 15:15:37 2016 +0000 +++ b/runner/FeatureExtractionManager.cpp Fri Mar 18 15:15:55 2016 +0000 @@ -323,6 +323,8 @@ << " (adapter step and block size " << m_blockSize << ")" << endl; +// cerr << "NOTE: That transform is: " << transform.toXmlString() << endl; + if (pida) { cerr << "NOTE: PluginInputDomainAdapter timestamp adjustment is " @@ -382,8 +384,11 @@ m_transformPluginMap[transform] = plugin; +// cerr << "NOTE: Assigned plugin " << plugin << " for transform: " << transform.toXmlString() << endl; + if (!(originalTransform == transform)) { m_transformPluginMap[originalTransform] = plugin; +// cerr << "NOTE: Also assigned plugin " << plugin << " for original transform: " << originalTransform.toXmlString() << endl; } } else { @@ -427,11 +432,36 @@ } bool FeatureExtractionManager::addFeatureExtractorFromFile -(QString transformXmlFile, const vector<FeatureWriter*> &writers) +(QString transformFile, const vector<FeatureWriter*> &writers) { + // We support two formats for transform description files, XML (in + // a format specific to Sonic Annotator) and RDF/Turtle. The RDF + // format can describe multiple transforms in a single file, the + // XML only one. + + // Possible errors we should report: + // + // 1. File does not exist or cannot be opened + // 2. File is ostensibly XML, but is not parseable + // 3. File is ostensibly Turtle, but is not parseable + // 4. File is XML, but contains no valid transform (e.g. is unrelated XML) + // 5. File is Turtle, but contains no valid transform(s) + // 6. File is Turtle and contains both valid and invalid transform(s) + + { + // We don't actually need to open this here yet, we just hoist + // it to the top for error reporting purposes + QFile file(transformFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + // Error case 1. File does not exist or cannot be opened + cerr << "ERROR: Failed to open transform file \"" << transformFile + << "\" for reading" << endl; + return false; + } + } + bool tryRdf = true; - - if (transformXmlFile.endsWith(".xml") || transformXmlFile.endsWith(".XML")) { + if (transformFile.endsWith(".xml") || transformFile.endsWith(".XML")) { // We don't support RDF-XML (and nor does the underlying // parser library) so skip the RDF parse if the filename // suggests XML, to avoid puking out a load of errors from @@ -439,44 +469,90 @@ tryRdf = false; } + bool tryXml = true; + if (transformFile.endsWith(".ttl") || transformFile.endsWith(".TTL") || + transformFile.endsWith(".ntriples") || transformFile.endsWith(".NTRIPLES") || + transformFile.endsWith(".n3") || transformFile.endsWith(".N3")) { + tryXml = false; + } + + QString rdfError, xmlError; + if (tryRdf) { + RDFTransformFactory factory - (QUrl::fromLocalFile(QFileInfo(transformXmlFile).absoluteFilePath()) + (QUrl::fromLocalFile(QFileInfo(transformFile).absoluteFilePath()) .toString()); ProgressPrinter printer("Parsing transforms RDF file"); std::vector<Transform> transforms = factory.getTransforms(&printer); - if (!factory.isOK()) { - cerr << "WARNING: FeatureExtractionManager::addFeatureExtractorFromFile: Failed to parse transforms file: " << factory.getErrorString().toStdString() << endl; + + if (factory.isOK()) { + if (transforms.empty()) { + cerr << "ERROR: Transform file \"" << transformFile + << "\" is valid RDF but defines no transforms" << endl; + return false; + } else { + bool success = true; + for (int i = 0; i < (int)transforms.size(); ++i) { + if (!addFeatureExtractor(transforms[i], writers)) { + success = false; + } + } + return success; + } + } else { // !factory.isOK() if (factory.isRDF()) { - return false; // no point trying it as XML + cerr << "ERROR: Invalid transform RDF file \"" << transformFile + << "\": " << factory.getErrorString() << endl; + return false; } - } - if (!transforms.empty()) { - bool success = true; - for (int i = 0; i < (int)transforms.size(); ++i) { - if (!addFeatureExtractor(transforms[i], writers)) { - success = false; - } - } - return success; + + // the not-RDF case: fall through without reporting an + // error, so we try the file as XML, and if that fails, we + // print a general unparseable-file error + rdfError = factory.getErrorString(); } } - QFile file(transformXmlFile); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - cerr << "ERROR: Failed to open transform XML file \"" - << transformXmlFile.toStdString() << "\" for reading" << endl; - return false; + if (tryXml) { + + QFile file(transformFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + cerr << "ERROR: Failed to open transform file \"" + << transformFile.toStdString() << "\" for reading" << endl; + return false; + } + + QTextStream *qts = new QTextStream(&file); + QString qs = qts->readAll(); + delete qts; + file.close(); + + Transform transform(qs); + xmlError = transform.getErrorString(); + + if (xmlError == "") { + + if (transform.getIdentifier() == "") { + cerr << "ERROR: Transform file \"" << transformFile + << "\" is valid XML but defines no transform" << endl; + return false; + } + + return addFeatureExtractor(transform, writers); + } } - QTextStream *qts = new QTextStream(&file); - QString qs = qts->readAll(); - delete qts; - file.close(); + cerr << "ERROR: Transform file \"" << transformFile + << "\" could not be parsed" << endl; + if (rdfError != "") { + cerr << "ERROR: RDF parser reported: " << rdfError << endl; + } + if (xmlError != "") { + cerr << "ERROR: XML parser reported: " << xmlError << endl; + } - Transform transform(qs); - - return addFeatureExtractor(transform, writers); + return false; } void FeatureExtractionManager::addSource(QString audioSource, bool willMultiplex) @@ -489,7 +565,7 @@ if (m_channels == 0 || m_defaultSampleRate == 0) { - ProgressPrinter retrievalProgress("Determining default rate and channel count from first input file..."); + ProgressPrinter retrievalProgress("Retrieving first input file to determine default rate and channel count..."); FileSource source(audioSource, &retrievalProgress); if (!source.isAvailable()) { @@ -524,14 +600,14 @@ if (m_channels == 0) { m_channels = reader->getChannelCount(); cerr << "Taking default channel count of " - << reader->getChannelCount() << " from file" << endl; + << reader->getChannelCount() << " from audio file" << endl; } } if (m_defaultSampleRate == 0) { m_defaultSampleRate = reader->getNativeRate(); cerr << "Taking default sample rate of " - << reader->getNativeRate() << "Hz from file" << endl; + << reader->getNativeRate() << "Hz from audio file" << endl; cerr << "(Note: Default may be overridden by transforms)" << endl; } @@ -616,6 +692,12 @@ if (!reader) { throw FailedToOpenFile(source); } + if (reader->getChannelCount() != m_channels || + reader->getNativeRate() != m_sampleRate) { + cerr << "NOTE: File will be mixed or resampled for processing, to: " + << m_channels << "ch at " + << m_sampleRate << "Hz" << endl; + } return reader; } @@ -628,12 +710,6 @@ cerr << "Audio file \"" << audioSource.toStdString() << "\": " << reader->getChannelCount() << "ch at " << reader->getNativeRate() << "Hz" << endl; - if (reader->getChannelCount() != m_channels || - reader->getNativeRate() != m_sampleRate) { - cerr << "NOTE: File will be mixed or resampled for processing, to: " - << m_channels << "ch at " - << m_sampleRate << "Hz" << endl; - } // allocate audio buffers float **data = new float *[m_channels]; @@ -671,7 +747,7 @@ PluginMap::iterator pi = m_plugins.find(plugin); - std::cerr << "Calling reset on " << plugin << std::endl; +// std::cerr << "Calling reset on " << plugin << std::endl; plugin->reset(); for (TransformWriterMap::iterator ti = pi->second.begin(); @@ -852,6 +928,7 @@ } if (!m_summaries.empty()) { + // Summaries requested on the command line, for all transforms PluginSummarisingAdapter *adapter = dynamic_cast<PluginSummarisingAdapter *>(plugin); if (!adapter) { @@ -868,12 +945,13 @@ featureSet = adapter->getSummaryForAllOutputs (getSummaryType(*sni), PluginSummarisingAdapter::ContinuousTimeAverage); - writeFeatures(audioSource, plugin, featureSet,//!!! *sni); + writeFeatures(audioSource, plugin, featureSet, Transform::stringToSummaryType(sni->c_str())); } } } + // Summaries specified in transform definitions themselves writeSummaries(audioSource, plugin); } @@ -895,11 +973,15 @@ const Transform &transform = ti->first; +// cerr << "FeatureExtractionManager::writeSummaries: plugin is " << plugin +// << ", found transform: " << transform.toXmlString() << endl; + Transform::SummaryType summaryType = transform.getSummaryType(); PluginSummarisingAdapter::SummaryType pType = (PluginSummarisingAdapter::SummaryType)summaryType; if (transform.getSummaryType() == Transform::NoSummary) { +// cerr << "(no summary, continuing)" << endl; continue; } @@ -913,7 +995,7 @@ Plugin::FeatureSet featureSet = adapter->getSummaryForAllOutputs (pType, PluginSummarisingAdapter::ContinuousTimeAverage); -// cout << "summary type " << int(pType) << " for transform:" << endl << transform.toXmlString().toStdString()<< endl << "... feature set with " << featureSet.size() << " elts" << endl; +// cerr << "summary type " << int(pType) << " for transform:" << endl << transform.toXmlString().toStdString()<< endl << "... feature set with " << featureSet.size() << " elts" << endl; writeFeatures(audioSource, plugin, featureSet, summaryType); } @@ -927,21 +1009,25 @@ // caller should have ensured plugin is in m_plugins PluginMap::iterator pi = m_plugins.find(plugin); + // Write features from the feature set passed in, according to the + // transforms listed for the given plugin with the given summary type + for (TransformWriterMap::const_iterator ti = pi->second.begin(); ti != pi->second.end(); ++ti) { const Transform &transform = ti->first; const vector<FeatureWriter *> &writers = ti->second; - - if (transform.getSummaryType() != Transform::NoSummary && - m_summaries.empty() && - summaryType == Transform::NoSummary) { - continue; - } - if (transform.getSummaryType() != Transform::NoSummary && - summaryType != Transform::NoSummary && - transform.getSummaryType() != summaryType) { +// cerr << "writeFeatures: plugin " << plugin << " has transform: " << transform.toXmlString() << endl; + + if (transform.getSummaryType() == Transform::NoSummary && + !m_summaries.empty()) { +// cerr << "transform has no summary, but summaries requested on command line, so going for it anyway" << endl; + } else if (transform.getSummaryType() != summaryType) { + // Either we're not writing a summary and the transform + // has one, or we're writing a summary but the transform + // has none or a different one; either way, skip it +// cerr << "summary type differs from passed-in one " << summaryType << endl; continue; } @@ -959,6 +1045,8 @@ Plugin::FeatureSet::const_iterator fsi = features.find(outputIndex); if (fsi == features.end()) continue; +// cerr << "this transform has " << writers.size() << " writer(s)" << endl; + for (int j = 0; j < (int)writers.size(); ++j) { writers[j]->write (audioSource, transform, desc, fsi->second,
--- a/runner/FeatureExtractionManager.h Fri Mar 18 15:15:37 2016 +0000 +++ b/runner/FeatureExtractionManager.h Fri Mar 18 15:15:55 2016 +0000 @@ -114,8 +114,8 @@ OutputIndexMap m_pluginOutputIndices; typedef set<std::string> SummaryNameSet; - SummaryNameSet m_summaries; - bool m_summariesOnly; + SummaryNameSet m_summaries; // requested on command line for all transforms + bool m_summariesOnly; // command line flag Vamp::HostExt::PluginSummarisingAdapter::SegmentBoundaries m_boundaries; AudioFileReader *prepareReader(QString audioSource);
--- a/runner/MultiplexedReader.cpp Fri Mar 18 15:15:37 2016 +0000 +++ b/runner/MultiplexedReader.cpp Fri Mar 18 15:15:55 2016 +0000 @@ -60,7 +60,7 @@ for (int out_chan = 0; out_chan < out_chans; ++out_chan) { AudioFileReader *reader = m_readers[out_chan]; - SampleBlock readerBlock = getInterleavedFrames(start, frameCount); + SampleBlock readerBlock = reader->getInterleavedFrames(start, frameCount); int in_chans = reader->getChannelCount();
--- a/runner/main.cpp Fri Mar 18 15:15:37 2016 +0000 +++ b/runner/main.cpp Fri Mar 18 15:15:55 2016 +0000 @@ -137,6 +137,10 @@ return ws; } +static QString wrapCol(QString s) { + return wrap(s, 56, 22); +} + static bool isVersionNewerThan(QString a, QString b) // from VersionTester in svapp { @@ -186,8 +190,8 @@ cerr << endl; cerr << "Sonic Annotator v" << RUNNER_VERSION << endl; cerr << "A utility for batch feature extraction from audio files." << endl; - cerr << "Mark Levy, Chris Sutton and Chris Cannam, Queen Mary, University of London." << endl; - cerr << "Copyright 2007-2015 Queen Mary, University of London." << endl; + cerr << "Mark Levy, Chris Sutton, and Chris Cannam, Queen Mary, University of London." << endl; + cerr << "Copyright 2007-2016 Queen Mary, University of London." << endl; cerr << endl; cerr << "This program is free software. You may redistribute copies of it under the" << endl; cerr << "terms of the GNU General Public License <http://www.gnu.org/licenses/gpl.html>." << endl; @@ -199,7 +203,7 @@ cerr << " " << myname << " [-mrnf] -T translist.txt [..] -w <writer> [..] <audio> [..]" << endl; cerr << " " << myname - << " [-mrnf] -d <plugin> [..] -w <writer> [..] <audio> [...]" << endl; + << " [-mrnf] -d <id> [..] -w <writer> [..] <audio> [...]" << endl; cerr << " " << myname << " -s <transform>" << endl; cerr << " " << myname @@ -207,7 +211,7 @@ cerr << endl; cerr << "Where <audio> is an audio file or URL to use as input: either a local file" << endl; cerr << "path, local \"file://\" URL, or remote \"http://\" or \"ftp://\" URL;" << endl; - cerr << "and <plugin> is a plugin output identified as vamp:libname:plugin:output." << endl; + cerr << "and <id> is a transform id of the form vamp:libname:plugin:output." << endl; cerr << endl; } @@ -218,7 +222,7 @@ if (p.hasArg) { cerr << "<X> "; spaceage -= 4; } for (int k = 0; k < spaceage; ++k) cerr << " "; QString s(p.description.c_str()); - s = wrap(s, 56, 22); + s = wrapCol(s); cerr << s << endl; } @@ -261,92 +265,112 @@ if (++i != writers.end()) writerText += ", "; else writerText += "."; } - writerText = wrap(writerText, 56, 22); + writerText = wrapCol(writerText); if (writer == "" || writers.find(writer) == writers.end()) { cerr << "Transformation options:" << endl; cerr << endl; - cerr << " -t, --transform <T> Apply transform described in transform file <T> to" << endl; - cerr << " all input audio files. You may supply this option" << endl; - cerr << " multiple times. You must supply this option or -T at" << endl; - cerr << " least once for any work to be done. Transform format" << endl; - cerr << " may be SV transform XML or Vamp transform RDF/Turtle." << endl; - cerr << " See accompanying documentation for transform examples." << endl; - cerr << endl; - cerr << " -T, --transforms <T> Apply all transforms described in transform files" << endl; - cerr << " whose names are listed in text file <T>. You may supply" << endl; - cerr << " this option multiple times." << endl; - cerr << endl; - cerr << " -d, --default <I> Apply the default transform for transform id <I>. This" << endl; - cerr << " is equivalent to generating a skeleton transform for this" << endl; - cerr << " id (using the -s option, below) and then applying that," << endl; - cerr << " unmodified, with the -t option in the normal way. Note" << endl; - cerr << " that results may vary, as the implementation's default" << endl; - cerr << " processing parameters are not guaranteed. Do not use" << endl; - cerr << " this in production systems. You may supply this option" << endl; - cerr << " multiple times, and mix it with -t and -T." << endl; - cerr << endl; - cerr << " -w, --writer <W> Write output using writer type <W>." << endl; - cerr << " " << writerText << endl; - cerr << " You may supply this option multiple times. You must" << endl; - cerr << " supply this option at least once for any work to be done." << endl; - cerr << endl; - cerr << " -S, --summary <S> In addition to the result features, write summary feature" << endl; - cerr << " of summary type <S>." << endl; - cerr << " Supported summary types are min, max, mean, median, mode," << endl; - cerr << " sum, variance, sd, count." << endl; - cerr << " You may supply this option multiple times." << endl; - cerr << endl; - cerr << " --summary-only Write only summary features; do not write the regular" << endl; - cerr << " result features." << endl; - cerr << endl; - cerr << " --segments <A>,<B>[,...]" << endl; - cerr << " Summarise in segments, with segment boundaries" << endl; - cerr << " at A, B, ... seconds." << endl; - cerr << endl; - cerr << " --segments-from <F>" << endl; - cerr << " Summarise in segments, with segment boundaries" << endl; - cerr << " at times read from the text file <F>. (one time per" << endl; - cerr << " line, in seconds)." << endl; - cerr << endl; - cerr << " -m, --multiplex If multiple input audio files are given, use mono" << endl; - cerr << " mixdowns of all files as the input channels for a single" << endl; - cerr << " invocation of each transform, instead of running the" << endl; - cerr << " transform against all files separately. The first file" << endl; - cerr << " will be used for output reference name and sample rate." << endl; - cerr << endl; - cerr << " -r, --recursive If any of the <audio> arguments is found to be a local" << endl; - cerr << " directory, search the tree starting at that directory" << endl; - cerr << " for all supported audio files and take all of those as" << endl; - cerr << " input instead." << endl; - cerr << endl; - cerr << " -n, --normalise Normalise input audio files to signal absolute max = 1.f." << endl; - cerr << endl; - cerr << " -f, --force Continue with subsequent files following an error." << endl; - cerr << endl; - cerr << "Housekeeping options:" << endl; - cerr << endl; + cerr << " -t, --transform <T> " + << wrapCol("Apply transform described in transform file <T> to" + " all input audio files. You may supply this option" + " multiple times. You must supply this option, -T, or -d" + " at least once for any work to be done. Transform format" + " may be SV transform XML or Vamp transform RDF/Turtle." + " A skeleton transform file for" + " a given transform id can be generated using the" + " -s option (see below). See accompanying" + " documentation for transform examples.") + << endl << endl; + cerr << " -T, --transforms <T> " + << wrapCol("Apply all transforms described in transform files" + " whose names are listed in text file <T>. You may supply" + " this option multiple times.") + << endl << endl; + cerr << " -d, --default <I> " + << wrapCol("Apply the default transform for transform id <I>. This" + " is equivalent to generating a skeleton transform for the" + " id (using the -s option, below) and then applying that," + " unmodified, with the -t option in the normal way. Note" + " that results may vary, as default" + " processing parameters may change between releases of " + + myname + " as well as of individual plugins. Do not use" + " this in production systems. You may supply this option" + " multiple times, and mix it with -t and -T.") + << endl << endl; + cerr << " -w, --writer <W> Write output using writer type <W>.\n" + << " " << writerText << endl + << " " + << wrapCol("You may supply this option multiple times. You must" + " supply this option at least once for any work to be done.") + << endl << endl; + cerr << " -S, --summary <S> " + << wrapCol("In addition to the result features, write summary feature" + " of summary type <S>.") << endl + << " " + << wrapCol("Supported summary types are min, max, mean, median, mode," + " sum, variance, sd, count.") << endl + << " You may supply this option multiple times." + << endl << endl; + cerr << " --summary-only " + << wrapCol("Write only summary features; do not write the regular" + " result features.") + << endl << endl; + cerr << " --segments <A>,<B>[,...]\n " + << wrapCol("Summarise in segments, with segment boundaries" + " at A, B, ... seconds.") + << endl << endl; + cerr << " --segments-from <F>\n " + << wrapCol("Summarise in segments, with segment boundaries" + " at times read from the text file <F>. (one time per" + " line, in seconds).") + << endl << endl; + cerr << " -m, --multiplex " + << wrapCol("If multiple input audio files are given, use mono" + " mixdowns of the files as the input channels for a single" + " invocation of each transform, instead of running the" + " transform against all files separately. The first file" + " will be used for output reference name and sample rate.") + << endl << endl; + cerr << " -r, --recursive " + << wrapCol("If any of the <audio> arguments is found to be a local" + " directory, search the tree starting at that directory" + " for all supported audio files and take all of those as" + " input in place of it.") + << endl << endl; + cerr << " -n, --normalise " + << wrapCol("Normalise each input audio file to signal abs max = 1.f.") + << endl << endl; + cerr << " -f, --force " + << wrapCol("Continue with subsequent files following an error.") + << endl << endl; + cerr << "Housekeeping options:" + << endl << endl; cerr << " -l, --list List available transform ids to standard output." << endl; cerr << " --list-writers List supported writer types to standard output." << endl; cerr << " --list-formats List supported input audio formats to standard output." << endl; cerr << endl; - cerr << " -s, --skeleton <I> Generate a skeleton transform file for transform id <I>" << endl; - cerr << " and write it to standard output." << endl; - cerr << endl; + cerr << " -s, --skeleton <I> " + << wrapCol("Generate a skeleton RDF transform file for transform id" + " <I>, with default parameters for that transform, and write it" + " to standard output.") + << endl << endl; cerr << " -v, --version Show the version number and exit." << endl; cerr << endl; - cerr << " --minversion <V> Exit with successful return code if the version of" << endl; - cerr << " " << myname << " is at least <V>, failure otherwise." << endl; - cerr << " For scripts that depend on certain option support." << endl; - cerr << endl; + cerr << " --minversion <V> " + << wrapCol("Exit with successful return code if the version of " + + myname + " is at least <V>, failure otherwise." + " For scripts that depend on certain option support.") + << endl << endl; cerr << " -h, --help Show help." << endl; cerr << " -h, --help <W> Show help for writer type W." << endl; cerr << " " << writerText << endl; - cerr << endl; - cerr << "If no -w (or --writer) options are supplied, either the -l -s -v or -h option" << endl; - cerr << "(or long equivalent) must be given instead." << endl; + cerr << endl + << wrap("If no -w (or --writer) options are supplied, one of the" + " housekeeping options (-l -s -v -h or long equivalent) must" + " be given instead.", 78, 0) + << endl; } else { @@ -857,8 +881,7 @@ if (!requestedSummaryTypes.empty()) { if (!manager.setSummaryTypes(requestedSummaryTypes, boundaries)) { - cerr << myname - << ": failed to set requested summary types" << endl; + cerr << myname << ": failed to set requested summary types" << endl; exit(1); } }
--- a/tests/include.sh Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/include.sh Fri Mar 18 15:15:55 2016 +0000 @@ -13,8 +13,8 @@ ;; esac -version=1.3 -nextversion=1.4 +version=1.4 +nextversion=1.5 testdir=$mypath/.. r=$testdir/../sonic-annotator @@ -60,11 +60,13 @@ } jsoncompare() { + # The Sonic Annotator version number appears in the JAMS output -- + # filter that out, and also reformat to ignore whitespace differences a="$1" b="$2" - cat "$a" | json_reformat > "${a}__" - cat "$b" | json_reformat > "${b}__" - cmp -s "$a" "$b" + cat "$a" | sed 's/Sonic Annotator v[0-9.]*/Sonic Annotator vXXX/' | json_reformat > "${a}__" + cat "$b" | sed 's/Sonic Annotator v[0-9.]*/Sonic Annotator vXXX/' | json_reformat > "${b}__" + cmp -s "${a}__" "${b}__" rv=$? rm "${a}__" "${b}__" return $rv @@ -81,7 +83,7 @@ echo "--" cat "$3" echo "--" - echo "Diff:" + echo "Diff (output on left, expected on right):" echo "--" sdiff -w78 "$2" "$3" echo "--"
--- a/tests/test-multiple-audio/expected/all-files.csv Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/test-multiple-audio/expected/all-files.csv Fri Mar 18 15:15:55 2016 +0000 @@ -1,36 +1,36 @@ "./../audio/20sec-silence.wav",0.000000000,20.015600906,mean,61.1636,"(mean value, continuous-time average)" ,0.000000000,20.015600906,median,0,"(median value, continuous-time average)" ,0.000000000,20.015600906,mode,0,"(modal value, continuous-time average)" -,0.000000000,20.015600906,mean,893.139,"(mean value, continuous-time average)" -"./../audio/3clicks.mp3",0.000000000,5.061950112,mean,169.206,"(mean value, continuous-time average)" -,0.000000000,5.061950112,median,170,"(median value, continuous-time average)" -,0.000000000,5.061950112,mode,162,"(modal value, continuous-time average)" -,0.000000000,5.061950112,mean,699.101,"(mean value, continuous-time average)" -"./../audio/3clicks.ogg",0.000000000,4.992290248,mean,169.505,"(mean value, continuous-time average)" -,0.000000000,4.992290248,median,170,"(median value, continuous-time average)" -,0.000000000,4.992290248,mode,174,"(modal value, continuous-time average)" -,0.000000000,4.992290248,mean,724.777,"(mean value, continuous-time average)" +,0.000000000,20.015600906,mean,1406.56,"(mean value, continuous-time average)" +"./../audio/3clicks.mp3",0.000000000,5.061950112,mean,174.507,"(mean value, continuous-time average)" +,0.000000000,5.061950112,median,173,"(median value, continuous-time average)" +,0.000000000,5.061950112,mode,173,"(modal value, continuous-time average)" +,0.000000000,5.061950112,mean,1510.95,"(mean value, continuous-time average)" +"./../audio/3clicks.ogg",0.000000000,4.992290248,mean,169.481,"(mean value, continuous-time average)" +,0.000000000,4.992290248,median,156,"(median value, continuous-time average)" +,0.000000000,4.992290248,mode,132,"(modal value, continuous-time average)" +,0.000000000,4.992290248,mean,1480.59,"(mean value, continuous-time average)" "./../audio/3clicks8.wav",0.000000000,4.992290248,mean,169.391,"(mean value, continuous-time average)" ,0.000000000,4.992290248,median,169,"(median value, continuous-time average)" ,0.000000000,4.992290248,mode,164,"(modal value, continuous-time average)" -,0.000000000,4.992290248,mean,703.191,"(mean value, continuous-time average)" +,0.000000000,4.992290248,mean,1403.77,"(mean value, continuous-time average)" "./../audio/3clicks8quiet.wav",0.000000000,4.992290248,mean,169.058,"(mean value, continuous-time average)" ,0.000000000,4.992290248,median,169,"(median value, continuous-time average)" ,0.000000000,4.992290248,mode,165,"(modal value, continuous-time average)" -,0.000000000,4.992290248,mean,673.623,"(mean value, continuous-time average)" -"./../audio/6clicks.ogg",0.000000000,9.961360543,mean,167.58,"(mean value, continuous-time average)" -,0.000000000,9.961360543,median,167,"(median value, continuous-time average)" -,0.000000000,9.961360543,mode,170,"(modal value, continuous-time average)" -,0.000000000,9.961360543,mean,714.928,"(mean value, continuous-time average)" +,0.000000000,4.992290248,mean,1342.8,"(mean value, continuous-time average)" +"./../audio/6clicks.ogg",0.000000000,9.961360543,mean,168.686,"(mean value, continuous-time average)" +,0.000000000,9.961360543,median,158,"(median value, continuous-time average)" +,0.000000000,9.961360543,mode,138,"(modal value, continuous-time average)" +,0.000000000,9.961360543,mean,1423.64,"(mean value, continuous-time average)" "./../audio/6clicks8.wav",0.000000000,9.961360543,mean,170.174,"(mean value, continuous-time average)" ,0.000000000,9.961360543,median,169,"(median value, continuous-time average)" ,0.000000000,9.961360543,mode,164,"(modal value, continuous-time average)" -,0.000000000,9.961360543,mean,698.921,"(mean value, continuous-time average)" -"./../audio/id3v2-iso-8859-1.mp3",0.000000000,5.015510203,mean,170.655,"(mean value, continuous-time average)" -,0.000000000,5.015510203,median,171,"(median value, continuous-time average)" -,0.000000000,5.015510203,mode,171,"(modal value, continuous-time average)" -,0.000000000,5.015510203,mean,690.028,"(mean value, continuous-time average)" -"./../audio/id3v2-ucs-2.mp3",0.000000000,5.061950112,mean,169.206,"(mean value, continuous-time average)" -,0.000000000,5.061950112,median,170,"(median value, continuous-time average)" -,0.000000000,5.061950112,mode,162,"(modal value, continuous-time average)" -,0.000000000,5.061950112,mean,699.101,"(mean value, continuous-time average)" +,0.000000000,9.961360543,mean,1411.85,"(mean value, continuous-time average)" +"./../audio/id3v2-iso-8859-1.mp3",0.000000000,5.015510203,mean,176.083,"(mean value, continuous-time average)" +,0.000000000,5.015510203,median,172,"(median value, continuous-time average)" +,0.000000000,5.015510203,mode,164,"(modal value, continuous-time average)" +,0.000000000,5.015510203,mean,1492.7,"(mean value, continuous-time average)" +"./../audio/id3v2-ucs-2.mp3",0.000000000,5.061950112,mean,174.507,"(mean value, continuous-time average)" +,0.000000000,5.061950112,median,173,"(median value, continuous-time average)" +,0.000000000,5.061950112,mode,173,"(modal value, continuous-time average)" +,0.000000000,5.061950112,mean,1510.95,"(mean value, continuous-time average)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-multiple-audio/expected/multiplexed.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,4 @@ +"3clicks.mp3",0.000000000,9.961360543,mean,168.908,"(mean value, continuous-time average)" +,0.000000000,9.961360543,median,162,"(median value, continuous-time average)" +,0.000000000,9.961360543,mode,144,"(modal value, continuous-time average)" +,0.000000000,9.961360543,mean,1418.17,"(mean value, continuous-time average)"
--- a/tests/test-multiple-audio/expected/playlist.csv Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/test-multiple-audio/expected/playlist.csv Fri Mar 18 15:15:55 2016 +0000 @@ -1,8 +1,8 @@ -"3clicks.mp3",0.000000000,5.061950112,mean,169.206,"(mean value, continuous-time average)" -,0.000000000,5.061950112,median,170,"(median value, continuous-time average)" -,0.000000000,5.061950112,mode,162,"(modal value, continuous-time average)" -,0.000000000,5.061950112,mean,699.101,"(mean value, continuous-time average)" -"6clicks.ogg",0.000000000,9.961360543,mean,167.58,"(mean value, continuous-time average)" -,0.000000000,9.961360543,median,167,"(median value, continuous-time average)" -,0.000000000,9.961360543,mode,170,"(modal value, continuous-time average)" -,0.000000000,9.961360543,mean,714.928,"(mean value, continuous-time average)" +"3clicks.mp3",0.000000000,5.061950112,mean,174.507,"(mean value, continuous-time average)" +,0.000000000,5.061950112,median,173,"(median value, continuous-time average)" +,0.000000000,5.061950112,mode,173,"(modal value, continuous-time average)" +,0.000000000,5.061950112,mean,1510.95,"(mean value, continuous-time average)" +"6clicks.ogg",0.000000000,9.961360543,mean,168.686,"(mean value, continuous-time average)" +,0.000000000,9.961360543,median,158,"(median value, continuous-time average)" +,0.000000000,9.961360543,mode,138,"(modal value, continuous-time average)" +,0.000000000,9.961360543,mean,1423.64,"(mean value, continuous-time average)"
--- a/tests/test-multiple-audio/test-multiple-audio.sh Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/test-multiple-audio/test-multiple-audio.sh Fri Mar 18 15:15:55 2016 +0000 @@ -2,14 +2,21 @@ . ../include.sh -tmpfile=$mypath/tmp_1_$$ +tmpfile1=$mypath/tmp_1_$$ +tmpfile2=$mypath/tmp_2_$$ -trap "rm -f $tmpfile" 0 +trap "rm -f $tmpfile1 $tmpfile2" 0 transform=$mypath/transforms/detectionfunction.n3 urlbase=http://vamp-plugins.org/sonic-annotator/testfiles +have_network=yes +if ! ping -c 1 8.8.8.8 2>/dev/null 1>&2 ; then + echo "(network appears unavailable, skipping networking tests)" + have_network=no +fi + # 1. Recursive local directory @@ -17,12 +24,12 @@ # would have to regenerate it if we added more test audio files. Note # that the -r flag is not supposed to pick up playlist files, only # audio files -$r -t $transform -w csv --csv-stdout -r --summary-only $audiopath > $tmpfile 2>/dev/null || \ +$r -t $transform -w csv --csv-stdout -r --summary-only $audiopath > $tmpfile1 2>/dev/null || \ fail "Fails to run transform $transform with recursive dir option" expected=$mypath/expected/all-files -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and recursive dir option" $tmpfile $expected.csv +csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and recursive dir option" $tmpfile1 $expected.csv # 2. Local playlist file referring to local audio files @@ -30,72 +37,101 @@ # Here we strip any leading path from the audio file in the output, # because the playlist reader will have resolved files to absolute # paths and those will differ between systems -$r -t $transform -w csv --csv-stdout $audiopath/playlist.m3u --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ +$r -t $transform -w csv --csv-stdout $audiopath/playlist.m3u --summary-only 2>/dev/null > "$tmpfile2" || \ fail "Fails to run transform $transform with playlist input" +cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" + expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and playlist input" $tmpfile $expected.csv +csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and playlist input" $tmpfile1 $expected.csv # 3. Multiple files supplied directly on command line # Strip paths again, just so we can use the same output comparison # file as above -$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ +$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \ fail "Fails to run transform $transform with 2-file input" +cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" + expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile $expected.csv +csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile1 $expected.csv # 4. Multiple files supplied directly on command line, with file: URL -$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 file://`pwd`/$audiopath/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ +$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 file://`pwd`/$audiopath/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \ fail "Fails to run transform $transform with 2-file input" -expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and 2-file input using file:// URL" $tmpfile $expected.csv - - -# 5. Remote playlist file referring to remote audio files - -$r -t $transform -w csv --csv-stdout $urlbase/playlist.m3u --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ - fail "Fails to run transform $transform with remote playlist input" +cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile $expected.csv +csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and 2-file input using file:// URL" $tmpfile1 $expected.csv -# 6. Local playlist file referring to mixture of remote and local audio files +if [ "$have_network" = "yes" ]; then -$r -t $transform -w csv --csv-stdout $audiopath/remote-playlist.m3u --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ - fail "Fails to run transform $transform with playlist of remote files" + # 5. Remote playlist file referring to remote audio files -expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile $expected.csv + $r -t $transform -w csv --csv-stdout $urlbase/playlist.m3u --summary-only 2>/dev/null > $tmpfile2 || \ + fail "Fails to run transform $transform with remote playlist input" + cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" -# 7. Multiple remote files supplied directly on command line + expected=$mypath/expected/playlist + csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile1 $expected.csv -$r -t $transform -w csv --csv-stdout $urlbase/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ - fail "Fails to run transform $transform with 2-file remote input" -expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile $expected.csv + # 6. Local playlist file referring to mixture of remote and local audio files + $r -t $transform -w csv --csv-stdout $audiopath/remote-playlist.m3u --summary-only 2>/dev/null > $tmpfile2 || \ + fail "Fails to run transform $transform with playlist of remote files" -# 8. Mixture of remote and local files supplied on command line + cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" -$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \ - fail "Fails to run transform $transform with 2-file remote input" + expected=$mypath/expected/playlist + csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile1 $expected.csv -expected=$mypath/expected/playlist -csvcompare $tmpfile $expected.csv || \ - faildiff "Output mismatch for transform $transform with summaries and mixed local/remote 2-file input" $tmpfile $expected.csv + # 7. Multiple remote files supplied directly on command line + + $r -t $transform -w csv --csv-stdout $urlbase/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \ + fail "Fails to run transform $transform with 2-file remote input" + + cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" + + expected=$mypath/expected/playlist + csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile1 $expected.csv + + + # 8. Mixture of remote and local files supplied on command line + + $r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \ + fail "Fails to run transform $transform with 2-file remote input" + + cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" + + expected=$mypath/expected/playlist + csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and mixed local/remote 2-file input" $tmpfile1 $expected.csv + +fi + +# 9. As 3, but multiplexing rather than extracting separately from each file + +$r -t $transform --multiplex -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \ + fail "Fails to run transform $transform with 2-file input" + +cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1" + +expected=$mypath/expected/multiplexed +csvcompare $tmpfile1 $expected.csv || \ + faildiff "Output mismatch for transform $transform with summaries and 2-file multiplexed input" $tmpfile1 $expected.csv +
--- a/tests/test-multiple-audio/transforms/detectionfunction.n3 Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/test-multiple-audio/transforms/detectionfunction.n3 Fri Mar 18 15:15:55 2016 +0000 @@ -13,6 +13,7 @@ vamp:output examples:percussiononsets_output_detectionfunction ; vamp:summary_type "median" . +# This is not a summary and so should not appear with --summary-only :transform2 a vamp:Transform; vamp:plugin examples:percussiononsets ; vamp:output examples:percussiononsets_output_onsets . @@ -22,11 +23,19 @@ vamp:output examples:percussiononsets_output_detectionfunction ; vamp:summary_type "mode" . +# This has different step and block sizes from the default +# (:transform0), and so should be listed separately with different +# values in the output :transform4 a vamp:Transform; vamp:plugin examples:percussiononsets ; vamp:output examples:percussiononsets_output_detectionfunction ; - vamp:step_size 2048 ; - vamp:block_size 4096 ; + vamp:step_size 4096 ; + vamp:block_size 8192 ; vamp:summary_type "mean" . +# This is not a summary and so should not appear with --summary-only +:transform5 a vamp:Transform; + vamp:plugin examples:percussiononsets ; + vamp:output examples:percussiononsets_output_detectionfunction . +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/empty.ttl.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +RDF parser reported: Failed to import model from URL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/empty.xml.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +XML parser reported: unexpected end of file at line 1, column 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/garbage.dat.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,2 @@ +ERROR: RDF parser reported: +ERROR: XML parser reported:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/invalid-turtle.ttl.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +RDF parser reported: Failed to import model from URL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/invalid-xml.xml.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +XML parser reported: tag mismatch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/valid-turtle-no-transform.ttl.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +valid RDF but defines no transforms
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/expected/valid-xml-no-transform.xml.txt Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +valid XML but defines no transform
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/inputs/garbage.dat Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +gZ~zN9Ԭb$7:2s𤇧0H2 zZ4#<An#|lTs:o_BKꥵ+-%WY[N-tLf7Ҷ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/inputs/invalid-turtle.ttl Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,2 @@ +# Trailing ; +<http://example/s> <http://example/p> <http://example/o> ;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/inputs/invalid-xml.xml Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<rss version="2.0"> + <channel> + <title>A Title</title> + <link>http://example.com</link> + <description/> + <!-- NB missing end-tag for channel --> +</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/inputs/valid-turtle-no-transform.ttl Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +<http://example/s> <http://example/p> <http://example/o> .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/inputs/valid-xml-no-transform.xml Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<rss version="2.0"> + <channel> + <title>A Title</title> + <link>http://example.com</link> + <description/> + </channel> +</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-parse-errors/test-parse-errors.sh Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,29 @@ +#!/bin/bash + +. ../include.sh + +infile=$audiopath/3clicks8.wav +tmpfile=$mypath/tmp_$$ +trap "rm -f $tmpfile" 0 + +for transform in "$mypath"/inputs/* ; do + + base=$(basename "$transform") + expected="$mypath"/expected/"$base".txt + + if [ ! -f "$expected" ]; then + fail "Internal error: Expected file $expected not found for transform $transform" + fi + + if $r -t "$transform" -w csv --csv-one-file /dev/null "$infile" 2>"$tmpfile" ; then + fail "Erroneously succeeds in running bogus transform $transform" + fi + + cat "$expected" | while read line; do + if ! fgrep -q "$line" "$tmpfile" ; then + fail "Expected output text \"$line\" not found in diagnostic output for transform $base" + fi + done + +done +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-count.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +0.000000000,9.750000000,count,10,"(count)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-max.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +0.000000000,9.750000000,max,0.9,"(maximum value)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-mean.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,20 @@ +# Sonic Annotator's summary method integrates the values across +# time. If an output lacks duration for its features, each feature is +# considered to extend until the timestamp of the following feature, +# and the final feature is considered to extend until the end of the +# input or the last-ending output, whichever is later. +# +# The curve-vsr output is therefore considered to have 9 values (0.0 +# to 0.8) that span 0.75 seconds each, followed by one value (0.9) +# that spans the 3 seconds from 6.75 to 9.75 where the final output of +# the plugin ends (that's the notes-regions output). +# +# The sum of 0.0..0.8 is 3.6, so the mean is (3.6 * 0.75 + 0.9 * 3.0) +# / 9.75 = 0.553846 approx. +# +# Equivalently we can consider the last feature the same as four +# features of 0.75 seconds each (i.e. the same durations as the first +# 9) each with the same value, 0.9. The mean is then the sum of +# 0.0..0.9 plus three more 0.9s, i.e. 7.2, divided by 13. +# +0.000000000,9.750000000,mean,0.553846,"(mean value, continuous-time average)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-median.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,16 @@ +# Sonic Annotator's summary method integrates the values across +# time. If an output lacks duration for its features, each feature is +# considered to extend until the timestamp of the following feature, +# and the final feature is considered to extend until the end of the +# input or the last-ending output, whichever is later. +# +# The curve-vsr output is therefore considered to have 9 values (0.0 +# to 0.8) that span 0.75 seconds each, followed by one value (0.9) +# that spans the 3 seconds from 6.75 to 9.75 where the final output of +# the plugin ends (that's the notes-regions output). +# +# Since the values from this output are already sorted and are +# distinct, the integrated median is just whatever is in effect at +# time 9.75 / 2.0 = 4.875. This value is 0.6. +# +0.000000000,9.750000000,median,0.6,"(median value, continuous-time average)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-min.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +0.000000000,9.750000000,min,0,"(minimum value)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-mode.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,15 @@ +# Sonic Annotator's summary method integrates the values across +# time. If an output lacks duration for its features, each feature is +# considered to extend until the timestamp of the following feature, +# and the final feature is considered to extend until the end of the +# input or the last-ending output, whichever is later. +# +# The curve-vsr output is therefore considered to have 9 values (0.0 +# to 0.8) that span 0.75 seconds each, followed by one value (0.9) +# that spans the 3 seconds from 6.75 to 9.75 where the final output of +# the plugin ends (that's the notes-regions output). +# +# The modal value is the one spanning the longest, which of course is +# that final one, 0.9. +# +0.000000000,9.750000000,mode,0.9,"(modal value, continuous-time average)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-sd.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,4 @@ +# Standard deviation is sqrt(variance), see the variance file for +# notes on that value. +# +0.000000000,9.750000000,sd,0.315291,"(standard deviation, continuous-time average)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-sum.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +0.000000000,9.750000000,sum,4.5,"(sum)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-curve-vsr-variance.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,20 @@ +# Sonic Annotator's summary method integrates the values across +# time. If an output lacks duration for its features, each feature is +# considered to extend until the timestamp of the following feature, +# and the final feature is considered to extend until the end of the +# input or the last-ending output, whichever is later. +# +# The curve-vsr output is therefore considered to have 9 values (0.0 +# to 0.8) that span 0.75 seconds each, followed by one value (0.9) +# that spans the 3 seconds from 6.75 to 9.75 where the final output of +# the plugin ends (that's the notes-regions output). +# +# We can consider the last feature the same as four features of 0.75 +# seconds each (i.e. the same durations as the first 9) each with the +# same value, 0.9. +# +# The mean m is then 7.2 / 13 = 0.553846 approx, and the variance is +# the sum for each of the 13 (partly fictitious) values v of (v-m)^2, +# divided by 13. This works out as 0.0994083 ish. +# +0.000000000,9.750000000,variance,0.0994083,"(variance, continuous-time average)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-grid-fsr-max.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +0.000000000,9.750000000,max,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1,"(maximum value)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/expected/testplug-grid-fsr-min.csv Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,1 @@ +0.000000000,9.750000000,min,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,"(minimum value)"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-summaries/test-summaries-testplugin.sh Fri Mar 18 15:15:55 2016 +0000 @@ -0,0 +1,36 @@ +#!/bin/bash + +. ../include.sh + +infile=$audiopath/3clicks8.wav +tmpfile=$mypath/tmp_1_$$ +tmpfile2=$mypath/tmp_2_$$ + +trap "rm -f $tmpfile $tmpfile2" 0 + +for output in curve-vsr grid-fsr; do + + for summary in min max mean median mode sum variance sd count; do + + # grid-fsr is bulkier, and we're only really concerned that + # we're getting a sane result per bin, so just do min and max + # there + if [ "$output" = "grid-fsr" ]; then + case "$summary" in + mean|median|mode|sum|variance|sd|count) continue;; + esac + fi + + id="$testplug:$output" + expected="$mypath/expected/testplug-$output-$summary.csv" + + cat "$expected" | grep -v '^#' > "$tmpfile2" + + $r -d $id -w csv --csv-stdout -S $summary --summary-only --csv-omit-filename $infile > $tmpfile 2>/dev/null || \ + fail "Fails to run transform id $id with summary type $summary" + + csvcompare "$tmpfile" "$tmpfile2" || + faildiff "Output mismatch for output $output with summary type $summary" "$tmpfile" "$tmpfile2" + + done +done
--- a/tests/test-summaries/test-summaries.sh Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/test-summaries/test-summaries.sh Fri Mar 18 15:15:55 2016 +0000 @@ -83,5 +83,6 @@ compare $tmpcanonical $expcanonical || \ faildiff "Output mismatch against expected $sexpected.n3 for canonicalised version of transform $stransform" $tmpcanonical $expcanonical -exit 0 +bash "$mypath/test-summaries-testplugin.sh" +
--- a/tests/test.sh Fri Mar 18 15:15:37 2016 +0000 +++ b/tests/test.sh Fri Mar 18 15:15:55 2016 +0000 @@ -5,22 +5,23 @@ for x in \ supportprogs \ helpfulflags \ + parse-errors \ transforms-basic \ audioformat \ vamp-test-plugin \ as-advertised \ - rdf-writer \ - rdf-destinations \ + summaries \ + multiple-audio \ csv-writer \ csv-destinations \ lab-writer \ lab-destinations \ + rdf-writer \ + rdf-destinations \ midi-writer \ midi-destinations \ jams-writer \ jams-destinations \ - summaries \ - multiple-audio \ ; do echo -n "$x: "