[SCM] vamp-plugin-sdk/master: New upstream version 2.7.1~repack0

mira-guest at users.alioth.debian.org mira-guest at users.alioth.debian.org
Sun Jun 25 22:36:47 UTC 2017


The following commit has been merged in the master branch:
commit 6a98842ee865449b4ef53a030754a9d6d30a4c7c
Author: Jaromír Mikeš <mira.mikes at seznam.cz>
Date:   Mon Jun 26 00:00:06 2017 +0200

    New upstream version 2.7.1~repack0

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b6b49be
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,25 @@
+dist:
+  - trusty
+
+language:
+  - cpp
+
+sudo:
+  - false
+
+os:
+  - linux
+  - osx
+
+addons:
+  apt:
+    packages:
+      - libsndfile-dev
+      
+before_install:
+  - ( cd ../ ; hg clone https://code.soundsoftware.ac.uk/hg/vamp-test-plugin )
+  - if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then brew install libsndfile ; fi
+
+script:
+  - if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then make -f build/Makefile.osx test ; else ./test/run-test-plugin-regression.sh ; fi
+
diff --git a/CHANGELOG b/CHANGELOG
index cceb32d..ba3617e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,23 @@
 
+Version 2.7.1, 2017-03-06 (maintenance release)
+
+  * Fix inclusion mechanism for FFTs which could cause a host
+    application to crash in certain circumstances due to
+    conflicting versions of C-linkage symbols
+
+Version 2.7, 2017-02-24 (maintenance and minor feature release)
+
+  * Add ability to PluginLoader to list plugins only in (or not in)
+    certain library files
+  * Fix fixed-sample-rate output timestamps in printout from the
+    simple host, and add regression test script using test plugin
+  * Switch the convenience FFT interface for plugin usage from the
+    very slow reference implementation previously provided, to the
+    somewhat faster KissFFT
+  * Add a top-secret compiler flag to switch internal FFTs to single-
+    precision only
+  * Fix some small but long-standing memory leaks and minor bugs
+
 Version 2.6, 2015-06-16 (maintenance and minor feature release)
 
   * Add a simple C-linkage API for plugin library discovery and
diff --git a/COPYING b/COPYING
index 309cbf7..13262ac 100644
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,7 @@
 
     Vamp Plugin SDK  
     Copyright (c) 2005-2006 Chris Cannam
-    Copyright (c) 2006-2015 Queen Mary, University of London
+    Copyright (c) 2006-2017 Queen Mary, University of London
 
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation
@@ -28,3 +28,38 @@
     use or other dealings in this Software without prior written
     authorization.
 
+The KissFFT code in src/vamp-sdk/ext is distributed under the following licence:
+
+    Copyright (c) 2003-2010 Mark Borgerding
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the author nor the names of any contributors may be used
+      to endorse or promote products derived from this software
+      without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+    TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
diff --git a/INSTALL b/INSTALL
index 4152528..4ec566f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,8 +6,6 @@ Compiling and Installing the SDK and Examples
 
  * Mac OS/X: Please read build/README.osx
 
- * Solaris: Please read build/README.osol
-
  * Linux: Please read build/README.linux
 
  * Windows cross-compiling from Linux: Try build/Makefile.mingw32
diff --git a/Makefile.in b/Makefile.in
index 4bab5ab..bc6eea8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -41,7 +41,7 @@ default:	@TARGETS@
 CC		= @CC@
 CXX		= @CXX@
 CFLAGS		= @CFLAGS@
-CXXFLAGS	= -I. @CXXFLAGS@ @SNDFILE_CFLAGS@
+CXXFLAGS	= -I. @CXXFLAGS@ @SNDFILE_CFLAGS@ 
 
 # ar, ranlib
 #
@@ -78,13 +78,13 @@ INSTALL_SDK_LIBS	  = $(INSTALL_PREFIX)/lib
 INSTALL_PLUGINS		  = $(INSTALL_PREFIX)/lib/vamp
 INSTALL_BINARIES	  = $(INSTALL_PREFIX)/bin 
 
-INSTALL_SDK_LIBNAME	  = libvamp-sdk.so.2.5.0
+INSTALL_SDK_LIBNAME	  = libvamp-sdk.so.2.7.0
 INSTALL_SDK_LINK_ABI	  = libvamp-sdk.so.2
 INSTALL_SDK_LINK_DEV	  = libvamp-sdk.so
 INSTALL_SDK_STATIC        = libvamp-sdk.a
 INSTALL_SDK_LA            = libvamp-sdk.la
 
-INSTALL_HOSTSDK_LIBNAME   = libvamp-hostsdk.so.3.5.0
+INSTALL_HOSTSDK_LIBNAME   = libvamp-hostsdk.so.3.7.0
 INSTALL_HOSTSDK_LINK_ABI  = libvamp-hostsdk.so.3
 INSTALL_HOSTSDK_LINK_DEV  = libvamp-hostsdk.so
 INSTALL_HOSTSDK_STATIC    = libvamp-hostsdk.a
@@ -104,15 +104,31 @@ HOSTSDK_DYNAMIC_LDFLAGS	= $(DYNAMIC_LDFLAGS) -Wl,-soname=$(INSTALL_HOSTSDK_LINK_
 PLUGIN_LDFLAGS		= $(DYNAMIC_LDFLAGS) -Wl,--version-script=build/vamp-plugin.map
 
 
-## For OS/X with g++:
-#DYNAMIC_LDFLAGS		= -dynamiclib
-#PLUGIN_LDFLAGS			= $(DYNAMIC_LDFLAGS)
-#SDK_DYNAMIC_LDFLAGS		= $(DYNAMIC_LDFLAGS)
-#HOSTSDK_DYNAMIC_LDFLAGS	= $(DYNAMIC_LDFLAGS)
+# Adapt install details when found to be running on OSX (thanks to David O)
+uname_S = $(shell uname -s)
+ifeq ($(uname_S),Darwin)
 
+	DYNAMIC_LDFLAGS		  = -dynamiclib
+	SDK_DYNAMIC_LDFLAGS	  = $(DYNAMIC_LDFLAGS)
+	HOSTSDK_DYNAMIC_LDFLAGS	  = $(DYNAMIC_LDFLAGS)
+	PLUGIN_LDFLAGS		  = $(DYNAMIC_LDFLAGS) -exported_symbols_list build/vamp-plugin.list
 
-### End of user-serviceable parts
+	INSTALL_HOSTSDK_LIBNAME   = libvamp-hostsdk.3.7.0.dylib
+	INSTALL_HOSTSDK_LINK_ABI  = libvamp-hostsdk.3.dylib
+
+# The OS X linker doesn't allow you to request static linkage when
+# linking by library search path, if the same library name is found in
+# both static and dynamic versions. So if we install both static and
+# dynamic, the static library will never be used. That's OK for the
+# host SDK, but we do want plugins to get static linkage of the plugin
+# SDK. So install the dynamic version under a different name.
+	INSTALL_SDK_LIBNAME	  = libvamp-sdk-dynamic.2.7.0.dylib
+	INSTALL_SDK_LINK_ABI	  = libvamp-sdk-dynamic.2.dylib
 
+endif
+
+
+### End of user-serviceable parts
 
 API_HEADERS	= \
 		$(APIDIR)/vamp.h
@@ -130,13 +146,13 @@ HOSTSDK_HEADERS	= \
 		$(HOSTSDKDIR)/Plugin.h \
 		$(HOSTSDKDIR)/PluginBase.h \
 		$(HOSTSDKDIR)/PluginHostAdapter.h \
-		$(HOSTSDKDIR)/RealTime.h \
 		$(HOSTSDKDIR)/PluginBufferingAdapter.h \
 		$(HOSTSDKDIR)/PluginChannelAdapter.h \
 		$(HOSTSDKDIR)/PluginInputDomainAdapter.h \
 		$(HOSTSDKDIR)/PluginLoader.h \
 		$(HOSTSDKDIR)/PluginSummarisingAdapter.h \
 		$(HOSTSDKDIR)/PluginWrapper.h \
+		$(HOSTSDKDIR)/RealTime.h \
 		$(HOSTSDKDIR)/hostguard.h \
 		$(HOSTSDKDIR)/host-c.h \
 		$(HOSTSDKDIR)/vamp-hostsdk.h
@@ -371,7 +387,7 @@ src/vamp-sdk/PluginAdapter.o: vamp-sdk/PluginAdapter.h vamp/vamp.h
 src/vamp-sdk/PluginAdapter.o: vamp-sdk/Plugin.h vamp-sdk/PluginBase.h
 src/vamp-sdk/PluginAdapter.o: vamp-sdk/plugguard.h vamp-sdk/RealTime.h
 src/vamp-sdk/RealTime.o: ./vamp-sdk/RealTime.h vamp-sdk/plugguard.h
-src/vamp-sdk/FFT.o: src/vamp-sdk/FFT.cpp vamp-sdk/FFT.h src/vamp-sdk/FFTimpl.cpp
+src/vamp-sdk/FFT.o: src/vamp-sdk/FFT.cpp vamp-sdk/FFT.h 
 src/vamp-hostsdk/PluginBufferingAdapter.o: ./vamp-hostsdk/PluginBufferingAdapter.h
 src/vamp-hostsdk/PluginBufferingAdapter.o: ./vamp-hostsdk/PluginWrapper.h
 src/vamp-hostsdk/PluginBufferingAdapter.o: ./vamp-hostsdk/Plugin.h
@@ -397,7 +413,6 @@ src/vamp-hostsdk/PluginInputDomainAdapter.o: vamp-sdk/PluginBase.h
 src/vamp-hostsdk/PluginInputDomainAdapter.o: vamp-sdk/plugguard.h
 src/vamp-hostsdk/PluginInputDomainAdapter.o: vamp-sdk/RealTime.h
 src/vamp-hostsdk/PluginInputDomainAdapter.o: vamp-sdk/FFT.h
-src/vamp-hostsdk/PluginInputDomainAdapter.o: src/vamp-sdk/FFTimpl.cpp
 src/vamp-hostsdk/PluginLoader.o: ./vamp-hostsdk/PluginHostAdapter.h
 src/vamp-hostsdk/PluginLoader.o: vamp/vamp.h vamp-sdk/Plugin.h
 src/vamp-hostsdk/PluginLoader.o: vamp-sdk/PluginBase.h
diff --git a/README b/README
index 05802bd..c4fe9b3 100644
--- a/README
+++ b/README
@@ -9,7 +9,10 @@ An API for audio analysis and feature extraction plugins.
 Vamp is an API for C and C++ plugins that process sampled audio data
 to produce descriptive output (measurements or semantic observations).
 
-This is version 2.6 of the Vamp plugin Software Development Kit.
+This is version 2.7.1 of the Vamp plugin Software Development Kit.
+
+Plugins and hosts built with this SDK are binary compatible with those
+built using any version 2.0 or newer of the SDK.
 
 Plugins and hosts built with this SDK are binary compatible with those
 built using version 1.0 of the SDK, with certain restrictions.  See
@@ -248,9 +251,12 @@ Authors
 Vamp and the Vamp SDK were designed and made at the Centre for Digital
 Music at Queen Mary, University of London.
 
-The SDK was written by Chris Cannam, copyright (c) 2005-2015
+The SDK was written by Chris Cannam, copyright (c) 2005-2017
 Chris Cannam and QMUL.
 
+The SDK incorporates KissFFT code, copyright (c) 2003-2010 Mark
+Borgerding.
+
 Mark Sandler and Christian Landone provided ideas and direction, and
 Mark Levy, Dan Stowell, Martin Gasser and Craig Sapp provided testing
 and other input for the 1.0 API and SDK.  The API also uses some ideas
diff --git a/build/Doxyfile b/build/Doxyfile
index f9ff494..7e10016 100644
--- a/build/Doxyfile
+++ b/build/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME           = VampPluginSDK
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 2.5
+PROJECT_NUMBER         = 2.7.1
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
diff --git a/build/Makefile.osx b/build/Makefile.osx
index 203d993..fcb21e1 100644
--- a/build/Makefile.osx
+++ b/build/Makefile.osx
@@ -70,11 +70,11 @@ ARCHFLAGS ?= -mmacosx-version-min=$(MINVERSION) -arch x86_64 -stdlib=libc++
 # Compile flags
 #
 CFLAGS		+= $(ARCHFLAGS) -fPIC
-CXXFLAGS	+= $(ARCHFLAGS) -O2 -Wall -I. -fPIC
+CXXFLAGS	+= $(ARCHFLAGS) -O2 -Wall -I. -I/usr/local/include -fPIC
 
 # Link flags common to all link targets
 #
-LDFLAGS		+= $(ARCHFLAGS) 
+LDFLAGS		+= $(ARCHFLAGS) -L/usr/local/lib
 
 # ar, ranlib
 #
diff --git a/build/Makefile.osx.106 b/build/Makefile.osx.106
index 18f6b96..d845ef9 100644
--- a/build/Makefile.osx.106
+++ b/build/Makefile.osx.106
@@ -162,6 +162,7 @@ HOSTSDK_HEADERS	= \
 		$(HOSTSDKDIR)/PluginSummarisingAdapter.h \
 		$(HOSTSDKDIR)/PluginWrapper.h \
 		$(HOSTSDKDIR)/hostguard.h \
+		$(HOSTSDKDIR)/host-c.h \
 		$(HOSTSDKDIR)/vamp-hostsdk.h
 
 SDK_OBJECTS	= \
diff --git a/build/README.msvc b/build/README.msvc
index d81c438..b786268 100644
--- a/build/README.msvc
+++ b/build/README.msvc
@@ -2,38 +2,60 @@
 The Vamp Plugin SDK -- Platform Notes for Visual C++ on Windows
 ===============================================================
 
-Visual C++ Project Files
-------------------------
+This version of the SDK is contains project files for Visual C++ 2013
+or newer. You can build the SDK in either 32-bit or 64-bit (x64) mode,
+but remember that a 32-bit host generally cannot load 64-bit plugins.
 
-Three Visual C++ project files are included with the SDK:
 
- - build/VampPluginSDK.vcproj
+Visual C++ Projects and Solution Files
+--------------------------------------
+
+Two Visual C++ solution files are included:
+
+ - build/VampSDK.sln
+
+   Builds the plugin SDK and the example plugins.
+   See the VampPluginSDK and VampExamplePlugins projects below.
+
+ - build/VampHostSDK.sln
+
+   Builds the host SDK and the simple-host command-line application.
+   See the VampHostSDK and VampSimpleHost projects below.
+   Note that the VampSimpleHost requires the libsndfile library; if
+   you want to build without that, use the VampHostSDK project rather
+   than this solution.
+
+Four Visual C++ project files are included:
+
+ - build/VampPluginSDK.vcxproj
 
    This builds the plugin SDK into a single static library, but does
    not build the example plugins, the host SDK, or the host.  (We
    recommend using static linkage for the SDK rather than distributing
    it as a DLL, particularly when building plugins.)
 
- - build/VampHostSDK.vcproj
-
-   This builds the host SDK into a single static library, but does not
-   build the plugin SDK, example plugins, or host.
-
- - build/VampExamplePlugins.vcproj
+ - build/VampExamplePlugins.vcxproj
 
    This builds the example plugins DLL, but does not build the plugin
    or host SDKs or the host.  You don't need to build the plugin SDK
    before this, because this project simply includes the plugin SDK
    files rather than using the library.
 
+ - build/VampHostSDK.vcxproj
+
+   This builds the host SDK into a single static library, but does not
+   build the plugin SDK, example plugins, or host.
+
+ - build/VampSimpleHost.vcxproj
+
+   This builds the simple host command line program. You must have
+   the libsndfile library installed in order to build this project.
+
 Of course, when using Visual Studio or another IDE to build a plugin
 or host using the SDK, you may simply add the .h and .cpp files in the
 vamp-sdk or vamp-hostsdk directories to your existing project.  This
 is the approach taken in the VampExamplePlugins project.
 
-As the command-line host has additional library dependencies (namely
-libsndfile), no pre-packaged project is included to build it.
-
 
 Installing the Example Plugins
 ------------------------------
@@ -45,10 +67,19 @@ copy the files
 and
    examples\vamp-example-plugins.cat
 
-to
+to the appropriate location as follows:
+
+ * For 32-bit plugins running on a 32-bit system, and
+   for 64-bit plugins running on a 64-bit system
 
    C:\Program Files\Vamp Plugins
 
+ * For 32-bit plugins running on a 64-bit system
+
+   C:\Program Files\Vamp Plugins (x86)
+
+You cannot use 64-bit plugins on a 32-bit system.
+
 
 Plugin Linkage
 --------------
@@ -61,13 +92,13 @@ One nice tidy way to achieve this with Visual Studio is to add the
 linker option /EXPORT:vampGetPluginDescriptor to your project.  (All
 of the other symbols will be properly hidden, because that is the
 default for the Visual Studio linker.)  The included example plugins
-project in build/VampExamplePlugins.vcproj does this.
+project in build/VampExamplePlugins.vcxproj does this.
 
 Alternatively, you may modify vamp/vamp.h to add the
 __declspec(dllexport) attribute to the vampGetPluginDescriptor
 declaration.  This is not present by default, because it isn't
-portable and, as we only want one symbol exported, the above linker
-option works equally well without code changes.
+portable among compilers and, as we only want one symbol exported, the
+above linker option works equally well without code changes.
 
 (If you don't take at least one of these actions, your plugin library
 simply will not load in any host.)
diff --git a/build/README.osx b/build/README.osx
index 3a4fd10..55b7bcb 100644
--- a/build/README.osx
+++ b/build/README.osx
@@ -23,13 +23,13 @@ To build the SDK, example plugins, and command-line host:
 To build only the SDK and example plugins (for example if you do not
 have libsndfile installed):
 
- $ make -f build/Makefile.osx sdk examples
+ $ make -f build/Makefile.osx sdk plugins
 
 See the comments at the top of Makefile.osx for more information about
 the libraries and other targets that are built in this way.
 
-If you are using an IDE such as Xcode, you may prefer to simply add
-the vamp-sdk and src/vamp-sdk (for plugins) or vamp-hostsdk and
+If you are using an IDE such as Xcode, you may prefer to add the
+vamp-sdk and src/vamp-sdk (for plugins) or vamp-hostsdk and
 src/vamp-hostsdk (for hosts) directories to your existing project.
 
 If you are using OS/X 10.6 or older, you could try Makefile.osx.106
diff --git a/build/VampExamplePlugins.sln b/build/VampExamplePlugins.sln
deleted file mode 100644
index 96afc9c..0000000
--- a/build/VampExamplePlugins.sln
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2012 for Windows Desktop
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampExamplePlugins", "VampExamplePlugins.vcxproj", "{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Debug|Win32.Build.0 = Debug|Win32
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Debug|x64.ActiveCfg = Debug|x64
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Debug|x64.Build.0 = Debug|x64
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|Win32.ActiveCfg = Release|Win32
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|Win32.Build.0 = Release|Win32
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|x64.ActiveCfg = Release|x64
-		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/build/VampExamplePlugins.vcproj b/build/VampExamplePlugins.vcproj
deleted file mode 100644
index 5201d55..0000000
--- a/build/VampExamplePlugins.vcproj
+++ /dev/null
@@ -1,273 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="VampExamplePlugins"
-	ProjectGUID="{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}"
-	RootNamespace="VampExamplePlugins"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="0"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="Debug"
-			IntermediateDirectory="Debug"
-			ConfigurationType="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories=""$(ProjectDir)/..""
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;VAMPEXAMPLEPLUGINS_EXPORTS"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				Detect64BitPortabilityProblems="true"
-				DebugInformationFormat="4"
-				DisableSpecificWarnings="4996"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:vampGetPluginDescriptor"
-				OutputFile="$(OutDir)\vamp-example-plugins.dll"
-				LinkIncremental="2"
-				GenerateDebugInformation="true"
-				SubSystem="2"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="Release"
-			IntermediateDirectory="Release"
-			ConfigurationType="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""$(ProjectDir)/..""
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;VAMPEXAMPLEPLUGINS_EXPORTS;"
-				RuntimeLibrary="2"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				Detect64BitPortabilityProblems="true"
-				DebugInformationFormat="3"
-				DisableSpecificWarnings="4996"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:vampGetPluginDescriptor"
-				OutputFile="$(OutDir)\vamp-example-plugins.dll"
-				LinkIncremental="2"
-				GenerateDebugInformation="true"
-				SubSystem="2"
-				OptimizeReferences="2"
-				EnableCOMDATFolding="2"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-			<File
-				RelativePath="..\examples\AmplitudeFollower.h"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\FixedTempoEstimator.h"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\PercussionOnsetDetector.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\plugguard.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\Plugin.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\PluginAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\PluginBase.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\RealTime.h"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\SpectralCentroid.h"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\PowerSpectrum.h"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\ZeroCrossing.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\examples\AmplitudeFollower.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\FixedTempoEstimator.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\PercussionOnsetDetector.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-sdk\PluginAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\plugins.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-sdk\RealTime.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\SpectralCentroid.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\PowerSpectrum.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\examples\ZeroCrossing.cpp"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/build/VampExamplePlugins.vcxproj b/build/VampExamplePlugins.vcxproj
index 4d9ab0b..813ea7c 100644
--- a/build/VampExamplePlugins.vcxproj
+++ b/build/VampExamplePlugins.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
@@ -22,23 +22,24 @@
     <ProjectGuid>{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}</ProjectGuid>
     <RootNamespace>VampExamplePlugins</RootNamespace>
     <Keyword>Win32Proj</Keyword>
+    <ProjectName>VampExamplePlugins</ProjectName>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
diff --git a/build/VampHostSDK.sln b/build/VampHostSDK.sln
index a12a602..ce5805a 100644
--- a/build/VampHostSDK.sln
+++ b/build/VampHostSDK.sln
@@ -1,24 +1,49 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2012 for Windows Desktop
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampHostSDK", "VampHostSDK.vcxproj", "{3875EF8B-14E8-4825-B2C1-A8B869C336F5}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampSimpleHost", "VampSimpleHost.vcxproj", "{6F6F2651-E7B2-42B2-8053-556FEB50A552}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3875EF8B-14E8-4825-B2C1-A8B869C336F5} = {3875EF8B-14E8-4825-B2C1-A8B869C336F5}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Mixed Platforms = Debug|Mixed Platforms
 		Debug|Win32 = Debug|Win32
 		Debug|x64 = Debug|x64
+		Release|Mixed Platforms = Release|Mixed Platforms
 		Release|Win32 = Release|Win32
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Mixed Platforms.Build.0 = Debug|Win32
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Win32.ActiveCfg = Debug|Win32
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Win32.Build.0 = Debug|Win32
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|x64.ActiveCfg = Debug|x64
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|x64.Build.0 = Debug|x64
+		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Mixed Platforms.Build.0 = Release|Win32
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Win32.ActiveCfg = Release|Win32
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Win32.Build.0 = Release|Win32
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|x64.ActiveCfg = Release|x64
 		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|x64.Build.0 = Release|x64
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Win32.Build.0 = Debug|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|x64.ActiveCfg = Debug|x64
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|x64.Build.0 = Debug|x64
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Win32.ActiveCfg = Release|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Win32.Build.0 = Release|Win32
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|x64.ActiveCfg = Release|x64
+		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/build/VampHostSDK.vcproj b/build/VampHostSDK.vcproj
deleted file mode 100644
index 65ccdd9..0000000
--- a/build/VampHostSDK.vcproj
+++ /dev/null
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="VampHostSDK"
-	ProjectGUID="{3875EF8B-14E8-4825-B2C1-A8B869C336F5}"
-	RootNamespace="VampHostSDK"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="0"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="Debug"
-			IntermediateDirectory="Debug"
-			ConfigurationType="4"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories=".."
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_USE_MATH_DEFINES"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				Detect64BitPortabilityProblems="true"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="Release"
-			IntermediateDirectory="Release"
-			ConfigurationType="4"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".."
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
-				RuntimeLibrary="2"
-				UsePrecompiledHeader="0"
-				WarningLevel="2"
-				Detect64BitPortabilityProblems="false"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-			<File
-				RelativePath="..\vamp-hostsdk\hostguard.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\Plugin.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginBase.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginBufferingAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginChannelAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginHostAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginInputDomainAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginLoader.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginSummarisingAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\PluginWrapper.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\RealTime.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\host-c.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-hostsdk\vamp-hostsdk.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\src\vamp-hostsdk\Files.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginBufferingAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginChannelAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginHostAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginInputDomainAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginLoader.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginSummarisingAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\PluginWrapper.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\RealTime.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-hostsdk\host-c.cpp"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/build/VampHostSDK.vcxproj b/build/VampHostSDK.vcxproj
index 7ef3a8c..fdbc332 100644
--- a/build/VampHostSDK.vcxproj
+++ b/build/VampHostSDK.vcxproj
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
@@ -26,19 +26,19 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
@@ -142,4 +142,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/build/VampPluginSDK.sln b/build/VampPluginSDK.sln
deleted file mode 100644
index abf1e9e..0000000
--- a/build/VampPluginSDK.sln
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2012 for Windows Desktop
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampPluginSDK", "VampPluginSDK.vcxproj", "{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|Win32.ActiveCfg = Debug|Win32
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|Win32.Build.0 = Debug|Win32
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|x64.ActiveCfg = Debug|x64
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|x64.Build.0 = Debug|x64
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Release|Win32.ActiveCfg = Release|Win32
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Release|Win32.Build.0 = Release|Win32
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Release|x64.ActiveCfg = Release|x64
-		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/build/VampPluginSDK.vcproj b/build/VampPluginSDK.vcproj
deleted file mode 100644
index 0bf16bc..0000000
--- a/build/VampPluginSDK.vcproj
+++ /dev/null
@@ -1,205 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="VampPluginSDK"
-	ProjectGUID="{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}"
-	RootNamespace="VampPluginSDK"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="0"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="Debug"
-			IntermediateDirectory="Debug"
-			ConfigurationType="4"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories=".."
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_USE_MATH_DEFINES"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				Detect64BitPortabilityProblems="true"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="Release"
-			IntermediateDirectory="Release"
-			ConfigurationType="4"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".."
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_USE_MATH_DEFINES"
-				RuntimeLibrary="2"
-				UsePrecompiledHeader="0"
-				WarningLevel="2"
-				Detect64BitPortabilityProblems="false"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-			<File
-				RelativePath="..\vamp-sdk\plugguard.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\Plugin.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\PluginAdapter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\PluginBase.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\FFT.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\RealTime.h"
-				>
-			</File>
-			<File
-				RelativePath="..\vamp-sdk\vamp-sdk.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\src\vamp-sdk\PluginAdapter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-sdk\FFT.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\src\vamp-sdk\RealTime.cpp"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/build/VampPluginSDK.vcxproj b/build/VampPluginSDK.vcxproj
index 47eac47..de72bd7 100644
--- a/build/VampPluginSDK.vcxproj
+++ b/build/VampPluginSDK.vcxproj
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
@@ -26,19 +26,19 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
@@ -129,4 +129,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/build/VampSDK.sln b/build/VampSDK.sln
index ccbabd9..ca11a04 100644
--- a/build/VampSDK.sln
+++ b/build/VampSDK.sln
@@ -1,8 +1,8 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2012 for Windows Desktop
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampHostSDK", "VampHostSDK.vcxproj", "{3875EF8B-14E8-4825-B2C1-A8B869C336F5}"
-EndProject
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampPluginSDK", "VampPluginSDK.vcxproj", "{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampExamplePlugins", "VampExamplePlugins.vcxproj", "{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}"
@@ -10,11 +10,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampExamplePlugins", "VampE
 		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5} = {65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampSimpleHost", "VampSimpleHost.vcxproj", "{6F6F2651-E7B2-42B2-8053-556FEB50A552}"
-	ProjectSection(ProjectDependencies) = postProject
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5} = {3875EF8B-14E8-4825-B2C1-A8B869C336F5}
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Mixed Platforms = Debug|Mixed Platforms
@@ -25,18 +20,6 @@ Global
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Mixed Platforms.Build.0 = Debug|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Win32.ActiveCfg = Debug|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|Win32.Build.0 = Debug|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|x64.ActiveCfg = Debug|x64
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Debug|x64.Build.0 = Debug|x64
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Mixed Platforms.ActiveCfg = Release|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Mixed Platforms.Build.0 = Release|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Win32.ActiveCfg = Release|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|Win32.Build.0 = Release|Win32
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|x64.ActiveCfg = Release|x64
-		{3875EF8B-14E8-4825-B2C1-A8B869C336F5}.Release|x64.Build.0 = Release|x64
 		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
 		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|Mixed Platforms.Build.0 = Debug|Win32
 		{65EFA7D7-C3CE-4D29-BE96-E27F2B5979A5}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -61,18 +44,6 @@ Global
 		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|Win32.Build.0 = Release|Win32
 		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|x64.ActiveCfg = Release|x64
 		{B3D1F5A4-4571-4D20-B184-8ACD03D6C97A}.Release|x64.Build.0 = Release|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Mixed Platforms.Build.0 = Debug|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Win32.Build.0 = Debug|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|x64.ActiveCfg = Debug|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|x64.Build.0 = Debug|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Mixed Platforms.ActiveCfg = Release|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Mixed Platforms.Build.0 = Release|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Win32.ActiveCfg = Release|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Win32.Build.0 = Release|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|x64.ActiveCfg = Release|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/build/VampSimpleHost.sln b/build/VampSimpleHost.sln
deleted file mode 100644
index 9e96d48..0000000
--- a/build/VampSimpleHost.sln
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2012 for Windows Desktop
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VampSimpleHost", "VampSimpleHost.vcxproj", "{6F6F2651-E7B2-42B2-8053-556FEB50A552}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|Win32.Build.0 = Debug|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|x64.ActiveCfg = Debug|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Debug|x64.Build.0 = Debug|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Win32.ActiveCfg = Release|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|Win32.Build.0 = Release|Win32
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|x64.ActiveCfg = Release|x64
-		{6F6F2651-E7B2-42B2-8053-556FEB50A552}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/build/VampSimpleHost.vcxproj b/build/VampSimpleHost.vcxproj
index f62a8dc..a4873a4 100644
--- a/build/VampSimpleHost.vcxproj
+++ b/build/VampSimpleHost.vcxproj
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
@@ -27,26 +27,26 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
@@ -154,4 +154,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/build/docker/Dockerfile_v2.7_ubuntu1404 b/build/docker/Dockerfile_v2.7_ubuntu1404
new file mode 100644
index 0000000..f92af13
--- /dev/null
+++ b/build/docker/Dockerfile_v2.7_ubuntu1404
@@ -0,0 +1,26 @@
+FROM ubuntu:14.04
+MAINTAINER Chris Cannam <cannam at all-day-breakfast.com>
+RUN apt-get update && \
+    apt-get install -y \
+    build-essential \
+    libsndfile-dev \
+    git \
+    mercurial
+RUN gcc --version
+RUN apt-get clean && rm -rf /var/lib/apt/lists/*
+RUN locale-gen en_US.UTF-8
+ENV LANG en_US.UTF-8  
+ENV LANGUAGE en_US:en  
+ENV LC_ALL en_US.UTF-8
+RUN git clone --branch vamp-plugin-sdk-v2.7 https://github.com/c4dm/vamp-plugin-sdk
+RUN hg clone https://code.soundsoftware.ac.uk/hg/vamp-test-plugin
+WORKDIR vamp-plugin-sdk
+RUN ./configure && make
+WORKDIR ../vamp-test-plugin
+RUN make -f Makefile.linux
+WORKDIR ../vamp-plugin-sdk
+RUN test/run-test-plugin-regression.sh
+RUN mkdir vamp-plugin-sdk-2.7-binaries-amd64-gcc4-linux
+RUN cp libvamp-sdk.a libvamp-hostsdk.a host/vamp-simple-host rdf/generator/vamp-rdf-template-generator vamp-plugin-sdk-2.7-binaries-amd64-gcc4-linux
+RUN tar cvzf vamp-plugin-sdk-2.7-binaries-amd64-gcc4-linux.tar.gz vamp-plugin-sdk-2.7-binaries-amd64-gcc4-linux
+RUN tar cvf output.tar *.tar.gz && cp output.tar ..
diff --git a/build/docker/Dockerfile_v2.7_ubuntu1604 b/build/docker/Dockerfile_v2.7_ubuntu1604
new file mode 100644
index 0000000..d99b250
--- /dev/null
+++ b/build/docker/Dockerfile_v2.7_ubuntu1604
@@ -0,0 +1,26 @@
+FROM ubuntu:16.04
+MAINTAINER Chris Cannam <cannam at all-day-breakfast.com>
+RUN apt-get update && \
+    apt-get install -y \
+    build-essential \
+    libsndfile-dev \
+    git \
+    mercurial
+RUN gcc --version
+RUN apt-get clean && rm -rf /var/lib/apt/lists/*
+RUN locale-gen en_US.UTF-8
+ENV LANG en_US.UTF-8  
+ENV LANGUAGE en_US:en  
+ENV LC_ALL en_US.UTF-8
+RUN git clone --branch vamp-plugin-sdk-v2.7 https://github.com/c4dm/vamp-plugin-sdk
+RUN hg clone https://code.soundsoftware.ac.uk/hg/vamp-test-plugin
+WORKDIR vamp-plugin-sdk
+RUN ./configure && make
+WORKDIR ../vamp-test-plugin
+RUN make -f Makefile.linux
+WORKDIR ../vamp-plugin-sdk
+RUN test/run-test-plugin-regression.sh
+RUN mkdir vamp-plugin-sdk-2.7-binaries-amd64-gcc5-linux
+RUN cp libvamp-sdk.a libvamp-hostsdk.a host/vamp-simple-host rdf/generator/vamp-rdf-template-generator vamp-plugin-sdk-2.7-binaries-amd64-gcc5-linux
+RUN tar cvzf vamp-plugin-sdk-2.7-binaries-amd64-gcc5-linux.tar.gz vamp-plugin-sdk-2.7-binaries-amd64-gcc5-linux
+RUN tar cvf output.tar *.tar.gz && cp output.tar ..
diff --git a/build/docker/build.sh b/build/docker/build.sh
new file mode 100755
index 0000000..dc9e176
--- /dev/null
+++ b/build/docker/build.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+dockerdir=./build/docker
+if [ ! -d "$dockerdir" ]; then
+    echo "Run this script from the build root"
+    exit 2
+fi
+
+version="$1"
+platform="$2"
+
+if [ -z "$platform" ] || [ -z "$version" ] || [ -n "$3" ]; then
+    echo "Usage: $0 <version> <platform>"
+    echo "where <platform> matches the suffix of the Docker file, e.g. ubuntu1604"
+    exit 2
+fi
+
+set -eu
+
+echo "Building for version $version, platform $platform"
+dockerfile="Dockerfile_v${version}_${platform}"
+
+if [ ! -f "$dockerdir/$dockerfile" ]; then
+    echo "No matching docker file $dockerfile found in $dockerdir"
+    exit 1
+fi
+
+dockertag="cannam/vamp-plugin-sdk-$platform"
+
+sudo docker build -t "$dockertag" -f "$dockerdir/$dockerfile" "$dockerdir"
+
+outdir="$dockerdir/output"
+mkdir -p "$outdir"
+
+container=$(sudo docker create "$dockertag")
+sudo docker cp "$container":output.tar "$outdir"
+sudo docker rm "$container"
+
+( cd "$outdir" ; tar xf output.tar && rm -f output.tar )
+
+echo
+echo "Done, output directory contains:"
+ls -ltr "$outdir"
diff --git a/build/libvamp-hostsdk.la.in b/build/libvamp-hostsdk.la.in
index cd17df6..707e40f 100644
--- a/build/libvamp-hostsdk.la.in
+++ b/build/libvamp-hostsdk.la.in
@@ -1,9 +1,14 @@
+# libvamp-hostsdk.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
 dlname='%LINK_ABI%'
 library_names='%LIBNAME% %LINK_ABI% %LINK_DEV%'
 old_library='%STATIC%'
 dependency_libs=''
 current=3
-age=5
+age=7
 revision=0
 installed=yes
 libdir='%LIBS%'
diff --git a/build/libvamp-sdk.la.in b/build/libvamp-sdk.la.in
index 164fb6f..1a4266a 100644
--- a/build/libvamp-sdk.la.in
+++ b/build/libvamp-sdk.la.in
@@ -1,9 +1,14 @@
+# libvamp-sdk.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
 dlname='%LINK_ABI%'
 library_names='%LIBNAME% %LINK_ABI% %LINK_DEV%'
 old_library='%STATIC%'
 dependency_libs=''
 current=2
-age=5
+age=7
 revision=0
 installed=yes
 libdir='%LIBS%'
diff --git a/build/update-version.sh b/build/update-version.sh
index 24721b3..4653e06 100644
--- a/build/update-version.sh
+++ b/build/update-version.sh
@@ -42,6 +42,12 @@ $p 's/(INSTALL_SDK_LIBNAME\s*=\s*libvamp-sdk.so).*/$1.'$sdkmajor'.'$sdkminor'.0/
 $p 's/(INSTALL_SDK_LINK_ABI\s*=\s*libvamp-sdk.so).*/$1.'$sdkmajor'/' \
     Makefile.in
 
+$p 's/(INSTALL_SDK_LIBNAME\s*=\s*libvamp-sdk-dynamic).*.dylib/$1.'$sdkmajor'.'$sdkminor'.0.dylib/' \
+    Makefile.in
+
+$p 's/(INSTALL_SDK_LINK_ABI\s*=\s*libvamp-sdk-dynamic).*.dylib/$1.'$sdkmajor'.dylib/' \
+    Makefile.in
+
 $p 's/(current)=.*/$1='$sdkmajor'/' \
     build/libvamp-sdk.la.in
 
@@ -54,6 +60,12 @@ $p 's/(INSTALL_HOSTSDK_LIBNAME\s*=\s*libvamp-hostsdk.so).*/$1.'$hostmajor'.'$hos
 $p 's/(INSTALL_HOSTSDK_LINK_ABI\s*=\s*libvamp-hostsdk.so).*/$1.'$hostmajor'/' \
     Makefile.in
 
+$p 's/(INSTALL_HOSTSDK_LIBNAME\s*=\s*libvamp-hostsdk).*.dylib/$1.'$hostmajor'.'$hostminor'.0.dylib/' \
+    Makefile.in
+
+$p 's/(INSTALL_HOSTSDK_LINK_ABI\s*=\s*libvamp-hostsdk).*.dylib/$1.'$hostmajor'.dylib/' \
+    Makefile.in
+
 $p 's/(current)=.*/$1='$hostmajor'/' \
     build/libvamp-hostsdk.la.in
 
@@ -114,4 +126,7 @@ fgrep -q 'libvamphostsdk_v_'$acs'_present' src/vamp-hostsdk/acsymbols.c || \
 $p 's/^$/\nextern void libvamphostsdk_v_'$acs'_present(void) { }/' \
     src/vamp-hostsdk/acsymbols.c
 
-echo "Done, now check with e.g. hg diff -- and don't forget to update CHANGELOG"
+echo "Done, now check changes with e.g. hg diff"
+echo "*** Don't forget to update CHANGELOG"
+echo "*** Don't forget to re-run \"aclocal -I . && autoconf\""
+
diff --git a/configure b/configure
index c0ba36d..b99e4f1 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for vamp-plugin-sdk 2.5.
+# Generated by GNU Autoconf 2.69 for vamp-plugin-sdk 2.7.1.
 #
 # Report bugs to <cannam at all-day-breakfast.com>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='vamp-plugin-sdk'
 PACKAGE_TARNAME='vamp-plugin-sdk'
-PACKAGE_VERSION='2.5'
-PACKAGE_STRING='vamp-plugin-sdk 2.5'
+PACKAGE_VERSION='2.7.1'
+PACKAGE_STRING='vamp-plugin-sdk 2.7.1'
 PACKAGE_BUGREPORT='cannam at all-day-breakfast.com'
 PACKAGE_URL=''
 
@@ -1243,7 +1243,7 @@ if test "$ac_init_help" = "long"; then
   # 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 vamp-plugin-sdk 2.5 to adapt to many kinds of systems.
+\`configure' configures vamp-plugin-sdk 2.7.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1304,7 +1304,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of vamp-plugin-sdk 2.5:";;
+     short | recursive ) echo "Configuration of vamp-plugin-sdk 2.7.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1402,7 +1402,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-vamp-plugin-sdk configure 2.5
+vamp-plugin-sdk configure 2.7.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1651,7 +1651,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by vamp-plugin-sdk $as_me 2.5, which was
+It was created by vamp-plugin-sdk $as_me 2.7.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3956,6 +3956,7 @@ if test "x$GCC" = "xyes"; then
     *[\ \	]-fPIC\ -Wall[\ \	]*) ;;
     *) CFLAGS="$CFLAGS -fPIC -Wall -Wextra" ;;
   esac
+  CXXFLAGS="$CXXFLAGS -std=c++98"
 fi
 
 
@@ -4505,7 +4506,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by vamp-plugin-sdk $as_me 2.5, which was
+This file was extended by vamp-plugin-sdk $as_me 2.7.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4558,7 +4559,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-vamp-plugin-sdk config.status 2.5
+vamp-plugin-sdk config.status 2.7.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 2e0c56e..0baed58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 
-AC_INIT(vamp-plugin-sdk, 2.5, cannam at all-day-breakfast.com)
+AC_INIT(vamp-plugin-sdk, 2.7.1, cannam at all-day-breakfast.com)
 
 AC_CONFIG_SRCDIR(vamp/vamp.h)
 AC_PROG_CXX
@@ -50,6 +50,7 @@ if test "x$GCC" = "xyes"; then
     *[\ \	]-fPIC\ -Wall[\ \	]*) ;;
     *) CFLAGS="$CFLAGS -fPIC -Wall -Wextra" ;;
   esac
+  CXXFLAGS="$CXXFLAGS -std=c++98"
 fi
 changequote([,])dnl
 
diff --git a/examples/AmplitudeFollower.cpp b/examples/AmplitudeFollower.cpp
index c94fb1c..117d030 100644
--- a/examples/AmplitudeFollower.cpp
+++ b/examples/AmplitudeFollower.cpp
@@ -199,7 +199,7 @@ float AmplitudeFollower::getParameter(std::string paramid) const
 
 AmplitudeFollower::FeatureSet
 AmplitudeFollower::process(const float *const *inputBuffers,
-                           Vamp::RealTime timestamp)
+                           Vamp::RealTime /* timestamp */)
 {
     if (m_stepSize == 0) {
 	cerr << "ERROR: AmplitudeFollower::process: "
diff --git a/host/vamp-simple-host.cpp b/host/vamp-simple-host.cpp
index 781e22b..e47ac52 100644
--- a/host/vamp-simple-host.cpp
+++ b/host/vamp-simple-host.cpp
@@ -80,7 +80,9 @@ enum Verbosity {
     PluginInformationDetailed
 };
 
-void printFeatures(int, int, int, Plugin::FeatureSet, ofstream *, bool frames);
+void printFeatures(int, int,
+                   const Plugin::OutputDescriptor &, int,
+                   const Plugin::FeatureSet &, ofstream *, bool frames);
 void transformInput(float *, size_t);
 void fft(unsigned int, bool, double *, double *, double *, double *);
 void printPluginPath(bool verbose);
@@ -364,6 +366,7 @@ int runPlugin(string myname, string soname, string id,
 
     Plugin::OutputList outputs = plugin->getOutputDescriptors();
     Plugin::OutputDescriptor od;
+    Plugin::FeatureSet features;
 
     int returnValue = 1;
     int progress = 0;
@@ -455,10 +458,11 @@ int runPlugin(string myname, string soname, string id,
 
         rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
 
+        features = plugin->process(plugbuf, rt);
+        
         printFeatures
             (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
-             sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
-             out, useFrames);
+             sfinfo.samplerate, od, outputNo, features, out, useFrames);
 
         if (sfinfo.frames > 0){
             int pp = progress;
@@ -476,9 +480,10 @@ int runPlugin(string myname, string soname, string id,
 
     rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
 
+    features = plugin->getRemainingFeatures();
+    
     printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
-                  sfinfo.samplerate, outputNo,
-                  plugin->getRemainingFeatures(), out, useFrames);
+                  sfinfo.samplerate, od, outputNo, features, out, useFrames);
 
     returnValue = 0;
 
@@ -492,26 +497,53 @@ done:
     return returnValue;
 }
 
+static double
+toSeconds(const RealTime &time)
+{
+    return time.sec + double(time.nsec + 1) / 1000000000.0;
+}
+
 void
-printFeatures(int frame, int sr, int output,
-              Plugin::FeatureSet features, ofstream *out, bool useFrames)
+printFeatures(int frame, int sr,
+              const Plugin::OutputDescriptor &output, int outputNo,
+              const Plugin::FeatureSet &features, ofstream *out, bool useFrames)
 {
-    for (unsigned int i = 0; i < features[output].size(); ++i) {
+    static int featureCount = -1;
+    
+    if (features.find(outputNo) == features.end()) return;
+    
+    for (size_t i = 0; i < features.at(outputNo).size(); ++i) {
 
+        const Plugin::Feature &f = features.at(outputNo).at(i);
+
+        bool haveRt = false;
+        RealTime rt;
+
+        if (output.sampleType == Plugin::OutputDescriptor::VariableSampleRate) {
+            rt = f.timestamp;
+            haveRt = true;
+        } else if (output.sampleType == Plugin::OutputDescriptor::FixedSampleRate) {
+            int n = featureCount + 1;
+            if (f.hasTimestamp) {
+                n = int(round(toSeconds(f.timestamp) * output.sampleRate));
+            }
+            rt = RealTime::fromSeconds(double(n) / output.sampleRate);
+            haveRt = true;
+            featureCount = n;
+        }
+        
         if (useFrames) {
 
             int displayFrame = frame;
 
-            if (features[output][i].hasTimestamp) {
-                displayFrame = RealTime::realTime2Frame
-                    (features[output][i].timestamp, sr);
+            if (haveRt) {
+                displayFrame = RealTime::realTime2Frame(rt, sr);
             }
 
             (out ? *out : cout) << displayFrame;
 
-            if (features[output][i].hasDuration) {
-                displayFrame = RealTime::realTime2Frame
-                    (features[output][i].duration, sr);
+            if (f.hasDuration) {
+                displayFrame = RealTime::realTime2Frame(f.duration, sr);
                 (out ? *out : cout) << "," << displayFrame;
             }
 
@@ -519,26 +551,24 @@ printFeatures(int frame, int sr, int output,
 
         } else {
 
-            RealTime rt = RealTime::frame2RealTime(frame, sr);
-
-            if (features[output][i].hasTimestamp) {
-                rt = features[output][i].timestamp;
+            if (!haveRt) {
+                rt = RealTime::frame2RealTime(frame, sr);
             }
 
             (out ? *out : cout) << rt.toString();
 
-            if (features[output][i].hasDuration) {
-                rt = features[output][i].duration;
+            if (f.hasDuration) {
+                rt = f.duration;
                 (out ? *out : cout) << "," << rt.toString();
             }
 
             (out ? *out : cout) << ":";
         }
 
-        for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
-            (out ? *out : cout) << " " << features[output][i].values[j];
+        for (unsigned int j = 0; j < f.values.size(); ++j) {
+            (out ? *out : cout) << " " << f.values[j];
         }
-        (out ? *out : cout) << " " << features[output][i].label;
+        (out ? *out : cout) << " " << f.label;
 
         (out ? *out : cout) << endl;
     }
diff --git a/pkgconfig/vamp-hostsdk.pc.in b/pkgconfig/vamp-hostsdk.pc.in
index 7a00be4..542e21e 100644
--- a/pkgconfig/vamp-hostsdk.pc.in
+++ b/pkgconfig/vamp-hostsdk.pc.in
@@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: vamp-hostsdk
-Version: 2.5
+Version: 2.7.1
 Description: Development library for Vamp audio analysis plugin hosts
 Libs: -L${libdir} -lvamp-hostsdk -ldl
 Cflags: -I${includedir} 
diff --git a/pkgconfig/vamp-sdk.pc.in b/pkgconfig/vamp-sdk.pc.in
index 554ef24..e25f6fc 100644
--- a/pkgconfig/vamp-sdk.pc.in
+++ b/pkgconfig/vamp-sdk.pc.in
@@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: vamp-sdk
-Version: 2.5
+Version: 2.7.1
 Description: Development library for Vamp audio analysis plugins
 Libs: -L${libdir} -lvamp-sdk
 Cflags: -I${includedir} 
diff --git a/pkgconfig/vamp.pc.in b/pkgconfig/vamp.pc.in
index 375e347..dea1a4d 100644
--- a/pkgconfig/vamp.pc.in
+++ b/pkgconfig/vamp.pc.in
@@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: vamp
-Version: 2.5
+Version: 2.7.1
 Description: An API for audio analysis and feature extraction plugins
 Libs: 
 Cflags: -I${includedir} 
diff --git a/skeleton/MyPlugin.h b/skeleton/MyPlugin.h
index dedc349..224d282 100644
--- a/skeleton/MyPlugin.h
+++ b/skeleton/MyPlugin.h
@@ -5,8 +5,8 @@
 
 
 // Remember to use a different guard symbol in each header!
-#ifndef _MY_PLUGIN_H_
-#define _MY_PLUGIN_H_
+#ifndef MY_PLUGIN_H
+#define MY_PLUGIN_H
 
 #include <vamp-sdk/Plugin.h>
 
diff --git a/src/vamp-hostsdk/Files.cpp b/src/vamp-hostsdk/Files.cpp
index 8a04dab..fd80ba9 100644
--- a/src/vamp-hostsdk/Files.cpp
+++ b/src/vamp-hostsdk/Files.cpp
@@ -66,18 +66,26 @@ using namespace std;
 vector<string>
 Files::listLibraryFiles()
 {
-    return listLibraryFilesMatching("");
+    return listLibraryFilesMatching(Filter());
 }
 
 vector<string>
-Files::listLibraryFilesMatching(string libraryName)
+Files::listLibraryFilesMatching(Filter filter)
 {
     vector<string> path = Vamp::PluginHostAdapter::getPluginPath();
     vector<string> libraryFiles;
 
-    // we match case-insensitively
-    for (size_t i = 0; i < libraryName.length(); ++i) {
-	libraryName[i] = tolower(libraryName[i]);
+    // we match case-insensitively, but only with ascii range
+    // characters (input strings are expected to be utf-8)
+    vector<string> libraryNames;
+    for (int j = 0; j < int(filter.libraryNames.size()); ++j) {
+        string n = filter.libraryNames[j];
+        for (size_t i = 0; i < n.length(); ++i) {
+            if (!(n[i] & 0x80)) {
+                n[i] = char(tolower(n[i]));
+            }
+        }
+        libraryNames.push_back(n);
     }
 
     for (size_t i = 0; i < path.size(); ++i) {
@@ -86,23 +94,53 @@ Files::listLibraryFilesMatching(string libraryName)
 
         for (vector<string>::iterator fi = files.begin();
              fi != files.end(); ++fi) {
+
+            // we match case-insensitively, but only with ascii range
+            // characters (this string is expected to be utf-8)
+            string cleaned = *fi;
+            for (size_t j = 0; j < cleaned.length(); ++j) {
+                if (!(cleaned[j] & 0x80)) {
+                    cleaned[j] = char(tolower(cleaned[j]));
+                }
+            }
+
+            // libraryName should be lacking an extension, as it is
+            // supposed to have come from the plugin key
+            string::size_type pi = cleaned.find('.');
+            if (pi != string::npos) {
+                cleaned = cleaned.substr(0, pi);
+            }
             
-            if (libraryName != "") {
-		// we match case-insensitively
-                string temp = *fi;
-                for (size_t i = 0; i < temp.length(); ++i) {
-                    temp[i] = tolower(temp[i]);
+            bool matched = false;
+
+            switch (filter.type) {
+
+            case Filter::All:
+                matched = true;
+                break;
+
+            case Filter::Matching:
+                for (int j = 0; j < int(libraryNames.size()); ++j) {
+                    if (cleaned == libraryNames[j]) {
+                        matched = true;
+                        break;
+                    }
                 }
-                // libraryName should be lacking an extension, as it
-                // is supposed to have come from the plugin key
-                string::size_type pi = temp.find('.');
-                if (pi == string::npos) {
-                    if (libraryName != temp) continue;
-                } else {
-                    if (libraryName != temp.substr(0, pi)) continue;
+                break;
+
+            case Filter::NotMatching:
+                matched = true;
+                for (int j = 0; j < int(libraryNames.size()); ++j) {
+                    if (cleaned == libraryNames[j]) {
+                        matched = false;
+                        break;
+                    }
                 }
+                break;
             }
 
+            if (!matched) continue;
+            
             string fullPath = path[i];
             fullPath = splicePath(fullPath, *fi);
 	    libraryFiles.push_back(fullPath);
@@ -118,15 +156,15 @@ Files::loadLibrary(string path)
     void *handle = 0;
 #ifdef _WIN32
 #ifdef UNICODE
-    int len = path.length() + 1; // cannot be more wchars than length in bytes of utf8 string
-    wchar_t *buffer = new wchar_t[len];
-    int rv = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), len, buffer, len);
-    if (rv <= 0) {
+    int wlen = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), path.length(), 0, 0);
+    if (wlen < 0) {
         cerr << "Vamp::HostExt: Unable to convert library path \""
              << path << "\" to wide characters " << endl;
-        delete[] buffer;
         return handle;
     }
+    wchar_t *buffer = new wchar_t[wlen+1];
+    (void)MultiByteToWideChar(CP_UTF8, 0, path.c_str(), path.length(), buffer, wlen);
+    buffer[wlen] = L'\0';
     handle = LoadLibrary(buffer);
     delete[] buffer;
 #else
@@ -182,8 +220,12 @@ Files::lcBasename(string path)
     li = basename.find('.');
     if (li != string::npos) basename = basename.substr(0, li);
 
+    // case-insensitive, but only with ascii range characters (this
+    // string is expected to be utf-8)
     for (size_t i = 0; i < basename.length(); ++i) {
-        basename[i] = tolower(basename[i]);
+        if (!(basename[i] & 0x80)) {
+            basename[i] = char(tolower(basename[i]));
+        }
     }
 
     return basename;
@@ -207,15 +249,15 @@ Files::listFiles(string dir, string extension)
 #ifdef _WIN32
     string expression = dir + "\\*." + extension;
 #ifdef UNICODE
-    int len = expression.length() + 1; // cannot be more wchars than length in bytes of utf8 string
-    wchar_t *buffer = new wchar_t[len];
-    int rv = MultiByteToWideChar(CP_UTF8, 0, expression.c_str(), len, buffer, len);
-    if (rv <= 0) {
+    int wlen = MultiByteToWideChar(CP_UTF8, 0, expression.c_str(), expression.length(), 0, 0);
+    if (wlen < 0) {
         cerr << "Vamp::HostExt: Unable to convert wildcard path \""
              << expression << "\" to wide characters" << endl;
-        delete[] buffer;
         return files;
     }
+    wchar_t *buffer = new wchar_t[wlen+1];
+    (void)MultiByteToWideChar(CP_UTF8, 0, expression.c_str(), expression.length(), buffer, wlen);
+    buffer[wlen] = L'\0';
     WIN32_FIND_DATA data;
     HANDLE fh = FindFirstFile(buffer, &data);
     if (fh == INVALID_HANDLE_VALUE) {
@@ -226,11 +268,16 @@ Files::listFiles(string dir, string extension)
     bool ok = true;
     while (ok) {
         wchar_t *fn = data.cFileName;
-        int wlen = wcslen(fn) + 1;
-        int maxlen = wlen * 6;
-        char *conv = new char[maxlen];
-        int rv = WideCharToMultiByte(CP_UTF8, 0, fn, wlen, conv, maxlen, 0, 0);
-        if (rv > 0) {
+        int wlen = wcslen(fn);
+        int len = WideCharToMultiByte(CP_UTF8, 0, fn, wlen, 0, 0, 0, 0);
+        if (len < 0) {
+            cerr << "Vamp::HostExt: Unable to convert wide char filename to utf-8" << endl;
+            break;
+        }
+        char *conv = new char[len+1];
+        (void)WideCharToMultiByte(CP_UTF8, 0, fn, wlen, conv, len, 0, 0);
+        conv[len] = '\0';
+        if (len > 0) {
             files.push_back(conv);
         }
         delete[] conv;
diff --git a/src/vamp-hostsdk/Files.h b/src/vamp-hostsdk/Files.h
index 6e3fd37..9a4ba07 100644
--- a/src/vamp-hostsdk/Files.h
+++ b/src/vamp-hostsdk/Files.h
@@ -47,7 +47,13 @@ class Files
 {
 public:
     static std::vector<std::string> listLibraryFiles();
-    static std::vector<std::string> listLibraryFilesMatching(std::string libname);
+
+    struct Filter {
+        enum { All, Matching, NotMatching } type;
+        std::vector<std::string> libraryNames;
+        Filter() : type(All) { }
+    };
+    static std::vector<std::string> listLibraryFilesMatching(Filter);
 
     static void *loadLibrary(std::string filename);
     static void unloadLibrary(void *);
diff --git a/src/vamp-hostsdk/PluginBufferingAdapter.cpp b/src/vamp-hostsdk/PluginBufferingAdapter.cpp
index a874743..7bc9379 100644
--- a/src/vamp-hostsdk/PluginBufferingAdapter.cpp
+++ b/src/vamp-hostsdk/PluginBufferingAdapter.cpp
@@ -41,6 +41,10 @@
 #include <vamp-hostsdk/PluginBufferingAdapter.h>
 #include <vamp-hostsdk/PluginInputDomainAdapter.h>
 
+#include <iostream>
+using std::cerr;
+using std::endl;
+
 using std::vector;
 using std::map;
 
@@ -477,7 +481,7 @@ PluginBufferingAdapter::Impl::initialise(size_t channels, size_t stepSize, size_
     m_buffers = new float *[m_channels];
 
     for (size_t i = 0; i < m_channels; ++i) {
-        m_queue.push_back(new RingBuffer(m_blockSize + m_inputBlockSize));
+        m_queue.push_back(new RingBuffer(int(m_blockSize + m_inputBlockSize)));
         m_buffers[i] = new float[m_blockSize];
     }
     
@@ -506,19 +510,19 @@ PluginBufferingAdapter::Impl::getOutputDescriptors() const
 
     PluginBufferingAdapter::OutputList outs = m_outputs;
 
-    for (size_t i = 0; i < outs.size(); ++i) {
+    for (int i = 0; i < int(outs.size()); ++i) {
 
         switch (outs[i].sampleType) {
 
         case OutputDescriptor::OneSamplePerStep:
             outs[i].sampleType = OutputDescriptor::FixedSampleRate;
-            outs[i].sampleRate = (1.f / m_inputSampleRate) * m_stepSize;
+            outs[i].sampleRate = m_inputSampleRate / float(m_stepSize);
             m_rewriteOutputTimes[i] = true;
             break;
             
         case OutputDescriptor::FixedSampleRate:
             if (outs[i].sampleRate == 0.f) {
-                outs[i].sampleRate = (1.f / m_inputSampleRate) * m_stepSize;
+                outs[i].sampleRate = m_inputSampleRate / float(m_stepSize);
             }
             // We actually only need to rewrite output times for
             // features that don't have timestamps already, but we
@@ -591,7 +595,7 @@ PluginBufferingAdapter::Impl::process(const float *const *inputBuffers,
     // queue the new input
     
     for (size_t i = 0; i < m_channels; ++i) {
-        int written = m_queue[i]->write(inputBuffers[i], m_inputBlockSize);
+        int written = m_queue[i]->write(inputBuffers[i], int(m_inputBlockSize));
         if (written < int(m_inputBlockSize) && i == 0) {
             std::cerr << "WARNING: PluginBufferingAdapter::Impl::process: "
                       << "Buffer overflow: wrote " << written 
@@ -615,16 +619,25 @@ void
 PluginBufferingAdapter::Impl::adjustFixedRateFeatureTime(int outputNo,
                                                          Feature &feature)
 {
+//    cerr << "adjustFixedRateFeatureTime: from " << feature.timestamp;
+    
+    double rate = m_outputs[outputNo].sampleRate;
+    if (rate == 0.0) {
+        rate = m_inputSampleRate / float(m_stepSize);
+    }
+    
     if (feature.hasTimestamp) {
         double secs = feature.timestamp.sec;
         secs += feature.timestamp.nsec / 1e9;
-        m_fixedRateFeatureNos[outputNo] =
-            int(secs * double(m_outputs[outputNo].sampleRate) + 0.5);
+        m_fixedRateFeatureNos[outputNo] = int(secs * rate + 0.5);
+//        cerr << " [secs = " << secs << ", no = " << m_fixedRateFeatureNos[outputNo] << "]";
     }
 
     feature.timestamp = RealTime::fromSeconds
-        (m_fixedRateFeatureNos[outputNo] / double(m_outputs[outputNo].sampleRate));
+        (m_fixedRateFeatureNos[outputNo] / rate);
 
+//    cerr << " to " << feature.timestamp << " (rate = " << rate << ", hasTimestamp = " << feature.hasTimestamp << ")" << endl;
+    
     feature.hasTimestamp = true;
     
     m_fixedRateFeatureNos[outputNo] = m_fixedRateFeatureNos[outputNo] + 1;
@@ -643,7 +656,7 @@ PluginBufferingAdapter::Impl::getRemainingFeatures()
     // pad any last samples remaining and process
     if (m_queue[0]->getReadSpace() > 0) {
         for (size_t i = 0; i < m_channels; ++i) {
-            m_queue[i]->zero(m_blockSize - m_queue[i]->getReadSpace());
+            m_queue[i]->zero(int(m_blockSize) - m_queue[i]->getReadSpace());
         }
         processBlock(allFeatureSets);
     }			
@@ -676,7 +689,7 @@ void
 PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
 {
     for (size_t i = 0; i < m_channels; ++i) {
-        m_queue[i]->peek(m_buffers[i], m_blockSize);
+        m_queue[i]->peek(m_buffers[i], int(m_blockSize));
     }
 
     long frame = m_frame;
@@ -736,7 +749,7 @@ PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
     // step forward
 
     for (size_t i = 0; i < m_channels; ++i) {
-        m_queue[i]->skip(m_stepSize);
+        m_queue[i]->skip(int(m_stepSize));
     }
     
     // increment internal frame counter each time we step forward
diff --git a/src/vamp-hostsdk/PluginChannelAdapter.cpp b/src/vamp-hostsdk/PluginChannelAdapter.cpp
index 8463a6e..b6e1d7f 100644
--- a/src/vamp-hostsdk/PluginChannelAdapter.cpp
+++ b/src/vamp-hostsdk/PluginChannelAdapter.cpp
@@ -248,7 +248,7 @@ PluginChannelAdapter::Impl::process(const float *const *inputBuffers,
                 }
             }
             for (size_t j = 0; j < m_blockSize; ++j) {
-                m_buffer[0][j] /= m_inputChannels;
+                m_buffer[0][j] /= float(m_inputChannels);
             }
             return m_plugin->process(m_buffer, timestamp);
         } else {
diff --git a/src/vamp-hostsdk/PluginHostAdapter.cpp b/src/vamp-hostsdk/PluginHostAdapter.cpp
index e4d48aa..77ebf9f 100644
--- a/src/vamp-hostsdk/PluginHostAdapter.cpp
+++ b/src/vamp-hostsdk/PluginHostAdapter.cpp
@@ -37,7 +37,7 @@
 #include <vamp-hostsdk/PluginHostAdapter.h>
 #include <cstdlib>
 
-#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 5 )
+#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 7 )
 #error Unexpected version of Vamp SDK header included
 #endif
 
@@ -126,7 +126,11 @@ PluginHostAdapter::initialise(size_t channels,
                               size_t blockSize)
 {
     if (!m_handle) return false;
-    return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
+    return m_descriptor->initialise
+        (m_handle,
+         (unsigned int)channels,
+         (unsigned int)stepSize,
+         (unsigned int)blockSize) ?
         true : false;
 }
 
diff --git a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
index 2bf396e..06e0775 100644
--- a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
+++ b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp
@@ -43,40 +43,16 @@
 
 #include "Window.h"
 
-
-/**
- * If you want to compile using FFTW instead of the built-in FFT
- * implementation for the PluginInputDomainAdapter, define HAVE_FFTW3
- * in the Makefile.
- *
- * Be aware that FFTW is licensed under the GPL -- unlike this SDK,
- * which is provided under a more liberal BSD license in order to
- * permit use in closed source applications.  The use of FFTW would
- * mean that your code would need to be licensed under the GPL as
- * well.  Do not define this symbol unless you understand and accept
- * the implications of this.
- *
- * Parties such as Linux distribution packagers who redistribute this
- * SDK for use in other programs should _not_ define this symbol, as
- * it would change the effective licensing terms under which the SDK
- * was available to third party developers.
- *
- * The default is not to use FFTW, and to use the built-in FFT instead.
- * 
- * Note: The FFTW code uses FFTW_MEASURE, and so will perform badly on
- * its first invocation unless the host has saved and restored FFTW
- * wisdom (see the FFTW documentation).
- */
-#ifdef HAVE_FFTW3
-#include <fftw3.h>
-#warning "Compiling with FFTW3 support will result in a GPL binary"
-#else
-#include "../vamp-sdk/FFTimpl.cpp"
-#endif
-
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <limits.h>
 
 _VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp)
 
+#include "../vamp-sdk/FFTimpl.cpp"
+
 namespace Vamp {
 
 namespace HostExt {
@@ -110,30 +86,25 @@ protected:
     int m_stepSize;
     int m_blockSize;
     float **m_freqbuf;
-
-    double *m_ri;
+    Kiss::kiss_fft_scalar *m_ri;
 
     WindowType m_windowType;
-    Window<double> *m_window;
+    typedef Window<Kiss::kiss_fft_scalar> W;
+    W *m_window;
 
     ProcessTimestampMethod m_method;
     int m_processCount;
     float **m_shiftBuffers;
 
-#ifdef HAVE_FFTW3
-    fftw_plan m_plan;
-    fftw_complex *m_cbuf;
-#else
-    double *m_ro;
-    double *m_io;
-#endif
+    Kiss::kiss_fftr_cfg m_cfg;
+    Kiss::kiss_fft_cpx *m_cbuf;
 
     FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp);
     FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp);
 
     size_t makeBlockSizeAcceptable(size_t) const;
     
-    Window<double>::WindowType convertType(WindowType t) const;
+    W::WindowType convertType(WindowType t) const;
 };
 
 PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) :
@@ -227,13 +198,8 @@ PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
     m_method(ShiftTimestamp),
     m_processCount(0),
     m_shiftBuffers(0),
-#ifdef HAVE_FFTW3
-    m_plan(0),
+    m_cfg(0),
     m_cbuf(0)
-#else
-    m_ro(0),
-    m_io(0)
-#endif
 {
 }
 
@@ -253,19 +219,13 @@ PluginInputDomainAdapter::Impl::~Impl()
             delete[] m_freqbuf[c];
         }
         delete[] m_freqbuf;
-#ifdef HAVE_FFTW3
-        if (m_plan) {
-            fftw_destroy_plan(m_plan);
-            fftw_free(m_ri);
-            fftw_free(m_cbuf);
-            m_plan = 0;
-        }
-#else
         delete[] m_ri;
-        delete[] m_ro;
-        delete[] m_io;
-#endif
-
+        if (m_cfg) {
+            Kiss::kiss_fftr_free(m_cfg);
+            m_cfg = 0;
+            delete[] m_cbuf;
+            m_cbuf = 0;
+        }
         delete m_window;
     }
 }
@@ -292,30 +252,23 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
         return false;
     }                
         
-#ifndef HAVE_FFTW3
-    if (blockSize & (blockSize-1)) {
-        std::cerr << "ERROR: PluginInputDomainAdapter::initialise: non-power-of-two\nblocksize " << blockSize << " not supported" << std::endl;
+    if (blockSize % 2) {
+        std::cerr << "ERROR: PluginInputDomainAdapter::initialise: odd blocksize " << blockSize << " not supported" << std::endl;
         return false;
     }
-#endif
 
     if (m_channels > 0) {
         for (int c = 0; c < m_channels; ++c) {
             delete[] m_freqbuf[c];
         }
         delete[] m_freqbuf;
-#ifdef HAVE_FFTW3
-        if (m_plan) {
-            fftw_destroy_plan(m_plan);
-            fftw_free(m_ri);
-            fftw_free(m_cbuf);
-            m_plan = 0;
-        }
-#else
         delete[] m_ri;
-        delete[] m_ro;
-        delete[] m_io;
-#endif
+        if (m_cfg) {
+            Kiss::kiss_fftr_free(m_cfg);
+            m_cfg = 0;
+            delete[] m_cbuf;
+            m_cbuf = 0;
+        }
         delete m_window;
     }
 
@@ -327,22 +280,16 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
     for (int c = 0; c < m_channels; ++c) {
         m_freqbuf[c] = new float[m_blockSize + 2];
     }
+    m_ri = new Kiss::kiss_fft_scalar[m_blockSize];
 
-    m_window = new Window<double>(convertType(m_windowType), m_blockSize);
+    m_window = new W(convertType(m_windowType), m_blockSize);
 
-#ifdef HAVE_FFTW3
-    m_ri = (double *)fftw_malloc(blockSize * sizeof(double));
-    m_cbuf = (fftw_complex *)fftw_malloc((blockSize/2 + 1) * sizeof(fftw_complex));
-    m_plan = fftw_plan_dft_r2c_1d(blockSize, m_ri, m_cbuf, FFTW_MEASURE);
-#else
-    m_ri = new double[m_blockSize];
-    m_ro = new double[m_blockSize];
-    m_io = new double[m_blockSize];
-#endif
+    m_cfg = Kiss::kiss_fftr_alloc(m_blockSize, false, 0, 0);
+    m_cbuf = new Kiss::kiss_fft_cpx[m_blockSize/2+1];
 
     m_processCount = 0;
 
-    return m_plugin->initialise(channels, stepSize, blockSize);
+    return m_plugin->initialise(channels, stepSize, m_blockSize);
 }
 
 void
@@ -388,36 +335,12 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
         std::cerr << "WARNING: PluginInputDomainAdapter::initialise: blocksize < 2 not" << std::endl
                   << "supported, increasing from " << blockSize << " to 2" << std::endl;
         blockSize = 2;
-        
-    } else if (blockSize & (blockSize-1)) {
-            
-#ifdef HAVE_FFTW3
-        // not an issue with FFTW
-#else
-
-        // not a power of two, can't handle that with our built-in FFT
-        // implementation
-
-        size_t nearest = blockSize;
-        size_t power = 0;
-        while (nearest > 1) {
-            nearest >>= 1;
-            ++power;
-        }
-        nearest = 1;
-        while (power) {
-            nearest <<= 1;
-            --power;
-        }
-        
-        if (blockSize - nearest > (nearest*2) - blockSize) {
-            nearest = nearest*2;
-        }
-        
-        std::cerr << "WARNING: PluginInputDomainAdapter::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl;
-        blockSize = nearest;
 
-#endif
+    } else if (blockSize % 2) {
+        
+        std::cerr << "WARNING: PluginInputDomainAdapter::initialise: odd blocksize not" << std::endl
+                  << "supported, increasing from " << blockSize << " to " << (blockSize+1) << std::endl;
+        blockSize = blockSize+1;
     }
 
     return blockSize;
@@ -455,7 +378,7 @@ PluginInputDomainAdapter::Impl::setWindowType(WindowType t)
     m_windowType = t;
     if (m_window) {
         delete m_window;
-        m_window = new Window<double>(convertType(m_windowType), m_blockSize);
+        m_window = new W(convertType(m_windowType), m_blockSize);
     }
 }
 
@@ -465,26 +388,26 @@ PluginInputDomainAdapter::Impl::getWindowType() const
     return m_windowType;
 }
 
-Window<double>::WindowType
+PluginInputDomainAdapter::Impl::W::WindowType
 PluginInputDomainAdapter::Impl::convertType(WindowType t) const
 {
     switch (t) {
     case RectangularWindow:
-        return Window<double>::RectangularWindow;
+        return W::RectangularWindow;
     case BartlettWindow:
-        return Window<double>::BartlettWindow;
+        return W::BartlettWindow;
     case HammingWindow:
-        return Window<double>::HammingWindow;
+        return W::HammingWindow;
     case HanningWindow:
-        return Window<double>::HanningWindow;
+        return W::HanningWindow;
     case BlackmanWindow:
-        return Window<double>::BlackmanWindow;
+        return W::BlackmanWindow;
     case NuttallWindow:
-        return Window<double>::NuttallWindow;
+        return W::NuttallWindow;
     case BlackmanHarrisWindow:
-        return Window<double>::BlackmanHarrisWindow;
+        return W::BlackmanHarrisWindow;
     default:
-	return Window<double>::HanningWindow;
+	return W::HanningWindow;
     }
 }
 
@@ -507,13 +430,18 @@ Plugin::FeatureSet
 PluginInputDomainAdapter::Impl::processShiftingTimestamp(const float *const *inputBuffers,
                                                          RealTime timestamp)
 {
+    unsigned int roundedRate = 1;
+    if (m_inputSampleRate > 0.f) {
+        roundedRate = (unsigned int)round(m_inputSampleRate);
+    }
+    
     if (m_method == ShiftTimestamp) {
         // we may need to add one nsec if timestamp +
         // getTimestampAdjustment() rounds down
         timestamp = timestamp + getTimestampAdjustment();
         RealTime nsec(0, 1);
-        if (RealTime::realTime2Frame(timestamp, m_inputSampleRate) <
-            RealTime::realTime2Frame(timestamp + nsec, m_inputSampleRate)) {
+        if (RealTime::realTime2Frame(timestamp, roundedRate) <
+            RealTime::realTime2Frame(timestamp + nsec, roundedRate)) {
             timestamp = timestamp + nsec;
         }
     }
@@ -524,26 +452,17 @@ PluginInputDomainAdapter::Impl::processShiftingTimestamp(const float *const *inp
 
         for (int i = 0; i < m_blockSize/2; ++i) {
             // FFT shift
-            double value = m_ri[i];
+            Kiss::kiss_fft_scalar value = m_ri[i];
             m_ri[i] = m_ri[i + m_blockSize/2];
             m_ri[i + m_blockSize/2] = value;
         }
 
-#ifdef HAVE_FFTW3
-        fftw_execute(m_plan);
-
-        for (int i = 0; i <= m_blockSize/2; ++i) {
-            m_freqbuf[c][i * 2] = float(m_cbuf[i][0]);
-            m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]);
-        }
-#else
-        fft(m_blockSize, false, m_ri, 0, m_ro, m_io);
-
+        Kiss::kiss_fftr(m_cfg, m_ri, m_cbuf);
+        
         for (int i = 0; i <= m_blockSize/2; ++i) {
-            m_freqbuf[c][i * 2] = float(m_ro[i]);
-            m_freqbuf[c][i * 2 + 1] = float(m_io[i]);
+            m_freqbuf[c][i * 2] = float(m_cbuf[i].r);
+            m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i].i);
         }
-#endif
     }
 
     return m_plugin->process(m_freqbuf, timestamp);
@@ -582,26 +501,17 @@ PluginInputDomainAdapter::Impl::processShiftingData(const float *const *inputBuf
 
         for (int i = 0; i < m_blockSize/2; ++i) {
             // FFT shift
-            double value = m_ri[i];
+            Kiss::kiss_fft_scalar value = m_ri[i];
             m_ri[i] = m_ri[i + m_blockSize/2];
             m_ri[i + m_blockSize/2] = value;
         }
 
-#ifdef HAVE_FFTW3
-        fftw_execute(m_plan);
-
-        for (int i = 0; i <= m_blockSize/2; ++i) {
-            m_freqbuf[c][i * 2] = float(m_cbuf[i][0]);
-            m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]);
-        }
-#else
-        fft(m_blockSize, false, m_ri, 0, m_ro, m_io);
-
+        Kiss::kiss_fftr(m_cfg, m_ri, m_cbuf);
+        
         for (int i = 0; i <= m_blockSize/2; ++i) {
-            m_freqbuf[c][i * 2] = float(m_ro[i]);
-            m_freqbuf[c][i * 2 + 1] = float(m_io[i]);
+            m_freqbuf[c][i * 2] = float(m_cbuf[i].r);
+            m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i].i);
         }
-#endif
     }
 
     ++m_processCount;
@@ -609,10 +519,6 @@ PluginInputDomainAdapter::Impl::processShiftingData(const float *const *inputBuf
     return m_plugin->process(m_freqbuf, timestamp);
 }
 
-#ifndef HAVE_FFTW3
-
-#endif
-
 }
         
 }
diff --git a/src/vamp-hostsdk/PluginLoader.cpp b/src/vamp-hostsdk/PluginLoader.cpp
index c5e8d39..2ede543 100644
--- a/src/vamp-hostsdk/PluginLoader.cpp
+++ b/src/vamp-hostsdk/PluginLoader.cpp
@@ -6,7 +6,7 @@
     An API for audio analysis and feature extraction plugins.
 
     Centre for Digital Music, Queen Mary, University of London.
-    Copyright 2006-2009 Chris Cannam and QMUL.
+    Copyright 2006-2016 Chris Cannam and QMUL.
   
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation
@@ -61,11 +61,13 @@ public:
     virtual ~Impl();
 
     PluginKeyList listPlugins();
+    PluginKeyList listPluginsIn(vector<string>);
+    PluginKeyList listPluginsNotIn(vector<string>);
 
     Plugin *loadPlugin(PluginKey key,
                        float inputSampleRate,
                        int adapterFlags);
-
+    
     PluginKey composePluginKey(string libraryName, string identifier);
 
     PluginCategoryHierarchy getPluginCategory(PluginKey key);
@@ -96,7 +98,18 @@ protected:
 
     map<PluginKey, string> m_pluginLibraryNameMap;
     bool m_allPluginsEnumerated;
-    void enumeratePlugins(PluginKey forPlugin = "");
+
+    struct Enumeration {
+        enum { All, SinglePlugin, InLibraries, NotInLibraries } type;
+        PluginKey key;
+        vector<string> libraryNames;
+        Enumeration() : type(All) { }
+    };
+    vector<string> listLibraryFilesFor(Enumeration);
+
+    /// Populate m_pluginLibraryNameMap and return a list of the keys
+    /// that were added to it
+    vector<PluginKey> enumeratePlugins(Enumeration);
 
     map<PluginKey, PluginCategoryHierarchy> m_taxonomy;
     void generateTaxonomy();
@@ -138,12 +151,24 @@ PluginLoader::getInstance()
     return m_instance;
 }
 
-vector<PluginLoader::PluginKey>
+PluginLoader::PluginKeyList
 PluginLoader::listPlugins() 
 {
     return m_impl->listPlugins();
 }
 
+PluginLoader::PluginKeyList
+PluginLoader::listPluginsIn(vector<string> libs) 
+{
+    return m_impl->listPluginsIn(libs);
+}
+
+PluginLoader::PluginKeyList
+PluginLoader::listPluginsNotIn(vector<string> libs) 
+{
+    return m_impl->listPluginsNotIn(libs);
+}
+
 Plugin *
 PluginLoader::loadPlugin(PluginKey key,
                          float inputSampleRate,
@@ -185,37 +210,95 @@ PluginLoader::Impl::setInstanceToClean(PluginLoader *instance)
     m_cleaner.setInstance(instance);
 }
 
-vector<PluginLoader::PluginKey>
+PluginLoader::PluginKeyList
 PluginLoader::Impl::listPlugins() 
 {
-    if (!m_allPluginsEnumerated) enumeratePlugins();
+    if (!m_allPluginsEnumerated) enumeratePlugins(Enumeration());
 
     vector<PluginKey> plugins;
-    for (map<PluginKey, string>::iterator mi = m_pluginLibraryNameMap.begin();
-         mi != m_pluginLibraryNameMap.end(); ++mi) {
-        plugins.push_back(mi->first);
+    for (map<PluginKey, string>::const_iterator i =
+             m_pluginLibraryNameMap.begin();
+         i != m_pluginLibraryNameMap.end(); ++i) {
+        plugins.push_back(i->first);
     }
 
     return plugins;
 }
 
-void
-PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
+PluginLoader::PluginKeyList
+PluginLoader::Impl::listPluginsIn(vector<string> libs) 
 {
-    string libraryName, identifier;
-    vector<string> fullPaths;
+    Enumeration enumeration;
+    enumeration.type = Enumeration::InLibraries;
+    enumeration.libraryNames = libs;
+    return enumeratePlugins(enumeration);
+}
+
+PluginLoader::PluginKeyList
+PluginLoader::Impl::listPluginsNotIn(vector<string> libs) 
+{
+    Enumeration enumeration;
+    enumeration.type = Enumeration::NotInLibraries;
+    enumeration.libraryNames = libs;
+    return enumeratePlugins(enumeration);
+}
+
+vector<string>
+PluginLoader::Impl::listLibraryFilesFor(Enumeration enumeration)
+{
+    Files::Filter filter;
     
-    if (forPlugin != "") {
-        if (!decomposePluginKey(forPlugin, libraryName, identifier)) {
-            std::cerr << "WARNING: Vamp::HostExt::PluginLoader: Invalid plugin key \""
-                      << forPlugin << "\" in enumerate" << std::endl;
-            return;
+    switch (enumeration.type) {
+
+    case Enumeration::All:
+        filter.type = Files::Filter::All;
+        break;
+
+    case Enumeration::SinglePlugin:
+    {
+        string libraryName, identifier;
+        if (!decomposePluginKey(enumeration.key, libraryName, identifier)) {
+            std::cerr << "WARNING: Vamp::HostExt::PluginLoader: "
+                      << "Invalid plugin key \"" << enumeration.key
+                      << "\" in enumerate" << std::endl;
+            return vector<string>();
         }
-        fullPaths = Files::listLibraryFilesMatching(libraryName);
-    } else {
-        fullPaths = Files::listLibraryFiles();
+        filter.type = Files::Filter::Matching;
+        filter.libraryNames.clear();
+        filter.libraryNames.push_back(libraryName);
+        break;
+    }
+
+    case Enumeration::InLibraries:
+        filter.type = Files::Filter::Matching;
+        filter.libraryNames = enumeration.libraryNames;
+        break;
+
+    case Enumeration::NotInLibraries:
+        filter.type = Files::Filter::NotMatching;
+        filter.libraryNames = enumeration.libraryNames;
+        break;
+    }
+        
+    return Files::listLibraryFilesMatching(filter);
+}
+
+vector<PluginLoader::PluginKey>
+PluginLoader::Impl::enumeratePlugins(Enumeration enumeration)
+{
+    string libraryName, identifier;
+    if (enumeration.type == Enumeration::SinglePlugin) {
+        decomposePluginKey(enumeration.key, libraryName, identifier);
     }
+    
+    vector<string> fullPaths = listLibraryFilesFor(enumeration);
+
+    // For these we should warn if a plugin can be loaded from a library
+    bool specific = (enumeration.type == Enumeration::SinglePlugin ||
+                     enumeration.type == Enumeration::InLibraries);
 
+    vector<PluginKey> added;
+    
     for (size_t i = 0; i < fullPaths.size(); ++i) {
 
         string fullPath = fullPaths[i];
@@ -227,8 +310,9 @@ PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
             (handle, "vampGetPluginDescriptor");
             
         if (!fn) {
-            if (forPlugin != "") {
-                cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
+            if (specific) {
+                cerr << "Vamp::HostExt::PluginLoader: "
+                    << "No vampGetPluginDescriptor function found in library \""
                      << fullPath << "\"" << endl;
             }
             Files::unloadLibrary(handle);
@@ -242,18 +326,20 @@ PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
         while ((descriptor = fn(VAMP_API_VERSION, index))) {
             ++index;
             if (identifier != "") {
-                if (descriptor->identifier != identifier) continue;
+                if (descriptor->identifier != identifier) {
+                    continue;
+                }
             }
             found = true;
             PluginKey key = composePluginKey(fullPath, descriptor->identifier);
-//                std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl;
             if (m_pluginLibraryNameMap.find(key) ==
                 m_pluginLibraryNameMap.end()) {
                 m_pluginLibraryNameMap[key] = fullPath;
             }
+            added.push_back(key);
         }
 
-        if (!found && forPlugin != "") {
+        if (!found && specific) {
             cerr << "Vamp::HostExt::PluginLoader: Plugin \""
                  << identifier << "\" not found in library \""
                  << fullPath << "\"" << endl;
@@ -262,7 +348,11 @@ PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
         Files::unloadLibrary(handle);
     }
 
-    if (forPlugin == "") m_allPluginsEnumerated = true;
+    if (enumeration.type == Enumeration::All) {
+        m_allPluginsEnumerated = true;
+    }
+
+    return added;
 }
 
 PluginLoader::PluginKey
@@ -302,7 +392,10 @@ PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin)
 {
     if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
         if (m_allPluginsEnumerated) return "";
-        enumeratePlugins(plugin);
+        Enumeration enumeration;
+        enumeration.type = Enumeration::SinglePlugin;
+        enumeration.key = plugin;
+        enumeratePlugins(enumeration);
     }
     if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
         return "";
diff --git a/src/vamp-hostsdk/PluginSummarisingAdapter.cpp b/src/vamp-hostsdk/PluginSummarisingAdapter.cpp
index b662134..315eccc 100644
--- a/src/vamp-hostsdk/PluginSummarisingAdapter.cpp
+++ b/src/vamp-hostsdk/PluginSummarisingAdapter.cpp
@@ -41,6 +41,8 @@
 #include <cmath>
 #include <climits>
 
+using namespace std;
+
 //#define DEBUG_PLUGIN_SUMMARISING_ADAPTER 1
 //#define DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT 1
 
@@ -80,7 +82,7 @@ protected:
 
     SegmentBoundaries m_boundaries;
 
-    typedef std::vector<float> ValueList;
+    typedef vector<float> ValueList;
 
     struct Result { // smaller than Feature
         RealTime time;
@@ -88,7 +90,7 @@ protected:
         ValueList values; // bin number -> value
     };
 
-    typedef std::vector<Result> ResultList;
+    typedef vector<Result> ResultList;
 
     struct OutputAccumulator {
         int bins;
@@ -96,14 +98,14 @@ protected:
         OutputAccumulator() : bins(0) { }
     };
 
-    typedef std::map<int, OutputAccumulator> OutputAccumulatorMap;
+    typedef map<int, OutputAccumulator> OutputAccumulatorMap;
     OutputAccumulatorMap m_accumulators; // output number -> accumulator
 
-    typedef std::map<RealTime, OutputAccumulator> SegmentAccumulatorMap;
-    typedef std::map<int, SegmentAccumulatorMap> OutputSegmentAccumulatorMap;
+    typedef map<RealTime, OutputAccumulator> SegmentAccumulatorMap;
+    typedef map<int, SegmentAccumulatorMap> OutputSegmentAccumulatorMap;
     OutputSegmentAccumulatorMap m_segmentedAccumulators; // output -> segmented
 
-    typedef std::map<int, RealTime> OutputTimestampMap;
+    typedef map<int, RealTime> OutputTimestampMap;
     OutputTimestampMap m_prevTimestamps; // output number -> timestamp
     OutputTimestampMap m_prevDurations; // output number -> durations
 
@@ -128,9 +130,9 @@ protected:
         double variance_c;
     };
 
-    typedef std::map<int, OutputBinSummary> OutputSummary;
-    typedef std::map<RealTime, OutputSummary> SummarySegmentMap;
-    typedef std::map<int, SummarySegmentMap> OutputSummarySegmentMap;
+    typedef map<int, OutputBinSummary> OutputSummary;
+    typedef map<RealTime, OutputSummary> SummarySegmentMap;
+    typedef map<int, SummarySegmentMap> OutputSummarySegmentMap;
 
     OutputSummarySegmentMap m_summaries;
 
@@ -144,7 +146,7 @@ protected:
     void segment();
     void reduce();
 
-    std::string getSummaryLabel(SummaryType type, AveragingMethod avg);
+    string getSummaryLabel(SummaryType type, AveragingMethod avg);
 };
 
 static RealTime INVALID_DURATION(INT_MIN, INT_MIN);
@@ -245,12 +247,16 @@ PluginSummarisingAdapter::Impl::process(const float *const *inputBuffers,
                                         RealTime timestamp)
 {
     if (m_reduced) {
-        std::cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << std::endl;
+        cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << endl;
     }
     FeatureSet fs = m_plugin->process(inputBuffers, timestamp);
     accumulate(fs, timestamp, false);
     m_endTime = timestamp + 
         RealTime::frame2RealTime(m_stepSize, int(m_inputSampleRate + 0.5));
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+    cerr << "timestamp = " << timestamp << ", end time becomes " << m_endTime
+         << endl;
+#endif
     return fs;
 }
 
@@ -258,7 +264,7 @@ Plugin::FeatureSet
 PluginSummarisingAdapter::Impl::getRemainingFeatures()
 {
     if (m_reduced) {
-        std::cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << std::endl;
+        cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << endl;
     }
     FeatureSet fs = m_plugin->getRemainingFeatures();
     accumulate(fs, m_endTime, true);
@@ -270,12 +276,12 @@ PluginSummarisingAdapter::Impl::setSummarySegmentBoundaries(const SegmentBoundar
 {
     m_boundaries = b;
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-    std::cerr << "PluginSummarisingAdapter::setSummarySegmentBoundaries: boundaries are:" << std::endl;
+    cerr << "PluginSummarisingAdapter::setSummarySegmentBoundaries: boundaries are:" << endl;
     for (SegmentBoundaries::const_iterator i = m_boundaries.begin();
          i != m_boundaries.end(); ++i) {
-        std::cerr << *i << "  ";
+        cerr << *i << "  ";
     }
-    std::cerr << std::endl;
+    cerr << endl;
 #endif
 }
 
@@ -360,8 +366,8 @@ PluginSummarisingAdapter::Impl::getSummaryForOutput(int output,
                 break;
 
             case StandardDeviation:
-                if (continuous) result = sqrtf(summary.variance_c);
-                else result = sqrtf(summary.variance);
+                if (continuous) result = sqrt(summary.variance_c);
+                else result = sqrt(summary.variance);
                 break;
 
             case Count:
@@ -375,7 +381,7 @@ PluginSummarisingAdapter::Impl::getSummaryForOutput(int output,
                 break;
             }
             
-            f.values.push_back(result);
+            f.values.push_back(float(result));
         }
 
         fl.push_back(f);
@@ -420,12 +426,12 @@ PluginSummarisingAdapter::Impl::accumulate(const FeatureSet &fs,
     }
 }
 
-std::string
+string
 PluginSummarisingAdapter::Impl::getSummaryLabel(SummaryType type,
                                                 AveragingMethod avg)
 {
-    std::string label;
-    std::string avglabel;
+    string label;
+    string avglabel;
 
     if (avg == SampleAverage) avglabel = ", sample average";
     else avglabel = ", continuous-time average";
@@ -450,7 +456,11 @@ void
 PluginSummarisingAdapter::Impl::accumulate(int output,
                                            const Feature &f,
                                            RealTime timestamp,
-                                           bool /* final */)
+                                           bool
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                                           final
+#endif
+    )
 {
     // What should happen if a feature's duration spans a segment
     // boundary?  I think we probably want to chop it, and pretend
@@ -466,7 +476,7 @@ PluginSummarisingAdapter::Impl::accumulate(int output,
     // into segments).
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-    std::cerr << "output " << output << ": timestamp " << timestamp << ", prev timestamp " << m_prevTimestamps[output] << ", final " << final << std::endl;
+    cerr << "output " << output << ": timestamp " << timestamp << ", prev timestamp " << m_prevTimestamps[output] << ", final " << final << endl;
 #endif
 
     // At each process step, accumulate() is called once for each
@@ -507,19 +517,19 @@ PluginSummarisingAdapter::Impl::accumulate(int output,
         if (m_prevDurations[output] != INVALID_DURATION) {
             prevDuration = m_prevDurations[output];
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-            std::cerr << "Previous duration from previous feature: " << prevDuration << std::endl;
+            cerr << "Previous duration from previous feature: " << prevDuration << endl;
 #endif
         } else {
             prevDuration = timestamp - m_prevTimestamps[output];
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-            std::cerr << "Previous duration from diff: " << timestamp << " - "
-                      << m_prevTimestamps[output] << std::endl;
+            cerr << "Previous duration from diff: " << timestamp << " - "
+                      << m_prevTimestamps[output] << endl;
 #endif
         }
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-        std::cerr << "output " << output << ": ";
-        std::cerr << "Pushing previous duration as " << prevDuration << std::endl;
+        cerr << "output " << output << ": ";
+        cerr << "Pushing previous duration as " << prevDuration << endl;
 #endif
         
         m_accumulators[output].results
@@ -536,6 +546,9 @@ PluginSummarisingAdapter::Impl::accumulate(int output,
         RealTime et = timestamp;
         et = et + f.duration;
         if (et > m_endTime) m_endTime = et;
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+        cerr << "feature has duration, updating end time to " << m_endTime << endl;
+#endif
     }
 
     Result result;
@@ -543,7 +556,7 @@ PluginSummarisingAdapter::Impl::accumulate(int output,
     result.duration = INVALID_DURATION;
 
     if (int(f.values.size()) > m_accumulators[output].bins) {
-        m_accumulators[output].bins = f.values.size();
+        m_accumulators[output].bins = int(f.values.size());
     }
 
     for (int i = 0; i < int(f.values.size()); ++i) {
@@ -561,19 +574,19 @@ PluginSummarisingAdapter::Impl::accumulateFinalDurations()
 
         int output = i->first;
 
-        int acount = m_accumulators[output].results.size();
+        int acount = int(m_accumulators[output].results.size());
 
         if (acount == 0) continue;
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-        std::cerr << "output " << output << ": ";
+        cerr << "output " << output << ": ";
 #endif
 
         if (m_prevDurations.find(output) != m_prevDurations.end() &&
             m_prevDurations[output] != INVALID_DURATION) {
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-            std::cerr << "Pushing final duration from feature as " << m_prevDurations[output] << std::endl;
+            cerr << "Pushing final duration from feature as " << m_prevDurations[output] << endl;
 #endif
 
             m_accumulators[output].results[acount - 1].duration =
@@ -582,7 +595,7 @@ PluginSummarisingAdapter::Impl::accumulateFinalDurations()
         } else {
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-            std::cerr << "Pushing final duration from diff as " << m_endTime << " - " << m_prevTimestamps[output] << std::endl;
+            cerr << "Pushing final duration from diff as " << m_endTime << " - " << m_prevTimestamps[output] << endl;
 #endif
 
             m_accumulators[output].results[acount - 1].duration =
@@ -590,9 +603,9 @@ PluginSummarisingAdapter::Impl::accumulateFinalDurations()
         }
         
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-        std::cerr << "so duration for result no " << acount-1 << " is "
+        cerr << "so duration for result no " << acount-1 << " is "
                   << m_accumulators[output].results[acount-1].duration
-                  << std::endl;
+                  << endl;
 #endif
     }
 }
@@ -603,10 +616,10 @@ PluginSummarisingAdapter::Impl::findSegmentBounds(RealTime t,
                                                   RealTime &end)
 {
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-    std::cerr << "findSegmentBounds: t = " << t <<  std::endl;
+    cerr << "findSegmentBounds: t = " << t <<  endl;
 #endif
 
-    SegmentBoundaries::const_iterator i = std::upper_bound
+    SegmentBoundaries::const_iterator i = upper_bound
         (m_boundaries.begin(), m_boundaries.end(), t);
 
     start = RealTime::zeroTime;
@@ -621,7 +634,7 @@ PluginSummarisingAdapter::Impl::findSegmentBounds(RealTime t,
     }
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-    std::cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << std::endl;
+    cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << endl;
 #endif
 }
 
@@ -629,7 +642,7 @@ void
 PluginSummarisingAdapter::Impl::segment()
 {
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-    std::cerr << "segment: starting" << std::endl;
+    cerr << "segment: starting" << endl;
 #endif
 
     for (OutputAccumulatorMap::iterator i = m_accumulators.begin();
@@ -639,8 +652,8 @@ PluginSummarisingAdapter::Impl::segment()
         OutputAccumulator &source = i->second;
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-        std::cerr << "segment: total results for output " << output << " = "
-                  << source.results.size() << std::endl;
+        cerr << "segment: total results for output " << output << " = "
+                  << source.results.size() << endl;
 #endif
 
         // This is basically nonsense if the results have no values
@@ -658,7 +671,7 @@ PluginSummarisingAdapter::Impl::segment()
             RealTime resultEnd = resultStart + source.results[n].duration;
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-            std::cerr << "output: " << output << ", result start = " << resultStart << ", end = " << resultEnd << std::endl;
+            cerr << "output: " << output << ", result start = " << resultStart << ", end = " << resultEnd << endl;
 #endif
 
             RealTime segmentStart = RealTime::zeroTime;
@@ -669,8 +682,8 @@ PluginSummarisingAdapter::Impl::segment()
             while (segmentEnd < resultEnd) {
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-                std::cerr << "segment end " << segmentEnd << " < result end "
-                          << resultEnd << " (with result start " << resultStart << ")" <<  std::endl;
+                cerr << "segment end " << segmentEnd << " < result end "
+                          << resultEnd << " (with result start " << resultStart << ")" <<  endl;
 #endif
 
                 findSegmentBounds(resultStart, segmentStart, segmentEnd);
@@ -697,7 +710,7 @@ PluginSummarisingAdapter::Impl::segment()
                 chunk.values = source.results[n].values;
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
-                std::cerr << "chunk for segment " << segmentStart << ": from " << chunk.time << ", duration " << chunk.duration << std::endl;
+                cerr << "chunk for segment " << segmentStart << ": from " << chunk.time << ", duration " << chunk.duration << endl;
 #endif
 
                 m_segmentedAccumulators[output][segmentStart].results
@@ -747,21 +760,21 @@ PluginSummarisingAdapter::Impl::reduce()
             RealTime segmentStart = j->first;
             OutputAccumulator &accumulator = j->second;
 
-            int sz = accumulator.results.size();
+            int sz = int(accumulator.results.size());
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-            std::cerr << "reduce: segment starting at " << segmentStart
-                      << " on output " << output << " has " << sz << " result(s)" << std::endl;
+            cerr << "reduce: segment starting at " << segmentStart
+                      << " on output " << output << " has " << sz << " result(s)" << endl;
 #endif
 
             double totalDuration = 0.0;
             //!!! is this right?
             if (sz > 0) {
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-                std::cerr << "last time = " << accumulator.results[sz-1].time 
+                cerr << "last time = " << accumulator.results[sz-1].time 
                           << ", duration = " << accumulator.results[sz-1].duration
                           << " (step = " << m_stepSize << ", block = " << m_blockSize << ")"
-                          << std::endl;
+                          << endl;
 #endif
                 totalDuration = toSec((accumulator.results[sz-1].time +
                                        accumulator.results[sz-1].duration) -
@@ -772,6 +785,10 @@ PluginSummarisingAdapter::Impl::reduce()
 
                 // work on all values over time for a single bin
 
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                cerr << "bin " << bin << ":" << endl;
+#endif
+                
                 OutputBinSummary summary;
 
                 summary.count = sz;
@@ -791,7 +808,7 @@ PluginSummarisingAdapter::Impl::reduce()
 
                 if (sz == 0) continue;
 
-                std::vector<ValueDurationFloatPair> valvec;
+                vector<ValueDurationFloatPair> valvec;
 
                 for (int k = 0; k < sz; ++k) {
                     while (int(accumulator.results[k].values.size()) <
@@ -802,27 +819,28 @@ PluginSummarisingAdapter::Impl::reduce()
 
                 for (int k = 0; k < sz; ++k) {
                     float value = accumulator.results[k].values[bin];
-                    valvec.push_back(ValueDurationFloatPair
-                                     (value,
-                                      toSec(accumulator.results[k].duration)));
+                    valvec.push_back
+                        (ValueDurationFloatPair
+                         (value,
+                          float(toSec(accumulator.results[k].duration))));
                 }
 
-                std::sort(valvec.begin(), valvec.end());
+                sort(valvec.begin(), valvec.end());
 
                 summary.minimum = valvec[0].value;
                 summary.maximum = valvec[sz-1].value;
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-                std::cerr << "total duration = " << totalDuration << std::endl;
+                cerr << "total duration = " << totalDuration << endl;
 #endif
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
 /*
-                std::cerr << "value vector for medians:" << std::endl;
+                cerr << "value vector for medians:" << endl;
                 for (int k = 0; k < sz; ++k) {
-                    std::cerr << "(" << valvec[k].value << "," << valvec[k].duration << ") ";
+                    cerr << "(" << valvec[k].value << "," << valvec[k].duration << ") ";
                 }
-                std::cerr << std::endl;
+                cerr << endl;
 */
 #endif
 
@@ -844,20 +862,29 @@ PluginSummarisingAdapter::Impl::reduce()
                 }
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-                std::cerr << "median_c = " << summary.median_c << std::endl;
-                std::cerr << "median = " << summary.median << std::endl;
+                cerr << "median_c = " << summary.median_c << endl;
+                cerr << "median = " << summary.median << endl;
 #endif
                 
-                std::map<float, int> distribution;
+                map<float, int> distribution;
 
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                cerr << "summing (discrete): ";
+#endif
                 for (int k = 0; k < sz; ++k) {
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                    cerr << accumulator.results[k].values[bin] << " ";
+#endif
                     summary.sum += accumulator.results[k].values[bin];
                     distribution[accumulator.results[k].values[bin]] += 1;
                 }
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                cerr << endl;
+#endif
 
                 int md = 0;
 
-                for (std::map<float, int>::iterator di = distribution.begin();
+                for (map<float, int>::iterator di = distribution.begin();
                      di != distribution.end(); ++di) {
                     if (di->second > md) {
                         md = di->second;
@@ -867,7 +894,7 @@ PluginSummarisingAdapter::Impl::reduce()
 
                 distribution.clear();
 
-                std::map<float, double> distribution_c;
+                map<float, double> distribution_c;
 
                 for (int k = 0; k < sz; ++k) {
                     distribution_c[accumulator.results[k].values[bin]]
@@ -876,7 +903,7 @@ PluginSummarisingAdapter::Impl::reduce()
 
                 double mrd = 0.0;
 
-                for (std::map<float, double>::iterator di = distribution_c.begin();
+                for (map<float, double>::iterator di = distribution_c.begin();
                      di != distribution_c.end(); ++di) {
                     if (di->second > mrd) {
                         mrd = di->second;
@@ -890,15 +917,25 @@ PluginSummarisingAdapter::Impl::reduce()
 
                     double sum_c = 0.0;
 
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                    cerr << "summing (continuous): ";
+#endif
                     for (int k = 0; k < sz; ++k) {
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                        cerr << accumulator.results[k].values[bin] << "*"
+                             << toSec(accumulator.results[k].duration) << " ";
+#endif
                         double value = accumulator.results[k].values[bin]
                             * toSec(accumulator.results[k].duration);
                         sum_c += value;
                     }
+#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
+                cerr << endl;
+#endif
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-                    std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = "
-                              << sum_c / totalDuration << " (sz = " << sz << ")" << std::endl;
+                    cerr << "mean_c = " << sum_c << " / " << totalDuration << " = "
+                              << sum_c / totalDuration << " (sz = " << sz << ")" << endl;
 #endif
                 
                     summary.mean_c = sum_c / totalDuration;
@@ -918,8 +955,8 @@ PluginSummarisingAdapter::Impl::reduce()
                 double mean = summary.sum / summary.count;
 
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER
-                std::cerr << "mean = " << summary.sum << " / " << summary.count << " = "
-                          << summary.sum / summary.count << std::endl;
+                cerr << "mean = " << summary.sum << " / " << summary.count << " = "
+                          << summary.sum / summary.count << endl;
 #endif
 
                 for (int k = 0; k < sz; ++k) {
diff --git a/src/vamp-hostsdk/Window.h b/src/vamp-hostsdk/Window.h
index bb1c537..4903f17 100644
--- a/src/vamp-hostsdk/Window.h
+++ b/src/vamp-hostsdk/Window.h
@@ -76,8 +76,8 @@ public:
     void cut(T *src, T *dst) const {
 	for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
     }
-    template <typename T0>
-    void cut(T0 *src, T *dst) const {
+    template <typename T0, typename T1>
+    void cut(T0 *src, T1 *dst) const {
 	for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
     }
 
diff --git a/src/vamp-hostsdk/acsymbols.c b/src/vamp-hostsdk/acsymbols.c
index da226a5..fcd0733 100644
--- a/src/vamp-hostsdk/acsymbols.c
+++ b/src/vamp-hostsdk/acsymbols.c
@@ -1,6 +1,8 @@
 /* These stubs are provided so that autoconf can check library
  * versions using C symbols only */
 
+extern void libvamphostsdk_v_2_7_1_present(void) { }
+extern void libvamphostsdk_v_2_7_present(void) { }
 extern void libvamphostsdk_v_2_6_present(void) { }
 extern void libvamphostsdk_v_2_5_present(void) { }
 extern void libvamphostsdk_v_2_4_present(void) { }
diff --git a/src/vamp-sdk/FFT.cpp b/src/vamp-sdk/FFT.cpp
index 3e4bf2d..a5df27d 100644
--- a/src/vamp-sdk/FFT.cpp
+++ b/src/vamp-sdk/FFT.cpp
@@ -36,37 +36,224 @@
 
 #include <vamp-sdk/FFT.h>
 
-#include <cmath>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
 
-#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 5 )
+#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 7 )
 #error Unexpected version of Vamp SDK header included
 #endif
 
-#ifdef _MSC_VER
-#include <stdlib.h>
-#include <malloc.h>
-#endif
-
 _VAMP_SDK_PLUGSPACE_BEGIN(FFT.cpp)
 
-namespace Vamp {
-
 #include "FFTimpl.cpp"
 
+namespace Vamp {
+
 void
-FFT::forward(unsigned int n,
+FFT::forward(unsigned int un,
 	     const double *ri, const double *ii,
 	     double *ro, double *io)
 {
-    fft(n, false, ri, ii, ro, io);
+    int n(un);
+    Kiss::kiss_fft_cfg c = Kiss::kiss_fft_alloc(n, false, 0, 0);
+    Kiss::kiss_fft_cpx *in = new Kiss::kiss_fft_cpx[n];
+    Kiss::kiss_fft_cpx *out = new Kiss::kiss_fft_cpx[n];
+    for (int i = 0; i < n; ++i) {
+        in[i].r = ri[i];
+        in[i].i = 0;
+    }
+    if (ii) {
+        for (int i = 0; i < n; ++i) {
+            in[i].i = ii[i];
+        }
+    }
+    kiss_fft(c, in, out);
+    for (int i = 0; i < n; ++i) {
+        ro[i] = out[i].r;
+        io[i] = out[i].i;
+    }
+    Kiss::kiss_fft_free(c);
+    delete[] in;
+    delete[] out;
 }
 
 void
-FFT::inverse(unsigned int n,
+FFT::inverse(unsigned int un,
 	     const double *ri, const double *ii,
 	     double *ro, double *io)
 {
-    fft(n, true, ri, ii, ro, io);
+    int n(un);
+    Kiss::kiss_fft_cfg c = Kiss::kiss_fft_alloc(n, true, 0, 0);
+    Kiss::kiss_fft_cpx *in = new Kiss::kiss_fft_cpx[n];
+    Kiss::kiss_fft_cpx *out = new Kiss::kiss_fft_cpx[n];
+    for (int i = 0; i < n; ++i) {
+        in[i].r = ri[i];
+        in[i].i = 0;
+    }
+    if (ii) {
+        for (int i = 0; i < n; ++i) {
+            in[i].i = ii[i];
+        }
+    }
+    kiss_fft(c, in, out);
+    double scale = 1.0 / double(n);
+    for (int i = 0; i < n; ++i) {
+        ro[i] = out[i].r * scale;
+        io[i] = out[i].i * scale;
+    }
+    Kiss::kiss_fft_free(c);
+    delete[] in;
+    delete[] out;
+}
+
+class FFTComplex::D
+{
+public:
+    D(int n) :
+        m_n(n),
+        m_fconf(Kiss::kiss_fft_alloc(n, false, 0, 0)),
+        m_iconf(Kiss::kiss_fft_alloc(n, true, 0, 0)),
+        m_ci(new Kiss::kiss_fft_cpx[m_n]),
+        m_co(new Kiss::kiss_fft_cpx[m_n]) { }
+
+    ~D() {
+        Kiss::kiss_fftr_free(m_fconf);
+        Kiss::kiss_fftr_free(m_iconf);
+        delete[] m_ci;
+        delete[] m_co;
+    }
+
+    void forward(const double *ci, double *co) {
+        for (int i = 0; i < m_n; ++i) {
+            m_ci[i].r = ci[i*2];
+            m_ci[i].i = ci[i*2+1];
+        }
+        Kiss::kiss_fft(m_fconf, m_ci, m_co);
+        for (int i = 0; i < m_n; ++i) {
+            co[i*2] = m_co[i].r;
+            co[i*2+1] = m_co[i].i;
+        }
+    }
+
+    void inverse(const double *ci, double *co) {
+        for (int i = 0; i < m_n; ++i) {
+            m_ci[i].r = ci[i*2];
+            m_ci[i].i = ci[i*2+1];
+        }
+        Kiss::kiss_fft(m_iconf, m_ci, m_co);
+        double scale = 1.0 / double(m_n);
+        for (int i = 0; i < m_n; ++i) {
+            co[i*2] = m_co[i].r * scale;
+            co[i*2+1] = m_co[i].i * scale;
+        }
+    }
+    
+private:
+    int m_n;
+    Kiss::kiss_fft_cfg m_fconf;
+    Kiss::kiss_fft_cfg m_iconf;
+    Kiss::kiss_fft_cpx *m_ci;
+    Kiss::kiss_fft_cpx *m_co;
+};
+
+FFTComplex::FFTComplex(unsigned int n) :
+    m_d(new D(n))
+{
+}
+
+FFTComplex::~FFTComplex()
+{
+    delete m_d;
+}
+
+void
+FFTComplex::forward(const double *ci, double *co)
+{
+    m_d->forward(ci, co);
+}
+
+void
+FFTComplex::inverse(const double *ci, double *co)
+{
+    m_d->inverse(ci, co);
+}
+
+class FFTReal::D
+{
+public:
+    D(int n) :
+        m_n(n),
+        m_fconf(Kiss::kiss_fftr_alloc(n, false, 0, 0)),
+        m_iconf(Kiss::kiss_fftr_alloc(n, true, 0, 0)),
+        m_ri(new Kiss::kiss_fft_scalar[m_n]),
+        m_ro(new Kiss::kiss_fft_scalar[m_n]),
+        m_freq(new Kiss::kiss_fft_cpx[n/2+1]) { }
+
+    ~D() {
+        Kiss::kiss_fftr_free(m_fconf);
+        Kiss::kiss_fftr_free(m_iconf);
+        delete[] m_ri;
+        delete[] m_ro;
+        delete[] m_freq;
+    }
+
+    void forward(const double *ri, double *co) {
+        for (int i = 0; i < m_n; ++i) {
+            // in case kiss_fft_scalar is float
+            m_ri[i] = ri[i];
+        }
+        Kiss::kiss_fftr(m_fconf, m_ri, m_freq);
+        int hs = m_n/2 + 1;
+        for (int i = 0; i < hs; ++i) {
+            co[i*2] = m_freq[i].r;
+            co[i*2+1] = m_freq[i].i;
+        }
+    }
+
+    void inverse(const double *ci, double *ro) {
+        int hs = m_n/2 + 1;
+        for (int i = 0; i < hs; ++i) {
+            m_freq[i].r = ci[i*2];
+            m_freq[i].i = ci[i*2+1];
+        }
+        Kiss::kiss_fftri(m_iconf, m_freq, m_ro);
+        double scale = 1.0 / double(m_n);
+        for (int i = 0; i < m_n; ++i) {
+            ro[i] = m_ro[i] * scale;
+        }
+    }
+    
+private:
+    int m_n;
+    Kiss::kiss_fftr_cfg m_fconf;
+    Kiss::kiss_fftr_cfg m_iconf;
+    Kiss::kiss_fft_scalar *m_ri;
+    Kiss::kiss_fft_scalar *m_ro;
+    Kiss::kiss_fft_cpx *m_freq;
+};
+
+FFTReal::FFTReal(unsigned int n) :
+    m_d(new D(n))
+{
+}
+
+FFTReal::~FFTReal()
+{
+    delete m_d;
+}
+
+void
+FFTReal::forward(const double *ri, double *co)
+{
+    m_d->forward(ri, co);
+}
+
+void
+FFTReal::inverse(const double *ci, double *ro)
+{
+    m_d->inverse(ci, ro);
 }
 
 }
diff --git a/src/vamp-sdk/FFTimpl.cpp b/src/vamp-sdk/FFTimpl.cpp
index 95fcee4..381f6c5 100644
--- a/src/vamp-sdk/FFTimpl.cpp
+++ b/src/vamp-sdk/FFTimpl.cpp
@@ -1,116 +1,38 @@
 
-/* Public domain FFT implementation from Don Cross. */
-
-static void
-fft(unsigned int n, bool inverse,
-    const double *ri, const double *ii,
-    double *ro, double *io)
-{
-    if (!ri || !ro || !io) return;
-
-    unsigned int bits;
-    unsigned int i, j, k, m;
-    unsigned int blockSize, blockEnd;
-
-    double tr, ti;
-
-    if (n < 2) return;
-    if (n & (n-1)) return;
-
-    double angle = 2.0 * M_PI;
-    if (inverse) angle = -angle;
-
-    for (i = 0; ; ++i) {
-	if (n & (1 << i)) {
-	    bits = i;
-	    break;
-	}
-    }
-
-#ifdef _MSC_VER
-    int *table = (int *)_malloca(n * sizeof(int));
+// Override C linkage for KissFFT headers. So long as we have already
+// included all of the other (system etc) headers KissFFT depends on,
+// this should work out OK
+#define KISSFFT_USE_CPP_LINKAGE 1
+
+namespace Kiss {
+
+#undef KISS_FFT_H
+#undef KISS_FTR_H
+#undef KISS_FFT__GUTS_H
+#undef FIXED_POINT
+#undef USE_SIMD
+#undef kiss_fft_scalar
+
+#ifdef SINGLE_PRECISION_FFT
+#pragma message("Using single-precision FFTs")
+typedef float kiss_fft_scalar;
+#define kiss_fft_scalar float
 #else
-    int table[n];
+typedef double kiss_fft_scalar;
+#define kiss_fft_scalar double
 #endif
 
-    for (i = 0; i < n; ++i) {
-        m = i;
-        for (j = k = 0; j < bits; ++j) {
-            k = (k << 1) | (m & 1);
-            m >>= 1;
-        }
-        table[i] = k;
-    }
-
-    if (ii) {
-	for (i = 0; i < n; ++i) {
-	    ro[table[i]] = ri[i];
-	    io[table[i]] = ii[i];
-	}
-    } else {
-	for (i = 0; i < n; ++i) {
-	    ro[table[i]] = ri[i];
-	    io[table[i]] = 0.0;
-	}
-    }
-
-    blockEnd = 1;
-
-    for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
-
-	double delta = angle / (double)blockSize;
-	double sm2 = -sin(-2 * delta);
-	double sm1 = -sin(-delta);
-	double cm2 = cos(-2 * delta);
-	double cm1 = cos(-delta);
-	double w = 2 * cm1;
-	double ar[3], ai[3];
-
-	for (i = 0; i < n; i += blockSize) {
-
-	    ar[2] = cm2;
-	    ar[1] = cm1;
+inline void free(void *ptr) { ::free(ptr); }
+#include "ext/kiss_fft.c"
+#include "ext/kiss_fftr.c"
 
-	    ai[2] = sm2;
-	    ai[1] = sm1;
+#undef kiss_fft_scalar // leaving only the namespaced typedef
 
-	    for (j = i, m = 0; m < blockEnd; j++, m++) {
-
-		ar[0] = w * ar[1] - ar[2];
-		ar[2] = ar[1];
-		ar[1] = ar[0];
-
-		ai[0] = w * ai[1] - ai[2];
-		ai[2] = ai[1];
-		ai[1] = ai[0];
-
-		k = j + blockEnd;
-		tr = ar[0] * ro[k] - ai[0] * io[k];
-		ti = ar[0] * io[k] + ai[0] * ro[k];
-
-		ro[k] = ro[j] - tr;
-		io[k] = io[j] - ti;
-
-		ro[j] += tr;
-		io[j] += ti;
-	    }
-	}
-
-	blockEnd = blockSize;
-    }
-
-    if (inverse) {
-
-	double denom = (double)n;
-
-	for (i = 0; i < n; i++) {
-	    ro[i] /= denom;
-	    io[i] /= denom;
-	}
-    }
-
-#ifdef _MSC_VER
-    _freea(table);
-#endif
 }
 
+// Check that this worked, i.e. that we have our own suitably
+// hacked KissFFT header which set this after making the
+// appropriate change
+#ifndef KISSFFT_USED_CPP_LINKAGE
+#error "KissFFT header lacks specific linkage adjustment needed for Vamp SDK"
+#endif
diff --git a/src/vamp-sdk/PluginAdapter.cpp b/src/vamp-sdk/PluginAdapter.cpp
index 0b6fe10..e3ed0c4 100644
--- a/src/vamp-sdk/PluginAdapter.cpp
+++ b/src/vamp-sdk/PluginAdapter.cpp
@@ -39,7 +39,7 @@
 #include <cstring>
 #include <cstdlib>
 
-#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 5 )
+#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 7 )
 #error Unexpected version of Vamp SDK header included
 #endif
 
@@ -166,7 +166,7 @@ PluginAdapterBase::Impl::getDescriptor()
 #endif
 
     if (m_populated) return &m_descriptor;
-
+    
     Plugin *plugin = m_base->createPlugin(48000);
   
     if (!plugin) {
@@ -298,6 +298,7 @@ PluginAdapterBase::Impl::~Impl()
             }
             free((void *)desc->valueNames);
         }
+        free((void *)desc);
     }
     free((void *)m_descriptor.parameters);
 
@@ -603,6 +604,9 @@ PluginAdapterBase::Impl::cleanup(Plugin *plugin)
         if (m_pluginOutputs[plugin]) {
             outputCount = m_pluginOutputs[plugin]->size();
         }
+#ifdef DEBUG_PLUGIN_ADAPTER
+        std::cerr << "PluginAdapterBase::Impl::cleanup: " << outputCount << " output(s)" << std::endl;
+#endif
         VampFeatureList *list = m_fs[plugin];
         for (unsigned int i = 0; i < outputCount; ++i) {
             for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
@@ -615,6 +619,7 @@ PluginAdapterBase::Impl::cleanup(Plugin *plugin)
             }
             if (list[i].features) free(list[i].features);
         }
+        if (list) free((void *)list);
         m_fs.erase(plugin);
         m_fsizes.erase(plugin);
         m_fvsizes.erase(plugin);
@@ -849,12 +854,16 @@ PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
 void
 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
 {
-//    std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
+#ifdef DEBUG_PLUGIN_ADAPTER
+    std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
+#endif
 
     int i = m_fsizes[plugin].size();
     if (i >= n) return;
 
-//    std::cerr << "resizing from " << i << std::endl;
+#ifdef DEBUG_PLUGIN_ADAPTER
+    std::cerr << "resizing from " << i << std::endl;
+#endif
 
     m_fs[plugin] = (VampFeatureList *)realloc
         (m_fs[plugin], n * sizeof(VampFeatureList));
@@ -871,13 +880,17 @@ PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
 void
 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
 {
-//    std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
-//              << sz << ")" << std::endl;
-
+#ifdef DEBUG_PLUGIN_ADAPTER
+    std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
+              << sz << ")" << std::endl;
+#endif
+    
     size_t i = m_fsizes[plugin][n];
     if (i >= sz) return;
 
-//    std::cerr << "resizing from " << i << std::endl;
+#ifdef DEBUG_PLUGIN_ADAPTER
+    std::cerr << "resizing from " << i << std::endl;
+#endif
 
     m_fs[plugin][n].features = (VampFeatureUnion *)realloc
         (m_fs[plugin][n].features, 2 * sz * sizeof(VampFeatureUnion));
@@ -896,14 +909,18 @@ PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
 void
 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
 {
-//    std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
-//              << j << ", " << sz << ")" << std::endl;
-
+#ifdef DEBUG_PLUGIN_ADAPTER
+    std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
+              << j << ", " << sz << ")" << std::endl;
+#endif
+    
     size_t i = m_fvsizes[plugin][n][j];
     if (i >= sz) return;
 
-//    std::cerr << "resizing from " << i << std::endl;
-
+#ifdef DEBUG_PLUGIN_ADAPTER
+    std::cerr << "resizing from " << i << std::endl;
+#endif
+    
     m_fs[plugin][n].features[j].v1.values = (float *)realloc
         (m_fs[plugin][n].features[j].v1.values, sz * sizeof(float));
 
diff --git a/src/vamp-sdk/RealTime.cpp b/src/vamp-sdk/RealTime.cpp
index d3c4364..e4b58f9 100644
--- a/src/vamp-sdk/RealTime.cpp
+++ b/src/vamp-sdk/RealTime.cpp
@@ -43,7 +43,7 @@
 
 #include <iostream>
 
-#if (__GNUC__ < 3)
+#if (defined(__GNUC__)) && (__GNUC__ < 3)
 #include <strstream>
 #define stringstream strstream
 #else
@@ -82,17 +82,24 @@ RealTime::RealTime(int s, int n) :
 	while (nsec >=  ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
     } else if (sec < 0) {
 	while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; }
-	while (nsec > 0)             { nsec -= ONE_BILLION; ++sec; }
+	while (nsec > 0 && sec < 0)  { nsec -= ONE_BILLION; ++sec; }
     } else { 
 	while (nsec >=  ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
-	while (nsec < 0)             { nsec += ONE_BILLION; --sec; }
+	while (nsec < 0 && sec > 0)  { nsec += ONE_BILLION; --sec; }
     }
 }
 
 RealTime
 RealTime::fromSeconds(double sec)
 {
-    return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION + 0.5));
+    if (sec != sec) { // NaN
+        cerr << "ERROR: NaN/Inf passed to Vamp::RealTime::fromSeconds" << endl;
+        return RealTime::zeroTime;
+    } else if (sec >= 0) {
+        return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION + 0.5));
+    } else {
+        return -fromSeconds(-sec);
+    }
 }
 
 RealTime
@@ -105,7 +112,7 @@ RealTime::fromMilliseconds(int msec)
 RealTime
 RealTime::fromTimeval(const struct timeval &tv)
 {
-    return RealTime(tv.tv_sec, tv.tv_usec * 1000);
+    return RealTime(int(tv.tv_sec), int(tv.tv_usec * 1000));
 }
 #endif
 
@@ -139,10 +146,6 @@ RealTime::toString() const
     std::stringstream out;
     out << *this;
     
-#if (__GNUC__ < 3)
-    out << std::ends;
-#endif
-
     std::string s = out.str();
 
     // remove trailing R
@@ -152,22 +155,24 @@ RealTime::toString() const
 std::string
 RealTime::toText(bool fixedDp) const
 {
-    if (*this < RealTime::zeroTime) return "-" + (-*this).toText();
+    if (*this < RealTime::zeroTime) return "-" + (-*this).toText(fixedDp);
 
     std::stringstream out;
 
     if (sec >= 3600) {
-	out << (sec / 3600) << ":";
+        out << (sec / 3600) << ":";
     }
-
+    
     if (sec >= 60) {
-	out << (sec % 3600) / 60 << ":";
+        int minutes = (sec % 3600) / 60;
+        if (sec >= 3600 && minutes < 10) out << "0";
+        out << minutes << ":";
     }
-
+    
     if (sec >= 10) {
-	out << ((sec % 60) / 10);
+        out << ((sec % 60) / 10);
     }
-
+    
     out << (sec % 10);
     
     int ms = msec();
@@ -191,16 +196,11 @@ RealTime::toText(bool fixedDp) const
 	out << ".000";
     }
 	
-#if (__GNUC__ < 3)
-    out << std::ends;
-#endif
-
     std::string s = out.str();
 
     return s;
 }
 
-
 RealTime
 RealTime::operator/(int d) const
 {
@@ -226,8 +226,8 @@ long
 RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate)
 {
     if (time < zeroTime) return -realTime2Frame(-time, sampleRate);
-    double s = time.sec + double(time.nsec + 1) / 1000000000.0;
-    return long(s * sampleRate);
+    double s = time.sec + double(time.nsec) / ONE_BILLION;
+    return long(s * sampleRate + 0.5);
 }
 
 RealTime
@@ -235,11 +235,13 @@ RealTime::frame2RealTime(long frame, unsigned int sampleRate)
 {
     if (frame < 0) return -frame2RealTime(-frame, sampleRate);
 
-    RealTime rt;
-    rt.sec = frame / long(sampleRate);
-    frame -= rt.sec * long(sampleRate);
-    rt.nsec = (int)(((double(frame) * 1000000.0) / sampleRate) * 1000.0);
-    return rt;
+    int sec = int(frame / long(sampleRate));
+    frame -= sec * long(sampleRate);
+    int nsec = (int)((double(frame) / double(sampleRate)) * ONE_BILLION + 0.5);
+    // Use ctor here instead of setting data members directly to
+    // ensure nsec > ONE_BILLION is handled properly.  It's extremely
+    // unlikely, but not impossible.
+    return RealTime(sec, nsec);
 }
 
 const RealTime RealTime::zeroTime(0,0);
diff --git a/src/vamp-sdk/acsymbols.c b/src/vamp-sdk/acsymbols.c
index 176d26d..a9eec7e 100644
--- a/src/vamp-sdk/acsymbols.c
+++ b/src/vamp-sdk/acsymbols.c
@@ -1,6 +1,8 @@
 /* These stubs are provided so that autoconf can check library
  * versions using C symbols only */
 
+extern void libvampsdk_v_2_7_1_present(void) { }
+extern void libvampsdk_v_2_7_present(void) { }
 extern void libvampsdk_v_2_6_present(void) { }
 extern void libvampsdk_v_2_5_present(void) { }
 extern void libvampsdk_v_2_4_present(void) { }
diff --git a/src/vamp-sdk/ext/_kiss_fft_guts.h b/src/vamp-sdk/ext/_kiss_fft_guts.h
new file mode 100644
index 0000000..7467bb7
--- /dev/null
+++ b/src/vamp-sdk/ext/_kiss_fft_guts.h
@@ -0,0 +1,168 @@
+#ifndef KISS_FFT__GUTS_H
+#define KISS_FFT__GUTS_H
+/*
+Copyright (c) 2003-2010, Mark Borgerding
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * 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.
+    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* kiss_fft.h
+   defines kiss_fft_scalar as either short or a float type
+   and defines
+   typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
+#include "kiss_fft.h"
+#include <limits.h>
+
+#define MAXFACTORS 32
+/* e.g. an fft of length 128 has 4 factors 
+ as far as kissfft is concerned
+ 4*4*4*2
+ */
+
+struct kiss_fft_state{
+    int nfft;
+    int inverse;
+    int factors[2*MAXFACTORS];
+    kiss_fft_cpx twiddles[1];
+};
+
+/*
+  Explanation of macros dealing with complex math:
+
+   C_MUL(m,a,b)         : m = a*b
+   C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise
+   C_SUB( res, a,b)     : res = a - b
+   C_SUBFROM( res , a)  : res -= a
+   C_ADDTO( res , a)    : res += a
+ * */
+#ifdef FIXED_POINT
+#if (FIXED_POINT==32)
+# define FRACBITS 31
+# define SAMPPROD int64_t
+#define SAMP_MAX 2147483647
+#else
+# define FRACBITS 15
+# define SAMPPROD int32_t 
+#define SAMP_MAX 32767
+#endif
+
+#define SAMP_MIN -SAMP_MAX
+
+#if defined(CHECK_OVERFLOW)
+#  define CHECK_OVERFLOW_OP(a,op,b)  \
+	if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
+		fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) );  }
+#endif
+
+
+#   define smul(a,b) ( (SAMPPROD)(a)*(b) )
+#   define sround( x )  (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
+
+#   define S_MUL(a,b) sround( smul(a,b) )
+
+#   define C_MUL(m,a,b) \
+      do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
+          (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
+
+#   define DIVSCALAR(x,k) \
+	(x) = sround( smul(  x, SAMP_MAX/k ) )
+
+#   define C_FIXDIV(c,div) \
+	do {    DIVSCALAR( (c).r , div);  \
+		DIVSCALAR( (c).i  , div); }while (0)
+
+#   define C_MULBYSCALAR( c, s ) \
+    do{ (c).r =  sround( smul( (c).r , s ) ) ;\
+        (c).i =  sround( smul( (c).i , s ) ) ; }while(0)
+
+#else  /* not FIXED_POINT*/
+
+#   define S_MUL(a,b) ( (a)*(b) )
+#define C_MUL(m,a,b) \
+    do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
+        (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
+#   define C_FIXDIV(c,div) /* NOOP */
+#   define C_MULBYSCALAR( c, s ) \
+    do{ (c).r *= (s);\
+        (c).i *= (s); }while(0)
+#endif
+
+#ifndef CHECK_OVERFLOW_OP
+#  define CHECK_OVERFLOW_OP(a,op,b) /* noop */
+#endif
+
+#define  C_ADD( res, a,b)\
+    do { \
+	    CHECK_OVERFLOW_OP((a).r,+,(b).r)\
+	    CHECK_OVERFLOW_OP((a).i,+,(b).i)\
+	    (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \
+    }while(0)
+#define  C_SUB( res, a,b)\
+    do { \
+	    CHECK_OVERFLOW_OP((a).r,-,(b).r)\
+	    CHECK_OVERFLOW_OP((a).i,-,(b).i)\
+	    (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \
+    }while(0)
+#define C_ADDTO( res , a)\
+    do { \
+	    CHECK_OVERFLOW_OP((res).r,+,(a).r)\
+	    CHECK_OVERFLOW_OP((res).i,+,(a).i)\
+	    (res).r += (a).r;  (res).i += (a).i;\
+    }while(0)
+
+#define C_SUBFROM( res , a)\
+    do {\
+	    CHECK_OVERFLOW_OP((res).r,-,(a).r)\
+	    CHECK_OVERFLOW_OP((res).i,-,(a).i)\
+	    (res).r -= (a).r;  (res).i -= (a).i; \
+    }while(0)
+
+
+#ifdef FIXED_POINT
+#  define KISS_FFT_COS(phase)  floor(.5+SAMP_MAX * cos (phase))
+#  define KISS_FFT_SIN(phase)  floor(.5+SAMP_MAX * sin (phase))
+#  define HALF_OF(x) ((x)>>1)
+#elif defined(USE_SIMD)
+#  define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
+#  define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
+#  define HALF_OF(x) ((x)*_mm_set1_ps(.5))
+#else
+#  define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
+#  define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
+#  define HALF_OF(x) ((x)*.5)
+#endif
+
+#define  kf_cexp(x,phase) \
+	do{ \
+		(x)->r = KISS_FFT_COS(phase);\
+		(x)->i = KISS_FFT_SIN(phase);\
+	}while(0)
+
+
+/* a debugging function */
+#define pcpx(c)\
+    fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
+
+
+#ifdef KISS_FFT_USE_ALLOCA
+// define this to allow use of alloca instead of malloc for temporary buffers
+// Temporary buffers are used in two case: 
+// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
+// 2. "in-place" FFTs.  Notice the quotes, since kissfft does not really do an in-place transform.
+#include <alloca.h>
+#define  KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
+#define  KISS_FFT_TMP_FREE(ptr) 
+#else
+#define  KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
+#define  KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
+#endif
+
+#endif
diff --git a/src/vamp-sdk/ext/kiss_fft.c b/src/vamp-sdk/ext/kiss_fft.c
new file mode 100644
index 0000000..fdda414
--- /dev/null
+++ b/src/vamp-sdk/ext/kiss_fft.c
@@ -0,0 +1,409 @@
+/*
+Copyright (c) 2003-2010, Mark Borgerding
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * 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.
+    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include "_kiss_fft_guts.h"
+/* The guts header contains all the multiplication and addition macros that are defined for
+ fixed or floating point complex numbers.  It also delares the kf_ internal functions.
+ */
+
+static void kf_bfly2(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        int m
+        )
+{
+    kiss_fft_cpx * Fout2;
+    kiss_fft_cpx * tw1 = st->twiddles;
+    kiss_fft_cpx t;
+    Fout2 = Fout + m;
+    do{
+        C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
+
+        C_MUL (t,  *Fout2 , *tw1);
+        tw1 += fstride;
+        C_SUB( *Fout2 ,  *Fout , t );
+        C_ADDTO( *Fout ,  t );
+        ++Fout2;
+        ++Fout;
+    }while (--m);
+}
+
+static void kf_bfly4(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        const size_t m
+        )
+{
+    kiss_fft_cpx *tw1,*tw2,*tw3;
+    kiss_fft_cpx scratch[6];
+    size_t k=m;
+    const size_t m2=2*m;
+    const size_t m3=3*m;
+
+
+    tw3 = tw2 = tw1 = st->twiddles;
+
+    do {
+        C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
+
+        C_MUL(scratch[0],Fout[m] , *tw1 );
+        C_MUL(scratch[1],Fout[m2] , *tw2 );
+        C_MUL(scratch[2],Fout[m3] , *tw3 );
+
+        C_SUB( scratch[5] , *Fout, scratch[1] );
+        C_ADDTO(*Fout, scratch[1]);
+        C_ADD( scratch[3] , scratch[0] , scratch[2] );
+        C_SUB( scratch[4] , scratch[0] , scratch[2] );
+        C_SUB( Fout[m2], *Fout, scratch[3] );
+        tw1 += fstride;
+        tw2 += fstride*2;
+        tw3 += fstride*3;
+        C_ADDTO( *Fout , scratch[3] );
+
+        if(st->inverse) {
+            Fout[m].r = scratch[5].r - scratch[4].i;
+            Fout[m].i = scratch[5].i + scratch[4].r;
+            Fout[m3].r = scratch[5].r + scratch[4].i;
+            Fout[m3].i = scratch[5].i - scratch[4].r;
+        }else{
+            Fout[m].r = scratch[5].r + scratch[4].i;
+            Fout[m].i = scratch[5].i - scratch[4].r;
+            Fout[m3].r = scratch[5].r - scratch[4].i;
+            Fout[m3].i = scratch[5].i + scratch[4].r;
+        }
+        ++Fout;
+    }while(--k);
+}
+
+static void kf_bfly3(
+         kiss_fft_cpx * Fout,
+         const size_t fstride,
+         const kiss_fft_cfg st,
+         size_t m
+         )
+{
+     size_t k=m;
+     const size_t m2 = 2*m;
+     kiss_fft_cpx *tw1,*tw2;
+     kiss_fft_cpx scratch[5];
+     kiss_fft_cpx epi3;
+     epi3 = st->twiddles[fstride*m];
+
+     tw1=tw2=st->twiddles;
+
+     do{
+         C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+
+         C_MUL(scratch[1],Fout[m] , *tw1);
+         C_MUL(scratch[2],Fout[m2] , *tw2);
+
+         C_ADD(scratch[3],scratch[1],scratch[2]);
+         C_SUB(scratch[0],scratch[1],scratch[2]);
+         tw1 += fstride;
+         tw2 += fstride*2;
+
+         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+         C_MULBYSCALAR( scratch[0] , epi3.i );
+
+         C_ADDTO(*Fout,scratch[3]);
+
+         Fout[m2].r = Fout[m].r + scratch[0].i;
+         Fout[m2].i = Fout[m].i - scratch[0].r;
+
+         Fout[m].r -= scratch[0].i;
+         Fout[m].i += scratch[0].r;
+
+         ++Fout;
+     }while(--k);
+}
+
+static void kf_bfly5(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        int m
+        )
+{
+    kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+    int u;
+    kiss_fft_cpx scratch[13];
+    kiss_fft_cpx * twiddles = st->twiddles;
+    kiss_fft_cpx *tw;
+    kiss_fft_cpx ya,yb;
+    ya = twiddles[fstride*m];
+    yb = twiddles[fstride*2*m];
+
+    Fout0=Fout;
+    Fout1=Fout0+m;
+    Fout2=Fout0+2*m;
+    Fout3=Fout0+3*m;
+    Fout4=Fout0+4*m;
+
+    tw=st->twiddles;
+    for ( u=0; u<m; ++u ) {
+        C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+        scratch[0] = *Fout0;
+
+        C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
+        C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
+        C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
+        C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+        C_ADD( scratch[7],scratch[1],scratch[4]);
+        C_SUB( scratch[10],scratch[1],scratch[4]);
+        C_ADD( scratch[8],scratch[2],scratch[3]);
+        C_SUB( scratch[9],scratch[2],scratch[3]);
+
+        Fout0->r += scratch[7].r + scratch[8].r;
+        Fout0->i += scratch[7].i + scratch[8].i;
+
+        scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+        scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+        scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+        scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+
+        C_SUB(*Fout1,scratch[5],scratch[6]);
+        C_ADD(*Fout4,scratch[5],scratch[6]);
+
+        scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+        scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+        scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+        scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+
+        C_ADD(*Fout2,scratch[11],scratch[12]);
+        C_SUB(*Fout3,scratch[11],scratch[12]);
+
+        ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+    }
+}
+
+/* perform the butterfly for one stage of a mixed radix FFT */
+static void kf_bfly_generic(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        int m,
+        int p
+        )
+{
+    int u,k,q1,q;
+    kiss_fft_cpx * twiddles = st->twiddles;
+    kiss_fft_cpx t;
+    int Norig = st->nfft;
+
+    kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
+
+    for ( u=0; u<m; ++u ) {
+        k=u;
+        for ( q1=0 ; q1<p ; ++q1 ) {
+            scratch[q1] = Fout[ k  ];
+            C_FIXDIV(scratch[q1],p);
+            k += m;
+        }
+
+        k=u;
+        for ( q1=0 ; q1<p ; ++q1 ) {
+            int twidx=0;
+            Fout[ k ] = scratch[0];
+            for (q=1;q<p;++q ) {
+                twidx += int(fstride * k);
+                if (twidx>=Norig) twidx-=Norig;
+                C_MUL(t,scratch[q] , twiddles[twidx] );
+                C_ADDTO( Fout[ k ] ,t);
+            }
+            k += m;
+        }
+    }
+    KISS_FFT_TMP_FREE(scratch);
+}
+
+static
+void kf_work(
+        kiss_fft_cpx * Fout,
+        const kiss_fft_cpx * f,
+        const size_t fstride,
+        int in_stride,
+        int * factors,
+        const kiss_fft_cfg st
+        )
+{
+    kiss_fft_cpx * Fout_beg=Fout;
+    const int p=*factors++; /* the radix  */
+    const int m=*factors++; /* stage's fft length/p */
+    const kiss_fft_cpx * Fout_end = Fout + p*m;
+
+#ifdef _OPENMP
+    // use openmp extensions at the 
+    // top-level (not recursive)
+    if (fstride==1 && p<=5)
+    {
+        int k;
+
+        // execute the p different work units in different threads
+#       pragma omp parallel for
+        for (k=0;k<p;++k) 
+            kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
+        // all threads have joined by this point
+
+        switch (p) {
+            case 2: kf_bfly2(Fout,fstride,st,m); break;
+            case 3: kf_bfly3(Fout,fstride,st,m); break; 
+            case 4: kf_bfly4(Fout,fstride,st,m); break;
+            case 5: kf_bfly5(Fout,fstride,st,m); break; 
+            default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+        }
+        return;
+    }
+#endif
+
+    if (m==1) {
+        do{
+            Fout->r = f->r;
+            Fout->i = f->i;
+            f += fstride*in_stride;
+        }while(++Fout != Fout_end );
+    }else{
+        do{
+            // recursive call:
+            // DFT of size m*p performed by doing
+            // p instances of smaller DFTs of size m, 
+            // each one takes a decimated version of the input
+            kf_work( Fout , f, fstride*p, in_stride, factors,st);
+            f += fstride*in_stride;
+        }while( (Fout += m) != Fout_end );
+    }
+
+    Fout=Fout_beg;
+
+    // recombine the p smaller DFTs 
+    switch (p) {
+        case 2: kf_bfly2(Fout,fstride,st,m); break;
+        case 3: kf_bfly3(Fout,fstride,st,m); break; 
+        case 4: kf_bfly4(Fout,fstride,st,m); break;
+        case 5: kf_bfly5(Fout,fstride,st,m); break; 
+        default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+    }
+}
+
+/*  facbuf is populated by p1,m1,p2,m2, ...
+    where 
+    p[i] * m[i] = m[i-1]
+    m0 = n                  */
+static 
+void kf_factor(int n,int * facbuf)
+{
+    int p=4;
+    double floor_sqrt;
+    floor_sqrt = floor( sqrt((double)n) );
+
+    /*factor out powers of 4, powers of 2, then any remaining primes */
+    do {
+        while (n % p) {
+            switch (p) {
+                case 4: p = 2; break;
+                case 2: p = 3; break;
+                default: p += 2; break;
+            }
+            if (p > floor_sqrt)
+                p = n;          /* no more factors, skip to end */
+        }
+        n /= p;
+        *facbuf++ = p;
+        *facbuf++ = n;
+    } while (n > 1);
+}
+
+/*
+ *
+ * User-callable function to allocate all necessary storage space for the fft.
+ *
+ * The return value is a contiguous block of memory, allocated with malloc.  As such,
+ * It can be freed with free(), rather than a kiss_fft-specific function.
+ * */
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
+{
+    kiss_fft_cfg st=NULL;
+    size_t memneeded = sizeof(struct kiss_fft_state)
+        + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
+
+    if ( lenmem==NULL ) {
+        st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
+    }else{
+        if (mem != NULL && *lenmem >= memneeded)
+            st = (kiss_fft_cfg)mem;
+        *lenmem = memneeded;
+    }
+    if (st) {
+        int i;
+        st->nfft=nfft;
+        st->inverse = inverse_fft;
+
+        for (i=0;i<nfft;++i) {
+            const double pi=3.141592653589793238462643383279502884197169399375105820974944;
+            double phase = -2*pi*i / nfft;
+            if (st->inverse)
+                phase *= -1;
+            kf_cexp(st->twiddles+i, phase );
+        }
+
+        kf_factor(nfft,st->factors);
+    }
+    return st;
+}
+
+
+void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
+{
+    if (fin == fout) {
+        //NOTE: this is not really an in-place FFT algorithm.
+        //It just performs an out-of-place FFT into a temp buffer
+        kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
+        kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
+        memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
+        KISS_FFT_TMP_FREE(tmpbuf);
+    }else{
+        kf_work( fout, fin, 1,in_stride, st->factors,st );
+    }
+}
+
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+    kiss_fft_stride(cfg,fin,fout,1);
+}
+
+
+void kiss_fft_cleanup(void)
+{
+    // nothing needed any more
+}
+
+int kiss_fft_next_fast_size(int n)
+{
+    while(1) {
+        int m=n;
+        while ( (m%2) == 0 ) m/=2;
+        while ( (m%3) == 0 ) m/=3;
+        while ( (m%5) == 0 ) m/=5;
+        if (m<=1)
+            break; /* n is completely factorable by twos, threes, and fives */
+        n++;
+    }
+    return n;
+}
diff --git a/src/vamp-sdk/ext/kiss_fft.h b/src/vamp-sdk/ext/kiss_fft.h
new file mode 100644
index 0000000..b8baff5
--- /dev/null
+++ b/src/vamp-sdk/ext/kiss_fft.h
@@ -0,0 +1,132 @@
+#ifndef KISS_FFT_H
+#define KISS_FFT_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifndef KISSFFT_USE_CPP_LINKAGE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif
+
+/*
+ ATTENTION!
+ If you would like a :
+ -- a utility that will handle the caching of fft objects
+ -- real-only (no imaginary time component ) FFT
+ -- a multi-dimensional FFT
+ -- a command-line utility to perform ffts
+ -- a command-line utility to perform fast-convolution filtering
+
+ Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
+  in the tools/ directory.
+*/
+
+#ifdef USE_SIMD
+# include <xmmintrin.h>
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
+#define KISS_FFT_FREE _mm_free
+#else	
+#define KISS_FFT_MALLOC malloc
+#define KISS_FFT_FREE free
+#endif	
+
+
+#ifdef FIXED_POINT
+#include <sys/types.h>	
+# if (FIXED_POINT == 32)
+#  define kiss_fft_scalar int32_t
+# else	
+#  define kiss_fft_scalar int16_t
+# endif
+#else
+# ifndef kiss_fft_scalar
+/*  default is float */
+#   define kiss_fft_scalar float
+# endif
+#endif
+
+typedef struct {
+    kiss_fft_scalar r;
+    kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct kiss_fft_state* kiss_fft_cfg;
+
+/* 
+ *  kiss_fft_alloc
+ *  
+ *  Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ *  typical usage:      kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
+ *
+ *  The return value from fft_alloc is a cfg buffer used internally
+ *  by the fft routine or NULL.
+ *
+ *  If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
+ *  The returned value should be free()d when done to avoid memory leaks.
+ *  
+ *  The state can be placed in a user supplied buffer 'mem':
+ *  If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ *      then the function places the cfg in mem and the size used in *lenmem
+ *      and returns mem.
+ *  
+ *  If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ *      then the function returns NULL and places the minimum cfg 
+ *      buffer size in *lenmem.
+ * */
+
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); 
+
+/*
+ * kiss_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be  f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be   F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+    f[k].r and f[k].i
+ * */
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+/*
+ A more generic version of the above function. It reads its input from every Nth sample.
+ * */
+void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
+
+/* If kiss_fft_alloc allocated a buffer, it is one contiguous 
+   buffer and can be simply free()d when no longer needed*/
+#define kiss_fft_free free
+
+/*
+ Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up 
+ your compiler output to call this before you exit.
+*/
+void kiss_fft_cleanup(void);
+	
+
+/*
+ * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
+ */
+int kiss_fft_next_fast_size(int n);
+
+/* for real ffts, we need an even size */
+#define kiss_fftr_next_fast_size_real(n) \
+        (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
+
+#ifndef KISSFFT_USE_CPP_LINKAGE
+#ifdef __cplusplus
+} 
+#endif
+#endif
+
+#ifdef KISSFFT_USE_CPP_LINKAGE
+#define KISSFFT_USED_CPP_LINKAGE 1
+#endif
+
+#endif
diff --git a/src/vamp-sdk/ext/kiss_fftr.c b/src/vamp-sdk/ext/kiss_fftr.c
new file mode 100644
index 0000000..b8e238b
--- /dev/null
+++ b/src/vamp-sdk/ext/kiss_fftr.c
@@ -0,0 +1,159 @@
+/*
+Copyright (c) 2003-2004, Mark Borgerding
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * 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.
+    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "kiss_fftr.h"
+#include "_kiss_fft_guts.h"
+
+struct kiss_fftr_state{
+    kiss_fft_cfg substate;
+    kiss_fft_cpx * tmpbuf;
+    kiss_fft_cpx * super_twiddles;
+#ifdef USE_SIMD
+    void * pad;
+#endif
+};
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
+{
+    int i;
+    kiss_fftr_cfg st = NULL;
+    size_t subsize, memneeded;
+
+    if (nfft & 1) {
+        fprintf(stderr,"Real FFT optimization must be even.\n");
+        return NULL;
+    }
+    nfft >>= 1;
+
+    kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
+    memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
+
+    if (lenmem == NULL) {
+        st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
+    } else {
+        if (*lenmem >= memneeded)
+            st = (kiss_fftr_cfg) mem;
+        *lenmem = memneeded;
+    }
+    if (!st)
+        return NULL;
+
+    st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
+    st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
+    st->super_twiddles = st->tmpbuf + nfft;
+    kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
+
+    for (i = 0; i < nfft/2; ++i) {
+        double phase =
+            -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
+        if (inverse_fft)
+            phase *= -1;
+        kf_cexp (st->super_twiddles+i,phase);
+    }
+    return st;
+}
+
+void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
+{
+    /* input buffer timedata is stored row-wise */
+    int k,ncfft;
+    kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
+
+    if ( st->substate->inverse) {
+        fprintf(stderr,"kiss fft usage error: improper alloc\n");
+        exit(1);
+    }
+
+    ncfft = st->substate->nfft;
+
+    /*perform the parallel fft of two real signals packed in real,imag*/
+    kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
+    /* The real part of the DC element of the frequency spectrum in st->tmpbuf
+     * contains the sum of the even-numbered elements of the input time sequence
+     * The imag part is the sum of the odd-numbered elements
+     *
+     * The sum of tdc.r and tdc.i is the sum of the input time sequence. 
+     *      yielding DC of input time sequence
+     * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... 
+     *      yielding Nyquist bin of input time sequence
+     */
+ 
+    tdc.r = st->tmpbuf[0].r;
+    tdc.i = st->tmpbuf[0].i;
+    C_FIXDIV(tdc,2);
+    CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
+    CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
+    freqdata[0].r = tdc.r + tdc.i;
+    freqdata[ncfft].r = tdc.r - tdc.i;
+#ifdef USE_SIMD    
+    freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
+#else
+    freqdata[ncfft].i = freqdata[0].i = 0;
+#endif
+
+    for ( k=1;k <= ncfft/2 ; ++k ) {
+        fpk    = st->tmpbuf[k]; 
+        fpnk.r =   st->tmpbuf[ncfft-k].r;
+        fpnk.i = - st->tmpbuf[ncfft-k].i;
+        C_FIXDIV(fpk,2);
+        C_FIXDIV(fpnk,2);
+
+        C_ADD( f1k, fpk , fpnk );
+        C_SUB( f2k, fpk , fpnk );
+        C_MUL( tw , f2k , st->super_twiddles[k-1]);
+
+        freqdata[k].r = HALF_OF(f1k.r + tw.r);
+        freqdata[k].i = HALF_OF(f1k.i + tw.i);
+        freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
+        freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
+    }
+}
+
+void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
+{
+    /* input buffer timedata is stored row-wise */
+    int k, ncfft;
+
+    if (st->substate->inverse == 0) {
+        fprintf (stderr, "kiss fft usage error: improper alloc\n");
+        exit (1);
+    }
+
+    ncfft = st->substate->nfft;
+
+    st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
+    st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
+    C_FIXDIV(st->tmpbuf[0],2);
+
+    for (k = 1; k <= ncfft / 2; ++k) {
+        kiss_fft_cpx fk, fnkc, fek, fok, tmp;
+        fk = freqdata[k];
+        fnkc.r = freqdata[ncfft - k].r;
+        fnkc.i = -freqdata[ncfft - k].i;
+        C_FIXDIV( fk , 2 );
+        C_FIXDIV( fnkc , 2 );
+
+        C_ADD (fek, fk, fnkc);
+        C_SUB (tmp, fk, fnkc);
+        C_MUL (fok, tmp, st->super_twiddles[k-1]);
+        C_ADD (st->tmpbuf[k],     fek, fok);
+        C_SUB (st->tmpbuf[ncfft - k], fek, fok);
+#ifdef USE_SIMD        
+        st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
+#else
+        st->tmpbuf[ncfft - k].i *= -1;
+#endif
+    }
+    kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
+}
diff --git a/src/vamp-sdk/ext/kiss_fftr.h b/src/vamp-sdk/ext/kiss_fftr.h
new file mode 100644
index 0000000..bfac16c
--- /dev/null
+++ b/src/vamp-sdk/ext/kiss_fftr.h
@@ -0,0 +1,56 @@
+#ifndef KISS_FTR_H
+#define KISS_FTR_H
+
+#include "kiss_fft.h"
+
+#ifndef KISSFFT_USE_CPP_LINKAGE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif
+
+    
+/* 
+ 
+ Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
+
+ 
+ 
+ */
+
+typedef struct kiss_fftr_state *kiss_fftr_cfg;
+
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
+/*
+ nfft must be even
+
+ If you don't care to allocate space, use mem = lenmem = NULL 
+*/
+
+
+void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
+/*
+ input timedata has nfft scalar points
+ output freqdata has nfft/2+1 complex points
+*/
+
+void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
+/*
+ input freqdata has  nfft/2+1 complex points
+ output timedata has nfft scalar points
+*/
+
+#define kiss_fftr_free free
+
+#ifndef KISSFFT_USE_CPP_LINKAGE
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#ifdef KISSFFT_USE_CPP_LINKAGE
+#define KISSFFT_USED_CPP_LINKAGE 1
+#endif
+
+#endif
diff --git a/test/expected/vamp-test-plugin-freq_curve-fsr-mixed.txt b/test/expected/vamp-test-plugin-freq_curve-fsr-mixed.txt
new file mode 100644
index 0000000..28c19a0
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_curve-fsr-mixed.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:curve-fsr-mixed
+ 2.400000000: 0 1 of 10: 0 at 2.4 snap to 2.4
+ 2.800000000: 0.1 2 of 10: 0.1 at 2.9 snap to 2.8
+ 3.200000000: 0.2 3 of 10: 0.2 at 3.14 snap to 3.2
+ 3.600000000: 0.3 4 of 10: 0.3 at 3.5 snap to 3.6
+ 4.000000000: 0.4 5 of 10: 0.4 at 4
+ 4.400000000: 0.5 6 of 10: 0.5 at 4.4
+ 4.000000000: 0.6 7 of 10: 0.6 at 3.9 snap to 4
+ 4.400000000: 0.7 8 of 10: 0.7 at 4.4 snap to 4.4
+ 4.800000000: 0.8 9 of 10: 0.8 at 4.8
+ 5.200000000: 0.9 10 of 10: 0.9 at 5 snap to 5.2
diff --git a/test/expected/vamp-test-plugin-freq_curve-fsr-timed.txt b/test/expected/vamp-test-plugin-freq_curve-fsr-timed.txt
new file mode 100644
index 0000000..9964c02
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_curve-fsr-timed.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:curve-fsr-timed
+ 0.000000000: 0 1 of 10: 0 at 0 snap to 0
+ 0.000000000: 0.1 2 of 10: 0.1 at 0 snap to 0
+ 0.000000000: 0.2 3 of 10: 0.2 at 0.166 snap to 0
+ 0.400000000: 0.3 4 of 10: 0.3 at 0.333 snap to 0.4
+ 2.000000000: 0.4 5 of 10: 0.4 at 2 snap to 2
+ 2.000000000: 0.5 6 of 10: 0.5 at 2 snap to 2
+ 2.000000000: 0.6 7 of 10: 0.6 at 2.166 snap to 2
+ 2.400000000: 0.7 8 of 10: 0.7 at 2.333 snap to 2.4
+ 4.000000000: 0.8 9 of 10: 0.8 at 4 snap to 4
+ 4.000000000: 0.9 10 of 10: 0.9 at 4 snap to 4
diff --git a/test/expected/vamp-test-plugin-freq_curve-fsr.txt b/test/expected/vamp-test-plugin-freq_curve-fsr.txt
new file mode 100644
index 0000000..4428f07
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_curve-fsr.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:curve-fsr
+ 0.000000000: 0 1 of 10: 0 at 0
+ 0.400000000: 0.1 2 of 10: 0.1 at 0.4
+ 0.800000000: 0.2 3 of 10: 0.2 at 0.8
+ 1.200000000: 0.3 4 of 10: 0.3 at 1.2
+ 1.600000000: 0.4 5 of 10: 0.4 at 1.6
+ 2.000000000: 0.5 6 of 10: 0.5 at 2
+ 2.400000000: 0.6 7 of 10: 0.6 at 2.4
+ 2.800000000: 0.7 8 of 10: 0.7 at 2.8
+ 3.200000000: 0.8 9 of 10: 0.8 at 3.2
+ 3.600000000: 0.9 10 of 10: 0.9 at 3.6
diff --git a/test/expected/vamp-test-plugin-freq_curve-oss.txt b/test/expected/vamp-test-plugin-freq_curve-oss.txt
new file mode 100644
index 0000000..d864844
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_curve-oss.txt
@@ -0,0 +1,21 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:curve-oss
+ 0.023219955: 0 1 of 20: 0 at 0.023
+ 0.046439909: 0.05 2 of 20: 0.05 at 0.046
+ 0.069659864: 0.1 3 of 20: 0.1 at 0.069
+ 0.092879819: 0.15 4 of 20: 0.15 at 0.092
+ 0.116099773: 0.2 5 of 20: 0.2 at 0.116
+ 0.139319728: 0.25 6 of 20: 0.25 at 0.139
+ 0.162539683: 0.3 7 of 20: 0.3 at 0.162
+ 0.185759637: 0.35 8 of 20: 0.35 at 0.185
+ 0.208979592: 0.4 9 of 20: 0.4 at 0.208
+ 0.232199546: 0.45 10 of 20: 0.45 at 0.232
+ 0.255419501: 0.5 11 of 20: 0.5 at 0.255
+ 0.278639456: 0.55 12 of 20: 0.55 at 0.278
+ 0.301859410: 0.6 13 of 20: 0.6 at 0.301
+ 0.325079365: 0.65 14 of 20: 0.65 at 0.325
+ 0.348299320: 0.7 15 of 20: 0.7 at 0.348
+ 0.371519274: 0.75 16 of 20: 0.75 at 0.371
+ 0.394739229: 0.8 17 of 20: 0.8 at 0.394
+ 0.417959184: 0.85 18 of 20: 0.85 at 0.417
+ 0.441179138: 0.9 19 of 20: 0.9 at 0.441
+ 0.464399093: 0.95 20 of 20: 0.95 at 0.464
diff --git a/test/expected/vamp-test-plugin-freq_curve-vsr.txt b/test/expected/vamp-test-plugin-freq_curve-vsr.txt
new file mode 100644
index 0000000..709134f
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_curve-vsr.txt
@@ -0,0 +1,10 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:curve-vsr
+ 0.750000000: 0.1 2 of 10: 0.1 at 0.75
+ 1.500000000: 0.2 3 of 10: 0.2 at 1.5
+ 2.250000000: 0.3 4 of 10: 0.3 at 2.25
+ 3.000000000: 0.4 5 of 10: 0.4 at 3
+ 3.750000000: 0.5 6 of 10: 0.5 at 3.75
+ 4.500000000: 0.6 7 of 10: 0.6 at 4.5
+ 5.250000000: 0.7 8 of 10: 0.7 at 5.25
+ 6.000000000: 0.8 9 of 10: 0.8 at 6
+ 6.750000000: 0.9 10 of 10: 0.9 at 6.75
diff --git a/test/expected/vamp-test-plugin-freq_grid-fsr.txt b/test/expected/vamp-test-plugin-freq_grid-fsr.txt
new file mode 100644
index 0000000..30db1f7
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_grid-fsr.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:grid-fsr
+ 0.000000000: 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 1 of 10 at 0
+ 0.400000000: 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 2 of 10 at 0.4
+ 0.800000000: 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 3 of 10 at 0.8
+ 1.200000000: 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 4 of 10 at 1.2
+ 1.600000000: 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 5 of 10 at 1.6
+ 2.000000000: 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 6 of 10 at 2
+ 2.400000000: 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 7 of 10 at 2.4
+ 2.800000000: 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 8 of 10 at 2.8
+ 3.200000000: 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 9 of 10 at 3.2
+ 3.600000000: 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 10 of 10 at 3.6
diff --git a/test/expected/vamp-test-plugin-freq_grid-oss.txt b/test/expected/vamp-test-plugin-freq_grid-oss.txt
new file mode 100644
index 0000000..38c96fe
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_grid-oss.txt
@@ -0,0 +1,21 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:grid-oss
+ 0.023219955: 0.0666667 0.1 0.133333 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 1 of 20 at 0.023
+ 0.046439909: 0.1 0.133333 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 2 of 20 at 0.046
+ 0.069659864: 0.133333 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 3 of 20 at 0.069
+ 0.092879819: 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 4 of 20 at 0.092
+ 0.116099773: 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 5 of 20 at 0.116
+ 0.139319728: 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 6 of 20 at 0.139
+ 0.162539683: 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 7 of 20 at 0.162
+ 0.185759637: 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 8 of 20 at 0.185
+ 0.208979592: 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 9 of 20 at 0.208
+ 0.232199546: 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 10 of 20 at 0.232
+ 0.255419501: 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 11 of 20 at 0.255
+ 0.278639456: 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 12 of 20 at 0.278
+ 0.301859410: 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 13 of 20 at 0.301
+ 0.325079365: 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 14 of 20 at 0.325
+ 0.348299320: 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 15 of 20 at 0.348
+ 0.371519274: 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 16 of 20 at 0.371
+ 0.394739229: 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 17 of 20 at 0.394
+ 0.417959184: 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 0.933333 18 of 20 at 0.417
+ 0.441179138: 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 0.933333 0.966667 19 of 20 at 0.441
+ 0.464399093: 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 0.933333 0.966667 1 20 of 20 at 0.464
diff --git a/test/expected/vamp-test-plugin-freq_input-summary.txt b/test/expected/vamp-test-plugin-freq_input-summary.txt
new file mode 100644
index 0000000..82bdefb
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_input-summary.txt
@@ -0,0 +1,841 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:input-summary
+ 0.023219955: 0 0 
+ 0.046439909: 1.04688 482 
+ 0.069659864: 0 968.992 
+ 0.092879819: 1.09375 981.992 
+ 0.116099773: 0 993.992 
+ 0.139319728: 1.14844 997.992 
+ 0.162539683: 0 999.992 
+ 0.185759637: 1.19531 1002.99 
+ 0.208979592: 0 1005.99 
+ 0.232199546: 1.24219 1005.99 
+ 0.255419501: 0 1007.99 
+ 0.278639456: 1.29688 1007.99 
+ 0.301859410: 0 1007 
+ 0.325079365: 1.34375 1011.99 
+ 0.348299320: 0 1014.99 
+ 0.371519274: 1.39062 1015.99 
+ 0.394739229: 0 1015 
+ 0.417959184: 1.44531 1015.99 
+ 0.441179138: 0 1015.99 
+ 0.464399093: 1.49219 1017.99 
+ 0.487619048: 0 1016 
+ 0.510839002: 1.53906 1016.99 
+ 0.534058957: 0 1015.99 
+ 0.557278912: 1.59375 1015.99 
+ 0.580498866: 0 1016 
+ 0.603718821: 1.64062 1016 
+ 0.626938776: 0 1016.99 
+ 0.650158730: 1.6875 1016.99 
+ 0.673378685: 0 1017 
+ 0.696598639: 1.74219 1017.99 
+ 0.719818594: 0 1016.99 
+ 0.743038549: 1.78906 1016.99 
+ 0.766258503: 0 1017.99 
+ 0.789478458: 1.83594 1017 
+ 0.812698413: 0 1016.99 
+ 0.835918367: 1.89062 1016.99 
+ 0.859138322: 0 1017.99 
+ 0.882358277: 1.9375 1016.99 
+ 0.905578231: 0 1015.99 
+ 0.928798186: 0 507 
+ 0.952018141: 0 0 
+ 0.975238095: 1.04688 482 
+ 0.998458050: 0 968.992 
+ 1.021678005: 1.09375 981.992 
+ 1.044897959: 0 993.992 
+ 1.068117914: 1.14844 997.992 
+ 1.091337868: 0 999.992 
+ 1.114557823: 1.19531 1002.99 
+ 1.137777778: 0 1005.99 
+ 1.160997732: 1.24219 1005.99 
+ 1.184217687: 0 1007.99 
+ 1.207437642: 1.29688 1007.99 
+ 1.230657596: 0 1007 
+ 1.253877551: 1.34375 1011.99 
+ 1.277097506: 0 1014.99 
+ 1.300317460: 1.39062 1015.99 
+ 1.323537415: 0 1015 
+ 1.346757370: 1.44531 1015.99 
+ 1.369977324: 0 1015.99 
+ 1.393197279: 1.49219 1017.99 
+ 1.416417234: 0 1016 
+ 1.439637188: 1.53906 1016.99 
+ 1.462857143: 0 1015.99 
+ 1.486077098: 1.59375 1015.99 
+ 1.509297052: 0 1016 
+ 1.532517007: 1.64062 1016 
+ 1.555736961: 0 1016.99 
+ 1.578956916: 1.6875 1016.99 
+ 1.602176871: 0 1017 
+ 1.625396825: 1.74219 1017.99 
+ 1.648616780: 0 1016.99 
+ 1.671836735: 1.78906 1016.99 
+ 1.695056689: 0 1017.99 
+ 1.718276644: 1.83594 1017 
+ 1.741496599: 0 1016.99 
+ 1.764716553: 1.89062 1016.99 
+ 1.787936508: 0 1017.99 
+ 1.811156463: 1.9375 1016.99 
+ 1.834376417: 0 1015.99 
+ 1.857596372: 0 507 
+ 1.880816327: 0 0 
+ 1.904036281: 1.04688 482 
+ 1.927256236: 0 968.992 
+ 1.950476190: 1.09375 981.992 
+ 1.973696145: 0 993.992 
+ 1.996916100: 1.14844 997.992 
+ 2.020136054: 0 999.992 
+ 2.043356009: 1.19531 1002.99 
+ 2.066575964: 0 1005.99 
+ 2.089795918: 1.24219 1005.99 
+ 2.113015873: 0 1007.99 
+ 2.136235828: 1.29688 1007.99 
+ 2.159455782: 0 1007 
+ 2.182675737: 1.34375 1011.99 
+ 2.205895692: 0 1014.99 
+ 2.229115646: 1.39062 1015.99 
+ 2.252335601: 0 1015 
+ 2.275555556: 1.44531 1015.99 
+ 2.298775510: 0 1015.99 
+ 2.321995465: 1.49219 1017.99 
+ 2.345215420: 0 1016 
+ 2.368435374: 1.53906 1016.99 
+ 2.391655329: 0 1015.99 
+ 2.414875283: 1.59375 1015.99 
+ 2.438095238: 0 1016 
+ 2.461315193: 1.64062 1016 
+ 2.484535147: 0 1016.99 
+ 2.507755102: 1.6875 1016.99 
+ 2.530975057: 0 1017 
+ 2.554195011: 1.74219 1017.99 
+ 2.577414966: 0 1016.99 
+ 2.600634921: 1.78906 1016.99 
+ 2.623854875: 0 1017.99 
+ 2.647074830: 1.83594 1017 
+ 2.670294785: 0 1016.99 
+ 2.693514739: 1.89062 1016.99 
+ 2.716734694: 0 1017.99 
+ 2.739954649: 1.9375 1016.99 
+ 2.763174603: 0 1015.99 
+ 2.786394558: 0 507 
+ 2.809614512: 0 0 
+ 2.832834467: 1.04688 482 
+ 2.856054422: 0 968.992 
+ 2.879274376: 1.09375 981.992 
+ 2.902494331: 0 993.992 
+ 2.925714286: 1.14844 997.992 
+ 2.948934240: 0 999.992 
+ 2.972154195: 1.19531 1002.99 
+ 2.995374150: 0 1005.99 
+ 3.018594104: 1.24219 1005.99 
+ 3.041814059: 0 1007.99 
+ 3.065034014: 1.29688 1007.99 
+ 3.088253968: 0 1007 
+ 3.111473923: 1.34375 1011.99 
+ 3.134693878: 0 1014.99 
+ 3.157913832: 1.39062 1015.99 
+ 3.181133787: 0 1015 
+ 3.204353741: 1.44531 1015.99 
+ 3.227573696: 0 1015.99 
+ 3.250793651: 1.49219 1017.99 
+ 3.274013605: 0 1016 
+ 3.297233560: 1.53906 1016.99 
+ 3.320453515: 0 1015.99 
+ 3.343673469: 1.59375 1015.99 
+ 3.366893424: 0 1016 
+ 3.390113379: 1.64062 1016 
+ 3.413333333: 0 1016.99 
+ 3.436553288: 1.6875 1016.99 
+ 3.459773243: 0 1017 
+ 3.482993197: 1.74219 1017.99 
+ 3.506213152: 0 1016.99 
+ 3.529433107: 1.78906 1016.99 
+ 3.552653061: 0 1017.99 
+ 3.575873016: 1.83594 1017 
+ 3.599092971: 0 1016.99 
+ 3.622312925: 1.89062 1016.99 
+ 3.645532880: 0 1017.99 
+ 3.668752834: 1.9375 1016.99 
+ 3.691972789: 0 1015.99 
+ 3.715192744: 0 507 
+ 3.738412698: 0 0 
+ 3.761632653: 1.04688 482 
+ 3.784852608: 0 968.992 
+ 3.808072562: 1.09375 981.992 
+ 3.831292517: 0 993.992 
+ 3.854512472: 1.14844 997.992 
+ 3.877732426: 0 999.992 
+ 3.900952381: 1.19531 1002.99 
+ 3.924172336: 0 1005.99 
+ 3.947392290: 1.24219 1005.99 
+ 3.970612245: 0 1007.99 
+ 3.993832200: 1.29688 1007.99 
+ 4.017052154: 0 1007 
+ 4.040272109: 1.34375 1011.99 
+ 4.063492063: 0 1014.99 
+ 4.086712018: 1.39062 1015.99 
+ 4.109931973: 0 1015 
+ 4.133151927: 1.44531 1015.99 
+ 4.156371882: 0 1015.99 
+ 4.179591837: 1.49219 1017.99 
+ 4.202811791: 0 1016 
+ 4.226031746: 1.53906 1016.99 
+ 4.249251701: 0 1015.99 
+ 4.272471655: 1.59375 1015.99 
+ 4.295691610: 0 1016 
+ 4.318911565: 1.64062 1016 
+ 4.342131519: 0 1016.99 
+ 4.365351474: 1.6875 1016.99 
+ 4.388571429: 0 1017 
+ 4.411791383: 1.74219 1017.99 
+ 4.435011338: 0 1016.99 
+ 4.458231293: 1.78906 1016.99 
+ 4.481451247: 0 1017.99 
+ 4.504671202: 1.83594 1017 
+ 4.527891156: 0 1016.99 
+ 4.551111111: 1.89062 1016.99 
+ 4.574331066: 0 1017.99 
+ 4.597551020: 1.9375 1016.99 
+ 4.620770975: 0 1015.99 
+ 4.643990930: 0 507 
+ 4.667210884: 0 0 
+ 4.690430839: 1.04688 482 
+ 4.713650794: 0 968.992 
+ 4.736870748: 1.09375 981.992 
+ 4.760090703: 0 993.992 
+ 4.783310658: 1.14844 997.992 
+ 4.806530612: 0 999.992 
+ 4.829750567: 1.19531 1002.99 
+ 4.852970522: 0 1005.99 
+ 4.876190476: 1.24219 1005.99 
+ 4.899410431: 0 1007.99 
+ 4.922630385: 1.29688 1007.99 
+ 4.945850340: 0 1007 
+ 4.969070295: 1.34375 1011.99 
+ 4.992290249: 0 1014.99 
+ 5.015510204: 1.39062 1015.99 
+ 5.038730159: 0 1015 
+ 5.061950113: 1.44531 1015.99 
+ 5.085170068: 0 1015.99 
+ 5.108390023: 1.49219 1017.99 
+ 5.131609977: 0 1016 
+ 5.154829932: 1.53906 1016.99 
+ 5.178049887: 0 1015.99 
+ 5.201269841: 1.59375 1015.99 
+ 5.224489796: 0 1016 
+ 5.247709751: 1.64062 1016 
+ 5.270929705: 0 1016.99 
+ 5.294149660: 1.6875 1016.99 
+ 5.317369615: 0 1017 
+ 5.340589569: 1.74219 1017.99 
+ 5.363809524: 0 1016.99 
+ 5.387029478: 1.78906 1016.99 
+ 5.410249433: 0 1017.99 
+ 5.433469388: 1.83594 1017 
+ 5.456689342: 0 1016.99 
+ 5.479909297: 1.89062 1016.99 
+ 5.503129252: 0 1017.99 
+ 5.526349206: 1.9375 1016.99 
+ 5.549569161: 0 1015.99 
+ 5.572789116: 0 507 
+ 5.596009070: 0 0 
+ 5.619229025: 1.04688 482 
+ 5.642448980: 0 968.992 
+ 5.665668934: 1.09375 981.992 
+ 5.688888889: 0 993.992 
+ 5.712108844: 1.14844 997.992 
+ 5.735328798: 0 999.992 
+ 5.758548753: 1.19531 1002.99 
+ 5.781768707: 0 1005.99 
+ 5.804988662: 1.24219 1005.99 
+ 5.828208617: 0 1007.99 
+ 5.851428571: 1.29688 1007.99 
+ 5.874648526: 0 1007 
+ 5.897868481: 1.34375 1011.99 
+ 5.921088435: 0 1014.99 
+ 5.944308390: 1.39062 1015.99 
+ 5.967528345: 0 1015 
+ 5.990748299: 1.44531 1015.99 
+ 6.013968254: 0 1015.99 
+ 6.037188209: 1.49219 1017.99 
+ 6.060408163: 0 1016 
+ 6.083628118: 1.53906 1016.99 
+ 6.106848073: 0 1015.99 
+ 6.130068027: 1.59375 1015.99 
+ 6.153287982: 0 1016 
+ 6.176507937: 1.64062 1016 
+ 6.199727891: 0 1016.99 
+ 6.222947846: 1.6875 1016.99 
+ 6.246167800: 0 1017 
+ 6.269387755: 1.74219 1017.99 
+ 6.292607710: 0 1016.99 
+ 6.315827664: 1.78906 1016.99 
+ 6.339047619: 0 1017.99 
+ 6.362267574: 1.83594 1017 
+ 6.385487528: 0 1016.99 
+ 6.408707483: 1.89062 1016.99 
+ 6.431927438: 0 1017.99 
+ 6.455147392: 1.9375 1016.99 
+ 6.478367347: 0 1015.99 
+ 6.501587302: 0 507 
+ 6.524807256: 0 0 
+ 6.548027211: 1.04688 482 
+ 6.571247166: 0 968.992 
+ 6.594467120: 1.09375 981.992 
+ 6.617687075: 0 993.992 
+ 6.640907029: 1.14844 997.992 
+ 6.664126984: 0 999.992 
+ 6.687346939: 1.19531 1002.99 
+ 6.710566893: 0 1005.99 
+ 6.733786848: 1.24219 1005.99 
+ 6.757006803: 0 1007.99 
+ 6.780226757: 1.29688 1007.99 
+ 6.803446712: 0 1007 
+ 6.826666667: 1.34375 1011.99 
+ 6.849886621: 0 1014.99 
+ 6.873106576: 1.39062 1015.99 
+ 6.896326531: 0 1015 
+ 6.919546485: 1.44531 1015.99 
+ 6.942766440: 0 1015.99 
+ 6.965986395: 1.49219 1017.99 
+ 6.989206349: 0 1016 
+ 7.012426304: 1.53906 1016.99 
+ 7.035646259: 0 1015.99 
+ 7.058866213: 1.59375 1015.99 
+ 7.082086168: 0 1016 
+ 7.105306122: 1.64062 1016 
+ 7.128526077: 0 1016.99 
+ 7.151746032: 1.6875 1016.99 
+ 7.174965986: 0 1017 
+ 7.198185941: 1.74219 1017.99 
+ 7.221405896: 0 1016.99 
+ 7.244625850: 1.78906 1016.99 
+ 7.267845805: 0 1017.99 
+ 7.291065760: 1.83594 1017 
+ 7.314285714: 0 1016.99 
+ 7.337505669: 1.89062 1016.99 
+ 7.360725624: 0 1017.99 
+ 7.383945578: 1.9375 1016.99 
+ 7.407165533: 0 1015.99 
+ 7.430385488: 0 507 
+ 7.453605442: 0 0 
+ 7.476825397: 1.04688 482 
+ 7.500045351: 0 968.992 
+ 7.523265306: 1.09375 981.992 
+ 7.546485261: 0 993.992 
+ 7.569705215: 1.14844 997.992 
+ 7.592925170: 0 999.992 
+ 7.616145125: 1.19531 1002.99 
+ 7.639365079: 0 1005.99 
+ 7.662585034: 1.24219 1005.99 
+ 7.685804989: 0 1007.99 
+ 7.709024943: 1.29688 1007.99 
+ 7.732244898: 0 1007 
+ 7.755464853: 1.34375 1011.99 
+ 7.778684807: 0 1014.99 
+ 7.801904762: 1.39062 1015.99 
+ 7.825124717: 0 1015 
+ 7.848344671: 1.44531 1015.99 
+ 7.871564626: 0 1015.99 
+ 7.894784580: 1.49219 1017.99 
+ 7.918004535: 0 1016 
+ 7.941224490: 1.53906 1016.99 
+ 7.964444444: 0 1015.99 
+ 7.987664399: 1.59375 1015.99 
+ 8.010884354: 0 1016 
+ 8.034104308: 1.64062 1016 
+ 8.057324263: 0 1016.99 
+ 8.080544218: 1.6875 1016.99 
+ 8.103764172: 0 1017 
+ 8.126984127: 1.74219 1017.99 
+ 8.150204082: 0 1016.99 
+ 8.173424036: 1.78906 1016.99 
+ 8.196643991: 0 1017.99 
+ 8.219863946: 1.83594 1017 
+ 8.243083900: 0 1016.99 
+ 8.266303855: 1.89062 1016.99 
+ 8.289523810: 0 1017.99 
+ 8.312743764: 1.9375 1016.99 
+ 8.335963719: 0 1015.99 
+ 8.359183673: 0 507 
+ 8.382403628: 0 0 
+ 8.405623583: 1.04688 482 
+ 8.428843537: 0 968.992 
+ 8.452063492: 1.09375 981.992 
+ 8.475283447: 0 993.992 
+ 8.498503401: 1.14844 997.992 
+ 8.521723356: 0 999.992 
+ 8.544943311: 1.19531 1002.99 
+ 8.568163265: 0 1005.99 
+ 8.591383220: 1.24219 1005.99 
+ 8.614603175: 0 1007.99 
+ 8.637823129: 1.29688 1007.99 
+ 8.661043084: 0 1007 
+ 8.684263039: 1.34375 1011.99 
+ 8.707482993: 0 1014.99 
+ 8.730702948: 1.39062 1015.99 
+ 8.753922902: 0 1015 
+ 8.777142857: 1.44531 1015.99 
+ 8.800362812: 0 1015.99 
+ 8.823582766: 1.49219 1017.99 
+ 8.846802721: 0 1016 
+ 8.870022676: 1.53906 1016.99 
+ 8.893242630: 0 1015.99 
+ 8.916462585: 1.59375 1015.99 
+ 8.939682540: 0 1016 
+ 8.962902494: 1.64062 1016 
+ 8.986122449: 0 1016.99 
+ 9.009342404: 1.6875 1016.99 
+ 9.032562358: 0 1017 
+ 9.055782313: 1.74219 1017.99 
+ 9.079002268: 0 1016.99 
+ 9.102222222: 1.78906 1016.99 
+ 9.125442177: 0 1017.99 
+ 9.148662132: 1.83594 1017 
+ 9.171882086: 0 1016.99 
+ 9.195102041: 1.89062 1016.99 
+ 9.218321995: 0 1017.99 
+ 9.241541950: 1.9375 1016.99 
+ 9.264761905: 0 1015.99 
+ 9.287981859: 0 507 
+ 9.311201814: 0 0 
+ 9.334421769: 1.04688 482 
+ 9.357641723: 0 968.992 
+ 9.380861678: 1.09375 981.992 
+ 9.404081633: 0 993.992 
+ 9.427301587: 1.14844 997.992 
+ 9.450521542: 0 999.992 
+ 9.473741497: 1.19531 1002.99 
+ 9.496961451: 0 1005.99 
+ 9.520181406: 1.24219 1005.99 
+ 9.543401361: 0 1007.99 
+ 9.566621315: 1.29688 1007.99 
+ 9.589841270: 0 1007 
+ 9.613061224: 1.34375 1011.99 
+ 9.636281179: 0 1014.99 
+ 9.659501134: 1.39062 1015.99 
+ 9.682721088: 0 1015 
+ 9.705941043: 1.44531 1015.99 
+ 9.729160998: 0 1015.99 
+ 9.752380952: 1.49219 1017.99 
+ 9.775600907: 0 1016 
+ 9.798820862: 1.53906 1016.99 
+ 9.822040816: 0 1015.99 
+ 9.845260771: 1.59375 1015.99 
+ 9.868480726: 0 1016 
+ 9.891700680: 1.64062 1016 
+ 9.914920635: 0 1016.99 
+ 9.938140590: 1.6875 1016.99 
+ 9.961360544: 0 1017 
+ 9.984580499: 1.74219 1017.99 
+ 10.007800454: 0 1016.99 
+ 10.031020408: 1.78906 1016.99 
+ 10.054240363: 0 1017.99 
+ 10.077460317: 1.83594 1017 
+ 10.100680272: 0 1016.99 
+ 10.123900227: 1.89062 1016.99 
+ 10.147120181: 0 1017.99 
+ 10.170340136: 1.9375 1016.99 
+ 10.193560091: 0 1015.99 
+ 10.216780045: 0 507 
+ 10.240000000: 0 0 
+ 10.263219955: 1.04688 482 
+ 10.286439909: 0 968.992 
+ 10.309659864: 1.09375 981.992 
+ 10.332879819: 0 993.992 
+ 10.356099773: 1.14844 997.992 
+ 10.379319728: 0 999.992 
+ 10.402539683: 1.19531 1002.99 
+ 10.425759637: 0 1005.99 
+ 10.448979592: 1.24219 1005.99 
+ 10.472199546: 0 1007.99 
+ 10.495419501: 1.29688 1007.99 
+ 10.518639456: 0 1007 
+ 10.541859410: 1.34375 1011.99 
+ 10.565079365: 0 1014.99 
+ 10.588299320: 1.39062 1015.99 
+ 10.611519274: 0 1015 
+ 10.634739229: 1.44531 1015.99 
+ 10.657959184: 0 1015.99 
+ 10.681179138: 1.49219 1017.99 
+ 10.704399093: 0 1016 
+ 10.727619048: 1.53906 1016.99 
+ 10.750839002: 0 1015.99 
+ 10.774058957: 1.59375 1015.99 
+ 10.797278912: 0 1016 
+ 10.820498866: 1.64062 1016 
+ 10.843718821: 0 1016.99 
+ 10.866938776: 1.6875 1016.99 
+ 10.890158730: 0 1017 
+ 10.913378685: 1.74219 1017.99 
+ 10.936598639: 0 1016.99 
+ 10.959818594: 1.78906 1016.99 
+ 10.983038549: 0 1017.99 
+ 11.006258503: 1.83594 1017 
+ 11.029478458: 0 1016.99 
+ 11.052698413: 1.89062 1016.99 
+ 11.075918367: 0 1017.99 
+ 11.099138322: 1.9375 1016.99 
+ 11.122358277: 0 1015.99 
+ 11.145578231: 0 507 
+ 11.168798186: 0 0 
+ 11.192018141: 1.04688 482 
+ 11.215238095: 0 968.992 
+ 11.238458050: 1.09375 981.992 
+ 11.261678005: 0 993.992 
+ 11.284897959: 1.14844 997.992 
+ 11.308117914: 0 999.992 
+ 11.331337868: 1.19531 1002.99 
+ 11.354557823: 0 1005.99 
+ 11.377777778: 1.24219 1005.99 
+ 11.400997732: 0 1007.99 
+ 11.424217687: 1.29688 1007.99 
+ 11.447437642: 0 1007 
+ 11.470657596: 1.34375 1011.99 
+ 11.493877551: 0 1014.99 
+ 11.517097506: 1.39062 1015.99 
+ 11.540317460: 0 1015 
+ 11.563537415: 1.44531 1015.99 
+ 11.586757370: 0 1015.99 
+ 11.609977324: 1.49219 1017.99 
+ 11.633197279: 0 1016 
+ 11.656417234: 1.53906 1016.99 
+ 11.679637188: 0 1015.99 
+ 11.702857143: 1.59375 1015.99 
+ 11.726077098: 0 1016 
+ 11.749297052: 1.64062 1016 
+ 11.772517007: 0 1016.99 
+ 11.795736961: 1.6875 1016.99 
+ 11.818956916: 0 1017 
+ 11.842176871: 1.74219 1017.99 
+ 11.865396825: 0 1016.99 
+ 11.888616780: 1.78906 1016.99 
+ 11.911836735: 0 1017.99 
+ 11.935056689: 1.83594 1017 
+ 11.958276644: 0 1016.99 
+ 11.981496599: 1.89062 1016.99 
+ 12.004716553: 0 1017.99 
+ 12.027936508: 1.9375 1016.99 
+ 12.051156463: 0 1015.99 
+ 12.074376417: 0 507 
+ 12.097596372: 0 0 
+ 12.120816327: 1.04688 482 
+ 12.144036281: 0 968.992 
+ 12.167256236: 1.09375 981.992 
+ 12.190476190: 0 993.992 
+ 12.213696145: 1.14844 997.992 
+ 12.236916100: 0 999.992 
+ 12.260136054: 1.19531 1002.99 
+ 12.283356009: 0 1005.99 
+ 12.306575964: 1.24219 1005.99 
+ 12.329795918: 0 1007.99 
+ 12.353015873: 1.29688 1007.99 
+ 12.376235828: 0 1007 
+ 12.399455782: 1.34375 1011.99 
+ 12.422675737: 0 1014.99 
+ 12.445895692: 1.39062 1015.99 
+ 12.469115646: 0 1015 
+ 12.492335601: 1.44531 1015.99 
+ 12.515555556: 0 1015.99 
+ 12.538775510: 1.49219 1017.99 
+ 12.561995465: 0 1016 
+ 12.585215420: 1.53906 1016.99 
+ 12.608435374: 0 1015.99 
+ 12.631655329: 1.59375 1015.99 
+ 12.654875283: 0 1016 
+ 12.678095238: 1.64062 1016 
+ 12.701315193: 0 1016.99 
+ 12.724535147: 1.6875 1016.99 
+ 12.747755102: 0 1017 
+ 12.770975057: 1.74219 1017.99 
+ 12.794195011: 0 1016.99 
+ 12.817414966: 1.78906 1016.99 
+ 12.840634921: 0 1017.99 
+ 12.863854875: 1.83594 1017 
+ 12.887074830: 0 1016.99 
+ 12.910294785: 1.89062 1016.99 
+ 12.933514739: 0 1017.99 
+ 12.956734694: 1.9375 1016.99 
+ 12.979954649: 0 1015.99 
+ 13.003174603: 0 507 
+ 13.026394558: 0 0 
+ 13.049614512: 1.04688 482 
+ 13.072834467: 0 968.992 
+ 13.096054422: 1.09375 981.992 
+ 13.119274376: 0 993.992 
+ 13.142494331: 1.14844 997.992 
+ 13.165714286: 0 999.992 
+ 13.188934240: 1.19531 1002.99 
+ 13.212154195: 0 1005.99 
+ 13.235374150: 1.24219 1005.99 
+ 13.258594104: 0 1007.99 
+ 13.281814059: 1.29688 1007.99 
+ 13.305034014: 0 1007 
+ 13.328253968: 1.34375 1011.99 
+ 13.351473923: 0 1014.99 
+ 13.374693878: 1.39062 1015.99 
+ 13.397913832: 0 1015 
+ 13.421133787: 1.44531 1015.99 
+ 13.444353741: 0 1015.99 
+ 13.467573696: 1.49219 1017.99 
+ 13.490793651: 0 1016 
+ 13.514013605: 1.53906 1016.99 
+ 13.537233560: 0 1015.99 
+ 13.560453515: 1.59375 1015.99 
+ 13.583673469: 0 1016 
+ 13.606893424: 1.64062 1016 
+ 13.630113379: 0 1016.99 
+ 13.653333333: 1.6875 1016.99 
+ 13.676553288: 0 1017 
+ 13.699773243: 1.74219 1017.99 
+ 13.722993197: 0 1016.99 
+ 13.746213152: 1.78906 1016.99 
+ 13.769433107: 0 1017.99 
+ 13.792653061: 1.83594 1017 
+ 13.815873016: 0 1016.99 
+ 13.839092971: 1.89062 1016.99 
+ 13.862312925: 0 1017.99 
+ 13.885532880: 1.9375 1016.99 
+ 13.908752834: 0 1015.99 
+ 13.931972789: 0 507 
+ 13.955192744: 0 0 
+ 13.978412698: 1.04688 482 
+ 14.001632653: 0 968.992 
+ 14.024852608: 1.09375 981.992 
+ 14.048072562: 0 993.992 
+ 14.071292517: 1.14844 997.992 
+ 14.094512472: 0 999.992 
+ 14.117732426: 1.19531 1002.99 
+ 14.140952381: 0 1005.99 
+ 14.164172336: 1.24219 1005.99 
+ 14.187392290: 0 1007.99 
+ 14.210612245: 1.29688 1007.99 
+ 14.233832200: 0 1007 
+ 14.257052154: 1.34375 1011.99 
+ 14.280272109: 0 1014.99 
+ 14.303492063: 1.39062 1015.99 
+ 14.326712018: 0 1015 
+ 14.349931973: 1.44531 1015.99 
+ 14.373151927: 0 1015.99 
+ 14.396371882: 1.49219 1017.99 
+ 14.419591837: 0 1016 
+ 14.442811791: 1.53906 1016.99 
+ 14.466031746: 0 1015.99 
+ 14.489251701: 1.59375 1015.99 
+ 14.512471655: 0 1016 
+ 14.535691610: 1.64062 1016 
+ 14.558911565: 0 1016.99 
+ 14.582131519: 1.6875 1016.99 
+ 14.605351474: 0 1017 
+ 14.628571429: 1.74219 1017.99 
+ 14.651791383: 0 1016.99 
+ 14.675011338: 1.78906 1016.99 
+ 14.698231293: 0 1017.99 
+ 14.721451247: 1.83594 1017 
+ 14.744671202: 0 1016.99 
+ 14.767891156: 1.89062 1016.99 
+ 14.791111111: 0 1017.99 
+ 14.814331066: 1.9375 1016.99 
+ 14.837551020: 0 1015.99 
+ 14.860770975: 0 507 
+ 14.883990930: 0 0 
+ 14.907210884: 1.04688 482 
+ 14.930430839: 0 968.992 
+ 14.953650794: 1.09375 981.992 
+ 14.976870748: 0 993.992 
+ 15.000090703: 1.14844 997.992 
+ 15.023310658: 0 999.992 
+ 15.046530612: 1.19531 1002.99 
+ 15.069750567: 0 1005.99 
+ 15.092970522: 1.24219 1005.99 
+ 15.116190476: 0 1007.99 
+ 15.139410431: 1.29688 1007.99 
+ 15.162630385: 0 1007 
+ 15.185850340: 1.34375 1011.99 
+ 15.209070295: 0 1014.99 
+ 15.232290249: 1.39062 1015.99 
+ 15.255510204: 0 1015 
+ 15.278730159: 1.44531 1015.99 
+ 15.301950113: 0 1015.99 
+ 15.325170068: 1.49219 1017.99 
+ 15.348390023: 0 1016 
+ 15.371609977: 1.53906 1016.99 
+ 15.394829932: 0 1015.99 
+ 15.418049887: 1.59375 1015.99 
+ 15.441269841: 0 1016 
+ 15.464489796: 1.64062 1016 
+ 15.487709751: 0 1016.99 
+ 15.510929705: 1.6875 1016.99 
+ 15.534149660: 0 1017 
+ 15.557369615: 1.74219 1017.99 
+ 15.580589569: 0 1016.99 
+ 15.603809524: 1.78906 1016.99 
+ 15.627029478: 0 1017.99 
+ 15.650249433: 1.83594 1017 
+ 15.673469388: 0 1016.99 
+ 15.696689342: 1.89062 1016.99 
+ 15.719909297: 0 1017.99 
+ 15.743129252: 1.9375 1016.99 
+ 15.766349206: 0 1015.99 
+ 15.789569161: 0 507 
+ 15.812789116: 0 0 
+ 15.836009070: 1.04688 482 
+ 15.859229025: 0 968.992 
+ 15.882448980: 1.09375 981.992 
+ 15.905668934: 0 993.992 
+ 15.928888889: 1.14844 997.992 
+ 15.952108844: 0 999.992 
+ 15.975328798: 1.19531 1002.99 
+ 15.998548753: 0 1005.99 
+ 16.021768707: 1.24219 1005.99 
+ 16.044988662: 0 1007.99 
+ 16.068208617: 1.29688 1007.99 
+ 16.091428571: 0 1007 
+ 16.114648526: 1.34375 1011.99 
+ 16.137868481: 0 1014.99 
+ 16.161088435: 1.39062 1015.99 
+ 16.184308390: 0 1015 
+ 16.207528345: 1.44531 1015.99 
+ 16.230748299: 0 1015.99 
+ 16.253968254: 1.49219 1017.99 
+ 16.277188209: 0 1016 
+ 16.300408163: 1.53906 1016.99 
+ 16.323628118: 0 1015.99 
+ 16.346848073: 1.59375 1015.99 
+ 16.370068027: 0 1016 
+ 16.393287982: 1.64062 1016 
+ 16.416507937: 0 1016.99 
+ 16.439727891: 1.6875 1016.99 
+ 16.462947846: 0 1017 
+ 16.486167800: 1.74219 1017.99 
+ 16.509387755: 0 1016.99 
+ 16.532607710: 1.78906 1016.99 
+ 16.555827664: 0 1017.99 
+ 16.579047619: 1.83594 1017 
+ 16.602267574: 0 1016.99 
+ 16.625487528: 1.89062 1016.99 
+ 16.648707483: 0 1017.99 
+ 16.671927438: 1.9375 1016.99 
+ 16.695147392: 0 1015.99 
+ 16.718367347: 0 507 
+ 16.741587302: 0 0 
+ 16.764807256: 1.04688 482 
+ 16.788027211: 0 968.992 
+ 16.811247166: 1.09375 981.992 
+ 16.834467120: 0 993.992 
+ 16.857687075: 1.14844 997.992 
+ 16.880907029: 0 999.992 
+ 16.904126984: 1.19531 1002.99 
+ 16.927346939: 0 1005.99 
+ 16.950566893: 1.24219 1005.99 
+ 16.973786848: 0 1007.99 
+ 16.997006803: 1.29688 1007.99 
+ 17.020226757: 0 1007 
+ 17.043446712: 1.34375 1011.99 
+ 17.066666667: 0 1014.99 
+ 17.089886621: 1.39062 1015.99 
+ 17.113106576: 0 1015 
+ 17.136326531: 1.44531 1015.99 
+ 17.159546485: 0 1015.99 
+ 17.182766440: 1.49219 1017.99 
+ 17.205986395: 0 1016 
+ 17.229206349: 1.53906 1016.99 
+ 17.252426304: 0 1015.99 
+ 17.275646259: 1.59375 1015.99 
+ 17.298866213: 0 1016 
+ 17.322086168: 1.64062 1016 
+ 17.345306122: 0 1016.99 
+ 17.368526077: 1.6875 1016.99 
+ 17.391746032: 0 1017 
+ 17.414965986: 1.74219 1017.99 
+ 17.438185941: 0 1016.99 
+ 17.461405896: 1.78906 1016.99 
+ 17.484625850: 0 1017.99 
+ 17.507845805: 1.83594 1017 
+ 17.531065760: 0 1016.99 
+ 17.554285714: 1.89062 1016.99 
+ 17.577505669: 0 1017.99 
+ 17.600725624: 1.9375 1016.99 
+ 17.623945578: 0 1015.99 
+ 17.647165533: 0 507 
+ 17.670385488: 0 0 
+ 17.693605442: 1.04688 482 
+ 17.716825397: 0 968.992 
+ 17.740045351: 1.09375 981.992 
+ 17.763265306: 0 993.992 
+ 17.786485261: 1.14844 997.992 
+ 17.809705215: 0 999.992 
+ 17.832925170: 1.19531 1002.99 
+ 17.856145125: 0 1005.99 
+ 17.879365079: 1.24219 1005.99 
+ 17.902585034: 0 1007.99 
+ 17.925804989: 1.29688 1007.99 
+ 17.949024943: 0 1007 
+ 17.972244898: 1.34375 1011.99 
+ 17.995464853: 0 1014.99 
+ 18.018684807: 1.39062 1015.99 
+ 18.041904762: 0 1015 
+ 18.065124717: 1.44531 1015.99 
+ 18.088344671: 0 1015.99 
+ 18.111564626: 1.49219 1017.99 
+ 18.134784580: 0 1016 
+ 18.158004535: 1.53906 1016.99 
+ 18.181224490: 0 1015.99 
+ 18.204444444: 1.59375 1015.99 
+ 18.227664399: 0 1016 
+ 18.250884354: 1.64062 1016 
+ 18.274104308: 0 1016.99 
+ 18.297324263: 1.6875 1016.99 
+ 18.320544218: 0 1017 
+ 18.343764172: 1.74219 1017.99 
+ 18.366984127: 0 1016.99 
+ 18.390204082: 1.78906 1016.99 
+ 18.413424036: 0 1017.99 
+ 18.436643991: 1.83594 1017 
+ 18.459863946: 0 1016.99 
+ 18.483083900: 1.89062 1016.99 
+ 18.506303855: 0 1017.99 
+ 18.529523810: 1.9375 1016.99 
+ 18.552743764: 0 1015.99 
+ 18.575963719: 0 507 
+ 18.599183673: 0 0 
+ 18.622403628: 1.04688 482 
+ 18.645623583: 0 968.992 
+ 18.668843537: 1.09375 981.992 
+ 18.692063492: 0 993.992 
+ 18.715283447: 1.14844 997.992 
+ 18.738503401: 0 999.992 
+ 18.761723356: 1.19531 1002.99 
+ 18.784943311: 0 1005.99 
+ 18.808163265: 1.24219 1005.99 
+ 18.831383220: 0 1007.99 
+ 18.854603175: 1.29688 1007.99 
+ 18.877823129: 0 1007 
+ 18.901043084: 1.34375 1011.99 
+ 18.924263039: 0 1014.99 
+ 18.947482993: 1.39062 1015.99 
+ 18.970702948: 0 1015 
+ 18.993922902: 1.44531 1015.99 
+ 19.017142857: 0 1015.99 
+ 19.040362812: 1.49219 1017.99 
+ 19.063582766: 0 1016 
+ 19.086802721: 1.53906 1016.99 
+ 19.110022676: 0 1015.99 
+ 19.133242630: 1.59375 1015.99 
+ 19.156462585: 0 1016 
+ 19.179682540: 1.64062 1016 
+ 19.202902494: 0 1016.99 
+ 19.226122449: 1.6875 1016.99 
+ 19.249342404: 0 1017 
+ 19.272562358: 1.74219 1017.99 
+ 19.295782313: 0 1016.99 
+ 19.319002268: 1.78906 1016.99 
+ 19.342222222: 0 1017.99 
+ 19.365442177: 1.83594 1017 
+ 19.388662132: 0 1016.99 
+ 19.411882086: 1.89062 1016.99 
+ 19.435102041: 0 1017.99 
+ 19.458321995: 1.9375 1016.99 
+ 19.481541950: 0 1015.99 
+ 19.504761905: 0 507 
diff --git a/test/expected/vamp-test-plugin-freq_input-timestamp.txt b/test/expected/vamp-test-plugin-freq_input-timestamp.txt
new file mode 100644
index 0000000..46c578a
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_input-timestamp.txt
@@ -0,0 +1,841 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:input-timestamp
+ 0.023219955: 512 
+ 0.046439909: 1024 
+ 0.069659864: 1536 
+ 0.092879819: 2048 
+ 0.116099773: 2560 
+ 0.139319728: 3072 
+ 0.162539683: 3584 
+ 0.185759637: 4096 
+ 0.208979592: 4608 
+ 0.232199546: 5120 
+ 0.255419501: 5632 
+ 0.278639456: 6144 
+ 0.301859410: 6656 
+ 0.325079365: 7168 
+ 0.348299320: 7680 
+ 0.371519274: 8192 
+ 0.394739229: 8704 
+ 0.417959184: 9216 
+ 0.441179138: 9728 
+ 0.464399093: 10240 
+ 0.487619048: 10752 
+ 0.510839002: 11264 
+ 0.534058957: 11776 
+ 0.557278912: 12288 
+ 0.580498866: 12800 
+ 0.603718821: 13312 
+ 0.626938776: 13824 
+ 0.650158730: 14336 
+ 0.673378685: 14848 
+ 0.696598639: 15360 
+ 0.719818594: 15872 
+ 0.743038549: 16384 
+ 0.766258503: 16896 
+ 0.789478458: 17408 
+ 0.812698413: 17920 
+ 0.835918367: 18432 
+ 0.859138322: 18944 
+ 0.882358277: 19456 
+ 0.905578231: 19968 
+ 0.928798186: 20480 
+ 0.952018141: 20992 
+ 0.975238095: 21504 
+ 0.998458050: 22016 
+ 1.021678005: 22528 
+ 1.044897959: 23040 
+ 1.068117914: 23552 
+ 1.091337868: 24064 
+ 1.114557823: 24576 
+ 1.137777778: 25088 
+ 1.160997732: 25600 
+ 1.184217687: 26112 
+ 1.207437642: 26624 
+ 1.230657596: 27136 
+ 1.253877551: 27648 
+ 1.277097506: 28160 
+ 1.300317460: 28672 
+ 1.323537415: 29184 
+ 1.346757370: 29696 
+ 1.369977324: 30208 
+ 1.393197279: 30720 
+ 1.416417234: 31232 
+ 1.439637188: 31744 
+ 1.462857143: 32256 
+ 1.486077098: 32768 
+ 1.509297052: 33280 
+ 1.532517007: 33792 
+ 1.555736961: 34304 
+ 1.578956916: 34816 
+ 1.602176871: 35328 
+ 1.625396825: 35840 
+ 1.648616780: 36352 
+ 1.671836735: 36864 
+ 1.695056689: 37376 
+ 1.718276644: 37888 
+ 1.741496599: 38400 
+ 1.764716553: 38912 
+ 1.787936508: 39424 
+ 1.811156463: 39936 
+ 1.834376417: 40448 
+ 1.857596372: 40960 
+ 1.880816327: 41472 
+ 1.904036281: 41984 
+ 1.927256236: 42496 
+ 1.950476190: 43008 
+ 1.973696145: 43520 
+ 1.996916100: 44032 
+ 2.020136054: 44544 
+ 2.043356009: 45056 
+ 2.066575964: 45568 
+ 2.089795918: 46080 
+ 2.113015873: 46592 
+ 2.136235828: 47104 
+ 2.159455782: 47616 
+ 2.182675737: 48128 
+ 2.205895692: 48640 
+ 2.229115646: 49152 
+ 2.252335601: 49664 
+ 2.275555556: 50176 
+ 2.298775510: 50688 
+ 2.321995465: 51200 
+ 2.345215420: 51712 
+ 2.368435374: 52224 
+ 2.391655329: 52736 
+ 2.414875283: 53248 
+ 2.438095238: 53760 
+ 2.461315193: 54272 
+ 2.484535147: 54784 
+ 2.507755102: 55296 
+ 2.530975057: 55808 
+ 2.554195011: 56320 
+ 2.577414966: 56832 
+ 2.600634921: 57344 
+ 2.623854875: 57856 
+ 2.647074830: 58368 
+ 2.670294785: 58880 
+ 2.693514739: 59392 
+ 2.716734694: 59904 
+ 2.739954649: 60416 
+ 2.763174603: 60928 
+ 2.786394558: 61440 
+ 2.809614512: 61952 
+ 2.832834467: 62464 
+ 2.856054422: 62976 
+ 2.879274376: 63488 
+ 2.902494331: 64000 
+ 2.925714286: 64512 
+ 2.948934240: 65024 
+ 2.972154195: 65536 
+ 2.995374150: 66048 
+ 3.018594104: 66560 
+ 3.041814059: 67072 
+ 3.065034014: 67584 
+ 3.088253968: 68096 
+ 3.111473923: 68608 
+ 3.134693878: 69120 
+ 3.157913832: 69632 
+ 3.181133787: 70144 
+ 3.204353741: 70656 
+ 3.227573696: 71168 
+ 3.250793651: 71680 
+ 3.274013605: 72192 
+ 3.297233560: 72704 
+ 3.320453515: 73216 
+ 3.343673469: 73728 
+ 3.366893424: 74240 
+ 3.390113379: 74752 
+ 3.413333333: 75264 
+ 3.436553288: 75776 
+ 3.459773243: 76288 
+ 3.482993197: 76800 
+ 3.506213152: 77312 
+ 3.529433107: 77824 
+ 3.552653061: 78336 
+ 3.575873016: 78848 
+ 3.599092971: 79360 
+ 3.622312925: 79872 
+ 3.645532880: 80384 
+ 3.668752834: 80896 
+ 3.691972789: 81408 
+ 3.715192744: 81920 
+ 3.738412698: 82432 
+ 3.761632653: 82944 
+ 3.784852608: 83456 
+ 3.808072562: 83968 
+ 3.831292517: 84480 
+ 3.854512472: 84992 
+ 3.877732426: 85504 
+ 3.900952381: 86016 
+ 3.924172336: 86528 
+ 3.947392290: 87040 
+ 3.970612245: 87552 
+ 3.993832200: 88064 
+ 4.017052154: 88576 
+ 4.040272109: 89088 
+ 4.063492063: 89600 
+ 4.086712018: 90112 
+ 4.109931973: 90624 
+ 4.133151927: 91136 
+ 4.156371882: 91648 
+ 4.179591837: 92160 
+ 4.202811791: 92672 
+ 4.226031746: 93184 
+ 4.249251701: 93696 
+ 4.272471655: 94208 
+ 4.295691610: 94720 
+ 4.318911565: 95232 
+ 4.342131519: 95744 
+ 4.365351474: 96256 
+ 4.388571429: 96768 
+ 4.411791383: 97280 
+ 4.435011338: 97792 
+ 4.458231293: 98304 
+ 4.481451247: 98816 
+ 4.504671202: 99328 
+ 4.527891156: 99840 
+ 4.551111111: 100352 
+ 4.574331066: 100864 
+ 4.597551020: 101376 
+ 4.620770975: 101888 
+ 4.643990930: 102400 
+ 4.667210884: 102912 
+ 4.690430839: 103424 
+ 4.713650794: 103936 
+ 4.736870748: 104448 
+ 4.760090703: 104960 
+ 4.783310658: 105472 
+ 4.806530612: 105984 
+ 4.829750567: 106496 
+ 4.852970522: 107008 
+ 4.876190476: 107520 
+ 4.899410431: 108032 
+ 4.922630385: 108544 
+ 4.945850340: 109056 
+ 4.969070295: 109568 
+ 4.992290249: 110080 
+ 5.015510204: 110592 
+ 5.038730159: 111104 
+ 5.061950113: 111616 
+ 5.085170068: 112128 
+ 5.108390023: 112640 
+ 5.131609977: 113152 
+ 5.154829932: 113664 
+ 5.178049887: 114176 
+ 5.201269841: 114688 
+ 5.224489796: 115200 
+ 5.247709751: 115712 
+ 5.270929705: 116224 
+ 5.294149660: 116736 
+ 5.317369615: 117248 
+ 5.340589569: 117760 
+ 5.363809524: 118272 
+ 5.387029478: 118784 
+ 5.410249433: 119296 
+ 5.433469388: 119808 
+ 5.456689342: 120320 
+ 5.479909297: 120832 
+ 5.503129252: 121344 
+ 5.526349206: 121856 
+ 5.549569161: 122368 
+ 5.572789116: 122880 
+ 5.596009070: 123392 
+ 5.619229025: 123904 
+ 5.642448980: 124416 
+ 5.665668934: 124928 
+ 5.688888889: 125440 
+ 5.712108844: 125952 
+ 5.735328798: 126464 
+ 5.758548753: 126976 
+ 5.781768707: 127488 
+ 5.804988662: 128000 
+ 5.828208617: 128512 
+ 5.851428571: 129024 
+ 5.874648526: 129536 
+ 5.897868481: 130048 
+ 5.921088435: 130560 
+ 5.944308390: 131072 
+ 5.967528345: 131584 
+ 5.990748299: 132096 
+ 6.013968254: 132608 
+ 6.037188209: 133120 
+ 6.060408163: 133632 
+ 6.083628118: 134144 
+ 6.106848073: 134656 
+ 6.130068027: 135168 
+ 6.153287982: 135680 
+ 6.176507937: 136192 
+ 6.199727891: 136704 
+ 6.222947846: 137216 
+ 6.246167800: 137728 
+ 6.269387755: 138240 
+ 6.292607710: 138752 
+ 6.315827664: 139264 
+ 6.339047619: 139776 
+ 6.362267574: 140288 
+ 6.385487528: 140800 
+ 6.408707483: 141312 
+ 6.431927438: 141824 
+ 6.455147392: 142336 
+ 6.478367347: 142848 
+ 6.501587302: 143360 
+ 6.524807256: 143872 
+ 6.548027211: 144384 
+ 6.571247166: 144896 
+ 6.594467120: 145408 
+ 6.617687075: 145920 
+ 6.640907029: 146432 
+ 6.664126984: 146944 
+ 6.687346939: 147456 
+ 6.710566893: 147968 
+ 6.733786848: 148480 
+ 6.757006803: 148992 
+ 6.780226757: 149504 
+ 6.803446712: 150016 
+ 6.826666667: 150528 
+ 6.849886621: 151040 
+ 6.873106576: 151552 
+ 6.896326531: 152064 
+ 6.919546485: 152576 
+ 6.942766440: 153088 
+ 6.965986395: 153600 
+ 6.989206349: 154112 
+ 7.012426304: 154624 
+ 7.035646259: 155136 
+ 7.058866213: 155648 
+ 7.082086168: 156160 
+ 7.105306122: 156672 
+ 7.128526077: 157184 
+ 7.151746032: 157696 
+ 7.174965986: 158208 
+ 7.198185941: 158720 
+ 7.221405896: 159232 
+ 7.244625850: 159744 
+ 7.267845805: 160256 
+ 7.291065760: 160768 
+ 7.314285714: 161280 
+ 7.337505669: 161792 
+ 7.360725624: 162304 
+ 7.383945578: 162816 
+ 7.407165533: 163328 
+ 7.430385488: 163840 
+ 7.453605442: 164352 
+ 7.476825397: 164864 
+ 7.500045351: 165376 
+ 7.523265306: 165888 
+ 7.546485261: 166400 
+ 7.569705215: 166912 
+ 7.592925170: 167424 
+ 7.616145125: 167936 
+ 7.639365079: 168448 
+ 7.662585034: 168960 
+ 7.685804989: 169472 
+ 7.709024943: 169984 
+ 7.732244898: 170496 
+ 7.755464853: 171008 
+ 7.778684807: 171520 
+ 7.801904762: 172032 
+ 7.825124717: 172544 
+ 7.848344671: 173056 
+ 7.871564626: 173568 
+ 7.894784580: 174080 
+ 7.918004535: 174592 
+ 7.941224490: 175104 
+ 7.964444444: 175616 
+ 7.987664399: 176128 
+ 8.010884354: 176640 
+ 8.034104308: 177152 
+ 8.057324263: 177664 
+ 8.080544218: 178176 
+ 8.103764172: 178688 
+ 8.126984127: 179200 
+ 8.150204082: 179712 
+ 8.173424036: 180224 
+ 8.196643991: 180736 
+ 8.219863946: 181248 
+ 8.243083900: 181760 
+ 8.266303855: 182272 
+ 8.289523810: 182784 
+ 8.312743764: 183296 
+ 8.335963719: 183808 
+ 8.359183673: 184320 
+ 8.382403628: 184832 
+ 8.405623583: 185344 
+ 8.428843537: 185856 
+ 8.452063492: 186368 
+ 8.475283447: 186880 
+ 8.498503401: 187392 
+ 8.521723356: 187904 
+ 8.544943311: 188416 
+ 8.568163265: 188928 
+ 8.591383220: 189440 
+ 8.614603175: 189952 
+ 8.637823129: 190464 
+ 8.661043084: 190976 
+ 8.684263039: 191488 
+ 8.707482993: 192000 
+ 8.730702948: 192512 
+ 8.753922902: 193024 
+ 8.777142857: 193536 
+ 8.800362812: 194048 
+ 8.823582766: 194560 
+ 8.846802721: 195072 
+ 8.870022676: 195584 
+ 8.893242630: 196096 
+ 8.916462585: 196608 
+ 8.939682540: 197120 
+ 8.962902494: 197632 
+ 8.986122449: 198144 
+ 9.009342404: 198656 
+ 9.032562358: 199168 
+ 9.055782313: 199680 
+ 9.079002268: 200192 
+ 9.102222222: 200704 
+ 9.125442177: 201216 
+ 9.148662132: 201728 
+ 9.171882086: 202240 
+ 9.195102041: 202752 
+ 9.218321995: 203264 
+ 9.241541950: 203776 
+ 9.264761905: 204288 
+ 9.287981859: 204800 
+ 9.311201814: 205312 
+ 9.334421769: 205824 
+ 9.357641723: 206336 
+ 9.380861678: 206848 
+ 9.404081633: 207360 
+ 9.427301587: 207872 
+ 9.450521542: 208384 
+ 9.473741497: 208896 
+ 9.496961451: 209408 
+ 9.520181406: 209920 
+ 9.543401361: 210432 
+ 9.566621315: 210944 
+ 9.589841270: 211456 
+ 9.613061224: 211968 
+ 9.636281179: 212480 
+ 9.659501134: 212992 
+ 9.682721088: 213504 
+ 9.705941043: 214016 
+ 9.729160998: 214528 
+ 9.752380952: 215040 
+ 9.775600907: 215552 
+ 9.798820862: 216064 
+ 9.822040816: 216576 
+ 9.845260771: 217088 
+ 9.868480726: 217600 
+ 9.891700680: 218112 
+ 9.914920635: 218624 
+ 9.938140590: 219136 
+ 9.961360544: 219648 
+ 9.984580499: 220160 
+ 10.007800454: 220672 
+ 10.031020408: 221184 
+ 10.054240363: 221696 
+ 10.077460317: 222208 
+ 10.100680272: 222720 
+ 10.123900227: 223232 
+ 10.147120181: 223744 
+ 10.170340136: 224256 
+ 10.193560091: 224768 
+ 10.216780045: 225280 
+ 10.240000000: 225792 
+ 10.263219955: 226304 
+ 10.286439909: 226816 
+ 10.309659864: 227328 
+ 10.332879819: 227840 
+ 10.356099773: 228352 
+ 10.379319728: 228864 
+ 10.402539683: 229376 
+ 10.425759637: 229888 
+ 10.448979592: 230400 
+ 10.472199546: 230912 
+ 10.495419501: 231424 
+ 10.518639456: 231936 
+ 10.541859410: 232448 
+ 10.565079365: 232960 
+ 10.588299320: 233472 
+ 10.611519274: 233984 
+ 10.634739229: 234496 
+ 10.657959184: 235008 
+ 10.681179138: 235520 
+ 10.704399093: 236032 
+ 10.727619048: 236544 
+ 10.750839002: 237056 
+ 10.774058957: 237568 
+ 10.797278912: 238080 
+ 10.820498866: 238592 
+ 10.843718821: 239104 
+ 10.866938776: 239616 
+ 10.890158730: 240128 
+ 10.913378685: 240640 
+ 10.936598639: 241152 
+ 10.959818594: 241664 
+ 10.983038549: 242176 
+ 11.006258503: 242688 
+ 11.029478458: 243200 
+ 11.052698413: 243712 
+ 11.075918367: 244224 
+ 11.099138322: 244736 
+ 11.122358277: 245248 
+ 11.145578231: 245760 
+ 11.168798186: 246272 
+ 11.192018141: 246784 
+ 11.215238095: 247296 
+ 11.238458050: 247808 
+ 11.261678005: 248320 
+ 11.284897959: 248832 
+ 11.308117914: 249344 
+ 11.331337868: 249856 
+ 11.354557823: 250368 
+ 11.377777778: 250880 
+ 11.400997732: 251392 
+ 11.424217687: 251904 
+ 11.447437642: 252416 
+ 11.470657596: 252928 
+ 11.493877551: 253440 
+ 11.517097506: 253952 
+ 11.540317460: 254464 
+ 11.563537415: 254976 
+ 11.586757370: 255488 
+ 11.609977324: 256000 
+ 11.633197279: 256512 
+ 11.656417234: 257024 
+ 11.679637188: 257536 
+ 11.702857143: 258048 
+ 11.726077098: 258560 
+ 11.749297052: 259072 
+ 11.772517007: 259584 
+ 11.795736961: 260096 
+ 11.818956916: 260608 
+ 11.842176871: 261120 
+ 11.865396825: 261632 
+ 11.888616780: 262144 
+ 11.911836735: 262656 
+ 11.935056689: 263168 
+ 11.958276644: 263680 
+ 11.981496599: 264192 
+ 12.004716553: 264704 
+ 12.027936508: 265216 
+ 12.051156463: 265728 
+ 12.074376417: 266240 
+ 12.097596372: 266752 
+ 12.120816327: 267264 
+ 12.144036281: 267776 
+ 12.167256236: 268288 
+ 12.190476190: 268800 
+ 12.213696145: 269312 
+ 12.236916100: 269824 
+ 12.260136054: 270336 
+ 12.283356009: 270848 
+ 12.306575964: 271360 
+ 12.329795918: 271872 
+ 12.353015873: 272384 
+ 12.376235828: 272896 
+ 12.399455782: 273408 
+ 12.422675737: 273920 
+ 12.445895692: 274432 
+ 12.469115646: 274944 
+ 12.492335601: 275456 
+ 12.515555556: 275968 
+ 12.538775510: 276480 
+ 12.561995465: 276992 
+ 12.585215420: 277504 
+ 12.608435374: 278016 
+ 12.631655329: 278528 
+ 12.654875283: 279040 
+ 12.678095238: 279552 
+ 12.701315193: 280064 
+ 12.724535147: 280576 
+ 12.747755102: 281088 
+ 12.770975057: 281600 
+ 12.794195011: 282112 
+ 12.817414966: 282624 
+ 12.840634921: 283136 
+ 12.863854875: 283648 
+ 12.887074830: 284160 
+ 12.910294785: 284672 
+ 12.933514739: 285184 
+ 12.956734694: 285696 
+ 12.979954649: 286208 
+ 13.003174603: 286720 
+ 13.026394558: 287232 
+ 13.049614512: 287744 
+ 13.072834467: 288256 
+ 13.096054422: 288768 
+ 13.119274376: 289280 
+ 13.142494331: 289792 
+ 13.165714286: 290304 
+ 13.188934240: 290816 
+ 13.212154195: 291328 
+ 13.235374150: 291840 
+ 13.258594104: 292352 
+ 13.281814059: 292864 
+ 13.305034014: 293376 
+ 13.328253968: 293888 
+ 13.351473923: 294400 
+ 13.374693878: 294912 
+ 13.397913832: 295424 
+ 13.421133787: 295936 
+ 13.444353741: 296448 
+ 13.467573696: 296960 
+ 13.490793651: 297472 
+ 13.514013605: 297984 
+ 13.537233560: 298496 
+ 13.560453515: 299008 
+ 13.583673469: 299520 
+ 13.606893424: 300032 
+ 13.630113379: 300544 
+ 13.653333333: 301056 
+ 13.676553288: 301568 
+ 13.699773243: 302080 
+ 13.722993197: 302592 
+ 13.746213152: 303104 
+ 13.769433107: 303616 
+ 13.792653061: 304128 
+ 13.815873016: 304640 
+ 13.839092971: 305152 
+ 13.862312925: 305664 
+ 13.885532880: 306176 
+ 13.908752834: 306688 
+ 13.931972789: 307200 
+ 13.955192744: 307712 
+ 13.978412698: 308224 
+ 14.001632653: 308736 
+ 14.024852608: 309248 
+ 14.048072562: 309760 
+ 14.071292517: 310272 
+ 14.094512472: 310784 
+ 14.117732426: 311296 
+ 14.140952381: 311808 
+ 14.164172336: 312320 
+ 14.187392290: 312832 
+ 14.210612245: 313344 
+ 14.233832200: 313856 
+ 14.257052154: 314368 
+ 14.280272109: 314880 
+ 14.303492063: 315392 
+ 14.326712018: 315904 
+ 14.349931973: 316416 
+ 14.373151927: 316928 
+ 14.396371882: 317440 
+ 14.419591837: 317952 
+ 14.442811791: 318464 
+ 14.466031746: 318976 
+ 14.489251701: 319488 
+ 14.512471655: 320000 
+ 14.535691610: 320512 
+ 14.558911565: 321024 
+ 14.582131519: 321536 
+ 14.605351474: 322048 
+ 14.628571429: 322560 
+ 14.651791383: 323072 
+ 14.675011338: 323584 
+ 14.698231293: 324096 
+ 14.721451247: 324608 
+ 14.744671202: 325120 
+ 14.767891156: 325632 
+ 14.791111111: 326144 
+ 14.814331066: 326656 
+ 14.837551020: 327168 
+ 14.860770975: 327680 
+ 14.883990930: 328192 
+ 14.907210884: 328704 
+ 14.930430839: 329216 
+ 14.953650794: 329728 
+ 14.976870748: 330240 
+ 15.000090703: 330752 
+ 15.023310658: 331264 
+ 15.046530612: 331776 
+ 15.069750567: 332288 
+ 15.092970522: 332800 
+ 15.116190476: 333312 
+ 15.139410431: 333824 
+ 15.162630385: 334336 
+ 15.185850340: 334848 
+ 15.209070295: 335360 
+ 15.232290249: 335872 
+ 15.255510204: 336384 
+ 15.278730159: 336896 
+ 15.301950113: 337408 
+ 15.325170068: 337920 
+ 15.348390023: 338432 
+ 15.371609977: 338944 
+ 15.394829932: 339456 
+ 15.418049887: 339968 
+ 15.441269841: 340480 
+ 15.464489796: 340992 
+ 15.487709751: 341504 
+ 15.510929705: 342016 
+ 15.534149660: 342528 
+ 15.557369615: 343040 
+ 15.580589569: 343552 
+ 15.603809524: 344064 
+ 15.627029478: 344576 
+ 15.650249433: 345088 
+ 15.673469388: 345600 
+ 15.696689342: 346112 
+ 15.719909297: 346624 
+ 15.743129252: 347136 
+ 15.766349206: 347648 
+ 15.789569161: 348160 
+ 15.812789116: 348672 
+ 15.836009070: 349184 
+ 15.859229025: 349696 
+ 15.882448980: 350208 
+ 15.905668934: 350720 
+ 15.928888889: 351232 
+ 15.952108844: 351744 
+ 15.975328798: 352256 
+ 15.998548753: 352768 
+ 16.021768707: 353280 
+ 16.044988662: 353792 
+ 16.068208617: 354304 
+ 16.091428571: 354816 
+ 16.114648526: 355328 
+ 16.137868481: 355840 
+ 16.161088435: 356352 
+ 16.184308390: 356864 
+ 16.207528345: 357376 
+ 16.230748299: 357888 
+ 16.253968254: 358400 
+ 16.277188209: 358912 
+ 16.300408163: 359424 
+ 16.323628118: 359936 
+ 16.346848073: 360448 
+ 16.370068027: 360960 
+ 16.393287982: 361472 
+ 16.416507937: 361984 
+ 16.439727891: 362496 
+ 16.462947846: 363008 
+ 16.486167800: 363520 
+ 16.509387755: 364032 
+ 16.532607710: 364544 
+ 16.555827664: 365056 
+ 16.579047619: 365568 
+ 16.602267574: 366080 
+ 16.625487528: 366592 
+ 16.648707483: 367104 
+ 16.671927438: 367616 
+ 16.695147392: 368128 
+ 16.718367347: 368640 
+ 16.741587302: 369152 
+ 16.764807256: 369664 
+ 16.788027211: 370176 
+ 16.811247166: 370688 
+ 16.834467120: 371200 
+ 16.857687075: 371712 
+ 16.880907029: 372224 
+ 16.904126984: 372736 
+ 16.927346939: 373248 
+ 16.950566893: 373760 
+ 16.973786848: 374272 
+ 16.997006803: 374784 
+ 17.020226757: 375296 
+ 17.043446712: 375808 
+ 17.066666667: 376320 
+ 17.089886621: 376832 
+ 17.113106576: 377344 
+ 17.136326531: 377856 
+ 17.159546485: 378368 
+ 17.182766440: 378880 
+ 17.205986395: 379392 
+ 17.229206349: 379904 
+ 17.252426304: 380416 
+ 17.275646259: 380928 
+ 17.298866213: 381440 
+ 17.322086168: 381952 
+ 17.345306122: 382464 
+ 17.368526077: 382976 
+ 17.391746032: 383488 
+ 17.414965986: 384000 
+ 17.438185941: 384512 
+ 17.461405896: 385024 
+ 17.484625850: 385536 
+ 17.507845805: 386048 
+ 17.531065760: 386560 
+ 17.554285714: 387072 
+ 17.577505669: 387584 
+ 17.600725624: 388096 
+ 17.623945578: 388608 
+ 17.647165533: 389120 
+ 17.670385488: 389632 
+ 17.693605442: 390144 
+ 17.716825397: 390656 
+ 17.740045351: 391168 
+ 17.763265306: 391680 
+ 17.786485261: 392192 
+ 17.809705215: 392704 
+ 17.832925170: 393216 
+ 17.856145125: 393728 
+ 17.879365079: 394240 
+ 17.902585034: 394752 
+ 17.925804989: 395264 
+ 17.949024943: 395776 
+ 17.972244898: 396288 
+ 17.995464853: 396800 
+ 18.018684807: 397312 
+ 18.041904762: 397824 
+ 18.065124717: 398336 
+ 18.088344671: 398848 
+ 18.111564626: 399360 
+ 18.134784580: 399872 
+ 18.158004535: 400384 
+ 18.181224490: 400896 
+ 18.204444444: 401408 
+ 18.227664399: 401920 
+ 18.250884354: 402432 
+ 18.274104308: 402944 
+ 18.297324263: 403456 
+ 18.320544218: 403968 
+ 18.343764172: 404480 
+ 18.366984127: 404992 
+ 18.390204082: 405504 
+ 18.413424036: 406016 
+ 18.436643991: 406528 
+ 18.459863946: 407040 
+ 18.483083900: 407552 
+ 18.506303855: 408064 
+ 18.529523810: 408576 
+ 18.552743764: 409088 
+ 18.575963719: 409600 
+ 18.599183673: 410112 
+ 18.622403628: 410624 
+ 18.645623583: 411136 
+ 18.668843537: 411648 
+ 18.692063492: 412160 
+ 18.715283447: 412672 
+ 18.738503401: 413184 
+ 18.761723356: 413696 
+ 18.784943311: 414208 
+ 18.808163265: 414720 
+ 18.831383220: 415232 
+ 18.854603175: 415744 
+ 18.877823129: 416256 
+ 18.901043084: 416768 
+ 18.924263039: 417280 
+ 18.947482993: 417792 
+ 18.970702948: 418304 
+ 18.993922902: 418816 
+ 19.017142857: 419328 
+ 19.040362812: 419840 
+ 19.063582766: 420352 
+ 19.086802721: 420864 
+ 19.110022676: 421376 
+ 19.133242630: 421888 
+ 19.156462585: 422400 
+ 19.179682540: 422912 
+ 19.202902494: 423424 
+ 19.226122449: 423936 
+ 19.249342404: 424448 
+ 19.272562358: 424960 
+ 19.295782313: 425472 
+ 19.319002268: 425984 
+ 19.342222222: 426496 
+ 19.365442177: 427008 
+ 19.388662132: 427520 
+ 19.411882086: 428032 
+ 19.435102041: 428544 
+ 19.458321995: 429056 
+ 19.481541950: 429568 
+ 19.504761905: 430080 
diff --git a/test/expected/vamp-test-plugin-freq_instants.txt b/test/expected/vamp-test-plugin-freq_instants.txt
new file mode 100644
index 0000000..689ebf5
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_instants.txt
@@ -0,0 +1,10 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:instants
+ 1.500000000: 2 of 10 at 1.5
+ 3.000000000: 3 of 10 at 3
+ 4.500000000: 4 of 10 at 4.5
+ 6.000000000: 5 of 10 at 6
+ 7.500000000: 6 of 10 at 7.5
+ 9.000000000: 7 of 10 at 9
+ 10.500000000: 8 of 10 at 10.5
+ 12.000000000: 9 of 10 at 12
+ 13.500000000: 10 of 10 at 13.5
diff --git a/test/expected/vamp-test-plugin-freq_notes-regions.txt b/test/expected/vamp-test-plugin-freq_notes-regions.txt
new file mode 100644
index 0000000..a2e7694
--- /dev/null
+++ b/test/expected/vamp-test-plugin-freq_notes-regions.txt
@@ -0,0 +1,10 @@
+=== vamp-test-plugin:vamp-test-plugin-freq:notes-regions
+ 1.000000000, 0.500000000: 0.1 2 of 10: 0.1 at 1 dur. 0.5
+ 2.000000000, 1.750000000: 0.2 3 of 10: 0.2 at 2 dur. 1.75
+ 3.000000000, 0.500000000: 0.3 4 of 10: 0.3 at 3 dur. 0.5
+ 4.000000000, 1.750000000: 0.4 5 of 10: 0.4 at 4 dur. 1.75
+ 5.000000000, 0.500000000: 0.5 6 of 10: 0.5 at 5 dur. 0.5
+ 6.000000000, 1.750000000: 0.6 7 of 10: 0.6 at 6 dur. 1.75
+ 7.000000000, 0.500000000: 0.7 8 of 10: 0.7 at 7 dur. 0.5
+ 8.000000000, 1.750000000: 0.8 9 of 10: 0.8 at 8 dur. 1.75
+ 9.000000000, 0.500000000: 0.9 10 of 10: 0.9 at 9 dur. 0.5
diff --git a/test/expected/vamp-test-plugin_curve-fsr-mixed.txt b/test/expected/vamp-test-plugin_curve-fsr-mixed.txt
new file mode 100644
index 0000000..7285fa1
--- /dev/null
+++ b/test/expected/vamp-test-plugin_curve-fsr-mixed.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:curve-fsr-mixed
+ 2.400000000: 0 1 of 10: 0 at 2.4 snap to 2.4
+ 2.800000000: 0.1 2 of 10: 0.1 at 2.9 snap to 2.8
+ 3.200000000: 0.2 3 of 10: 0.2 at 3.14 snap to 3.2
+ 3.600000000: 0.3 4 of 10: 0.3 at 3.5 snap to 3.6
+ 4.000000000: 0.4 5 of 10: 0.4 at 4
+ 4.400000000: 0.5 6 of 10: 0.5 at 4.4
+ 4.000000000: 0.6 7 of 10: 0.6 at 3.9 snap to 4
+ 4.400000000: 0.7 8 of 10: 0.7 at 4.4 snap to 4.4
+ 4.800000000: 0.8 9 of 10: 0.8 at 4.8
+ 5.200000000: 0.9 10 of 10: 0.9 at 5 snap to 5.2
diff --git a/test/expected/vamp-test-plugin_curve-fsr-timed.txt b/test/expected/vamp-test-plugin_curve-fsr-timed.txt
new file mode 100644
index 0000000..b42e910
--- /dev/null
+++ b/test/expected/vamp-test-plugin_curve-fsr-timed.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:curve-fsr-timed
+ 0.000000000: 0 1 of 10: 0 at 0 snap to 0
+ 0.000000000: 0.1 2 of 10: 0.1 at 0 snap to 0
+ 0.000000000: 0.2 3 of 10: 0.2 at 0.166 snap to 0
+ 0.400000000: 0.3 4 of 10: 0.3 at 0.333 snap to 0.4
+ 2.000000000: 0.4 5 of 10: 0.4 at 2 snap to 2
+ 2.000000000: 0.5 6 of 10: 0.5 at 2 snap to 2
+ 2.000000000: 0.6 7 of 10: 0.6 at 2.166 snap to 2
+ 2.400000000: 0.7 8 of 10: 0.7 at 2.333 snap to 2.4
+ 4.000000000: 0.8 9 of 10: 0.8 at 4 snap to 4
+ 4.000000000: 0.9 10 of 10: 0.9 at 4 snap to 4
diff --git a/test/expected/vamp-test-plugin_curve-fsr.txt b/test/expected/vamp-test-plugin_curve-fsr.txt
new file mode 100644
index 0000000..c2b55a6
--- /dev/null
+++ b/test/expected/vamp-test-plugin_curve-fsr.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:curve-fsr
+ 0.000000000: 0 1 of 10: 0 at 0
+ 0.400000000: 0.1 2 of 10: 0.1 at 0.4
+ 0.800000000: 0.2 3 of 10: 0.2 at 0.8
+ 1.200000000: 0.3 4 of 10: 0.3 at 1.2
+ 1.600000000: 0.4 5 of 10: 0.4 at 1.6
+ 2.000000000: 0.5 6 of 10: 0.5 at 2
+ 2.400000000: 0.6 7 of 10: 0.6 at 2.4
+ 2.800000000: 0.7 8 of 10: 0.7 at 2.8
+ 3.200000000: 0.8 9 of 10: 0.8 at 3.2
+ 3.600000000: 0.9 10 of 10: 0.9 at 3.6
diff --git a/test/expected/vamp-test-plugin_curve-oss.txt b/test/expected/vamp-test-plugin_curve-oss.txt
new file mode 100644
index 0000000..6b28153
--- /dev/null
+++ b/test/expected/vamp-test-plugin_curve-oss.txt
@@ -0,0 +1,21 @@
+=== vamp-test-plugin:vamp-test-plugin:curve-oss
+ 0.000000000: 0 1 of 20: 0 at 0
+ 0.046439909: 0.05 2 of 20: 0.05 at 0.046
+ 0.092879819: 0.1 3 of 20: 0.1 at 0.092
+ 0.139319728: 0.15 4 of 20: 0.15 at 0.139
+ 0.185759637: 0.2 5 of 20: 0.2 at 0.185
+ 0.232199546: 0.25 6 of 20: 0.25 at 0.232
+ 0.278639456: 0.3 7 of 20: 0.3 at 0.278
+ 0.325079365: 0.35 8 of 20: 0.35 at 0.325
+ 0.371519274: 0.4 9 of 20: 0.4 at 0.371
+ 0.417959184: 0.45 10 of 20: 0.45 at 0.417
+ 0.464399093: 0.5 11 of 20: 0.5 at 0.464
+ 0.510839002: 0.55 12 of 20: 0.55 at 0.51
+ 0.557278912: 0.6 13 of 20: 0.6 at 0.557
+ 0.603718821: 0.65 14 of 20: 0.65 at 0.603
+ 0.650158730: 0.7 15 of 20: 0.7 at 0.65
+ 0.696598639: 0.75 16 of 20: 0.75 at 0.696
+ 0.743038549: 0.8 17 of 20: 0.8 at 0.743
+ 0.789478458: 0.85 18 of 20: 0.85 at 0.789
+ 0.835918367: 0.9 19 of 20: 0.9 at 0.835
+ 0.882358277: 0.95 20 of 20: 0.95 at 0.882
diff --git a/test/expected/vamp-test-plugin_curve-vsr.txt b/test/expected/vamp-test-plugin_curve-vsr.txt
new file mode 100644
index 0000000..3094586
--- /dev/null
+++ b/test/expected/vamp-test-plugin_curve-vsr.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:curve-vsr
+ 0.000000000: 0 1 of 10: 0 at 0
+ 0.750000000: 0.1 2 of 10: 0.1 at 0.75
+ 1.500000000: 0.2 3 of 10: 0.2 at 1.5
+ 2.250000000: 0.3 4 of 10: 0.3 at 2.25
+ 3.000000000: 0.4 5 of 10: 0.4 at 3
+ 3.750000000: 0.5 6 of 10: 0.5 at 3.75
+ 4.500000000: 0.6 7 of 10: 0.6 at 4.5
+ 5.250000000: 0.7 8 of 10: 0.7 at 5.25
+ 6.000000000: 0.8 9 of 10: 0.8 at 6
+ 6.750000000: 0.9 10 of 10: 0.9 at 6.75
diff --git a/test/expected/vamp-test-plugin_grid-fsr.txt b/test/expected/vamp-test-plugin_grid-fsr.txt
new file mode 100644
index 0000000..3d5c2a6
--- /dev/null
+++ b/test/expected/vamp-test-plugin_grid-fsr.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:grid-fsr
+ 0.000000000: 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 1 of 10 at 0
+ 0.400000000: 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 2 of 10 at 0.4
+ 0.800000000: 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 3 of 10 at 0.8
+ 1.200000000: 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 4 of 10 at 1.2
+ 1.600000000: 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 5 of 10 at 1.6
+ 2.000000000: 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 6 of 10 at 2
+ 2.400000000: 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 7 of 10 at 2.4
+ 2.800000000: 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 8 of 10 at 2.8
+ 3.200000000: 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 9 of 10 at 3.2
+ 3.600000000: 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 10 of 10 at 3.6
diff --git a/test/expected/vamp-test-plugin_grid-oss.txt b/test/expected/vamp-test-plugin_grid-oss.txt
new file mode 100644
index 0000000..df94353
--- /dev/null
+++ b/test/expected/vamp-test-plugin_grid-oss.txt
@@ -0,0 +1,21 @@
+=== vamp-test-plugin:vamp-test-plugin:grid-oss
+ 0.000000000: 0.0666667 0.1 0.133333 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 1 of 20 at 0
+ 0.046439909: 0.1 0.133333 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 2 of 20 at 0.046
+ 0.092879819: 0.133333 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 3 of 20 at 0.092
+ 0.139319728: 0.166667 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 4 of 20 at 0.139
+ 0.185759637: 0.2 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 5 of 20 at 0.185
+ 0.232199546: 0.233333 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 6 of 20 at 0.232
+ 0.278639456: 0.266667 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 7 of 20 at 0.278
+ 0.325079365: 0.3 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 8 of 20 at 0.325
+ 0.371519274: 0.333333 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 9 of 20 at 0.371
+ 0.417959184: 0.366667 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 10 of 20 at 0.417
+ 0.464399093: 0.4 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 11 of 20 at 0.464
+ 0.510839002: 0.433333 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 12 of 20 at 0.51
+ 0.557278912: 0.466667 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 13 of 20 at 0.557
+ 0.603718821: 0.5 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 14 of 20 at 0.603
+ 0.650158730: 0.533333 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 15 of 20 at 0.65
+ 0.696598639: 0.566667 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 16 of 20 at 0.696
+ 0.743038549: 0.6 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 17 of 20 at 0.743
+ 0.789478458: 0.633333 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 0.933333 18 of 20 at 0.789
+ 0.835918367: 0.666667 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 0.933333 0.966667 19 of 20 at 0.835
+ 0.882358277: 0.7 0.733333 0.766667 0.8 0.833333 0.866667 0.9 0.933333 0.966667 1 20 of 20 at 0.882
diff --git a/test/expected/vamp-test-plugin_input-summary.txt b/test/expected/vamp-test-plugin_input-summary.txt
new file mode 100644
index 0000000..0fb192c
--- /dev/null
+++ b/test/expected/vamp-test-plugin_input-summary.txt
@@ -0,0 +1,422 @@
+=== vamp-test-plugin:vamp-test-plugin:input-summary
+ 0.000000000: 0 0 
+ 0.046439909: 1.04688 972 
+ 0.092879819: 1.09375 997.992 
+ 0.139319728: 1.14844 1003.99 
+ 0.185759637: 1.19531 1010.99 
+ 0.232199546: 1.24219 1011.99 
+ 0.278639456: 1.29688 1010.99 
+ 0.325079365: 1.34375 1019.99 
+ 0.371519274: 1.39062 1019.99 
+ 0.417959184: 1.44531 1020.99 
+ 0.464399093: 1.49219 1019.99 
+ 0.510839002: 1.53906 1019.99 
+ 0.557278912: 1.59375 1019.99 
+ 0.603718821: 1.64062 1019 
+ 0.650158730: 1.6875 1019.99 
+ 0.696598639: 1.74219 1019.99 
+ 0.743038549: 1.78906 1020.99 
+ 0.789478458: 1.83594 1019 
+ 0.835918367: 1.89062 1020.99 
+ 0.882358277: 1.9375 1018.99 
+ 0.928798186: 0 0 
+ 0.975238095: 1.04688 972 
+ 1.021678005: 1.09375 997.992 
+ 1.068117914: 1.14844 1003.99 
+ 1.114557823: 1.19531 1010.99 
+ 1.160997732: 1.24219 1011.99 
+ 1.207437642: 1.29688 1010.99 
+ 1.253877551: 1.34375 1019.99 
+ 1.300317460: 1.39062 1019.99 
+ 1.346757370: 1.44531 1020.99 
+ 1.393197279: 1.49219 1019.99 
+ 1.439637188: 1.53906 1019.99 
+ 1.486077098: 1.59375 1019.99 
+ 1.532517007: 1.64062 1019 
+ 1.578956916: 1.6875 1019.99 
+ 1.625396825: 1.74219 1019.99 
+ 1.671836735: 1.78906 1020.99 
+ 1.718276644: 1.83594 1019 
+ 1.764716553: 1.89062 1020.99 
+ 1.811156463: 1.9375 1018.99 
+ 1.857596372: 0 0 
+ 1.904036281: 1.04688 972 
+ 1.950476190: 1.09375 997.992 
+ 1.996916100: 1.14844 1003.99 
+ 2.043356009: 1.19531 1010.99 
+ 2.089795918: 1.24219 1011.99 
+ 2.136235828: 1.29688 1010.99 
+ 2.182675737: 1.34375 1019.99 
+ 2.229115646: 1.39062 1019.99 
+ 2.275555556: 1.44531 1020.99 
+ 2.321995465: 1.49219 1019.99 
+ 2.368435374: 1.53906 1019.99 
+ 2.414875283: 1.59375 1019.99 
+ 2.461315193: 1.64062 1019 
+ 2.507755102: 1.6875 1019.99 
+ 2.554195011: 1.74219 1019.99 
+ 2.600634921: 1.78906 1020.99 
+ 2.647074830: 1.83594 1019 
+ 2.693514739: 1.89062 1020.99 
+ 2.739954649: 1.9375 1018.99 
+ 2.786394558: 0 0 
+ 2.832834467: 1.04688 972 
+ 2.879274376: 1.09375 997.992 
+ 2.925714286: 1.14844 1003.99 
+ 2.972154195: 1.19531 1010.99 
+ 3.018594104: 1.24219 1011.99 
+ 3.065034014: 1.29688 1010.99 
+ 3.111473923: 1.34375 1019.99 
+ 3.157913832: 1.39062 1019.99 
+ 3.204353741: 1.44531 1020.99 
+ 3.250793651: 1.49219 1019.99 
+ 3.297233560: 1.53906 1019.99 
+ 3.343673469: 1.59375 1019.99 
+ 3.390113379: 1.64062 1019 
+ 3.436553288: 1.6875 1019.99 
+ 3.482993197: 1.74219 1019.99 
+ 3.529433107: 1.78906 1020.99 
+ 3.575873016: 1.83594 1019 
+ 3.622312925: 1.89062 1020.99 
+ 3.668752834: 1.9375 1018.99 
+ 3.715192744: 0 0 
+ 3.761632653: 1.04688 972 
+ 3.808072562: 1.09375 997.992 
+ 3.854512472: 1.14844 1003.99 
+ 3.900952381: 1.19531 1010.99 
+ 3.947392290: 1.24219 1011.99 
+ 3.993832200: 1.29688 1010.99 
+ 4.040272109: 1.34375 1019.99 
+ 4.086712018: 1.39062 1019.99 
+ 4.133151927: 1.44531 1020.99 
+ 4.179591837: 1.49219 1019.99 
+ 4.226031746: 1.53906 1019.99 
+ 4.272471655: 1.59375 1019.99 
+ 4.318911565: 1.64062 1019 
+ 4.365351474: 1.6875 1019.99 
+ 4.411791383: 1.74219 1019.99 
+ 4.458231293: 1.78906 1020.99 
+ 4.504671202: 1.83594 1019 
+ 4.551111111: 1.89062 1020.99 
+ 4.597551020: 1.9375 1018.99 
+ 4.643990930: 0 0 
+ 4.690430839: 1.04688 972 
+ 4.736870748: 1.09375 997.992 
+ 4.783310658: 1.14844 1003.99 
+ 4.829750567: 1.19531 1010.99 
+ 4.876190476: 1.24219 1011.99 
+ 4.922630385: 1.29688 1010.99 
+ 4.969070295: 1.34375 1019.99 
+ 5.015510204: 1.39062 1019.99 
+ 5.061950113: 1.44531 1020.99 
+ 5.108390023: 1.49219 1019.99 
+ 5.154829932: 1.53906 1019.99 
+ 5.201269841: 1.59375 1019.99 
+ 5.247709751: 1.64062 1019 
+ 5.294149660: 1.6875 1019.99 
+ 5.340589569: 1.74219 1019.99 
+ 5.387029478: 1.78906 1020.99 
+ 5.433469388: 1.83594 1019 
+ 5.479909297: 1.89062 1020.99 
+ 5.526349206: 1.9375 1018.99 
+ 5.572789116: 0 0 
+ 5.619229025: 1.04688 972 
+ 5.665668934: 1.09375 997.992 
+ 5.712108844: 1.14844 1003.99 
+ 5.758548753: 1.19531 1010.99 
+ 5.804988662: 1.24219 1011.99 
+ 5.851428571: 1.29688 1010.99 
+ 5.897868481: 1.34375 1019.99 
+ 5.944308390: 1.39062 1019.99 
+ 5.990748299: 1.44531 1020.99 
+ 6.037188209: 1.49219 1019.99 
+ 6.083628118: 1.53906 1019.99 
+ 6.130068027: 1.59375 1019.99 
+ 6.176507937: 1.64062 1019 
+ 6.222947846: 1.6875 1019.99 
+ 6.269387755: 1.74219 1019.99 
+ 6.315827664: 1.78906 1020.99 
+ 6.362267574: 1.83594 1019 
+ 6.408707483: 1.89062 1020.99 
+ 6.455147392: 1.9375 1018.99 
+ 6.501587302: 0 0 
+ 6.548027211: 1.04688 972 
+ 6.594467120: 1.09375 997.992 
+ 6.640907029: 1.14844 1003.99 
+ 6.687346939: 1.19531 1010.99 
+ 6.733786848: 1.24219 1011.99 
+ 6.780226757: 1.29688 1010.99 
+ 6.826666667: 1.34375 1019.99 
+ 6.873106576: 1.39062 1019.99 
+ 6.919546485: 1.44531 1020.99 
+ 6.965986395: 1.49219 1019.99 
+ 7.012426304: 1.53906 1019.99 
+ 7.058866213: 1.59375 1019.99 
+ 7.105306122: 1.64062 1019 
+ 7.151746032: 1.6875 1019.99 
+ 7.198185941: 1.74219 1019.99 
+ 7.244625850: 1.78906 1020.99 
+ 7.291065760: 1.83594 1019 
+ 7.337505669: 1.89062 1020.99 
+ 7.383945578: 1.9375 1018.99 
+ 7.430385488: 0 0 
+ 7.476825397: 1.04688 972 
+ 7.523265306: 1.09375 997.992 
+ 7.569705215: 1.14844 1003.99 
+ 7.616145125: 1.19531 1010.99 
+ 7.662585034: 1.24219 1011.99 
+ 7.709024943: 1.29688 1010.99 
+ 7.755464853: 1.34375 1019.99 
+ 7.801904762: 1.39062 1019.99 
+ 7.848344671: 1.44531 1020.99 
+ 7.894784580: 1.49219 1019.99 
+ 7.941224490: 1.53906 1019.99 
+ 7.987664399: 1.59375 1019.99 
+ 8.034104308: 1.64062 1019 
+ 8.080544218: 1.6875 1019.99 
+ 8.126984127: 1.74219 1019.99 
+ 8.173424036: 1.78906 1020.99 
+ 8.219863946: 1.83594 1019 
+ 8.266303855: 1.89062 1020.99 
+ 8.312743764: 1.9375 1018.99 
+ 8.359183673: 0 0 
+ 8.405623583: 1.04688 972 
+ 8.452063492: 1.09375 997.992 
+ 8.498503401: 1.14844 1003.99 
+ 8.544943311: 1.19531 1010.99 
+ 8.591383220: 1.24219 1011.99 
+ 8.637823129: 1.29688 1010.99 
+ 8.684263039: 1.34375 1019.99 
+ 8.730702948: 1.39062 1019.99 
+ 8.777142857: 1.44531 1020.99 
+ 8.823582766: 1.49219 1019.99 
+ 8.870022676: 1.53906 1019.99 
+ 8.916462585: 1.59375 1019.99 
+ 8.962902494: 1.64062 1019 
+ 9.009342404: 1.6875 1019.99 
+ 9.055782313: 1.74219 1019.99 
+ 9.102222222: 1.78906 1020.99 
+ 9.148662132: 1.83594 1019 
+ 9.195102041: 1.89062 1020.99 
+ 9.241541950: 1.9375 1018.99 
+ 9.287981859: 0 0 
+ 9.334421769: 1.04688 972 
+ 9.380861678: 1.09375 997.992 
+ 9.427301587: 1.14844 1003.99 
+ 9.473741497: 1.19531 1010.99 
+ 9.520181406: 1.24219 1011.99 
+ 9.566621315: 1.29688 1010.99 
+ 9.613061224: 1.34375 1019.99 
+ 9.659501134: 1.39062 1019.99 
+ 9.705941043: 1.44531 1020.99 
+ 9.752380952: 1.49219 1019.99 
+ 9.798820862: 1.53906 1019.99 
+ 9.845260771: 1.59375 1019.99 
+ 9.891700680: 1.64062 1019 
+ 9.938140590: 1.6875 1019.99 
+ 9.984580499: 1.74219 1019.99 
+ 10.031020408: 1.78906 1020.99 
+ 10.077460317: 1.83594 1019 
+ 10.123900227: 1.89062 1020.99 
+ 10.170340136: 1.9375 1018.99 
+ 10.216780045: 0 0 
+ 10.263219955: 1.04688 972 
+ 10.309659864: 1.09375 997.992 
+ 10.356099773: 1.14844 1003.99 
+ 10.402539683: 1.19531 1010.99 
+ 10.448979592: 1.24219 1011.99 
+ 10.495419501: 1.29688 1010.99 
+ 10.541859410: 1.34375 1019.99 
+ 10.588299320: 1.39062 1019.99 
+ 10.634739229: 1.44531 1020.99 
+ 10.681179138: 1.49219 1019.99 
+ 10.727619048: 1.53906 1019.99 
+ 10.774058957: 1.59375 1019.99 
+ 10.820498866: 1.64062 1019 
+ 10.866938776: 1.6875 1019.99 
+ 10.913378685: 1.74219 1019.99 
+ 10.959818594: 1.78906 1020.99 
+ 11.006258503: 1.83594 1019 
+ 11.052698413: 1.89062 1020.99 
+ 11.099138322: 1.9375 1018.99 
+ 11.145578231: 0 0 
+ 11.192018141: 1.04688 972 
+ 11.238458050: 1.09375 997.992 
+ 11.284897959: 1.14844 1003.99 
+ 11.331337868: 1.19531 1010.99 
+ 11.377777778: 1.24219 1011.99 
+ 11.424217687: 1.29688 1010.99 
+ 11.470657596: 1.34375 1019.99 
+ 11.517097506: 1.39062 1019.99 
+ 11.563537415: 1.44531 1020.99 
+ 11.609977324: 1.49219 1019.99 
+ 11.656417234: 1.53906 1019.99 
+ 11.702857143: 1.59375 1019.99 
+ 11.749297052: 1.64062 1019 
+ 11.795736961: 1.6875 1019.99 
+ 11.842176871: 1.74219 1019.99 
+ 11.888616780: 1.78906 1020.99 
+ 11.935056689: 1.83594 1019 
+ 11.981496599: 1.89062 1020.99 
+ 12.027936508: 1.9375 1018.99 
+ 12.074376417: 0 0 
+ 12.120816327: 1.04688 972 
+ 12.167256236: 1.09375 997.992 
+ 12.213696145: 1.14844 1003.99 
+ 12.260136054: 1.19531 1010.99 
+ 12.306575964: 1.24219 1011.99 
+ 12.353015873: 1.29688 1010.99 
+ 12.399455782: 1.34375 1019.99 
+ 12.445895692: 1.39062 1019.99 
+ 12.492335601: 1.44531 1020.99 
+ 12.538775510: 1.49219 1019.99 
+ 12.585215420: 1.53906 1019.99 
+ 12.631655329: 1.59375 1019.99 
+ 12.678095238: 1.64062 1019 
+ 12.724535147: 1.6875 1019.99 
+ 12.770975057: 1.74219 1019.99 
+ 12.817414966: 1.78906 1020.99 
+ 12.863854875: 1.83594 1019 
+ 12.910294785: 1.89062 1020.99 
+ 12.956734694: 1.9375 1018.99 
+ 13.003174603: 0 0 
+ 13.049614512: 1.04688 972 
+ 13.096054422: 1.09375 997.992 
+ 13.142494331: 1.14844 1003.99 
+ 13.188934240: 1.19531 1010.99 
+ 13.235374150: 1.24219 1011.99 
+ 13.281814059: 1.29688 1010.99 
+ 13.328253968: 1.34375 1019.99 
+ 13.374693878: 1.39062 1019.99 
+ 13.421133787: 1.44531 1020.99 
+ 13.467573696: 1.49219 1019.99 
+ 13.514013605: 1.53906 1019.99 
+ 13.560453515: 1.59375 1019.99 
+ 13.606893424: 1.64062 1019 
+ 13.653333333: 1.6875 1019.99 
+ 13.699773243: 1.74219 1019.99 
+ 13.746213152: 1.78906 1020.99 
+ 13.792653061: 1.83594 1019 
+ 13.839092971: 1.89062 1020.99 
+ 13.885532880: 1.9375 1018.99 
+ 13.931972789: 0 0 
+ 13.978412698: 1.04688 972 
+ 14.024852608: 1.09375 997.992 
+ 14.071292517: 1.14844 1003.99 
+ 14.117732426: 1.19531 1010.99 
+ 14.164172336: 1.24219 1011.99 
+ 14.210612245: 1.29688 1010.99 
+ 14.257052154: 1.34375 1019.99 
+ 14.303492063: 1.39062 1019.99 
+ 14.349931973: 1.44531 1020.99 
+ 14.396371882: 1.49219 1019.99 
+ 14.442811791: 1.53906 1019.99 
+ 14.489251701: 1.59375 1019.99 
+ 14.535691610: 1.64062 1019 
+ 14.582131519: 1.6875 1019.99 
+ 14.628571429: 1.74219 1019.99 
+ 14.675011338: 1.78906 1020.99 
+ 14.721451247: 1.83594 1019 
+ 14.767891156: 1.89062 1020.99 
+ 14.814331066: 1.9375 1018.99 
+ 14.860770975: 0 0 
+ 14.907210884: 1.04688 972 
+ 14.953650794: 1.09375 997.992 
+ 15.000090703: 1.14844 1003.99 
+ 15.046530612: 1.19531 1010.99 
+ 15.092970522: 1.24219 1011.99 
+ 15.139410431: 1.29688 1010.99 
+ 15.185850340: 1.34375 1019.99 
+ 15.232290249: 1.39062 1019.99 
+ 15.278730159: 1.44531 1020.99 
+ 15.325170068: 1.49219 1019.99 
+ 15.371609977: 1.53906 1019.99 
+ 15.418049887: 1.59375 1019.99 
+ 15.464489796: 1.64062 1019 
+ 15.510929705: 1.6875 1019.99 
+ 15.557369615: 1.74219 1019.99 
+ 15.603809524: 1.78906 1020.99 
+ 15.650249433: 1.83594 1019 
+ 15.696689342: 1.89062 1020.99 
+ 15.743129252: 1.9375 1018.99 
+ 15.789569161: 0 0 
+ 15.836009070: 1.04688 972 
+ 15.882448980: 1.09375 997.992 
+ 15.928888889: 1.14844 1003.99 
+ 15.975328798: 1.19531 1010.99 
+ 16.021768707: 1.24219 1011.99 
+ 16.068208617: 1.29688 1010.99 
+ 16.114648526: 1.34375 1019.99 
+ 16.161088435: 1.39062 1019.99 
+ 16.207528345: 1.44531 1020.99 
+ 16.253968254: 1.49219 1019.99 
+ 16.300408163: 1.53906 1019.99 
+ 16.346848073: 1.59375 1019.99 
+ 16.393287982: 1.64062 1019 
+ 16.439727891: 1.6875 1019.99 
+ 16.486167800: 1.74219 1019.99 
+ 16.532607710: 1.78906 1020.99 
+ 16.579047619: 1.83594 1019 
+ 16.625487528: 1.89062 1020.99 
+ 16.671927438: 1.9375 1018.99 
+ 16.718367347: 0 0 
+ 16.764807256: 1.04688 972 
+ 16.811247166: 1.09375 997.992 
+ 16.857687075: 1.14844 1003.99 
+ 16.904126984: 1.19531 1010.99 
+ 16.950566893: 1.24219 1011.99 
+ 16.997006803: 1.29688 1010.99 
+ 17.043446712: 1.34375 1019.99 
+ 17.089886621: 1.39062 1019.99 
+ 17.136326531: 1.44531 1020.99 
+ 17.182766440: 1.49219 1019.99 
+ 17.229206349: 1.53906 1019.99 
+ 17.275646259: 1.59375 1019.99 
+ 17.322086168: 1.64062 1019 
+ 17.368526077: 1.6875 1019.99 
+ 17.414965986: 1.74219 1019.99 
+ 17.461405896: 1.78906 1020.99 
+ 17.507845805: 1.83594 1019 
+ 17.554285714: 1.89062 1020.99 
+ 17.600725624: 1.9375 1018.99 
+ 17.647165533: 0 0 
+ 17.693605442: 1.04688 972 
+ 17.740045351: 1.09375 997.992 
+ 17.786485261: 1.14844 1003.99 
+ 17.832925170: 1.19531 1010.99 
+ 17.879365079: 1.24219 1011.99 
+ 17.925804989: 1.29688 1010.99 
+ 17.972244898: 1.34375 1019.99 
+ 18.018684807: 1.39062 1019.99 
+ 18.065124717: 1.44531 1020.99 
+ 18.111564626: 1.49219 1019.99 
+ 18.158004535: 1.53906 1019.99 
+ 18.204444444: 1.59375 1019.99 
+ 18.250884354: 1.64062 1019 
+ 18.297324263: 1.6875 1019.99 
+ 18.343764172: 1.74219 1019.99 
+ 18.390204082: 1.78906 1020.99 
+ 18.436643991: 1.83594 1019 
+ 18.483083900: 1.89062 1020.99 
+ 18.529523810: 1.9375 1018.99 
+ 18.575963719: 0 0 
+ 18.622403628: 1.04688 972 
+ 18.668843537: 1.09375 997.992 
+ 18.715283447: 1.14844 1003.99 
+ 18.761723356: 1.19531 1010.99 
+ 18.808163265: 1.24219 1011.99 
+ 18.854603175: 1.29688 1010.99 
+ 18.901043084: 1.34375 1019.99 
+ 18.947482993: 1.39062 1019.99 
+ 18.993922902: 1.44531 1020.99 
+ 19.040362812: 1.49219 1019.99 
+ 19.086802721: 1.53906 1019.99 
+ 19.133242630: 1.59375 1019.99 
+ 19.179682540: 1.64062 1019 
+ 19.226122449: 1.6875 1019.99 
+ 19.272562358: 1.74219 1019.99 
+ 19.319002268: 1.78906 1020.99 
+ 19.365442177: 1.83594 1019 
+ 19.411882086: 1.89062 1020.99 
+ 19.458321995: 1.9375 1018.99 
+ 19.504761905: 0 0 
diff --git a/test/expected/vamp-test-plugin_input-timestamp.txt b/test/expected/vamp-test-plugin_input-timestamp.txt
new file mode 100644
index 0000000..aa4423a
--- /dev/null
+++ b/test/expected/vamp-test-plugin_input-timestamp.txt
@@ -0,0 +1,422 @@
+=== vamp-test-plugin:vamp-test-plugin:input-timestamp
+ 0.000000000: 0 
+ 0.046439909: 1024 
+ 0.092879819: 2048 
+ 0.139319728: 3072 
+ 0.185759637: 4096 
+ 0.232199546: 5120 
+ 0.278639456: 6144 
+ 0.325079365: 7168 
+ 0.371519274: 8192 
+ 0.417959184: 9216 
+ 0.464399093: 10240 
+ 0.510839002: 11264 
+ 0.557278912: 12288 
+ 0.603718821: 13312 
+ 0.650158730: 14336 
+ 0.696598639: 15360 
+ 0.743038549: 16384 
+ 0.789478458: 17408 
+ 0.835918367: 18432 
+ 0.882358277: 19456 
+ 0.928798186: 20480 
+ 0.975238095: 21504 
+ 1.021678005: 22528 
+ 1.068117914: 23552 
+ 1.114557823: 24576 
+ 1.160997732: 25600 
+ 1.207437642: 26624 
+ 1.253877551: 27648 
+ 1.300317460: 28672 
+ 1.346757370: 29696 
+ 1.393197279: 30720 
+ 1.439637188: 31744 
+ 1.486077098: 32768 
+ 1.532517007: 33792 
+ 1.578956916: 34816 
+ 1.625396825: 35840 
+ 1.671836735: 36864 
+ 1.718276644: 37888 
+ 1.764716553: 38912 
+ 1.811156463: 39936 
+ 1.857596372: 40960 
+ 1.904036281: 41984 
+ 1.950476190: 43008 
+ 1.996916100: 44032 
+ 2.043356009: 45056 
+ 2.089795918: 46080 
+ 2.136235828: 47104 
+ 2.182675737: 48128 
+ 2.229115646: 49152 
+ 2.275555556: 50176 
+ 2.321995465: 51200 
+ 2.368435374: 52224 
+ 2.414875283: 53248 
+ 2.461315193: 54272 
+ 2.507755102: 55296 
+ 2.554195011: 56320 
+ 2.600634921: 57344 
+ 2.647074830: 58368 
+ 2.693514739: 59392 
+ 2.739954649: 60416 
+ 2.786394558: 61440 
+ 2.832834467: 62464 
+ 2.879274376: 63488 
+ 2.925714286: 64512 
+ 2.972154195: 65536 
+ 3.018594104: 66560 
+ 3.065034014: 67584 
+ 3.111473923: 68608 
+ 3.157913832: 69632 
+ 3.204353741: 70656 
+ 3.250793651: 71680 
+ 3.297233560: 72704 
+ 3.343673469: 73728 
+ 3.390113379: 74752 
+ 3.436553288: 75776 
+ 3.482993197: 76800 
+ 3.529433107: 77824 
+ 3.575873016: 78848 
+ 3.622312925: 79872 
+ 3.668752834: 80896 
+ 3.715192744: 81920 
+ 3.761632653: 82944 
+ 3.808072562: 83968 
+ 3.854512472: 84992 
+ 3.900952381: 86016 
+ 3.947392290: 87040 
+ 3.993832200: 88064 
+ 4.040272109: 89088 
+ 4.086712018: 90112 
+ 4.133151927: 91136 
+ 4.179591837: 92160 
+ 4.226031746: 93184 
+ 4.272471655: 94208 
+ 4.318911565: 95232 
+ 4.365351474: 96256 
+ 4.411791383: 97280 
+ 4.458231293: 98304 
+ 4.504671202: 99328 
+ 4.551111111: 100352 
+ 4.597551020: 101376 
+ 4.643990930: 102400 
+ 4.690430839: 103424 
+ 4.736870748: 104448 
+ 4.783310658: 105472 
+ 4.829750567: 106496 
+ 4.876190476: 107520 
+ 4.922630385: 108544 
+ 4.969070295: 109568 
+ 5.015510204: 110592 
+ 5.061950113: 111616 
+ 5.108390023: 112640 
+ 5.154829932: 113664 
+ 5.201269841: 114688 
+ 5.247709751: 115712 
+ 5.294149660: 116736 
+ 5.340589569: 117760 
+ 5.387029478: 118784 
+ 5.433469388: 119808 
+ 5.479909297: 120832 
+ 5.526349206: 121856 
+ 5.572789116: 122880 
+ 5.619229025: 123904 
+ 5.665668934: 124928 
+ 5.712108844: 125952 
+ 5.758548753: 126976 
+ 5.804988662: 128000 
+ 5.851428571: 129024 
+ 5.897868481: 130048 
+ 5.944308390: 131072 
+ 5.990748299: 132096 
+ 6.037188209: 133120 
+ 6.083628118: 134144 
+ 6.130068027: 135168 
+ 6.176507937: 136192 
+ 6.222947846: 137216 
+ 6.269387755: 138240 
+ 6.315827664: 139264 
+ 6.362267574: 140288 
+ 6.408707483: 141312 
+ 6.455147392: 142336 
+ 6.501587302: 143360 
+ 6.548027211: 144384 
+ 6.594467120: 145408 
+ 6.640907029: 146432 
+ 6.687346939: 147456 
+ 6.733786848: 148480 
+ 6.780226757: 149504 
+ 6.826666667: 150528 
+ 6.873106576: 151552 
+ 6.919546485: 152576 
+ 6.965986395: 153600 
+ 7.012426304: 154624 
+ 7.058866213: 155648 
+ 7.105306122: 156672 
+ 7.151746032: 157696 
+ 7.198185941: 158720 
+ 7.244625850: 159744 
+ 7.291065760: 160768 
+ 7.337505669: 161792 
+ 7.383945578: 162816 
+ 7.430385488: 163840 
+ 7.476825397: 164864 
+ 7.523265306: 165888 
+ 7.569705215: 166912 
+ 7.616145125: 167936 
+ 7.662585034: 168960 
+ 7.709024943: 169984 
+ 7.755464853: 171008 
+ 7.801904762: 172032 
+ 7.848344671: 173056 
+ 7.894784580: 174080 
+ 7.941224490: 175104 
+ 7.987664399: 176128 
+ 8.034104308: 177152 
+ 8.080544218: 178176 
+ 8.126984127: 179200 
+ 8.173424036: 180224 
+ 8.219863946: 181248 
+ 8.266303855: 182272 
+ 8.312743764: 183296 
+ 8.359183673: 184320 
+ 8.405623583: 185344 
+ 8.452063492: 186368 
+ 8.498503401: 187392 
+ 8.544943311: 188416 
+ 8.591383220: 189440 
+ 8.637823129: 190464 
+ 8.684263039: 191488 
+ 8.730702948: 192512 
+ 8.777142857: 193536 
+ 8.823582766: 194560 
+ 8.870022676: 195584 
+ 8.916462585: 196608 
+ 8.962902494: 197632 
+ 9.009342404: 198656 
+ 9.055782313: 199680 
+ 9.102222222: 200704 
+ 9.148662132: 201728 
+ 9.195102041: 202752 
+ 9.241541950: 203776 
+ 9.287981859: 204800 
+ 9.334421769: 205824 
+ 9.380861678: 206848 
+ 9.427301587: 207872 
+ 9.473741497: 208896 
+ 9.520181406: 209920 
+ 9.566621315: 210944 
+ 9.613061224: 211968 
+ 9.659501134: 212992 
+ 9.705941043: 214016 
+ 9.752380952: 215040 
+ 9.798820862: 216064 
+ 9.845260771: 217088 
+ 9.891700680: 218112 
+ 9.938140590: 219136 
+ 9.984580499: 220160 
+ 10.031020408: 221184 
+ 10.077460317: 222208 
+ 10.123900227: 223232 
+ 10.170340136: 224256 
+ 10.216780045: 225280 
+ 10.263219955: 226304 
+ 10.309659864: 227328 
+ 10.356099773: 228352 
+ 10.402539683: 229376 
+ 10.448979592: 230400 
+ 10.495419501: 231424 
+ 10.541859410: 232448 
+ 10.588299320: 233472 
+ 10.634739229: 234496 
+ 10.681179138: 235520 
+ 10.727619048: 236544 
+ 10.774058957: 237568 
+ 10.820498866: 238592 
+ 10.866938776: 239616 
+ 10.913378685: 240640 
+ 10.959818594: 241664 
+ 11.006258503: 242688 
+ 11.052698413: 243712 
+ 11.099138322: 244736 
+ 11.145578231: 245760 
+ 11.192018141: 246784 
+ 11.238458050: 247808 
+ 11.284897959: 248832 
+ 11.331337868: 249856 
+ 11.377777778: 250880 
+ 11.424217687: 251904 
+ 11.470657596: 252928 
+ 11.517097506: 253952 
+ 11.563537415: 254976 
+ 11.609977324: 256000 
+ 11.656417234: 257024 
+ 11.702857143: 258048 
+ 11.749297052: 259072 
+ 11.795736961: 260096 
+ 11.842176871: 261120 
+ 11.888616780: 262144 
+ 11.935056689: 263168 
+ 11.981496599: 264192 
+ 12.027936508: 265216 
+ 12.074376417: 266240 
+ 12.120816327: 267264 
+ 12.167256236: 268288 
+ 12.213696145: 269312 
+ 12.260136054: 270336 
+ 12.306575964: 271360 
+ 12.353015873: 272384 
+ 12.399455782: 273408 
+ 12.445895692: 274432 
+ 12.492335601: 275456 
+ 12.538775510: 276480 
+ 12.585215420: 277504 
+ 12.631655329: 278528 
+ 12.678095238: 279552 
+ 12.724535147: 280576 
+ 12.770975057: 281600 
+ 12.817414966: 282624 
+ 12.863854875: 283648 
+ 12.910294785: 284672 
+ 12.956734694: 285696 
+ 13.003174603: 286720 
+ 13.049614512: 287744 
+ 13.096054422: 288768 
+ 13.142494331: 289792 
+ 13.188934240: 290816 
+ 13.235374150: 291840 
+ 13.281814059: 292864 
+ 13.328253968: 293888 
+ 13.374693878: 294912 
+ 13.421133787: 295936 
+ 13.467573696: 296960 
+ 13.514013605: 297984 
+ 13.560453515: 299008 
+ 13.606893424: 300032 
+ 13.653333333: 301056 
+ 13.699773243: 302080 
+ 13.746213152: 303104 
+ 13.792653061: 304128 
+ 13.839092971: 305152 
+ 13.885532880: 306176 
+ 13.931972789: 307200 
+ 13.978412698: 308224 
+ 14.024852608: 309248 
+ 14.071292517: 310272 
+ 14.117732426: 311296 
+ 14.164172336: 312320 
+ 14.210612245: 313344 
+ 14.257052154: 314368 
+ 14.303492063: 315392 
+ 14.349931973: 316416 
+ 14.396371882: 317440 
+ 14.442811791: 318464 
+ 14.489251701: 319488 
+ 14.535691610: 320512 
+ 14.582131519: 321536 
+ 14.628571429: 322560 
+ 14.675011338: 323584 
+ 14.721451247: 324608 
+ 14.767891156: 325632 
+ 14.814331066: 326656 
+ 14.860770975: 327680 
+ 14.907210884: 328704 
+ 14.953650794: 329728 
+ 15.000090703: 330752 
+ 15.046530612: 331776 
+ 15.092970522: 332800 
+ 15.139410431: 333824 
+ 15.185850340: 334848 
+ 15.232290249: 335872 
+ 15.278730159: 336896 
+ 15.325170068: 337920 
+ 15.371609977: 338944 
+ 15.418049887: 339968 
+ 15.464489796: 340992 
+ 15.510929705: 342016 
+ 15.557369615: 343040 
+ 15.603809524: 344064 
+ 15.650249433: 345088 
+ 15.696689342: 346112 
+ 15.743129252: 347136 
+ 15.789569161: 348160 
+ 15.836009070: 349184 
+ 15.882448980: 350208 
+ 15.928888889: 351232 
+ 15.975328798: 352256 
+ 16.021768707: 353280 
+ 16.068208617: 354304 
+ 16.114648526: 355328 
+ 16.161088435: 356352 
+ 16.207528345: 357376 
+ 16.253968254: 358400 
+ 16.300408163: 359424 
+ 16.346848073: 360448 
+ 16.393287982: 361472 
+ 16.439727891: 362496 
+ 16.486167800: 363520 
+ 16.532607710: 364544 
+ 16.579047619: 365568 
+ 16.625487528: 366592 
+ 16.671927438: 367616 
+ 16.718367347: 368640 
+ 16.764807256: 369664 
+ 16.811247166: 370688 
+ 16.857687075: 371712 
+ 16.904126984: 372736 
+ 16.950566893: 373760 
+ 16.997006803: 374784 
+ 17.043446712: 375808 
+ 17.089886621: 376832 
+ 17.136326531: 377856 
+ 17.182766440: 378880 
+ 17.229206349: 379904 
+ 17.275646259: 380928 
+ 17.322086168: 381952 
+ 17.368526077: 382976 
+ 17.414965986: 384000 
+ 17.461405896: 385024 
+ 17.507845805: 386048 
+ 17.554285714: 387072 
+ 17.600725624: 388096 
+ 17.647165533: 389120 
+ 17.693605442: 390144 
+ 17.740045351: 391168 
+ 17.786485261: 392192 
+ 17.832925170: 393216 
+ 17.879365079: 394240 
+ 17.925804989: 395264 
+ 17.972244898: 396288 
+ 18.018684807: 397312 
+ 18.065124717: 398336 
+ 18.111564626: 399360 
+ 18.158004535: 400384 
+ 18.204444444: 401408 
+ 18.250884354: 402432 
+ 18.297324263: 403456 
+ 18.343764172: 404480 
+ 18.390204082: 405504 
+ 18.436643991: 406528 
+ 18.483083900: 407552 
+ 18.529523810: 408576 
+ 18.575963719: 409600 
+ 18.622403628: 410624 
+ 18.668843537: 411648 
+ 18.715283447: 412672 
+ 18.761723356: 413696 
+ 18.808163265: 414720 
+ 18.854603175: 415744 
+ 18.901043084: 416768 
+ 18.947482993: 417792 
+ 18.993922902: 418816 
+ 19.040362812: 419840 
+ 19.086802721: 420864 
+ 19.133242630: 421888 
+ 19.179682540: 422912 
+ 19.226122449: 423936 
+ 19.272562358: 424960 
+ 19.319002268: 425984 
+ 19.365442177: 427008 
+ 19.411882086: 428032 
+ 19.458321995: 429056 
+ 19.504761905: 430080 
diff --git a/test/expected/vamp-test-plugin_instants.txt b/test/expected/vamp-test-plugin_instants.txt
new file mode 100644
index 0000000..cf869b8
--- /dev/null
+++ b/test/expected/vamp-test-plugin_instants.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:instants
+ 0.000000000: 1 of 10 at 0
+ 1.500000000: 2 of 10 at 1.5
+ 3.000000000: 3 of 10 at 3
+ 4.500000000: 4 of 10 at 4.5
+ 6.000000000: 5 of 10 at 6
+ 7.500000000: 6 of 10 at 7.5
+ 9.000000000: 7 of 10 at 9
+ 10.500000000: 8 of 10 at 10.5
+ 12.000000000: 9 of 10 at 12
+ 13.500000000: 10 of 10 at 13.5
diff --git a/test/expected/vamp-test-plugin_notes-regions.txt b/test/expected/vamp-test-plugin_notes-regions.txt
new file mode 100644
index 0000000..96fe9f3
--- /dev/null
+++ b/test/expected/vamp-test-plugin_notes-regions.txt
@@ -0,0 +1,11 @@
+=== vamp-test-plugin:vamp-test-plugin:notes-regions
+ 0.000000000, 1.750000000: 0 1 of 10: 0 at 0 dur. 1.75
+ 1.000000000, 0.500000000: 0.1 2 of 10: 0.1 at 1 dur. 0.5
+ 2.000000000, 1.750000000: 0.2 3 of 10: 0.2 at 2 dur. 1.75
+ 3.000000000, 0.500000000: 0.3 4 of 10: 0.3 at 3 dur. 0.5
+ 4.000000000, 1.750000000: 0.4 5 of 10: 0.4 at 4 dur. 1.75
+ 5.000000000, 0.500000000: 0.5 6 of 10: 0.5 at 5 dur. 0.5
+ 6.000000000, 1.750000000: 0.6 7 of 10: 0.6 at 6 dur. 1.75
+ 7.000000000, 0.500000000: 0.7 8 of 10: 0.7 at 7 dur. 0.5
+ 8.000000000, 1.750000000: 0.8 9 of 10: 0.8 at 8 dur. 1.75
+ 9.000000000, 0.500000000: 0.9 10 of 10: 0.9 at 9 dur. 0.5
diff --git a/test/run-test-plugin-regression.sh b/test/run-test-plugin-regression.sh
new file mode 100755
index 0000000..455e446
--- /dev/null
+++ b/test/run-test-plugin-regression.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+set -eu
+
+MYDIR=$(dirname "$0")
+
+TEST_PLUGIN_DIR="$MYDIR/../../vamp-test-plugin"
+HOST_DIR="$MYDIR/../host"
+HOST="$HOST_DIR/vamp-simple-host"
+TEST_FILE="$MYDIR/testsignal.wav"
+
+mkdir -p "$MYDIR/obtained"
+mkdir -p "$MYDIR/failures"
+
+echo "Rebuilding SDK and simple host..." 1>&2
+( cd "$MYDIR/.." && ./configure && make clean && make )
+
+if [ ! -d "$TEST_PLUGIN_DIR" ]; then
+    echo "Can't find test plugin dir at $TEST_PLUGIN_DIR" 1>&2
+    exit 1
+fi
+
+if [ ! -x "$HOST" ]; then
+    echo "Can't find host at $HOST" 1>&2
+    exit 1
+fi
+
+echo "Rebuilding test plugin..." 1>&2
+( cd "$TEST_PLUGIN_DIR" && make -f Makefile.linux clean && make -f Makefile.linux )
+
+export VAMP_PATH="$TEST_PLUGIN_DIR"
+
+# check that the two expected test plugin ids are present:
+
+ids=$("$HOST" --list-ids)
+
+expected="vamp:vamp-test-plugin:vamp-test-plugin
+vamp:vamp-test-plugin:vamp-test-plugin-freq"
+
+if [ "$ids" != "$expected" ]; then
+    echo "Unexpected id list: $ids" 1>&2
+    echo "Expected: $expected" 1>&2
+    exit 1
+fi
+
+some_failed=nope
+echo
+
+for test in $("$HOST" --list-outputs | sed 's/^vamp://') ; do
+
+    filename="$(echo "$test.txt" | sed 's/^[^:]*://' | sed 's/:/_/g')"
+    expected="$MYDIR/expected/$filename"
+    obtained="$MYDIR/obtained/$filename"
+    failure="$MYDIR/failures/$filename"
+
+    rm -f "$failure"
+    echo "=== $test" > "$obtained"
+    "$HOST" "$test" "$TEST_FILE" >> "$obtained" 2>/dev/null
+    
+    if cmp -s "$expected" "$obtained" ; then
+	echo "$test: ok"
+    else
+	sdiff "$expected" "$obtained" > "$failure" || true # avoid exit-on-failure
+	echo "*** $test: FAILED, see $failure for diff"
+	some_failed=yup
+    fi
+    
+done
+
+if [ "$some_failed" != "nope" ]; then
+    echo; echo "*** Some tests failed!"; echo
+fi
+
diff --git a/test/testsignal.ipynb b/test/testsignal.ipynb
new file mode 100644
index 0000000..8fdc163
--- /dev/null
+++ b/test/testsignal.ipynb
@@ -0,0 +1,236 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import librosa\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "block=1024\n",
+    "length=block*20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "diracs = [ x/float(length) if (x % block) == 0 else 0.0 for x in range(0,length) ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x7f7fe1e18320>]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\nAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f8020199278>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.plot(diracs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "import math\n",
+    "wave = [ (int(x/block) / float(length/block)) * math.sin(x*math.pi/(block/8)) for x in range(0,length)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x7f7fe1e54780>]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f7fe1e54cc0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plt.plot(wave)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "duration=20.0\n",
+    "rate=22050\n",
+    "nsamples=duration*rate\n",
+    "repeats=int(nsamples/length)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "data=[diracs * repeats, wave * repeats]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "ndata = np.uint8(np.array(data) * 127.0 + 128.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(430080, 2)"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ndata = np.swapaxes(ndata, 0, 1)\n",
+    "ndata.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "from scipy.io.wavfile import write\n",
+    "write('/tmp/test.wav', rate, ndata)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.5.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/test/testsignal.wav b/test/testsignal.wav
new file mode 100644
index 0000000..8ba28e7
Binary files /dev/null and b/test/testsignal.wav differ
diff --git a/vamp-hostsdk/PluginLoader.h b/vamp-hostsdk/PluginLoader.h
index c511301..19fd494 100644
--- a/vamp-hostsdk/PluginLoader.h
+++ b/vamp-hostsdk/PluginLoader.h
@@ -128,6 +128,34 @@ public:
     PluginKeyList listPlugins();
 
     /**
+     * Search for available Vamp plugins in libraries with the given
+     * library names, and return a list of them in the order in which
+     * they were found. Do not attempt to load any plugin libraries
+     * other than those named.
+     *
+     * The library names should be supplied without path or
+     * suffix. For example, use "vamp-example-plugins" to find plugins
+     * in /install/path/of/vamp-example-plugins.dll (or .so etc). This
+     * is the same concept of "library name" as appears in the plugin
+     * key: \see composePluginKey().
+     */
+    PluginKeyList listPluginsIn(std::vector<std::string> libraryNames);
+
+    /**
+     * Search for available Vamp plugins in libraries other than those
+     * with the given library names, and return a list of them in the
+     * order in which they were found. Do not attempt to load any of
+     * the libraries named.
+     *
+     * The library names should be supplied without path or
+     * suffix. For example, use "vamp-example-plugins" to find plugins
+     * not appearing in /install/path/of/vamp-example-plugins.dll (or
+     * .so etc). This is the same concept of "library name" as appears
+     * in the plugin key: \see composePluginKey().
+     */
+    PluginKeyList listPluginsNotIn(std::vector<std::string> libraryNames);
+
+    /**
      * AdapterFlags contains a set of values that may be OR'd together
      * to indicate in which circumstances PluginLoader should use a
      * plugin adapter to make a plugin easier to use for a host that
@@ -200,7 +228,7 @@ public:
     Plugin *loadPlugin(PluginKey key,
                        float inputSampleRate,
                        int adapterFlags = 0);
-
+    
     /**
      * Given a Vamp plugin library name and plugin identifier, return
      * the corresponding plugin key in a form suitable for passing in to
diff --git a/vamp-hostsdk/hostguard.h b/vamp-hostsdk/hostguard.h
index bf3b850..c4876d9 100644
--- a/vamp-hostsdk/hostguard.h
+++ b/vamp-hostsdk/hostguard.h
@@ -43,9 +43,9 @@
 
 #define _VAMP_IN_HOSTSDK
 
-#define VAMP_SDK_VERSION "2.5"
+#define VAMP_SDK_VERSION "2.7.1"
 #define VAMP_SDK_MAJOR_VERSION 2
-#define VAMP_SDK_MINOR_VERSION 5
+#define VAMP_SDK_MINOR_VERSION 7
 
 #ifdef _VAMP_NO_HOST_NAMESPACE
 #define _VAMP_SDK_HOSTSPACE_BEGIN(h)
diff --git a/vamp-sdk/FFT.h b/vamp-sdk/FFT.h
index f7082d8..0f51b60 100644
--- a/vamp-sdk/FFT.h
+++ b/vamp-sdk/FFT.h
@@ -44,23 +44,24 @@ namespace Vamp {
 
 /**
  * A simple FFT implementation provided for convenience of plugin
- * authors.
- * 
- * This class provides double-precision FFTs in power-of-two sizes
- * only. It is slower than more sophisticated library
- * implementations. If these requirements aren't suitable, make other
- * arrangements.
+ * authors. This class provides one-shot (i.e. fixed table state is
+ * recalculated every time) double-precision complex-complex
+ * transforms. For repeated transforms from real time-domain data, use
+ * an FFTComplex or FFTReal object instead.
  *
- * The inverse transform is scaled by 1/n.
+ * Note: If the SDK has been compiled with the SINGLE_PRECISION_FFT
+ * flag, then all FFTs will use single precision internally. The
+ * default is double precision. The API uses doubles in either case.
  *
- * The implementation is from Don Cross's public domain FFT code.
+ * The forward transform is unscaled; the inverse transform is scaled
+ * by 1/n.
  */
 class FFT
 {
 public:
     /**
-     * Calculate a forward transform of size n.
-     * n must be a power of 2, greater than 1.
+     * Calculate a one-shot forward transform of size n.
+     * n must be a multiple of 2.
      *
      * ri and ii must point to the real and imaginary component arrays
      * of the input. For real input, ii may be NULL.
@@ -75,7 +76,7 @@ public:
                         double *ro, double *io);
 
     /**
-     * Calculate an inverse transform of size n.
+     * Calculate a one-shot inverse transform of size n.
      * n must be a power of 2, greater than 1.
      *
      * ri and ii must point to the real and imaginary component arrays
@@ -93,6 +94,108 @@ public:
                         double *ro, double *io);
 };
 
+/**
+ * A simple FFT implementation provided for convenience of plugin
+ * authors. This class provides double-precision complex-complex
+ * transforms.
+ *
+ * Note: If the SDK has been compiled with the SINGLE_PRECISION_FFT
+ * flag, then all FFTs will use single precision internally. The
+ * default is double precision. The API uses doubles in either case.
+ *
+ * The forward transform is unscaled; the inverse transform is scaled
+ * by 1/n.
+ */
+class FFTComplex
+{
+public:
+    /**
+     * Prepare to calculate transforms of size n.
+     * n must be a multiple of 2.
+     */
+    FFTComplex(unsigned int n);
+
+    ~FFTComplex();
+
+    /**
+     * Calculate a forward transform of size n.
+     *
+     * ci must point to the interleaved complex input data of size n
+     * (that is, 2n doubles in total).
+     *
+     * co must point to enough space to receive an interleaved complex
+     * output array of size n (that is, 2n doubles in total).
+     */
+    void forward(const double *ci, double *co);
+
+    /**
+     * Calculate an inverse transform of size n.
+     *
+     * ci must point to an interleaved complex input array of size n
+     * (that is, 2n doubles in total).
+     *
+     * co must point to enough space to receive the interleaved
+     * complex output data of size n (that is, 2n doubles in
+     * total). The output is scaled by 1/n.
+     */
+    void inverse(const double *ci, double *co);
+
+private:
+    class D;
+    D *m_d;
+};
+
+/**
+ * A simple FFT implementation provided for convenience of plugin
+ * authors. This class provides transforms between double-precision
+ * real time-domain and double-precision complex frequency-domain
+ * data.
+ *
+ * Note: If the SDK has been compiled with the SINGLE_PRECISION_FFT
+ * flag, then all FFTs will use single precision internally. The
+ * default is double precision. The API uses doubles in either case.
+ *
+ * The forward transform is unscaled; the inverse transform is scaled
+ * by 1/n.
+ */
+class FFTReal
+{
+public:
+    /**
+     * Prepare to calculate transforms of size n.
+     * n must be a multiple of 2.
+     */
+    FFTReal(unsigned int n);
+
+    ~FFTReal();
+
+    /**
+     * Calculate a forward transform of size n.
+     *
+     * ri must point to the real input data of size n.
+     *
+     * co must point to enough space to receive an interleaved complex
+     * output array of size n/2+1 (that is, n+2 doubles in total).
+     */
+    void forward(const double *ri, double *co);
+
+    /**
+     * Calculate an inverse transform of size n.
+     *
+     * ci must point to an interleaved complex input array of size
+     * n/2+1 (that is, n+2 doubles in total).
+     *
+     * ro must point to enough space to receive the real output data
+     * of size n. The output is scaled by 1/n and only the real part
+     * is returned.
+     */
+    void inverse(const double *ci, double *ro);
+
+private:
+    class D;
+    D *m_d;
+};
+
 }
 
 _VAMP_SDK_PLUGSPACE_END(FFT.h)
diff --git a/vamp-sdk/plugguard.h b/vamp-sdk/plugguard.h
index a3f05a8..800865b 100644
--- a/vamp-sdk/plugguard.h
+++ b/vamp-sdk/plugguard.h
@@ -71,9 +71,9 @@
 
 #define _VAMP_IN_PLUGINSDK 1
 
-#define VAMP_SDK_VERSION "2.5"
+#define VAMP_SDK_VERSION "2.7.1"
 #define VAMP_SDK_MAJOR_VERSION 2
-#define VAMP_SDK_MINOR_VERSION 5
+#define VAMP_SDK_MINOR_VERSION 7
 
 #ifdef _VAMP_NO_PLUGIN_NAMESPACE
 #define _VAMP_SDK_PLUGSPACE_BEGIN(h)
diff --git a/vamp/vamp.h b/vamp/vamp.h
index f54d7e0..fced082 100644
--- a/vamp/vamp.h
+++ b/vamp/vamp.h
@@ -70,7 +70,7 @@ extern "C" {
 
 typedef struct _VampParameterDescriptor
 {
-    /** Computer-usable name of the parameter. Must not change. [a-zA-Z0-9_] */
+    /** Computer-usable name of the parameter. Must not change. [a-zA-Z0-9_-] */
     const char *identifier;
 
     /** Human-readable name of the parameter. May be translatable. */
@@ -117,7 +117,7 @@ typedef enum
 
 typedef struct _VampOutputDescriptor
 {
-    /** Computer-usable name of the output. Must not change. [a-zA-Z0-9_] */
+    /** Computer-usable name of the output. Must not change. [a-zA-Z0-9_-] */
     const char *identifier;
 
     /** Human-readable name of the output. May be translatable. */

-- 
vamp-plugin-sdk packaging



More information about the pkg-multimedia-commits mailing list