changeset 419:55de53d7c777

Merge
author Chris Cannam
date Tue, 01 Mar 2016 12:21:23 +0000
parents a13635e9c440 (current diff) fae1ba2cb534 (diff)
children 99868cd95acb
files src/vamp-hostsdk/PluginSummarisingAdapter.cpp
diffstat 51 files changed, 937 insertions(+), 341 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Mar 01 12:10:29 2016 +0000
+++ b/.hgignore	Tue Mar 01 12:21:23 2016 +0000
@@ -24,5 +24,6 @@
 *.filters
 re:^build/_UpgradeReport_Files/
 *.ipch
+*.opensdf
 re:^build/x64/Debug/
 re:^build/x64/Release/
--- a/.hgtags	Tue Mar 01 12:10:29 2016 +0000
+++ b/.hgtags	Tue Mar 01 12:21:23 2016 +0000
@@ -22,3 +22,8 @@
 8cab5a0198d64ee606727e5f8a0683c44a55f432 vamp-plugin-sdk-v2.3
 393885d7ea72d6678ea7973363cf38623fa829f5 vamp-plugin-sdk-v2.4
 92b1fbb1cc878a60a3dfd4aa036e938767705b3a vamp-plugin-sdk-v2.5
+b7268e8bd292718c809ee2c3963379e82c7e8a6f vamp-plugin-sdk-v2.6
+b7268e8bd292718c809ee2c3963379e82c7e8a6f vamp-plugin-sdk-v2.6
+32e38d394dc6ab3b81069f4092fb6a15087fed04 vamp-plugin-sdk-v2.6
+32e38d394dc6ab3b81069f4092fb6a15087fed04 vamp-plugin-sdk-v2.6
+5628c5ec4000b29160f5e7bb41c5fa92fb2183f6 vamp-plugin-sdk-v2.6
--- a/CHANGELOG	Tue Mar 01 12:10:29 2016 +0000
+++ b/CHANGELOG	Tue Mar 01 12:21:23 2016 +0000
@@ -1,3 +1,18 @@
+
+Version 2.6, 2015-06-16 (maintenance and minor feature release)
+
+  * Add a simple C-linkage API for plugin library discovery and
+    loading -- the missing part when trying to use Vamp plugins from C
+    or a language with only C-linkage foreign-function interface
+  * Fix bug in PluginBufferingAdapter reset() function, which failed
+    to reset timestamp rewrites (symptom: timestamps appeared to
+    continue to ascend from end point on next run after a reset)
+  * Fix sometime 1-sample rounding error in PluginInputDomainAdapter
+  * Update build files for more recent OS versions
+  * Add -L option to simple host, as synonym for --list-full
+  * Add a combined Visual C++ solution that includes the plugin SDK,
+    host SDK, example plugins, and simple host projects
+
 Version 2.5, 2013-05-08 (maintenance release):
 
   * Fix incorrect handling of FixedSampleRate outputs in the
--- a/COPYING	Tue Mar 01 12:10:29 2016 +0000
+++ b/COPYING	Tue Mar 01 12:21:23 2016 +0000
@@ -1,7 +1,7 @@
 
     Vamp Plugin SDK  
     Copyright (c) 2005-2006 Chris Cannam
-    Copyright (c) 2006-2014 Queen Mary, University of London
+    Copyright (c) 2006-2015 Queen Mary, University of London
 
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation
--- a/Makefile.in	Tue Mar 01 12:10:29 2016 +0000
+++ b/Makefile.in	Tue Mar 01 12:21:23 2016 +0000
@@ -78,13 +78,13 @@
 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.6.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.6.0
 INSTALL_HOSTSDK_LINK_ABI  = libvamp-hostsdk.so.3
 INSTALL_HOSTSDK_LINK_DEV  = libvamp-hostsdk.so
 INSTALL_HOSTSDK_STATIC    = libvamp-hostsdk.a
@@ -104,16 +104,32 @@
 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
+
+	INSTALL_HOSTSDK_LIBNAME   = libvamp-hostsdk.3.6.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.6.0.dylib
+	INSTALL_SDK_LINK_ABI	  = libvamp-sdk-dynamic.2.dylib
+
+endif
 
 
 ### End of user-serviceable parts
 
-
 API_HEADERS	= \
 		$(APIDIR)/vamp.h
 
@@ -138,6 +154,7 @@
 		$(HOSTSDKDIR)/PluginSummarisingAdapter.h \
 		$(HOSTSDKDIR)/PluginWrapper.h \
 		$(HOSTSDKDIR)/hostguard.h \
+		$(HOSTSDKDIR)/host-c.h \
 		$(HOSTSDKDIR)/vamp-hostsdk.h
 
 SDK_OBJECTS	= \
@@ -147,6 +164,7 @@
 		$(SDKSRCDIR)/acsymbols.o
 
 HOSTSDK_OBJECTS	= \
+		$(HOSTSDKSRCDIR)/Files.o \
 		$(HOSTSDKSRCDIR)/PluginHostAdapter.o \
 		$(HOSTSDKSRCDIR)/RealTime.o \
 		$(HOSTSDKSRCDIR)/PluginBufferingAdapter.o \
@@ -155,6 +173,7 @@
 		$(HOSTSDKSRCDIR)/PluginLoader.o \
 		$(HOSTSDKSRCDIR)/PluginSummarisingAdapter.o \
 		$(HOSTSDKSRCDIR)/PluginWrapper.o \
+		$(HOSTSDKSRCDIR)/host-c.o \
 		$(HOSTSDKSRCDIR)/acsymbols.o
 
 SDK_STATIC	= \
--- a/README	Tue Mar 01 12:10:29 2016 +0000
+++ b/README	Tue Mar 01 12:21:23 2016 +0000
@@ -9,7 +9,7 @@
 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.5 of the Vamp plugin Software Development Kit.
+This is version 2.6 of the Vamp plugin Software Development Kit.
 
 Plugins and hosts built with this SDK are binary compatible with those
 built using version 1.0 of the SDK, with certain restrictions.  See
@@ -117,6 +117,17 @@
 Hosts should link with -lvamp-hostsdk.
 
 
+vamp-hostsdk/host-c.h
+---------------------
+
+A C-linkage header wrapping the part of the C++ SDK code that handles
+plugin discovery and library loading. Host programs written in C or in
+a language with a C-linkage foreign function interface may choose to
+use this header to discover and load plugin libraries, together with
+the vamp/vamp.h formal API to interact with plugins themselves. See
+the header for more documentation.
+
+
 examples
 --------
 
@@ -237,7 +248,7 @@
 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-2014
+The SDK was written by Chris Cannam, copyright (c) 2005-2015
 Chris Cannam and QMUL.
 
 Mark Sandler and Christian Landone provided ideas and direction, and
--- a/build/Doxyfile	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/Doxyfile	Tue Mar 01 12:21:23 2016 +0000
@@ -31,7 +31,7 @@
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 2.5
+PROJECT_NUMBER         = 2.6
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
--- a/build/Makefile.mingw32	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/Makefile.mingw32	Tue Mar 01 12:21:23 2016 +0000
@@ -133,6 +133,7 @@
 		$(HOSTSDKDIR)/PluginSummarisingAdapter.h \
 		$(HOSTSDKDIR)/PluginWrapper.h \
 		$(HOSTSDKDIR)/hostguard.h \
+		$(HOSTSDKDIR)/host-c.h \
 		$(HOSTSDKDIR)/vamp-hostsdk.h
 
 SDK_OBJECTS	= \
@@ -142,6 +143,7 @@
 		$(SDKSRCDIR)/acsymbols.o
 
 HOSTSDK_OBJECTS	= \
+		$(HOSTSDKSRCDIR)/Files.o \
 		$(HOSTSDKSRCDIR)/PluginHostAdapter.o \
 		$(HOSTSDKSRCDIR)/RealTime.o \
 		$(HOSTSDKSRCDIR)/PluginBufferingAdapter.o \
@@ -150,6 +152,7 @@
 		$(HOSTSDKSRCDIR)/PluginLoader.o \
 		$(HOSTSDKSRCDIR)/PluginSummarisingAdapter.o \
 		$(HOSTSDKSRCDIR)/PluginWrapper.o \
+		$(HOSTSDKSRCDIR)/host-c.o \
 		$(HOSTSDKSRCDIR)/acsymbols.o
 
 SDK_STATIC	= \
--- a/build/Makefile.mingw64	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/Makefile.mingw64	Tue Mar 01 12:21:23 2016 +0000
@@ -133,6 +133,7 @@
 		$(HOSTSDKDIR)/PluginSummarisingAdapter.h \
 		$(HOSTSDKDIR)/PluginWrapper.h \
 		$(HOSTSDKDIR)/hostguard.h \
+		$(HOSTSDKDIR)/host-c.h \
 		$(HOSTSDKDIR)/vamp-hostsdk.h
 
 SDK_OBJECTS	= \
@@ -142,6 +143,7 @@
 		$(SDKSRCDIR)/acsymbols.o
 
 HOSTSDK_OBJECTS	= \
+		$(HOSTSDKSRCDIR)/Files.o \
 		$(HOSTSDKSRCDIR)/PluginHostAdapter.o \
 		$(HOSTSDKSRCDIR)/RealTime.o \
 		$(HOSTSDKSRCDIR)/PluginBufferingAdapter.o \
@@ -150,6 +152,7 @@
 		$(HOSTSDKSRCDIR)/PluginLoader.o \
 		$(HOSTSDKSRCDIR)/PluginSummarisingAdapter.o \
 		$(HOSTSDKSRCDIR)/PluginWrapper.o \
+		$(HOSTSDKSRCDIR)/host-c.o \
 		$(HOSTSDKSRCDIR)/acsymbols.o
 
 SDK_STATIC	= \
--- a/build/Makefile.osx	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/Makefile.osx	Tue Mar 01 12:21:23 2016 +0000
@@ -60,12 +60,12 @@
 
 # Minimum version of OS/X to target. This will determine the
 # compiler's choice of platform SDK material
-MINVERSION := 10.6
+MINVERSION := 10.7
 
 # Our default is to try to build for all architectures supported by
 # the MINVERSION in a universal binary.
 #
-ARCHFLAGS ?= -mmacosx-version-min=$(MINVERSION) -arch x86_64 -arch i386
+ARCHFLAGS ?= -mmacosx-version-min=$(MINVERSION) -arch x86_64 -stdlib=libc++
 
 # Compile flags
 #
@@ -141,6 +141,7 @@
 		$(HOSTSDKDIR)/PluginSummarisingAdapter.h \
 		$(HOSTSDKDIR)/PluginWrapper.h \
 		$(HOSTSDKDIR)/hostguard.h \
+		$(HOSTSDKDIR)/host-c.h \
 		$(HOSTSDKDIR)/vamp-hostsdk.h
 
 SDK_OBJECTS	= \
@@ -150,6 +151,7 @@
 		$(SDKSRCDIR)/acsymbols.o 
 
 HOSTSDK_OBJECTS	= \
+		$(HOSTSDKSRCDIR)/Files.o \
 		$(HOSTSDKSRCDIR)/PluginHostAdapter.o \
 		$(HOSTSDKSRCDIR)/RealTime.o \
 		$(HOSTSDKSRCDIR)/PluginBufferingAdapter.o \
@@ -158,6 +160,7 @@
 		$(HOSTSDKSRCDIR)/PluginLoader.o \
 		$(HOSTSDKSRCDIR)/PluginSummarisingAdapter.o \
 		$(HOSTSDKSRCDIR)/PluginWrapper.o \
+		$(HOSTSDKSRCDIR)/host-c.o \
 		$(HOSTSDKSRCDIR)/acsymbols.o 
 
 SDK_STATIC	= \
--- a/build/Makefile.osx.106	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/Makefile.osx.106	Tue Mar 01 12:21:23 2016 +0000
@@ -171,6 +171,7 @@
 		$(SDKSRCDIR)/acsymbols.o
 
 HOSTSDK_OBJECTS	= \
+		$(HOSTSDKSRCDIR)/Files.o \
 		$(HOSTSDKSRCDIR)/PluginHostAdapter.o \
 		$(HOSTSDKSRCDIR)/RealTime.o \
 		$(HOSTSDKSRCDIR)/PluginBufferingAdapter.o \
@@ -179,6 +180,7 @@
 		$(HOSTSDKSRCDIR)/PluginLoader.o \
 		$(HOSTSDKSRCDIR)/PluginSummarisingAdapter.o \
 		$(HOSTSDKSRCDIR)/PluginWrapper.o \
+		$(HOSTSDKSRCDIR)/host-c.o \
 		$(HOSTSDKSRCDIR)/acsymbols.o
 
 SDK_STATIC	= \
--- a/build/README.osx	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/README.osx	Tue Mar 01 12:21:23 2016 +0000
@@ -5,10 +5,8 @@
 Prerequisites
 -------------
 
-You must have Xcode installed, with the command-line build tools.
-
-(If you are using Xcode 4, you may have to go to Preferences ->
-Downloads -> Components and install the Command Line Tools component.)
+You must have Xcode installed, with the command-line build tools (an
+optional component).
 
 You must have libsndfile (http://www.mega-nerd.com/libsndfile/)
 installed in order to build the command-line host successfully.  But
@@ -34,8 +32,8 @@
 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, use Makefile.osx.106 instead of
-Makefile.osx.
+If you are using OS/X 10.6 or older, you could try Makefile.osx.106
+instead of Makefile.osx.
 
 
 Installing the Example Plugins
--- a/build/VampHostSDK.vcproj	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/VampHostSDK.vcproj	Tue Mar 01 12:21:23 2016 +0000
@@ -191,6 +191,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\vamp-hostsdk\host-c.h"
+				>
+			</File>
+			<File
 				RelativePath="..\vamp-hostsdk\vamp-hostsdk.h"
 				>
 			</File>
@@ -207,6 +211,10 @@
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
 			<File
+				RelativePath="..\src\vamp-hostsdk\Files.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\src\vamp-hostsdk\PluginBufferingAdapter.cpp"
 				>
 			</File>
@@ -238,6 +246,10 @@
 				RelativePath="..\src\vamp-hostsdk\RealTime.cpp"
 				>
 			</File>
+			<File
+				RelativePath="..\src\vamp-hostsdk\host-c.cpp"
+				>
+			</File>
 		</Filter>
 	</Files>
 	<Globals>
--- a/build/VampHostSDK.vcxproj	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/VampHostSDK.vcxproj	Tue Mar 01 12:21:23 2016 +0000
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -93,7 +93,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_USE_MATH_DEFINES;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <PrecompiledHeader>
       </PrecompiledHeader>
@@ -124,9 +124,11 @@
     <ClInclude Include="..\vamp-hostsdk\PluginSummarisingAdapter.h" />
     <ClInclude Include="..\vamp-hostsdk\PluginWrapper.h" />
     <ClInclude Include="..\vamp-hostsdk\RealTime.h" />
+    <ClInclude Include="..\vamp-hostsdk\host-c.h" />
     <ClInclude Include="..\vamp-hostsdk\vamp-hostsdk.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\src\vamp-hostsdk\Files.cpp" />
     <ClCompile Include="..\src\vamp-hostsdk\PluginBufferingAdapter.cpp" />
     <ClCompile Include="..\src\vamp-hostsdk\PluginChannelAdapter.cpp" />
     <ClCompile Include="..\src\vamp-hostsdk\PluginHostAdapter.cpp" />
@@ -135,8 +137,9 @@
     <ClCompile Include="..\src\vamp-hostsdk\PluginSummarisingAdapter.cpp" />
     <ClCompile Include="..\src\vamp-hostsdk\PluginWrapper.cpp" />
     <ClCompile Include="..\src\vamp-hostsdk\RealTime.cpp" />
+    <ClCompile Include="..\src\vamp-hostsdk\host-c.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
--- a/build/VampPluginSDK.vcxproj	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/VampPluginSDK.vcxproj	Tue Mar 01 12:21:23 2016 +0000
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -93,7 +93,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_USE_MATH_DEFINES</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <PrecompiledHeader>
       </PrecompiledHeader>
@@ -129,4 +129,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
--- a/build/VampSimpleHost.vcxproj	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/VampSimpleHost.vcxproj	Tue Mar 01 12:21:23 2016 +0000
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -116,12 +116,14 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..;C:\Program Files\Mega-Nerd\libsndfile\include</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>Release\VampHostSDK.lib;C:\Program Files\Mega-Nerd\libsndfile\lib\libsndfile-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -152,4 +154,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
--- a/build/libvamp-hostsdk.la.in	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/libvamp-hostsdk.la.in	Tue Mar 01 12:21:23 2016 +0000
@@ -3,7 +3,7 @@
 old_library='%STATIC%'
 dependency_libs=''
 current=3
-age=5
+age=6
 revision=0
 installed=yes
 libdir='%LIBS%'
--- a/build/libvamp-sdk.la.in	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/libvamp-sdk.la.in	Tue Mar 01 12:21:23 2016 +0000
@@ -3,7 +3,7 @@
 old_library='%STATIC%'
 dependency_libs=''
 current=2
-age=5
+age=6
 revision=0
 installed=yes
 libdir='%LIBS%'
--- a/build/update-version.sh	Tue Mar 01 12:10:29 2016 +0000
+++ b/build/update-version.sh	Tue Mar 01 12:21:23 2016 +0000
@@ -42,6 +42,12 @@
 $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_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
 
--- a/configure	Tue Mar 01 12:10:29 2016 +0000
+++ b/configure	Tue Mar 01 12:21:23 2016 +0000
@@ -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.6.
 #
 # Report bugs to <cannam@all-day-breakfast.com>.
 #
@@ -580,8 +580,8 @@
 # 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.6'
+PACKAGE_STRING='vamp-plugin-sdk 2.6'
 PACKAGE_BUGREPORT='cannam@all-day-breakfast.com'
 PACKAGE_URL=''
 
@@ -1243,7 +1243,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures vamp-plugin-sdk 2.5 to adapt to many kinds of systems.
+\`configure' configures vamp-plugin-sdk 2.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1304,7 +1304,7 @@
 
 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.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1402,7 +1402,7 @@
 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.6
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1651,7 +1651,7 @@
 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.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3950,11 +3950,11 @@
 if test "x$GCC" = "xyes"; then
   case " $CXXFLAGS " in
     *[\ \	]-fPIC\ -Wall[\ \	]*) ;;
-    *) CXXFLAGS="$CXXFLAGS -fPIC -Wall" ;;
+    *) CXXFLAGS="$CXXFLAGS -fPIC -Wall -Wextra" ;;
   esac
   case " $CFLAGS " in
     *[\ \	]-fPIC\ -Wall[\ \	]*) ;;
-    *) CFLAGS="$CFLAGS -fPIC -Wall" ;;
+    *) CFLAGS="$CFLAGS -fPIC -Wall -Wextra" ;;
   esac
 fi
 
@@ -4505,7 +4505,7 @@
 # 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.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4558,7 +4558,7 @@
 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.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
--- a/configure.ac	Tue Mar 01 12:10:29 2016 +0000
+++ b/configure.ac	Tue Mar 01 12:21:23 2016 +0000
@@ -1,5 +1,5 @@
 
-AC_INIT(vamp-plugin-sdk, 2.5, cannam@all-day-breakfast.com)
+AC_INIT(vamp-plugin-sdk, 2.6, cannam@all-day-breakfast.com)
 
 AC_CONFIG_SRCDIR(vamp/vamp.h)
 AC_PROG_CXX
@@ -44,11 +44,11 @@
 if test "x$GCC" = "xyes"; then
   case " $CXXFLAGS " in
     *[\ \	]-fPIC\ -Wall[\ \	]*) ;;
-    *) CXXFLAGS="$CXXFLAGS -fPIC -Wall" ;;
+    *) CXXFLAGS="$CXXFLAGS -fPIC -Wall -Wextra" ;;
   esac
   case " $CFLAGS " in
     *[\ \	]-fPIC\ -Wall[\ \	]*) ;;
-    *) CFLAGS="$CFLAGS -fPIC -Wall" ;;
+    *) CFLAGS="$CFLAGS -fPIC -Wall -Wextra" ;;
   esac
 fi
 changequote([,])dnl
--- a/examples/AmplitudeFollower.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/examples/AmplitudeFollower.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -41,6 +41,7 @@
 #include <string>
 #include <vector>
 #include <iostream>
+#include <algorithm>
 
 using std::string;
 using std::vector;
--- a/examples/FixedTempoEstimator.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/examples/FixedTempoEstimator.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -431,7 +431,7 @@
 
             if (k0 >= 0 && k0 < int(n/2)) {
 
-                int kmax = 0, kmin = 0;
+                int kmax = 0;
                 float kvmax = 0, kvmin = 0;
                 bool have = false;
 
@@ -439,8 +439,8 @@
 
                     if (k < 0 || k >= n/2) continue;
 
-                    if (!have || (m_r[k] > kvmax)) { kmax = k; kvmax = m_r[k]; }
-                    if (!have || (m_r[k] < kvmin)) { kmin = k; kvmin = m_r[k]; }
+                    if (!have || (m_r[k] > kvmax)) { kvmax = m_r[k]; kmax = k; }
+                    if (!have || (m_r[k] < kvmin)) { kvmin = m_r[k]; }
                     
                     have = true;
                 }
--- a/examples/PowerSpectrum.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/examples/PowerSpectrum.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -89,7 +89,7 @@
 }
 
 bool
-PowerSpectrum::initialise(size_t channels, size_t stepSize, size_t blockSize)
+PowerSpectrum::initialise(size_t channels, size_t, size_t blockSize)
 {
     if (channels < getMinChannelCount() ||
 	channels > getMaxChannelCount()) return false;
@@ -133,7 +133,7 @@
 }
 
 PowerSpectrum::FeatureSet
-PowerSpectrum::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
+PowerSpectrum::process(const float *const *inputBuffers, Vamp::RealTime)
 {
     FeatureSet fs;
 
--- a/examples/SpectralCentroid.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/examples/SpectralCentroid.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -143,7 +143,7 @@
 }
 
 SpectralCentroid::FeatureSet
-SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
+SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime)
 {
     if (m_stepSize == 0) {
 	cerr << "ERROR: SpectralCentroid::process: "
--- a/examples/ZeroCrossing.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/examples/ZeroCrossing.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -42,6 +42,7 @@
 using std::endl;
 
 #include <cmath>
+#include <algorithm>
 
 ZeroCrossing::ZeroCrossing(float inputSampleRate) :
     Plugin(inputSampleRate),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host/test-c.c	Tue Mar 01 12:21:23 2016 +0000
@@ -0,0 +1,40 @@
+
+#include <vamp-hostsdk/host-c.h>
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    int i;
+    int libcount = vhGetLibraryCount();
+
+    printf("Vamp plugin libraries found:\n");
+    for (i = 0; i < libcount; ++i) {
+	printf("%d: %s\n", i, vhGetLibraryName(i));
+    }
+
+    printf("Going to try loading qm-vamp-plugins...\n");
+    int libindex = vhGetLibraryIndex("qm-vamp-plugins");
+    vhLibrary lib = vhLoadLibrary(libindex);
+    if (!lib) {
+	printf("Failure!\n");
+	return 1;
+    }
+
+    int plugincount = vhGetPluginCount(lib);
+    printf("Success: it contains %d plugins; they are:\n", plugincount);
+
+    for (i = 0; i < plugincount; ++i) {
+	const VampPluginDescriptor *descriptor = vhGetPluginDescriptor(lib, i);
+	if (!descriptor) {
+	    printf("<unknown! failed to load>\n");
+	} else {
+	    printf("%s\n", descriptor->identifier);
+	}
+    }
+
+    vhUnloadLibrary(lib);
+    
+    return 0;
+}
+
--- a/pkgconfig/vamp-hostsdk.pc.in	Tue Mar 01 12:10:29 2016 +0000
+++ b/pkgconfig/vamp-hostsdk.pc.in	Tue Mar 01 12:21:23 2016 +0000
@@ -4,7 +4,7 @@
 includedir=${prefix}/include
 
 Name: vamp-hostsdk
-Version: 2.5
+Version: 2.6
 Description: Development library for Vamp audio analysis plugin hosts
 Libs: -L${libdir} -lvamp-hostsdk -ldl
 Cflags: -I${includedir} 
--- a/pkgconfig/vamp-sdk.pc.in	Tue Mar 01 12:10:29 2016 +0000
+++ b/pkgconfig/vamp-sdk.pc.in	Tue Mar 01 12:21:23 2016 +0000
@@ -4,7 +4,7 @@
 includedir=${prefix}/include
 
 Name: vamp-sdk
-Version: 2.5
+Version: 2.6
 Description: Development library for Vamp audio analysis plugins
 Libs: -L${libdir} -lvamp-sdk
 Cflags: -I${includedir} 
--- a/pkgconfig/vamp.pc.in	Tue Mar 01 12:10:29 2016 +0000
+++ b/pkgconfig/vamp.pc.in	Tue Mar 01 12:21:23 2016 +0000
@@ -4,7 +4,7 @@
 includedir=${prefix}/include
 
 Name: vamp
-Version: 2.5
+Version: 2.6
 Description: An API for audio analysis and feature extraction plugins
 Libs: 
 Cflags: -I${includedir} 
--- a/skeleton/Makefile.osx	Tue Mar 01 12:10:29 2016 +0000
+++ b/skeleton/Makefile.osx	Tue Mar 01 12:21:23 2016 +0000
@@ -14,12 +14,12 @@
 
 # ... or for a release build
 
-#CFLAGS		:= -Wall -Wextra -O3 -ftree-vectorize -fPIC
+#CFLAGS		:= -Wall -Wextra -O3 -fPIC
 
 
 # Flags to determine processor architecture and system SDK
 
-ARCHFLAGS	?= -mmacosx-version-min=10.6 -arch x86_64 -arch i386
+ARCHFLAGS	?= -mmacosx-version-min=10.7 -arch x86_64 -stdlib=libc++
 
 
 # Location of Vamp plugin SDK relative to the project directory
--- a/skeleton/MyPlugin.h	Tue Mar 01 12:10:29 2016 +0000
+++ b/skeleton/MyPlugin.h	Tue Mar 01 12:21:23 2016 +0000
@@ -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>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vamp-hostsdk/Files.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -0,0 +1,277 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp
+
+    An API for audio analysis and feature extraction plugins.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    Copyright 2006-2015 Chris Cannam and QMUL.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    Except as contained in this notice, the names of the Centre for
+    Digital Music; Queen Mary, University of London; and Chris Cannam
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#include <vamp-hostsdk/PluginHostAdapter.h>
+
+#include "Files.h"
+
+#include <cctype> // tolower
+
+#include <cstring>
+
+#ifdef _WIN32
+
+#include <windows.h>
+#include <tchar.h>
+#define PLUGIN_SUFFIX "dll"
+
+#else /* ! _WIN32 */
+
+#include <dirent.h>
+#include <dlfcn.h>
+
+#ifdef __APPLE__
+#define PLUGIN_SUFFIX "dylib"
+#else /* ! __APPLE__ */
+#define PLUGIN_SUFFIX "so"
+#endif /* ! __APPLE__ */
+
+#endif /* ! _WIN32 */
+
+using namespace std;
+
+vector<string>
+Files::listLibraryFiles()
+{
+    return listLibraryFilesMatching("");
+}
+
+vector<string>
+Files::listLibraryFilesMatching(string libraryName)
+{
+    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]);
+    }
+
+    for (size_t i = 0; i < path.size(); ++i) {
+        
+        vector<string> files = listFiles(path[i], PLUGIN_SUFFIX);
+
+        for (vector<string>::iterator fi = files.begin();
+             fi != files.end(); ++fi) {
+            
+            if (libraryName != "") {
+		// we match case-insensitively
+                string temp = *fi;
+                for (size_t i = 0; i < temp.length(); ++i) {
+                    temp[i] = tolower(temp[i]);
+                }
+                // 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;
+                }
+            }
+
+            string fullPath = path[i];
+            fullPath = splicePath(fullPath, *fi);
+	    libraryFiles.push_back(fullPath);
+	}
+    }
+
+    return libraryFiles;
+}
+
+void *
+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) {
+        cerr << "Vamp::HostExt: Unable to convert library path \""
+             << path << "\" to wide characters " << endl;
+        delete[] buffer;
+        return handle;
+    }
+    handle = LoadLibrary(buffer);
+    delete[] buffer;
+#else
+    handle = LoadLibrary(path.c_str());
+#endif
+    if (!handle) {
+        cerr << "Vamp::HostExt: Unable to load library \""
+             << path << "\"" << endl;
+    }
+#else
+    handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
+    if (!handle) {
+        cerr << "Vamp::HostExt: Unable to load library \""
+             << path << "\": " << dlerror() << endl;
+    }
+#endif
+    return handle;
+}
+
+void
+Files::unloadLibrary(void *handle)
+{
+#ifdef _WIN32
+    FreeLibrary((HINSTANCE)handle);
+#else
+    dlclose(handle);
+#endif
+}
+
+void *
+Files::lookupInLibrary(void *handle, const char *symbol)
+{
+#ifdef _WIN32
+    return (void *)GetProcAddress((HINSTANCE)handle, symbol);
+#else
+    return (void *)dlsym(handle, symbol);
+#endif
+}
+
+string
+Files::lcBasename(string path)
+{
+    string basename(path);
+	
+    string::size_type li = basename.rfind('/');
+    if (li != string::npos) basename = basename.substr(li + 1);
+
+#ifdef _WIN32
+    li = basename.rfind('\\');
+    if (li != string::npos) basename = basename.substr(li + 1);
+#endif
+
+    li = basename.find('.');
+    if (li != string::npos) basename = basename.substr(0, li);
+
+    for (size_t i = 0; i < basename.length(); ++i) {
+        basename[i] = tolower(basename[i]);
+    }
+
+    return basename;
+}
+
+string
+Files::splicePath(string a, string b)
+{
+#ifdef _WIN32
+    return a + "\\" + b;
+#else
+    return a + "/" + b;
+#endif
+}
+
+vector<string>
+Files::listFiles(string dir, string extension)
+{
+    vector<string> files;
+
+#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) {
+        cerr << "Vamp::HostExt: Unable to convert wildcard path \""
+             << expression << "\" to wide characters" << endl;
+        delete[] buffer;
+        return files;
+    }
+    WIN32_FIND_DATA data;
+    HANDLE fh = FindFirstFile(buffer, &data);
+    if (fh == INVALID_HANDLE_VALUE) {
+        delete[] buffer;
+        return files;
+    }
+
+    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) {
+            files.push_back(conv);
+        }
+        delete[] conv;
+        ok = FindNextFile(fh, &data);
+    }
+
+    FindClose(fh);
+    delete[] buffer;
+#else
+    WIN32_FIND_DATA data;
+    HANDLE fh = FindFirstFile(expression.c_str(), &data);
+    if (fh == INVALID_HANDLE_VALUE) return files;
+
+    bool ok = true;
+    while (ok) {
+        files.push_back(data.cFileName);
+        ok = FindNextFile(fh, &data);
+    }
+
+    FindClose(fh);
+#endif
+#else
+
+    size_t extlen = extension.length();
+    DIR *d = opendir(dir.c_str());
+    if (!d) return files;
+            
+    struct dirent *e = 0;
+    while ((e = readdir(d))) {
+ 
+        size_t len = strlen(e->d_name);
+        if (len < extlen + 2 ||
+            e->d_name + len - extlen - 1 != "." + extension) {
+            continue;
+        }
+
+        files.push_back(e->d_name);
+    }
+
+    closedir(d);
+#endif
+
+    return files;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vamp-hostsdk/Files.h	Tue Mar 01 12:21:23 2016 +0000
@@ -0,0 +1,63 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp
+
+    An API for audio analysis and feature extraction plugins.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    Copyright 2006-2015 Chris Cannam and QMUL.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    Except as contained in this notice, the names of the Centre for
+    Digital Music; Queen Mary, University of London; and Chris Cannam
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#ifndef VAMP_FILES_H
+#define VAMP_FILES_H
+
+#include <vector>
+#include <string>
+
+/**
+ * This is a private implementation class for the Vamp Host SDK.
+ */
+class Files
+{
+public:
+    static std::vector<std::string> listLibraryFiles();
+    static std::vector<std::string> listLibraryFilesMatching(std::string libname);
+
+    static void *loadLibrary(std::string filename);
+    static void unloadLibrary(void *);
+    static void *lookupInLibrary(void *, const char *symbol);
+
+    static std::string lcBasename(std::string path);
+    static std::string splicePath(std::string a, std::string b);
+    static std::vector<std::string> listFiles(std::string dir, std::string ext);
+};
+
+#endif
+
+    
--- a/src/vamp-hostsdk/PluginBufferingAdapter.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-hostsdk/PluginBufferingAdapter.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -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;
 
@@ -512,13 +516,13 @@
 
         case OutputDescriptor::OneSamplePerStep:
             outs[i].sampleType = OutputDescriptor::FixedSampleRate;
-            outs[i].sampleRate = (1.f / m_inputSampleRate) * m_stepSize;
+            outs[i].sampleRate = m_inputSampleRate / 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 / m_stepSize;
             }
             // We actually only need to rewrite output times for
             // features that don't have timestamps already, but we
@@ -615,16 +619,25 @@
 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 / 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;
--- a/src/vamp-hostsdk/PluginHostAdapter.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-hostsdk/PluginHostAdapter.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -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 != 6 )
 #error Unexpected version of Vamp SDK header included
 #endif
 
--- a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -508,7 +508,14 @@
                                                          RealTime timestamp)
 {
     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)) {
+            timestamp = timestamp + nsec;
+        }
     }
 
     for (int c = 0; c < m_channels; ++c) {
--- a/src/vamp-hostsdk/PluginLoader.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-hostsdk/PluginLoader.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -34,35 +34,17 @@
     authorization.
 */
 
-#include <vamp-hostsdk/PluginHostAdapter.h>
 #include <vamp-hostsdk/PluginLoader.h>
 #include <vamp-hostsdk/PluginInputDomainAdapter.h>
 #include <vamp-hostsdk/PluginChannelAdapter.h>
 #include <vamp-hostsdk/PluginBufferingAdapter.h>
+#include <vamp-hostsdk/PluginHostAdapter.h>
+
+#include <vamp/vamp.h>
+
+#include "Files.h"
 
 #include <fstream>
-#include <cctype> // tolower
-
-#include <cstring>
-
-#ifdef _WIN32
-
-#include <windows.h>
-#include <tchar.h>
-#define PLUGIN_SUFFIX "dll"
-
-#else /* ! _WIN32 */
-
-#include <dirent.h>
-#include <dlfcn.h>
-
-#ifdef __APPLE__
-#define PLUGIN_SUFFIX "dylib"
-#else /* ! __APPLE__ */
-#define PLUGIN_SUFFIX "so"
-#endif /* ! __APPLE__ */
-
-#endif /* ! _WIN32 */
 
 using namespace std;
 
@@ -124,13 +106,6 @@
     bool decomposePluginKey(PluginKey key,
                             string &libraryName, string &identifier);
 
-    void *loadLibrary(string path);
-    void unloadLibrary(void *handle);
-    void *lookupInLibrary(void *handle, const char *symbol);
-
-    string splicePath(string a, string b);
-    vector<string> listFiles(string dir, string ext);
-    
     static InstanceCleaner m_cleaner;
 };
 
@@ -227,83 +202,64 @@
 void
 PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
 {
-    vector<string> path = PluginHostAdapter::getPluginPath();
-
     string libraryName, identifier;
+    vector<string> fullPaths;
+    
     if (forPlugin != "") {
         if (!decomposePluginKey(forPlugin, libraryName, identifier)) {
             std::cerr << "WARNING: Vamp::HostExt::PluginLoader: Invalid plugin key \""
                       << forPlugin << "\" in enumerate" << std::endl;
             return;
         }
+        fullPaths = Files::listLibraryFilesMatching(libraryName);
+    } else {
+        fullPaths = Files::listLibraryFiles();
     }
 
-    for (size_t i = 0; i < path.size(); ++i) {
-        
-        vector<string> files = listFiles(path[i], PLUGIN_SUFFIX);
+    for (size_t i = 0; i < fullPaths.size(); ++i) {
 
-        for (vector<string>::iterator fi = files.begin();
-             fi != files.end(); ++fi) {
+        string fullPath = fullPaths[i];
+        void *handle = Files::loadLibrary(fullPath);
+        if (!handle) continue;
             
-            if (libraryName != "") {
-                // libraryName is lowercased and lacking an extension,
-                // as it came from the plugin key
-                string temp = *fi;
-                for (size_t i = 0; i < temp.length(); ++i) {
-                    temp[i] = tolower(temp[i]);
-                }
-                string::size_type pi = temp.find('.');
-                if (pi == string::npos) {
-                    if (libraryName != temp) continue;
-                } else {
-                    if (libraryName != temp.substr(0, pi)) continue;
-                }
-            }
-
-            string fullPath = path[i];
-            fullPath = splicePath(fullPath, *fi);
-            void *handle = loadLibrary(fullPath);
-            if (!handle) continue;
+        VampGetPluginDescriptorFunction fn =
+            (VampGetPluginDescriptorFunction)Files::lookupInLibrary
+            (handle, "vampGetPluginDescriptor");
             
-            VampGetPluginDescriptorFunction fn =
-                (VampGetPluginDescriptorFunction)lookupInLibrary
-                (handle, "vampGetPluginDescriptor");
-            
-            if (!fn) {
-                if (forPlugin != "") {
-                    cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
-                         << fullPath << "\"" << endl;
-                }
-                unloadLibrary(handle);
-                continue;
-            }
-            
-            int index = 0;
-            const VampPluginDescriptor *descriptor = 0;
-            bool found = false;
-            
-            while ((descriptor = fn(VAMP_API_VERSION, index))) {
-                ++index;
-                if (identifier != "") {
-                    if (descriptor->identifier != identifier) continue;
-                }
-                found = true;
-                PluginKey key = composePluginKey(*fi, descriptor->identifier);
-//                std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl;
-                if (m_pluginLibraryNameMap.find(key) ==
-                    m_pluginLibraryNameMap.end()) {
-                    m_pluginLibraryNameMap[key] = fullPath;
-                }
-            }
-
-            if (!found && forPlugin != "") {
-                cerr << "Vamp::HostExt::PluginLoader: Plugin \""
-                     << identifier << "\" not found in library \""
+        if (!fn) {
+            if (forPlugin != "") {
+                cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
                      << fullPath << "\"" << endl;
             }
+            Files::unloadLibrary(handle);
+            continue;
+        }
             
-            unloadLibrary(handle);
+        int index = 0;
+        const VampPluginDescriptor *descriptor = 0;
+        bool found = false;
+            
+        while ((descriptor = fn(VAMP_API_VERSION, index))) {
+            ++index;
+            if (identifier != "") {
+                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;
+            }
         }
+
+        if (!found && forPlugin != "") {
+            cerr << "Vamp::HostExt::PluginLoader: Plugin \""
+                 << identifier << "\" not found in library \""
+                 << fullPath << "\"" << endl;
+        }
+            
+        Files::unloadLibrary(handle);
     }
 
     if (forPlugin == "") m_allPluginsEnumerated = true;
@@ -312,18 +268,7 @@
 PluginLoader::PluginKey
 PluginLoader::Impl::composePluginKey(string libraryName, string identifier)
 {
-    string basename = libraryName;
-
-    string::size_type li = basename.rfind('/');
-    if (li != string::npos) basename = basename.substr(li + 1);
-
-    li = basename.find('.');
-    if (li != string::npos) basename = basename.substr(0, li);
-
-    for (size_t i = 0; i < basename.length(); ++i) {
-        basename[i] = tolower(basename[i]);
-    }
-
+    string basename = Files::lcBasename(libraryName);
     return basename + ":" + identifier;
 }
 
@@ -382,17 +327,17 @@
         return 0;
     }
     
-    void *handle = loadLibrary(fullPath);
+    void *handle = Files::loadLibrary(fullPath);
     if (!handle) return 0;
     
     VampGetPluginDescriptorFunction fn =
-        (VampGetPluginDescriptorFunction)lookupInLibrary
+        (VampGetPluginDescriptorFunction)Files::lookupInLibrary
         (handle, "vampGetPluginDescriptor");
 
     if (!fn) {
         cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \""
              << fullPath << "\"" << endl;
-        unloadLibrary(handle);
+        Files::unloadLibrary(handle);
         return 0;
     }
 
@@ -474,12 +419,12 @@
     for (vector<string>::iterator i = catpath.begin();
          i != catpath.end(); ++i) {
         
-        vector<string> files = listFiles(*i, suffix);
+        vector<string> files = Files::listFiles(*i, suffix);
 
         for (vector<string>::iterator fi = files.begin();
              fi != files.end(); ++fi) {
 
-            string filepath = splicePath(*i, *fi);
+            string filepath = Files::splicePath(*i, *fi);
             ifstream is(filepath.c_str(), ifstream::in | ifstream::binary);
 
             if (is.fail()) {
@@ -525,154 +470,11 @@
     }
 }    
 
-void *
-PluginLoader::Impl::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) {
-        cerr << "Vamp::HostExt::PluginLoader: Unable to convert library path \""
-             << path << "\" to wide characters " << endl;
-        delete[] buffer;
-        return handle;
-    }
-    handle = LoadLibrary(buffer);
-    delete[] buffer;
-#else
-    handle = LoadLibrary(path.c_str());
-#endif
-    if (!handle) {
-        cerr << "Vamp::HostExt::PluginLoader: Unable to load library \""
-             << path << "\"" << endl;
-    }
-#else
-    handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
-    if (!handle) {
-        cerr << "Vamp::HostExt::PluginLoader: Unable to load library \""
-             << path << "\": " << dlerror() << endl;
-    }
-#endif
-    return handle;
-}
-
-void
-PluginLoader::Impl::unloadLibrary(void *handle)
-{
-#ifdef _WIN32
-    FreeLibrary((HINSTANCE)handle);
-#else
-    dlclose(handle);
-#endif
-}
-
-void *
-PluginLoader::Impl::lookupInLibrary(void *handle, const char *symbol)
-{
-#ifdef _WIN32
-    return (void *)GetProcAddress((HINSTANCE)handle, symbol);
-#else
-    return (void *)dlsym(handle, symbol);
-#endif
-}
-
-string
-PluginLoader::Impl::splicePath(string a, string b)
-{
-#ifdef _WIN32
-    return a + "\\" + b;
-#else
-    return a + "/" + b;
-#endif
-}
-
-vector<string>
-PluginLoader::Impl::listFiles(string dir, string extension)
-{
-    vector<string> files;
-
-#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) {
-        cerr << "Vamp::HostExt::PluginLoader: Unable to convert wildcard path \""
-             << expression << "\" to wide characters" << endl;
-        delete[] buffer;
-        return files;
-    }
-    WIN32_FIND_DATA data;
-    HANDLE fh = FindFirstFile(buffer, &data);
-    if (fh == INVALID_HANDLE_VALUE) {
-        delete[] buffer;
-        return files;
-    }
-
-    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) {
-            files.push_back(conv);
-        }
-        delete[] conv;
-        ok = FindNextFile(fh, &data);
-    }
-
-    FindClose(fh);
-    delete[] buffer;
-#else
-    WIN32_FIND_DATA data;
-    HANDLE fh = FindFirstFile(expression.c_str(), &data);
-    if (fh == INVALID_HANDLE_VALUE) return files;
-
-    bool ok = true;
-    while (ok) {
-        files.push_back(data.cFileName);
-        ok = FindNextFile(fh, &data);
-    }
-
-    FindClose(fh);
-#endif
-#else
-
-    size_t extlen = extension.length();
-    DIR *d = opendir(dir.c_str());
-    if (!d) return files;
-            
-    struct dirent *e = 0;
-    while ((e = readdir(d))) {
- 
-        if (!e->d_name) continue;
-       
-        size_t len = strlen(e->d_name);
-        if (len < extlen + 2 ||
-            e->d_name + len - extlen - 1 != "." + extension) {
-            continue;
-        }
-
-        files.push_back(e->d_name);
-    }
-
-    closedir(d);
-#endif
-
-    return files;
-}
-
 void
 PluginLoader::Impl::pluginDeleted(PluginDeletionNotifyAdapter *adapter)
 {
     void *handle = m_pluginLibraryHandleMap[adapter];
-    if (handle) unloadLibrary(handle);
+    if (handle) Files::unloadLibrary(handle);
     m_pluginLibraryHandleMap.erase(adapter);
 }
 
--- a/src/vamp-hostsdk/PluginSummarisingAdapter.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-hostsdk/PluginSummarisingAdapter.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -641,8 +641,6 @@
 void
 PluginSummarisingAdapter::Impl::segment()
 {
-    SegmentBoundaries::iterator boundaryitr = m_boundaries.begin();
-    
 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT
     cerr << "segment: starting" << endl;
 #endif
--- a/src/vamp-hostsdk/acsymbols.c	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-hostsdk/acsymbols.c	Tue Mar 01 12:21:23 2016 +0000
@@ -1,6 +1,7 @@
 /* These stubs are provided so that autoconf can check library
  * versions using C symbols only */
 
+extern void libvamphostsdk_v_2_6_present(void) { }
 extern void libvamphostsdk_v_2_5_present(void) { }
 extern void libvamphostsdk_v_2_4_present(void) { }
 extern void libvamphostsdk_v_2_3_1_present(void) { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vamp-hostsdk/host-c.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -0,0 +1,151 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp
+
+    An API for audio analysis and feature extraction plugins.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    Copyright 2006-2015 Chris Cannam and QMUL.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    Except as contained in this notice, the names of the Centre for
+    Digital Music; Queen Mary, University of London; and Chris Cannam
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#include <vamp-hostsdk/host-c.h>
+
+#include "Files.h"
+
+#include <map>
+#include <iostream>
+
+#include <cstring>
+
+using namespace std;
+
+static vector<string> files;
+static map<string, const char *> cnames;
+static bool haveFiles = false;
+
+struct vhLibrary_t {
+    vhLibrary_t(void *h, VampGetPluginDescriptorFunction f)
+        : handle(h), func(f), nplugins(0) { } 
+    void *handle;
+    VampGetPluginDescriptorFunction func;
+    int nplugins;
+};
+
+static void initFilenames()
+{
+    if (!haveFiles) {
+        files = Files::listLibraryFiles();
+        for (size_t i = 0; i < files.size(); ++i) {
+            cnames[files[i]] = strdup(Files::lcBasename(files[i]).c_str());
+        }
+        haveFiles = true;
+    }
+}
+
+int vhGetLibraryCount()
+{
+    initFilenames();
+    return int(files.size());
+}
+
+const char *vhGetLibraryName(int index)
+{
+    initFilenames();
+    if (index >= 0 && index < int(files.size())) {
+        return cnames[files[index]];
+    }
+    else return 0;
+}
+
+int vhGetLibraryIndex(const char *name)
+{
+    for (size_t i = 0; i < files.size(); ++i) {
+        if (Files::lcBasename(name) == Files::lcBasename(files[i])) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+vhLibrary vhLoadLibrary(int index)
+{
+    initFilenames();
+    if (index < 0 || index >= int(files.size())) {
+        return 0;
+    }
+
+    string fullPath = files[index];
+    void *lib = Files::loadLibrary(fullPath);
+
+    if (!lib) return 0;
+            
+    VampGetPluginDescriptorFunction func =
+        (VampGetPluginDescriptorFunction)Files::lookupInLibrary
+        (lib, "vampGetPluginDescriptor");
+    if (!func) {
+        cerr << "vhLoadLibrary: No vampGetPluginDescriptor function found in library \""
+             << fullPath << "\"" << endl;
+        Files::unloadLibrary(lib);
+        return 0;
+    }
+
+    vhLibrary_t *vhl = new vhLibrary_t(lib, func);
+    while (vhl->func(VAMP_API_VERSION, vhl->nplugins)) {
+        ++vhl->nplugins;
+    }
+    return vhl;
+}
+
+int vhGetPluginCount(vhLibrary library)
+{
+    vhLibrary_t *vhl = static_cast<vhLibrary_t *>(library);
+    if (vhl) return vhl->nplugins;
+    else return 0;
+}
+
+const VampPluginDescriptor *vhGetPluginDescriptor(vhLibrary library,
+                                                  int plugin)
+{
+    vhLibrary_t *vhl = static_cast<vhLibrary_t *>(library);
+    if (vhl && plugin >= 0 && plugin < vhl->nplugins) {
+        return vhl->func(VAMP_API_VERSION, plugin);
+    } else {
+        return 0;
+    }
+}
+
+void vhUnloadLibrary(vhLibrary library)
+{
+    vhLibrary_t *vhl = static_cast<vhLibrary_t *>(library);
+    if (vhl && vhl->handle) {
+        Files::unloadLibrary(vhl->handle);
+    }
+    delete vhl;
+}
+
--- a/src/vamp-sdk/FFT.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-sdk/FFT.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -38,7 +38,7 @@
 
 #include <cmath>
 
-#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 5 )
+#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 6 )
 #error Unexpected version of Vamp SDK header included
 #endif
 
--- a/src/vamp-sdk/PluginAdapter.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-sdk/PluginAdapter.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -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 != 6 )
 #error Unexpected version of Vamp SDK header included
 #endif
 
@@ -588,7 +588,7 @@
 }
 
 void
-PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
+PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *)
 {
 #ifdef DEBUG_PLUGIN_ADAPTER
     std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
--- a/src/vamp-sdk/RealTime.cpp	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-sdk/RealTime.cpp	Tue Mar 01 12:21:23 2016 +0000
@@ -92,7 +92,14 @@
 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
@@ -139,10 +146,6 @@
     std::stringstream out;
     out << *this;
     
-#if (__GNUC__ < 3)
-    out << std::ends;
-#endif
-
     std::string s = out.str();
 
     // remove trailing R
@@ -157,17 +160,19 @@
     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 @@
 	out << ".000";
     }
 	
-#if (__GNUC__ < 3)
-    out << std::ends;
-#endif
-
     std::string s = out.str();
 
     return s;
 }
 
-
 RealTime
 RealTime::operator/(int d) const
 {
--- a/src/vamp-sdk/acsymbols.c	Tue Mar 01 12:10:29 2016 +0000
+++ b/src/vamp-sdk/acsymbols.c	Tue Mar 01 12:21:23 2016 +0000
@@ -1,6 +1,7 @@
 /* These stubs are provided so that autoconf can check library
  * versions using C symbols only */
 
+extern void libvampsdk_v_2_6_present(void) { }
 extern void libvampsdk_v_2_5_present(void) { }
 extern void libvampsdk_v_2_4_present(void) { }
 extern void libvampsdk_v_2_3_1_present(void) { }
--- a/vamp-hostsdk/PluginLoader.h	Tue Mar 01 12:10:29 2016 +0000
+++ b/vamp-hostsdk/PluginLoader.h	Tue Mar 01 12:21:23 2016 +0000
@@ -66,6 +66,9 @@
  * class, and are certainly not required to use this actual class.
  * But we do strongly recommend it.
  *
+ * This class is not thread-safe; use it from a single application
+ * thread, or guard access to it with a mutex.
+ *
  * \note This class was introduced in version 1.1 of the Vamp plugin SDK.
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vamp-hostsdk/host-c.h	Tue Mar 01 12:21:23 2016 +0000
@@ -0,0 +1,147 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp
+
+    An API for audio analysis and feature extraction plugins.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    Copyright 2006-2015 Chris Cannam and QMUL.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    Except as contained in this notice, the names of the Centre for
+    Digital Music; Queen Mary, University of London; and Chris Cannam
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+/*
+    This file defines a low-level API for enumerating and loading
+    plugin libraries using C calling conventions. It could be used in
+    C programs, or in languages with C-compatible foreign-function
+    interfaces. Note that this works by calling to the C++ Vamp host
+    SDK, so any program using this interface must still link against
+    the rest of the Vamp plugin library and the C++ standard library.
+
+    This is not the simplest or easiest interface for hosting Vamp
+    plugins -- if you have the capability to use the C++ API, please
+    do that instead. (Most programs should not even include this
+    header.)
+
+    The C and C++ interfaces provide different abstraction levels:
+
+    In the C++ interface, the class PluginLoader provides a list of
+    keys corresponding to the installed plugins (where a key combines
+    the plugin's library name and plugin identifier into a single
+    string) plus a method to load a single plugin based on its key
+    (obtaining an instance of class Plugin). With the C++ interface
+    you go straight from the key to a live instance of the plugin. The
+    PluginLoader also provides various facilities to adapt the plugin
+    based on your requirements (e.g. to do time- to frequency-domain
+    conversion for you if the plugin requires it).
+
+    This low-level C interface, on the other hand, deals only in
+    plugin libraries and static descriptors, not in plugin
+    instances. You can enumerate the installed libraries, getting just
+    the base .soname of each library. Then you can retrieve each of
+    the raw C plugin descriptors from a library, and use the
+    descriptor (whose interface is defined in vamp/vamp.h) to
+    instantiate the plugin.
+
+    So this header corresponds to the first part of the PluginLoader
+    class interface: finding and loading plugin libraries and
+    retrieving plugin descriptors from them. But it does not do any of
+    the rest, i.e. instantiating and adapting the plugins themselves.
+    Although this makes the API appear very simple, it means the
+    resulting plugins are relatively hard to use compared to those
+    obtained by the PluginLoader API. There is no way to get to the
+    full C++ abstraction using this API.
+
+    This API is not thread-safe; use it from a single application
+    thread, or guard access to it with a mutex.
+
+    This header was introduced in version 2.6 of the Vamp plugin SDK.
+*/
+
+#ifndef VAMPHOST_C_H_INCLUDED
+#define VAMPHOST_C_H_INCLUDED
+
+#include <vamp/vamp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct vhLibrary_t *vhLibrary;
+
+/**
+ * Return the number of Vamp plugin libraries discovered in the
+ * installation path. This number will remain fixed after the first
+ * call -- plugins are only discovered once, the first time this
+ * function is called.
+ */
+extern int vhGetLibraryCount();
+
+/**
+ * Return the library name (base soname) of the library with the given
+ * index, in the range 0..(vhGetLibraryCount()-1).
+ */
+extern const char *vhGetLibraryName(int library);
+
+/**
+ * Return the library index for the given library name, or -1 if the
+ * name is not known.
+ */
+extern int vhGetLibraryIndex(const char *name);
+    
+/**
+ * Load the library with the given index. If the library cannot be
+ * loaded for any reason, the return value is 0; otherwise it is an
+ * opaque pointer suitable for passing to other functions in this API.
+ */
+extern vhLibrary vhLoadLibrary(int library);
+
+/**
+ * Return the number of Vamp plugins in the given library.
+ */
+extern int vhGetPluginCount(vhLibrary library);
+
+/**
+ * Return a Vamp plugin descriptor for a plugin in a given
+ * library. This simply calls the vampGetPluginDescriptor function in
+ * that library with the given plugin index and returns the
+ * result. See vamp/vamp.h for details about the plugin descriptor.
+ */ 
+extern const VampPluginDescriptor *vhGetPluginDescriptor(vhLibrary library,
+							 int plugin);
+
+/**
+ * Unload a plugin library. Do not do this while any of its plugins
+ * are still in use.
+ */
+extern void vhUnloadLibrary(vhLibrary);
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- a/vamp-hostsdk/hostguard.h	Tue Mar 01 12:10:29 2016 +0000
+++ b/vamp-hostsdk/hostguard.h	Tue Mar 01 12:21:23 2016 +0000
@@ -43,9 +43,9 @@
 
 #define _VAMP_IN_HOSTSDK
 
-#define VAMP_SDK_VERSION "2.5"
+#define VAMP_SDK_VERSION "2.6"
 #define VAMP_SDK_MAJOR_VERSION 2
-#define VAMP_SDK_MINOR_VERSION 5
+#define VAMP_SDK_MINOR_VERSION 6
 
 #ifdef _VAMP_NO_HOST_NAMESPACE
 #define _VAMP_SDK_HOSTSPACE_BEGIN(h)
--- a/vamp-sdk/FFT.h	Tue Mar 01 12:10:29 2016 +0000
+++ b/vamp-sdk/FFT.h	Tue Mar 01 12:21:23 2016 +0000
@@ -60,6 +60,7 @@
 public:
     /**
      * Calculate a forward 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
      * of the input. For real input, ii may be NULL.
@@ -75,6 +76,7 @@
 
     /**
      * Calculate an 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
      * of the input. For real input, ii may be NULL.
--- a/vamp-sdk/plugguard.h	Tue Mar 01 12:10:29 2016 +0000
+++ b/vamp-sdk/plugguard.h	Tue Mar 01 12:21:23 2016 +0000
@@ -71,9 +71,9 @@
 
 #define _VAMP_IN_PLUGINSDK 1
 
-#define VAMP_SDK_VERSION "2.5"
+#define VAMP_SDK_VERSION "2.6"
 #define VAMP_SDK_MAJOR_VERSION 2
-#define VAMP_SDK_MINOR_VERSION 5
+#define VAMP_SDK_MINOR_VERSION 6
 
 #ifdef _VAMP_NO_PLUGIN_NAMESPACE
 #define _VAMP_SDK_PLUGSPACE_BEGIN(h)
--- a/vamp/vamp.h	Tue Mar 01 12:10:29 2016 +0000
+++ b/vamp/vamp.h	Tue Mar 01 12:21:23 2016 +0000
@@ -250,7 +250,7 @@
     /** API version with which this descriptor is compatible. */
     unsigned int vampApiVersion;
 
-    /** Computer-usable name of the plugin. Must not change. [a-zA-Z0-9_] */
+    /** Computer-usable name of the plugin. Must not change. [a-zA-Z0-9_-] */
     const char *identifier;
 
     /** Human-readable name of the plugin. May be translatable. */