mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-07 14:15:46 +01:00
bringing vamp-sdk into 2.0-ongoing branch
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2867 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
b3e24ac78f
commit
051d64131f
39 changed files with 8747 additions and 0 deletions
26
libs/vamp-sdk/COPYING
Normal file
26
libs/vamp-sdk/COPYING
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 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.
|
||||
|
||||
1235
libs/vamp-sdk/Doxyfile
Normal file
1235
libs/vamp-sdk/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
249
libs/vamp-sdk/Makefile
Normal file
249
libs/vamp-sdk/Makefile
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
|
||||
# Makefile for the Vamp plugin SDK. This builds the SDK objects,
|
||||
# libraries, example plugins, and the test host. Please adjust to
|
||||
# suit your operating system requirements.
|
||||
|
||||
APIDIR = vamp
|
||||
SDKDIR = vamp-sdk
|
||||
HOSTEXTDIR = vamp-sdk/hostext
|
||||
EXAMPLEDIR = examples
|
||||
HOSTDIR = host
|
||||
|
||||
###
|
||||
### Start of user-serviceable parts
|
||||
###
|
||||
|
||||
# Default build target (or use "make <target>" to select one).
|
||||
# Targets are:
|
||||
# all -- build everything
|
||||
# sdk -- build all the Vamp SDK libraries for plugins and hosts
|
||||
# sdkstatic -- build only the static versions of the SDK libraries
|
||||
# plugins -- build the example plugins (and the SDK if required)
|
||||
# host -- build the simple Vamp plugin host (and the SDK if required)
|
||||
# test -- build the host and example plugins, and run a quick test
|
||||
# clean -- remove binary targets
|
||||
# distclean -- remove all targets
|
||||
#
|
||||
default: all
|
||||
|
||||
# Compile flags
|
||||
#
|
||||
CXXFLAGS := $(CXXFLAGS) -O2 -Wall -I. -fpic
|
||||
|
||||
# ar, ranlib
|
||||
#
|
||||
AR := ar
|
||||
RANLIB := ranlib
|
||||
|
||||
# Libraries required for the plugins.
|
||||
# (Note that it is desirable to statically link libstdc++ if possible,
|
||||
# because our plugin exposes only a C API so there are no boundary
|
||||
# compatibility problems.)
|
||||
#
|
||||
PLUGIN_LIBS = $(SDKDIR)/libvamp-sdk.a
|
||||
#PLUGIN_LIBS = $(SDKDIR)/libvamp-sdk.a $(shell g++ -print-file-name=libstdc++.a)
|
||||
|
||||
# File extension for a dynamically loadable object
|
||||
#
|
||||
PLUGIN_EXT = .so
|
||||
#PLUGIN_EXT = .dll
|
||||
#PLUGIN_EXT = .dylib
|
||||
|
||||
# Libraries required for the host.
|
||||
#
|
||||
HOST_LIBS = $(SDKDIR)/libvamp-hostsdk.a -lsndfile -ldl
|
||||
|
||||
# Locations for "make install". This will need quite a bit of
|
||||
# editing for non-Linux platforms. Of course you don't necessarily
|
||||
# have to use "make install".
|
||||
#
|
||||
INSTALL_PREFIX := /usr
|
||||
INSTALL_API_HEADERS := $(INSTALL_PREFIX)/include/vamp
|
||||
INSTALL_SDK_HEADERS := $(INSTALL_PREFIX)/include/vamp-sdk
|
||||
INSTALL_HOSTEXT_HEADERS := $(INSTALL_PREFIX)/include/vamp-sdk/hostext
|
||||
INSTALL_SDK_LIBS := $(INSTALL_PREFIX)/lib
|
||||
|
||||
INSTALL_SDK_LIBNAME := libvamp-sdk.so.1.1.0
|
||||
INSTALL_SDK_LINK_ABI := libvamp-sdk.so.1
|
||||
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.2.0.0
|
||||
INSTALL_HOSTSDK_LINK_ABI := libvamp-hostsdk.so.2
|
||||
INSTALL_HOSTSDK_LINK_DEV := libvamp-hostsdk.so
|
||||
INSTALL_HOSTSDK_STATIC := libvamp-hostsdk.a
|
||||
INSTALL_HOSTSDK_LA := libvamp-hostsdk.la
|
||||
|
||||
INSTALL_PKGCONFIG := $(INSTALL_PREFIX)/lib/pkgconfig
|
||||
|
||||
# Flags required to tell the compiler to create a dynamically loadable object
|
||||
#
|
||||
DYNAMIC_LDFLAGS = -shared -Wl,-Bsymbolic
|
||||
PLUGIN_LDFLAGS = $(DYNAMIC_LDFLAGS)
|
||||
SDK_DYNAMIC_LDFLAGS = $(DYNAMIC_LDFLAGS) -Wl,-soname=$(INSTALL_SDK_LIBNAME)
|
||||
HOSTSDK_DYNAMIC_LDFLAGS = $(DYNAMIC_LDFLAGS) -Wl,-soname=$(INSTALL_HOSTSDK_LIBNAME)
|
||||
|
||||
## For OS/X with g++:
|
||||
#PLUGIN_LDFLAGS = -dynamiclib
|
||||
|
||||
|
||||
### End of user-serviceable parts
|
||||
|
||||
|
||||
API_HEADERS = \
|
||||
$(APIDIR)/vamp.h
|
||||
|
||||
SDK_HEADERS = \
|
||||
$(SDKDIR)/Plugin.h \
|
||||
$(SDKDIR)/PluginAdapter.h \
|
||||
$(SDKDIR)/PluginBase.h \
|
||||
$(SDKDIR)/RealTime.h
|
||||
|
||||
HOSTSDK_HEADERS = \
|
||||
$(SDKDIR)/Plugin.h \
|
||||
$(SDKDIR)/PluginBase.h \
|
||||
$(SDKDIR)/PluginHostAdapter.h \
|
||||
$(SDKDIR)/RealTime.h
|
||||
|
||||
HOSTEXT_HEADERS = \
|
||||
$(HOSTEXTDIR)/PluginChannelAdapter.h \
|
||||
$(HOSTEXTDIR)/PluginInputDomainAdapter.h \
|
||||
$(HOSTEXTDIR)/PluginLoader.h \
|
||||
$(HOSTEXTDIR)/PluginWrapper.h
|
||||
|
||||
SDK_OBJECTS = \
|
||||
$(SDKDIR)/PluginAdapter.o \
|
||||
$(SDKDIR)/RealTime.o
|
||||
|
||||
HOSTSDK_OBJECTS = \
|
||||
$(SDKDIR)/PluginHostAdapter.o \
|
||||
$(HOSTEXTDIR)/PluginChannelAdapter.o \
|
||||
$(HOSTEXTDIR)/PluginInputDomainAdapter.o \
|
||||
$(HOSTEXTDIR)/PluginLoader.o \
|
||||
$(HOSTEXTDIR)/PluginWrapper.o \
|
||||
$(SDKDIR)/RealTime.o
|
||||
|
||||
SDK_STATIC = \
|
||||
$(SDKDIR)/libvamp-sdk.a
|
||||
|
||||
HOSTSDK_STATIC = \
|
||||
$(SDKDIR)/libvamp-hostsdk.a
|
||||
|
||||
SDK_DYNAMIC = \
|
||||
$(SDKDIR)/libvamp-sdk.so
|
||||
|
||||
HOSTSDK_DYNAMIC = \
|
||||
$(SDKDIR)/libvamp-hostsdk.so
|
||||
|
||||
SDK_LA = \
|
||||
$(SDKDIR)/libvamp-sdk.la
|
||||
|
||||
HOSTSDK_LA = \
|
||||
$(SDKDIR)/libvamp-hostsdk.la
|
||||
|
||||
PLUGIN_HEADERS = \
|
||||
$(EXAMPLEDIR)/SpectralCentroid.h \
|
||||
$(EXAMPLEDIR)/PercussionOnsetDetector.h \
|
||||
$(EXAMPLEDIR)/AmplitudeFollower.h \
|
||||
$(EXAMPLEDIR)/ZeroCrossing.h
|
||||
|
||||
PLUGIN_OBJECTS = \
|
||||
$(EXAMPLEDIR)/SpectralCentroid.o \
|
||||
$(EXAMPLEDIR)/PercussionOnsetDetector.o \
|
||||
$(EXAMPLEDIR)/AmplitudeFollower.o \
|
||||
$(EXAMPLEDIR)/ZeroCrossing.o \
|
||||
$(EXAMPLEDIR)/plugins.o
|
||||
|
||||
PLUGIN_TARGET = \
|
||||
$(EXAMPLEDIR)/vamp-example-plugins$(PLUGIN_EXT)
|
||||
|
||||
HOST_HEADERS = \
|
||||
$(HOSTDIR)/system.h
|
||||
|
||||
HOST_OBJECTS = \
|
||||
$(HOSTDIR)/vamp-simple-host.o
|
||||
|
||||
HOST_TARGET = \
|
||||
$(HOSTDIR)/vamp-simple-host
|
||||
|
||||
sdk: sdkstatic $(SDK_DYNAMIC) $(HOSTSDK_DYNAMIC)
|
||||
|
||||
sdkstatic: $(SDK_STATIC) $(HOSTSDK_STATIC)
|
||||
$(RANLIB) $(SDK_STATIC)
|
||||
$(RANLIB) $(HOSTSDK_STATIC)
|
||||
|
||||
plugins: $(PLUGIN_TARGET)
|
||||
|
||||
host: $(HOST_TARGET)
|
||||
|
||||
all: sdk plugins host test
|
||||
|
||||
$(SDK_STATIC): $(SDK_OBJECTS) $(API_HEADERS) $(SDK_HEADERS)
|
||||
$(AR) r $@ $(SDK_OBJECTS)
|
||||
|
||||
$(HOSTSDK_STATIC): $(HOSTSDK_OBJECTS) $(API_HEADERS) $(HOSTSDK_HEADERS) $(HOSTEXT_HEADERS)
|
||||
$(AR) r $@ $(HOSTSDK_OBJECTS)
|
||||
|
||||
$(SDK_DYNAMIC): $(SDK_OBJECTS) $(API_HEADERS) $(SDK_HEADERS)
|
||||
$(CXX) $(LDFLAGS) $(SDK_DYNAMIC_LDFLAGS) -o $@ $(SDK_OBJECTS)
|
||||
|
||||
$(HOSTSDK_DYNAMIC): $(HOSTSDK_OBJECTS) $(API_HEADERS) $(HOSTSDK_HEADERS) $(HOSTEXT_HEADERS)
|
||||
$(CXX) $(LDFLAGS) $(HOSTSDK_DYNAMIC_LDFLAGS) -o $@ $(HOSTSDK_OBJECTS)
|
||||
|
||||
$(PLUGIN_TARGET): $(PLUGIN_OBJECTS) $(SDK_STATIC) $(PLUGIN_HEADERS)
|
||||
$(CXX) $(LDFLAGS) $(PLUGIN_LDFLAGS) -o $@ $(PLUGIN_OBJECTS) $(PLUGIN_LIBS)
|
||||
|
||||
$(HOST_TARGET): $(HOST_OBJECTS) $(HOSTSDK_STATIC) $(HOST_HEADERS)
|
||||
$(CXX) $(LDFLAGS) $(HOST_LDFLAGS) -o $@ $(HOST_OBJECTS) $(HOST_LIBS)
|
||||
|
||||
test: plugins host
|
||||
VAMP_PATH=$(EXAMPLEDIR) $(HOST_TARGET) -l
|
||||
|
||||
clean:
|
||||
rm -f $(SDK_OBJECTS) $(HOSTSDK_OBJECTS) $(PLUGIN_OBJECTS) $(HOST_OBJECTS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(SDK_STATIC) $(SDK_DYNAMIC) $(HOSTSDK_STATIC) $(HOSTSDK_DYNAMIC) $(PLUGIN_TARGET) $(HOST_TARGET) *~ */*~
|
||||
|
||||
install: $(SDK_STATIC) $(SDK_DYNAMIC) $(HOSTSDK_STATIC) $(HOSTSDK_DYNAMIC) $(PLUGIN_TARGET) $(HOST_TARGET)
|
||||
mkdir -p $(INSTALL_API_HEADERS)
|
||||
mkdir -p $(INSTALL_SDK_HEADERS)
|
||||
mkdir -p $(INSTALL_HOSTEXT_HEADERS)
|
||||
mkdir -p $(INSTALL_SDK_LIBS)
|
||||
mkdir -p $(INSTALL_PKGCONFIG)
|
||||
cp $(API_HEADERS) $(INSTALL_API_HEADERS)
|
||||
cp $(SDK_HEADERS) $(INSTALL_SDK_HEADERS)
|
||||
cp $(HOSTSDK_HEADERS) $(INSTALL_SDK_HEADERS)
|
||||
cp $(HOSTEXT_HEADERS) $(INSTALL_HOSTEXT_HEADERS)
|
||||
cp $(SDK_STATIC) $(INSTALL_SDK_LIBS)
|
||||
cp $(HOSTSDK_STATIC) $(INSTALL_SDK_LIBS)
|
||||
cp $(SDK_DYNAMIC) $(INSTALL_SDK_LIBS)/$(INSTALL_SDK_LIBNAME)
|
||||
cp $(HOSTSDK_DYNAMIC) $(INSTALL_SDK_LIBS)/$(INSTALL_HOSTSDK_LIBNAME)
|
||||
rm -f $(INSTALL_SDK_LIBS)/$(INSTALL_SDK_LINK_ABI)
|
||||
ln -s $(INSTALL_SDK_LIBNAME) $(INSTALL_SDK_LIBS)/$(INSTALL_SDK_LINK_ABI)
|
||||
rm -f $(INSTALL_SDK_LIBS)/$(INSTALL_HOSTSDK_LINK_ABI)
|
||||
ln -s $(INSTALL_HOSTSDK_LIBNAME) $(INSTALL_SDK_LIBS)/$(INSTALL_HOSTSDK_LINK_ABI)
|
||||
rm -f $(INSTALL_SDK_LIBS)/$(INSTALL_SDK_LINK_DEV)
|
||||
ln -s $(INSTALL_SDK_LIBNAME) $(INSTALL_SDK_LIBS)/$(INSTALL_SDK_LINK_DEV)
|
||||
rm -f $(INSTALL_SDK_LIBS)/$(INSTALL_HOSTSDK_LINK_DEV)
|
||||
ln -s $(INSTALL_HOSTSDK_LIBNAME) $(INSTALL_SDK_LIBS)/$(INSTALL_HOSTSDK_LINK_DEV)
|
||||
sed "s,%PREFIX%,$(INSTALL_PREFIX)," $(APIDIR)/vamp.pc.in \
|
||||
> $(INSTALL_PKGCONFIG)/vamp.pc
|
||||
sed "s,%PREFIX%,$(INSTALL_PREFIX)," $(SDKDIR)/vamp-sdk.pc.in \
|
||||
> $(INSTALL_PKGCONFIG)/vamp-sdk.pc
|
||||
sed "s,%PREFIX%,$(INSTALL_PREFIX)," $(SDKDIR)/vamp-hostsdk.pc.in \
|
||||
> $(INSTALL_PKGCONFIG)/vamp-hostsdk.pc
|
||||
sed -e "s,%LIBNAME%,$(INSTALL_SDK_LIBNAME),g" \
|
||||
-e "s,%LINK_ABI%,$(INSTALL_SDK_LINK_ABI),g" \
|
||||
-e "s,%LINK_DEV%,$(INSTALL_SDK_LINK_DEV),g" \
|
||||
-e "s,%STATIC%,$(INSTALL_SDK_STATIC),g" \
|
||||
-e "s,%LIBS%,$(INSTALL_SDK_LIBS),g" $(SDK_LA).in \
|
||||
> $(INSTALL_SDK_LIBS)/$(INSTALL_SDK_LA)
|
||||
sed -e "s,%LIBNAME%,$(INSTALL_HOSTSDK_LIBNAME),g" \
|
||||
-e "s,%LINK_ABI%,$(INSTALL_HOSTSDK_LINK_ABI),g" \
|
||||
-e "s,%LINK_DEV%,$(INSTALL_HOSTSDK_LINK_DEV),g" \
|
||||
-e "s,%STATIC%,$(INSTALL_HOSTSDK_STATIC),g" \
|
||||
-e "s,%LIBS%,$(INSTALL_SDK_LIBS),g" $(HOSTSDK_LA).in \
|
||||
> $(INSTALL_SDK_LIBS)/$(INSTALL_HOSTSDK_LA)
|
||||
|
||||
240
libs/vamp-sdk/README
Normal file
240
libs/vamp-sdk/README
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
Vamp
|
||||
====
|
||||
|
||||
An API for audio analysis and feature extraction plugins.
|
||||
|
||||
http://www.vamp-plugins.org/
|
||||
|
||||
Vamp is an API for C and C++ plugins that process sampled audio data
|
||||
to produce descriptive output (measurements or semantic observations).
|
||||
|
||||
The principal differences between Vamp and a real-time audio
|
||||
processing plugin system such as VST are:
|
||||
|
||||
* Vamp plugins may output complex multidimensional data with labels.
|
||||
As a consequence, they are likely to work best when the output
|
||||
data has a much lower sampling rate than the input. (This also
|
||||
means it is usually desirable to implement them in C++ using the
|
||||
high-level base class provided rather than use the raw C API.)
|
||||
|
||||
* While Vamp plugins receive data block-by-block, they are not
|
||||
required to return output immediately on receiving the input.
|
||||
A Vamp plugin may be non-causal, preferring to store up data
|
||||
based on its input until the end of a processing run and then
|
||||
return all results at once.
|
||||
|
||||
* Vamp plugins have more control over their inputs than a typical
|
||||
real-time processing plugin. For example, they can indicate to
|
||||
the host their preferred processing block and step sizes, and these
|
||||
may differ.
|
||||
|
||||
* Vamp plugins may ask to receive data in the frequency domain
|
||||
instead of the time domain. The host takes the responsibility
|
||||
for converting the input data using an FFT of windowed frames.
|
||||
This simplifies plugins that do straightforward frequency-domain
|
||||
processing and permits the host to cache frequency-domain data
|
||||
when possible.
|
||||
|
||||
* A Vamp plugin is configured once before each processing run, and
|
||||
receives no further parameter changes during use -- unlike real-
|
||||
time plugin APIs in which the input parameters may change at any
|
||||
time. This also means that fundamental properties such as the
|
||||
number of values per output or the preferred processing block
|
||||
size may depend on the input parameters.
|
||||
|
||||
* Vamp plugins do not have to be able to run in real time.
|
||||
|
||||
|
||||
About this SDK
|
||||
==============
|
||||
|
||||
This is version 1.1b 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.
|
||||
|
||||
This SDK contains the following:
|
||||
|
||||
* vamp/vamp.h
|
||||
|
||||
The formal C language plugin API for Vamp plugins.
|
||||
|
||||
A Vamp plugin is a dynamic library (.so, .dll or .dylib depending on
|
||||
platform) exposing one C-linkage entry point (vampGetPluginDescriptor)
|
||||
which returns data defined in the rest of this C header.
|
||||
|
||||
Although the C API is the official API for Vamp, we don't recommend
|
||||
that you program directly to it. The C++ abstraction found in the
|
||||
vamp-sdk directory (below) is preferable for most purposes and is
|
||||
more thoroughly documented.
|
||||
|
||||
* vamp-sdk
|
||||
|
||||
C++ classes for straightforwardly implementing Vamp plugins and hosts.
|
||||
|
||||
Plugins should subclass Vamp::Plugin and then use Vamp::PluginAdapter
|
||||
to expose the correct C API for the plugin. Plugin authors should
|
||||
read vamp-sdk/PluginBase.h and Plugin.h for code documentation, and
|
||||
refer to the example plugin code in the examples directory. Plugins
|
||||
should link with -lvampsdk. [*NOTE: this has changed from vamp-sdk in
|
||||
previous versions, to avoid conflict with the use of hyphens for
|
||||
library versioning schemes on some platforms.]
|
||||
|
||||
Hosts may use the Vamp::PluginHostAdapter to convert the loaded
|
||||
plugin's C API back into a Vamp::Plugin object. Host authors should
|
||||
refer to the example host code in the host directory. Hosts should
|
||||
link with -lvamphostsdk. [*NOTE: this has changed from vamp-hostsdk
|
||||
in previous versions, to avoid conflict with the use of hyphens for
|
||||
library versioning schemes on some platforms.]
|
||||
|
||||
* vamp-sdk/hostext
|
||||
|
||||
Additional C++ classes to make a host's life easier (introduced in
|
||||
version 1.1 of the Vamp SDK).
|
||||
|
||||
Vamp::HostExt::PluginLoader provides a very easy interface for a host
|
||||
to discover, load, and find out category information about the
|
||||
available plugins. Most "casual" Vamp hosts will probably want to use
|
||||
this class.
|
||||
|
||||
Vamp::HostExt::PluginInputDomainAdapter provides a means for hosts to
|
||||
handle plugins that expect frequency-domain input, without having to
|
||||
convert the input themselves.
|
||||
|
||||
Vamp::HostExt::PluginChannelAdapter provides a means for hosts to use
|
||||
plugins that do not necessarily support the same number of audio
|
||||
channels as they have available, without having to worry about
|
||||
applying a channel management / mixdown policy themselves.
|
||||
|
||||
The PluginLoader class can also use the input domain and channel
|
||||
adapters automatically to make the entire conversion process
|
||||
transparent to the host if required.
|
||||
|
||||
* examples
|
||||
|
||||
Example plugins implemented using the C++ classes. ZeroCrossing
|
||||
calculates the positions and density of zero-crossing points in an
|
||||
audio waveform. SpectralCentroid calculates the centre of gravity of
|
||||
the frequency domain representation of each block of audio.
|
||||
AmplitudeFollower tracks the amplitude of a signal based on a method
|
||||
from the SuperCollider real-time audio system.
|
||||
PercussionOnsetDetector estimates the locations of percussive onsets
|
||||
using a simple method described in "Drum Source Separation using
|
||||
Percussive Feature Detection and Spectral Modulation" by Dan Barry,
|
||||
Derry Fitzgerald, Eugene Coyle and Bob Lawlor, ISSC 2005.
|
||||
|
||||
* host
|
||||
|
||||
A simple command-line Vamp host, capable of loading a plugin and using
|
||||
it to process a complete audio file, with its default parameters.
|
||||
Requires libsndfile (http://www.mega-nerd.com/libsndfile/).
|
||||
|
||||
If you don't have libsndfile, you may want to edit the Makefile to
|
||||
change the default build target from "all" to "sdk", so as to compile
|
||||
only the SDK and not the host.
|
||||
|
||||
|
||||
Plugin Lookup and Categorisation
|
||||
================================
|
||||
|
||||
The Vamp API does not officially specify how to load plugin libraries
|
||||
or where to find them. However, the SDK does include a function
|
||||
(Vamp::PluginHostAdapter::getPluginPath()) that returns a recommended
|
||||
directory search path that hosts may use for plugin libraries, and a
|
||||
class (Vamp::HostExt::PluginLoader) that implements a sensible
|
||||
cross-platform lookup policy using this path. We recommend using this
|
||||
class in your host unless you have a good reason not to want to. This
|
||||
implementation also permits the user to set the environment variable
|
||||
VAMP_PATH to override the default path if desired.
|
||||
|
||||
The policy used by Vamp::HostExt::PluginLoader -- and our
|
||||
recommendation for any host -- is to search each directory in the path
|
||||
returned by getPluginPath for .DLL (on Windows), .so (on Linux,
|
||||
Solaris, BSD etc) or .dylib (on OS/X) files, then to load each one and
|
||||
perform a dynamic name lookup on the vampGetPluginDescriptor function
|
||||
to enumerate the plugins in the library. This operation will
|
||||
necessarily be system-dependent.
|
||||
|
||||
Vamp also has an informal convention for sorting plugins into
|
||||
functional categories. In addition to the library file itself, a
|
||||
plugin library may install a category file with the same name as the
|
||||
library but .cat extension. The existence and format of this file are
|
||||
not specified by the Vamp API, but by convention the file may contain
|
||||
lines of the format
|
||||
|
||||
vamp:pluginlibrary:pluginname::General Category > Specific Category
|
||||
|
||||
which a host may read and use to assign plugins a location within a
|
||||
category tree for display to the user. The expectation is that
|
||||
advanced users may also choose to set up their own preferred category
|
||||
trees, which is why this information is not queried as part of the
|
||||
Vamp plugin's API itself. The Vamp::HostExt::PluginLoader class also
|
||||
provides support for plugin category lookup using this scheme.
|
||||
|
||||
|
||||
Building and Installing the SDK and Examples
|
||||
============================================
|
||||
|
||||
To build the SDK, the simple host, and the example plugins, edit the
|
||||
Makefile to suit your platform according to the comments in it, then
|
||||
run "make".
|
||||
|
||||
To use an IDE to build a plugin or host using the Vamp SDK, simply add
|
||||
the .cpp files in the vamp-sdk directory to your project.
|
||||
|
||||
Installing the example plugins so that they can be found by other Vamp
|
||||
hosts depends on your platform:
|
||||
|
||||
* Windows: copy the files
|
||||
examples/vamp-example-plugins.dll
|
||||
examples/vamp-example-plugins.cat
|
||||
to
|
||||
C:\Program Files\Vamp Plugins
|
||||
|
||||
* Linux: copy the files
|
||||
examples/vamp-example-plugins.so
|
||||
examples/vamp-example-plugins.cat
|
||||
to
|
||||
/usr/local/lib/vamp/
|
||||
|
||||
* OS/X: copy the files
|
||||
examples/vamp-example-plugins.dylib
|
||||
examples/vamp-example-plugins.cat
|
||||
to
|
||||
/Library/Audio/Plug-Ins/Vamp
|
||||
|
||||
|
||||
Licensing
|
||||
=========
|
||||
|
||||
This plugin SDK is freely redistributable under a "new-style BSD"
|
||||
licence. See the file COPYING for more details. In short, you may
|
||||
modify and redistribute the SDK and example plugins within any
|
||||
commercial or non-commercial, proprietary or open-source plugin or
|
||||
application under almost any conditions, with no obligation to provide
|
||||
source code, provided you retain the original copyright note.
|
||||
|
||||
|
||||
See Also
|
||||
========
|
||||
|
||||
Sonic Visualiser, an interactive open-source graphical audio
|
||||
inspection, analysis and visualisation tool supporting Vamp plugins.
|
||||
http://www.sonicvisualiser.org/
|
||||
|
||||
|
||||
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-2007
|
||||
Chris Cannam and QMUL.
|
||||
|
||||
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
|
||||
from prior plugin systems, notably DSSI (http://dssi.sourceforge.net)
|
||||
and FEAPI (http://feapi.sourceforge.net).
|
||||
|
||||
247
libs/vamp-sdk/examples/AmplitudeFollower.cpp
Normal file
247
libs/vamp-sdk/examples/AmplitudeFollower.cpp
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/* -*- 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.
|
||||
This file copyright 2006 Dan Stowell.
|
||||
|
||||
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 "AmplitudeFollower.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
/**
|
||||
* An implementation of SuperCollider's amplitude-follower algorithm
|
||||
* as a simple Vamp plugin.
|
||||
*/
|
||||
|
||||
AmplitudeFollower::AmplitudeFollower(float inputSampleRate) :
|
||||
Plugin(inputSampleRate),
|
||||
m_stepSize(0),
|
||||
m_previn(0.0f),
|
||||
m_clampcoef(0.01f),
|
||||
m_relaxcoef(0.01f)
|
||||
{
|
||||
}
|
||||
|
||||
AmplitudeFollower::~AmplitudeFollower()
|
||||
{
|
||||
}
|
||||
|
||||
string
|
||||
AmplitudeFollower::getIdentifier() const
|
||||
{
|
||||
return "amplitudefollower";
|
||||
}
|
||||
|
||||
string
|
||||
AmplitudeFollower::getName() const
|
||||
{
|
||||
return "Amplitude Follower";
|
||||
}
|
||||
|
||||
string
|
||||
AmplitudeFollower::getDescription() const
|
||||
{
|
||||
return "Track the amplitude of the audio signal";
|
||||
}
|
||||
|
||||
string
|
||||
AmplitudeFollower::getMaker() const
|
||||
{
|
||||
return "Vamp SDK Example Plugins";
|
||||
}
|
||||
|
||||
int
|
||||
AmplitudeFollower::getPluginVersion() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
string
|
||||
AmplitudeFollower::getCopyright() const
|
||||
{
|
||||
return "Code copyright 2006 Dan Stowell; method from SuperCollider. Freely redistributable (BSD license)";
|
||||
}
|
||||
|
||||
bool
|
||||
AmplitudeFollower::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
if (channels < getMinChannelCount() ||
|
||||
channels > getMaxChannelCount()) return false;
|
||||
|
||||
m_stepSize = std::min(stepSize, blockSize);
|
||||
|
||||
// Translate the coefficients
|
||||
// from their "convenient" 60dB convergence-time values
|
||||
// to real coefficients
|
||||
m_clampcoef = m_clampcoef==0.0 ? 0.0 : exp(log(0.1)/(m_clampcoef * m_inputSampleRate));
|
||||
m_relaxcoef = m_relaxcoef==0.0 ? 0.0 : exp(log(0.1)/(m_relaxcoef * m_inputSampleRate));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AmplitudeFollower::reset()
|
||||
{
|
||||
m_previn = 0.0f;
|
||||
}
|
||||
|
||||
AmplitudeFollower::OutputList
|
||||
AmplitudeFollower::getOutputDescriptors() const
|
||||
{
|
||||
OutputList list;
|
||||
|
||||
OutputDescriptor sca;
|
||||
sca.identifier = "amplitude";
|
||||
sca.name = "Amplitude";
|
||||
sca.description = "";
|
||||
sca.unit = "V";
|
||||
sca.hasFixedBinCount = true;
|
||||
sca.binCount = 1;
|
||||
sca.hasKnownExtents = false;
|
||||
sca.isQuantized = false;
|
||||
sca.sampleType = OutputDescriptor::OneSamplePerStep;
|
||||
list.push_back(sca);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
AmplitudeFollower::ParameterList
|
||||
AmplitudeFollower::getParameterDescriptors() const
|
||||
{
|
||||
ParameterList list;
|
||||
|
||||
ParameterDescriptor att;
|
||||
att.identifier = "attack";
|
||||
att.name = "Attack time";
|
||||
att.description = "";
|
||||
att.unit = "s";
|
||||
att.minValue = 0.0f;
|
||||
att.maxValue = 1.f;
|
||||
att.defaultValue = 0.01f;
|
||||
att.isQuantized = false;
|
||||
|
||||
list.push_back(att);
|
||||
|
||||
ParameterDescriptor dec;
|
||||
dec.identifier = "release";
|
||||
dec.name = "Release time";
|
||||
dec.description = "";
|
||||
dec.unit = "s";
|
||||
dec.minValue = 0.0f;
|
||||
dec.maxValue = 1.f;
|
||||
dec.defaultValue = 0.01f;
|
||||
dec.isQuantized = false;
|
||||
|
||||
list.push_back(dec);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void AmplitudeFollower::setParameter(std::string paramid, float newval)
|
||||
{
|
||||
if (paramid == "attack") {
|
||||
m_clampcoef = newval;
|
||||
} else if (paramid == "release") {
|
||||
m_relaxcoef = newval;
|
||||
}
|
||||
}
|
||||
|
||||
float AmplitudeFollower::getParameter(std::string paramid) const
|
||||
{
|
||||
if (paramid == "attack") {
|
||||
return m_clampcoef;
|
||||
} else if (paramid == "release") {
|
||||
return m_relaxcoef;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
AmplitudeFollower::FeatureSet
|
||||
AmplitudeFollower::process(const float *const *inputBuffers,
|
||||
Vamp::RealTime timestamp)
|
||||
{
|
||||
if (m_stepSize == 0) {
|
||||
cerr << "ERROR: AmplitudeFollower::process: "
|
||||
<< "AmplitudeFollower has not been initialised"
|
||||
<< endl;
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
float previn = m_previn;
|
||||
|
||||
FeatureSet returnFeatures;
|
||||
|
||||
float val;
|
||||
float peak = 0.0f;
|
||||
|
||||
for (size_t i = 0; i < m_stepSize; ++i) {
|
||||
|
||||
val = fabs(inputBuffers[0][i]);
|
||||
|
||||
if (val < previn) {
|
||||
val = val + (previn - val) * m_relaxcoef;
|
||||
} else {
|
||||
val = val + (previn - val) * m_clampcoef;
|
||||
}
|
||||
|
||||
if (val > peak) peak = val;
|
||||
previn = val;
|
||||
}
|
||||
|
||||
m_previn = previn;
|
||||
|
||||
// Now store the "feature" (peak amp) for this sample
|
||||
Feature feature;
|
||||
feature.hasTimestamp = false;
|
||||
feature.values.push_back(peak);
|
||||
returnFeatures[0].push_back(feature);
|
||||
|
||||
return returnFeatures;
|
||||
}
|
||||
|
||||
AmplitudeFollower::FeatureSet
|
||||
AmplitudeFollower::getRemainingFeatures()
|
||||
{
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
84
libs/vamp-sdk/examples/AmplitudeFollower.h
Normal file
84
libs/vamp-sdk/examples/AmplitudeFollower.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- 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.
|
||||
This file copyright 2006 Dan Stowell.
|
||||
|
||||
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 _AMPLITUDE_FOLLOWER_PLUGIN_H_
|
||||
#define _AMPLITUDE_FOLLOWER_PLUGIN_H_
|
||||
|
||||
#include "vamp-sdk/Plugin.h"
|
||||
|
||||
/**
|
||||
* Example plugin implementing the SuperCollider amplitude follower
|
||||
* function.
|
||||
*/
|
||||
|
||||
class AmplitudeFollower : public Vamp::Plugin
|
||||
{
|
||||
public:
|
||||
AmplitudeFollower(float inputSampleRate);
|
||||
virtual ~AmplitudeFollower();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
void reset();
|
||||
|
||||
InputDomain getInputDomain() const { return TimeDomain; }
|
||||
|
||||
std::string getIdentifier() const;
|
||||
std::string getName() const;
|
||||
std::string getDescription() const;
|
||||
std::string getMaker() const;
|
||||
int getPluginVersion() const;
|
||||
std::string getCopyright() const;
|
||||
|
||||
OutputList getOutputDescriptors() const;
|
||||
|
||||
ParameterList getParameterDescriptors() const;
|
||||
float getParameter(std::string paramid) const;
|
||||
void setParameter(std::string paramid, float newval);
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers,
|
||||
Vamp::RealTime timestamp);
|
||||
|
||||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
size_t m_stepSize;
|
||||
float m_previn;
|
||||
float m_clampcoef;
|
||||
float m_relaxcoef;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
285
libs/vamp-sdk/examples/PercussionOnsetDetector.cpp
Normal file
285
libs/vamp-sdk/examples/PercussionOnsetDetector.cpp
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 "PercussionOnsetDetector.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
PercussionOnsetDetector::PercussionOnsetDetector(float inputSampleRate) :
|
||||
Plugin(inputSampleRate),
|
||||
m_stepSize(0),
|
||||
m_blockSize(0),
|
||||
m_threshold(3),
|
||||
m_sensitivity(40),
|
||||
m_priorMagnitudes(0),
|
||||
m_dfMinus1(0),
|
||||
m_dfMinus2(0)
|
||||
{
|
||||
}
|
||||
|
||||
PercussionOnsetDetector::~PercussionOnsetDetector()
|
||||
{
|
||||
delete[] m_priorMagnitudes;
|
||||
}
|
||||
|
||||
string
|
||||
PercussionOnsetDetector::getIdentifier() const
|
||||
{
|
||||
return "percussiononsets";
|
||||
}
|
||||
|
||||
string
|
||||
PercussionOnsetDetector::getName() const
|
||||
{
|
||||
return "Simple Percussion Onset Detector";
|
||||
}
|
||||
|
||||
string
|
||||
PercussionOnsetDetector::getDescription() const
|
||||
{
|
||||
return "Detect percussive note onsets by identifying broadband energy rises";
|
||||
}
|
||||
|
||||
string
|
||||
PercussionOnsetDetector::getMaker() const
|
||||
{
|
||||
return "Vamp SDK Example Plugins";
|
||||
}
|
||||
|
||||
int
|
||||
PercussionOnsetDetector::getPluginVersion() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
string
|
||||
PercussionOnsetDetector::getCopyright() const
|
||||
{
|
||||
return "Code copyright 2006 Queen Mary, University of London, after Dan Barry et al 2005. Freely redistributable (BSD license)";
|
||||
}
|
||||
|
||||
size_t
|
||||
PercussionOnsetDetector::getPreferredStepSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
PercussionOnsetDetector::getPreferredBlockSize() const
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
|
||||
bool
|
||||
PercussionOnsetDetector::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
if (channels < getMinChannelCount() ||
|
||||
channels > getMaxChannelCount()) return false;
|
||||
|
||||
m_stepSize = stepSize;
|
||||
m_blockSize = blockSize;
|
||||
|
||||
m_priorMagnitudes = new float[m_blockSize/2];
|
||||
|
||||
for (size_t i = 0; i < m_blockSize/2; ++i) {
|
||||
m_priorMagnitudes[i] = 0.f;
|
||||
}
|
||||
|
||||
m_dfMinus1 = 0.f;
|
||||
m_dfMinus2 = 0.f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PercussionOnsetDetector::reset()
|
||||
{
|
||||
for (size_t i = 0; i < m_blockSize/2; ++i) {
|
||||
m_priorMagnitudes[i] = 0.f;
|
||||
}
|
||||
|
||||
m_dfMinus1 = 0.f;
|
||||
m_dfMinus2 = 0.f;
|
||||
}
|
||||
|
||||
PercussionOnsetDetector::ParameterList
|
||||
PercussionOnsetDetector::getParameterDescriptors() const
|
||||
{
|
||||
ParameterList list;
|
||||
|
||||
ParameterDescriptor d;
|
||||
d.identifier = "threshold";
|
||||
d.name = "Energy rise threshold";
|
||||
d.description = "Energy rise within a frequency bin necessary to count toward broadband total";
|
||||
d.unit = "dB";
|
||||
d.minValue = 0;
|
||||
d.maxValue = 20;
|
||||
d.defaultValue = 3;
|
||||
d.isQuantized = false;
|
||||
list.push_back(d);
|
||||
|
||||
d.identifier = "sensitivity";
|
||||
d.name = "Sensitivity";
|
||||
d.description = "Sensitivity of peak detector applied to broadband detection function";
|
||||
d.unit = "%";
|
||||
d.minValue = 0;
|
||||
d.maxValue = 100;
|
||||
d.defaultValue = 40;
|
||||
d.isQuantized = false;
|
||||
list.push_back(d);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
float
|
||||
PercussionOnsetDetector::getParameter(std::string id) const
|
||||
{
|
||||
if (id == "threshold") return m_threshold;
|
||||
if (id == "sensitivity") return m_sensitivity;
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
void
|
||||
PercussionOnsetDetector::setParameter(std::string id, float value)
|
||||
{
|
||||
if (id == "threshold") {
|
||||
if (value < 0) value = 0;
|
||||
if (value > 20) value = 20;
|
||||
m_threshold = value;
|
||||
} else if (id == "sensitivity") {
|
||||
if (value < 0) value = 0;
|
||||
if (value > 100) value = 100;
|
||||
m_sensitivity = value;
|
||||
}
|
||||
}
|
||||
|
||||
PercussionOnsetDetector::OutputList
|
||||
PercussionOnsetDetector::getOutputDescriptors() const
|
||||
{
|
||||
OutputList list;
|
||||
|
||||
OutputDescriptor d;
|
||||
d.identifier = "onsets";
|
||||
d.name = "Onsets";
|
||||
d.description = "Percussive note onset locations";
|
||||
d.unit = "";
|
||||
d.hasFixedBinCount = true;
|
||||
d.binCount = 0;
|
||||
d.hasKnownExtents = false;
|
||||
d.isQuantized = false;
|
||||
d.sampleType = OutputDescriptor::VariableSampleRate;
|
||||
d.sampleRate = m_inputSampleRate;
|
||||
list.push_back(d);
|
||||
|
||||
d.identifier = "detectionfunction";
|
||||
d.name = "Detection Function";
|
||||
d.description = "Broadband energy rise detection function";
|
||||
d.binCount = 1;
|
||||
d.isQuantized = true;
|
||||
d.quantizeStep = 1.0;
|
||||
d.sampleType = OutputDescriptor::OneSamplePerStep;
|
||||
list.push_back(d);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
PercussionOnsetDetector::FeatureSet
|
||||
PercussionOnsetDetector::process(const float *const *inputBuffers,
|
||||
Vamp::RealTime ts)
|
||||
{
|
||||
if (m_stepSize == 0) {
|
||||
cerr << "ERROR: PercussionOnsetDetector::process: "
|
||||
<< "PercussionOnsetDetector has not been initialised"
|
||||
<< endl;
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (size_t i = 1; i < m_blockSize/2; ++i) {
|
||||
|
||||
float real = inputBuffers[0][i*2];
|
||||
float imag = inputBuffers[0][i*2 + 1];
|
||||
|
||||
float sqrmag = real * real + imag * imag;
|
||||
|
||||
if (m_priorMagnitudes[i] > 0.f) {
|
||||
float diff = 10.f * log10f(sqrmag / m_priorMagnitudes[i]);
|
||||
|
||||
// std::cout << "i=" << i << ", mag=" << mag << ", prior=" << m_priorMagnitudes[i] << ", diff=" << diff << ", threshold=" << m_threshold << std::endl;
|
||||
|
||||
if (diff >= m_threshold) ++count;
|
||||
}
|
||||
|
||||
m_priorMagnitudes[i] = sqrmag;
|
||||
}
|
||||
|
||||
FeatureSet returnFeatures;
|
||||
|
||||
Feature detectionFunction;
|
||||
detectionFunction.hasTimestamp = false;
|
||||
detectionFunction.values.push_back(count);
|
||||
returnFeatures[1].push_back(detectionFunction);
|
||||
|
||||
if (m_dfMinus2 < m_dfMinus1 &&
|
||||
m_dfMinus1 >= count &&
|
||||
m_dfMinus1 > ((100 - m_sensitivity) * m_blockSize) / 200) {
|
||||
|
||||
Feature onset;
|
||||
onset.hasTimestamp = true;
|
||||
onset.timestamp = ts - Vamp::RealTime::frame2RealTime
|
||||
(m_stepSize, lrintf(m_inputSampleRate));
|
||||
returnFeatures[0].push_back(onset);
|
||||
}
|
||||
|
||||
m_dfMinus2 = m_dfMinus1;
|
||||
m_dfMinus1 = count;
|
||||
|
||||
return returnFeatures;
|
||||
}
|
||||
|
||||
PercussionOnsetDetector::FeatureSet
|
||||
PercussionOnsetDetector::getRemainingFeatures()
|
||||
{
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
90
libs/vamp-sdk/examples/PercussionOnsetDetector.h
Normal file
90
libs/vamp-sdk/examples/PercussionOnsetDetector.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 _PERCUSSION_ONSET_DETECTOR_PLUGIN_H_
|
||||
#define _PERCUSSION_ONSET_DETECTOR_PLUGIN_H_
|
||||
|
||||
#include "vamp-sdk/Plugin.h"
|
||||
|
||||
/**
|
||||
* Example plugin that detects percussive events.
|
||||
*/
|
||||
|
||||
class PercussionOnsetDetector : public Vamp::Plugin
|
||||
{
|
||||
public:
|
||||
PercussionOnsetDetector(float inputSampleRate);
|
||||
virtual ~PercussionOnsetDetector();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
void reset();
|
||||
|
||||
InputDomain getInputDomain() const { return FrequencyDomain; }
|
||||
|
||||
std::string getIdentifier() const;
|
||||
std::string getName() const;
|
||||
std::string getDescription() const;
|
||||
std::string getMaker() const;
|
||||
int getPluginVersion() const;
|
||||
std::string getCopyright() const;
|
||||
|
||||
size_t getPreferredStepSize() const;
|
||||
size_t getPreferredBlockSize() const;
|
||||
|
||||
ParameterList getParameterDescriptors() const;
|
||||
float getParameter(std::string id) const;
|
||||
void setParameter(std::string id, float value);
|
||||
|
||||
OutputList getOutputDescriptors() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers,
|
||||
Vamp::RealTime timestamp);
|
||||
|
||||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
size_t m_stepSize;
|
||||
size_t m_blockSize;
|
||||
|
||||
float m_threshold;
|
||||
float m_sensitivity;
|
||||
float *m_priorMagnitudes;
|
||||
float m_dfMinus1;
|
||||
float m_dfMinus2;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
188
libs/vamp-sdk/examples/SpectralCentroid.cpp
Normal file
188
libs/vamp-sdk/examples/SpectralCentroid.cpp
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 "SpectralCentroid.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
SpectralCentroid::SpectralCentroid(float inputSampleRate) :
|
||||
Plugin(inputSampleRate),
|
||||
m_stepSize(0),
|
||||
m_blockSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
SpectralCentroid::~SpectralCentroid()
|
||||
{
|
||||
}
|
||||
|
||||
string
|
||||
SpectralCentroid::getIdentifier() const
|
||||
{
|
||||
return "spectralcentroid";
|
||||
}
|
||||
|
||||
string
|
||||
SpectralCentroid::getName() const
|
||||
{
|
||||
return "Spectral Centroid";
|
||||
}
|
||||
|
||||
string
|
||||
SpectralCentroid::getDescription() const
|
||||
{
|
||||
return "Calculate the centroid frequency of the spectrum of the input signal";
|
||||
}
|
||||
|
||||
string
|
||||
SpectralCentroid::getMaker() const
|
||||
{
|
||||
return "Vamp SDK Example Plugins";
|
||||
}
|
||||
|
||||
int
|
||||
SpectralCentroid::getPluginVersion() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
string
|
||||
SpectralCentroid::getCopyright() const
|
||||
{
|
||||
return "Freely redistributable (BSD license)";
|
||||
}
|
||||
|
||||
bool
|
||||
SpectralCentroid::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
if (channels < getMinChannelCount() ||
|
||||
channels > getMaxChannelCount()) return false;
|
||||
|
||||
m_stepSize = stepSize;
|
||||
m_blockSize = blockSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SpectralCentroid::reset()
|
||||
{
|
||||
}
|
||||
|
||||
SpectralCentroid::OutputList
|
||||
SpectralCentroid::getOutputDescriptors() const
|
||||
{
|
||||
OutputList list;
|
||||
|
||||
OutputDescriptor d;
|
||||
d.identifier = "logcentroid";
|
||||
d.name = "Log Frequency Centroid";
|
||||
d.description = "Centroid of the log weighted frequency spectrum";
|
||||
d.unit = "Hz";
|
||||
d.hasFixedBinCount = true;
|
||||
d.binCount = 1;
|
||||
d.hasKnownExtents = false;
|
||||
d.isQuantized = false;
|
||||
d.sampleType = OutputDescriptor::OneSamplePerStep;
|
||||
list.push_back(d);
|
||||
|
||||
d.identifier = "linearcentroid";
|
||||
d.name = "Linear Frequency Centroid";
|
||||
d.description = "Centroid of the linear frequency spectrum";
|
||||
list.push_back(d);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
SpectralCentroid::FeatureSet
|
||||
SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime)
|
||||
{
|
||||
if (m_stepSize == 0) {
|
||||
cerr << "ERROR: SpectralCentroid::process: "
|
||||
<< "SpectralCentroid has not been initialised"
|
||||
<< endl;
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
double numLin = 0.0, numLog = 0.0, denom = 0.0;
|
||||
|
||||
for (size_t i = 1; i <= m_blockSize/2; ++i) {
|
||||
double freq = (double(i) * m_inputSampleRate) / m_blockSize;
|
||||
double real = inputBuffers[0][i*2];
|
||||
double imag = inputBuffers[0][i*2 + 1];
|
||||
double power = sqrt(real * real + imag * imag) / (m_blockSize/2);
|
||||
numLin += freq * power;
|
||||
numLog += log10f(freq) * power;
|
||||
denom += power;
|
||||
}
|
||||
|
||||
FeatureSet returnFeatures;
|
||||
|
||||
// std::cerr << "power " << denom << ", block size " << m_blockSize << std::endl;
|
||||
|
||||
if (denom != 0.0) {
|
||||
float centroidLin = float(numLin / denom);
|
||||
float centroidLog = powf(10, float(numLog / denom));
|
||||
|
||||
Feature feature;
|
||||
feature.hasTimestamp = false;
|
||||
if (!std::isnan(centroidLog) && !std::isinf(centroidLog)) {
|
||||
feature.values.push_back(centroidLog);
|
||||
}
|
||||
returnFeatures[0].push_back(feature);
|
||||
|
||||
feature.values.clear();
|
||||
if (!std::isnan(centroidLin) && !std::isinf(centroidLin)) {
|
||||
feature.values.push_back(centroidLin);
|
||||
}
|
||||
returnFeatures[1].push_back(feature);
|
||||
}
|
||||
|
||||
return returnFeatures;
|
||||
}
|
||||
|
||||
SpectralCentroid::FeatureSet
|
||||
SpectralCentroid::getRemainingFeatures()
|
||||
{
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
78
libs/vamp-sdk/examples/SpectralCentroid.h
Normal file
78
libs/vamp-sdk/examples/SpectralCentroid.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 _SPECTRAL_CENTROID_PLUGIN_H_
|
||||
#define _SPECTRAL_CENTROID_PLUGIN_H_
|
||||
|
||||
#include "vamp-sdk/Plugin.h"
|
||||
|
||||
/**
|
||||
* Example plugin that calculates the centre of gravity of the
|
||||
* frequency domain representation of each block of audio.
|
||||
*/
|
||||
|
||||
class SpectralCentroid : public Vamp::Plugin
|
||||
{
|
||||
public:
|
||||
SpectralCentroid(float inputSampleRate);
|
||||
virtual ~SpectralCentroid();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
void reset();
|
||||
|
||||
InputDomain getInputDomain() const { return FrequencyDomain; }
|
||||
|
||||
std::string getIdentifier() const;
|
||||
std::string getName() const;
|
||||
std::string getDescription() const;
|
||||
std::string getMaker() const;
|
||||
int getPluginVersion() const;
|
||||
std::string getCopyright() const;
|
||||
|
||||
OutputList getOutputDescriptors() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers,
|
||||
Vamp::RealTime timestamp);
|
||||
|
||||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
size_t m_stepSize;
|
||||
size_t m_blockSize;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
194
libs/vamp-sdk/examples/ZeroCrossing.cpp
Normal file
194
libs/vamp-sdk/examples/ZeroCrossing.cpp
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 "ZeroCrossing.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
|
||||
ZeroCrossing::ZeroCrossing(float inputSampleRate) :
|
||||
Plugin(inputSampleRate),
|
||||
m_stepSize(0),
|
||||
m_previousSample(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
ZeroCrossing::~ZeroCrossing()
|
||||
{
|
||||
}
|
||||
|
||||
string
|
||||
ZeroCrossing::getIdentifier() const
|
||||
{
|
||||
return "zerocrossing";
|
||||
}
|
||||
|
||||
string
|
||||
ZeroCrossing::getName() const
|
||||
{
|
||||
return "Zero Crossings";
|
||||
}
|
||||
|
||||
string
|
||||
ZeroCrossing::getDescription() const
|
||||
{
|
||||
return "Detect and count zero crossing points";
|
||||
}
|
||||
|
||||
string
|
||||
ZeroCrossing::getMaker() const
|
||||
{
|
||||
return "Vamp SDK Example Plugins";
|
||||
}
|
||||
|
||||
int
|
||||
ZeroCrossing::getPluginVersion() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
string
|
||||
ZeroCrossing::getCopyright() const
|
||||
{
|
||||
return "Freely redistributable (BSD license)";
|
||||
}
|
||||
|
||||
bool
|
||||
ZeroCrossing::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
if (channels < getMinChannelCount() ||
|
||||
channels > getMaxChannelCount()) return false;
|
||||
|
||||
m_stepSize = std::min(stepSize, blockSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ZeroCrossing::reset()
|
||||
{
|
||||
m_previousSample = 0.0f;
|
||||
}
|
||||
|
||||
ZeroCrossing::OutputList
|
||||
ZeroCrossing::getOutputDescriptors() const
|
||||
{
|
||||
OutputList list;
|
||||
|
||||
OutputDescriptor zc;
|
||||
zc.identifier = "counts";
|
||||
zc.name = "Zero Crossing Counts";
|
||||
zc.description = "The number of zero crossing points per processing block";
|
||||
zc.unit = "crossings";
|
||||
zc.hasFixedBinCount = true;
|
||||
zc.binCount = 1;
|
||||
zc.hasKnownExtents = false;
|
||||
zc.isQuantized = true;
|
||||
zc.quantizeStep = 1.0;
|
||||
zc.sampleType = OutputDescriptor::OneSamplePerStep;
|
||||
list.push_back(zc);
|
||||
|
||||
zc.identifier = "zerocrossings";
|
||||
zc.name = "Zero Crossings";
|
||||
zc.description = "The locations of zero crossing points";
|
||||
zc.unit = "";
|
||||
zc.hasFixedBinCount = true;
|
||||
zc.binCount = 0;
|
||||
zc.sampleType = OutputDescriptor::VariableSampleRate;
|
||||
zc.sampleRate = m_inputSampleRate;
|
||||
list.push_back(zc);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
ZeroCrossing::FeatureSet
|
||||
ZeroCrossing::process(const float *const *inputBuffers,
|
||||
Vamp::RealTime timestamp)
|
||||
{
|
||||
if (m_stepSize == 0) {
|
||||
cerr << "ERROR: ZeroCrossing::process: "
|
||||
<< "ZeroCrossing has not been initialised"
|
||||
<< endl;
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
float prev = m_previousSample;
|
||||
size_t count = 0;
|
||||
|
||||
FeatureSet returnFeatures;
|
||||
|
||||
for (size_t i = 0; i < m_stepSize; ++i) {
|
||||
|
||||
float sample = inputBuffers[0][i];
|
||||
bool crossing = false;
|
||||
|
||||
if (sample <= 0.0) {
|
||||
if (prev > 0.0) crossing = true;
|
||||
} else if (sample > 0.0) {
|
||||
if (prev <= 0.0) crossing = true;
|
||||
}
|
||||
|
||||
if (crossing) {
|
||||
++count;
|
||||
Feature feature;
|
||||
feature.hasTimestamp = true;
|
||||
feature.timestamp = timestamp +
|
||||
Vamp::RealTime::frame2RealTime(i, (size_t)m_inputSampleRate);
|
||||
returnFeatures[1].push_back(feature);
|
||||
}
|
||||
|
||||
prev = sample;
|
||||
}
|
||||
|
||||
m_previousSample = prev;
|
||||
|
||||
Feature feature;
|
||||
feature.hasTimestamp = false;
|
||||
feature.values.push_back(count);
|
||||
|
||||
returnFeatures[0].push_back(feature);
|
||||
return returnFeatures;
|
||||
}
|
||||
|
||||
ZeroCrossing::FeatureSet
|
||||
ZeroCrossing::getRemainingFeatures()
|
||||
{
|
||||
return FeatureSet();
|
||||
}
|
||||
|
||||
78
libs/vamp-sdk/examples/ZeroCrossing.h
Normal file
78
libs/vamp-sdk/examples/ZeroCrossing.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 _ZERO_CROSSING_PLUGIN_H_
|
||||
#define _ZERO_CROSSING_PLUGIN_H_
|
||||
|
||||
#include "vamp-sdk/Plugin.h"
|
||||
|
||||
/**
|
||||
* Example plugin that calculates the positions and density of
|
||||
* zero-crossing points in an audio waveform.
|
||||
*/
|
||||
|
||||
class ZeroCrossing : public Vamp::Plugin
|
||||
{
|
||||
public:
|
||||
ZeroCrossing(float inputSampleRate);
|
||||
virtual ~ZeroCrossing();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
void reset();
|
||||
|
||||
InputDomain getInputDomain() const { return TimeDomain; }
|
||||
|
||||
std::string getIdentifier() const;
|
||||
std::string getName() const;
|
||||
std::string getDescription() const;
|
||||
std::string getMaker() const;
|
||||
int getPluginVersion() const;
|
||||
std::string getCopyright() const;
|
||||
|
||||
OutputList getOutputDescriptors() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers,
|
||||
Vamp::RealTime timestamp);
|
||||
|
||||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
size_t m_stepSize;
|
||||
float m_previousSample;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
63
libs/vamp-sdk/examples/plugins.cpp
Normal file
63
libs/vamp-sdk/examples/plugins.cpp
Normal file
|
|
@ -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 Chris Cannam.
|
||||
|
||||
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/vamp.h"
|
||||
#include "vamp-sdk/PluginAdapter.h"
|
||||
|
||||
#include "ZeroCrossing.h"
|
||||
#include "SpectralCentroid.h"
|
||||
#include "PercussionOnsetDetector.h"
|
||||
#include "AmplitudeFollower.h"
|
||||
|
||||
static Vamp::PluginAdapter<ZeroCrossing> zeroCrossingAdapter;
|
||||
static Vamp::PluginAdapter<SpectralCentroid> spectralCentroidAdapter;
|
||||
static Vamp::PluginAdapter<PercussionOnsetDetector> percussionOnsetAdapter;
|
||||
static Vamp::PluginAdapter<AmplitudeFollower> amplitudeAdapter;
|
||||
|
||||
const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
|
||||
unsigned int index)
|
||||
{
|
||||
if (version < 1) return 0;
|
||||
|
||||
switch (index) {
|
||||
case 0: return zeroCrossingAdapter.getDescriptor();
|
||||
case 1: return spectralCentroidAdapter.getDescriptor();
|
||||
case 2: return percussionOnsetAdapter.getDescriptor();
|
||||
case 3: return amplitudeAdapter.getDescriptor();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
5
libs/vamp-sdk/examples/vamp-example-plugins.cat
Normal file
5
libs/vamp-sdk/examples/vamp-example-plugins.cat
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
vamp:vamp-example-plugins:zerocrossing::Low Level Features
|
||||
vamp:vamp-example-plugins:spectralcentroid::Low Level Features
|
||||
vamp:vamp-example-plugins:percussiononsets::Time > Onsets
|
||||
vamp:vamp-example-plugins:amplitudefollower::Low Level Features
|
||||
|
||||
75
libs/vamp-sdk/host/system.h
Normal file
75
libs/vamp-sdk/host/system.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 _SYSTEM_H_
|
||||
#define _SYSTEM_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define DLOPEN(a,b) LoadLibrary((a).c_str())
|
||||
#define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b))
|
||||
#define DLCLOSE(a) FreeLibrary((HINSTANCE)(a))
|
||||
#define DLERROR() ""
|
||||
|
||||
#define PLUGIN_SUFFIX "dll"
|
||||
|
||||
#else
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define DLOPEN(a,b) dlopen((a).c_str(),(b))
|
||||
#define DLSYM(a,b) dlsym((a),(b))
|
||||
#define DLCLOSE(a) dlclose((a))
|
||||
#define DLERROR() dlerror()
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#define PLUGIN_SUFFIX "dylib"
|
||||
#define HAVE_OPENDIR 1
|
||||
|
||||
#else
|
||||
|
||||
#define PLUGIN_SUFFIX "so"
|
||||
#define HAVE_OPENDIR 1
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
#endif
|
||||
|
||||
492
libs/vamp-sdk/host/vamp-simple-host.cpp
Normal file
492
libs/vamp-sdk/host/vamp-simple-host.cpp
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
FFT code from Don Cross's public domain FFT implementation.
|
||||
|
||||
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-sdk/PluginHostAdapter.h"
|
||||
#include "vamp-sdk/hostext/PluginChannelAdapter.h"
|
||||
#include "vamp-sdk/hostext/PluginInputDomainAdapter.h"
|
||||
#include "vamp-sdk/hostext/PluginLoader.h"
|
||||
#include "vamp/vamp.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sndfile.h>
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ofstream;
|
||||
using std::ios;
|
||||
|
||||
using Vamp::HostExt::PluginLoader;
|
||||
|
||||
#define HOST_VERSION "1.1"
|
||||
|
||||
void printFeatures(int, int, int, Vamp::Plugin::FeatureSet, ofstream *);
|
||||
void transformInput(float *, size_t);
|
||||
void fft(unsigned int, bool, double *, double *, double *, double *);
|
||||
void printPluginPath(bool verbose);
|
||||
void enumeratePlugins();
|
||||
void listPluginsInLibrary(string soname);
|
||||
int runPlugin(string myname, string soname, string id, string output,
|
||||
int outputNo, string inputFile, string outfilename);
|
||||
|
||||
void usage(const char *name)
|
||||
{
|
||||
cerr << "\n"
|
||||
<< name << ": A simple Vamp plugin host.\n\n"
|
||||
"Centre for Digital Music, Queen Mary, University of London.\n"
|
||||
"Copyright 2006-2007 Chris Cannam and QMUL.\n"
|
||||
"Freely redistributable; published under a BSD-style license.\n\n"
|
||||
"Usage:\n\n"
|
||||
" " << name << " pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin[:output] file.wav [-o outfile.txt]\n"
|
||||
" " << name << " pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin file.wav [outputno] [-o outfile.txt]\n\n"
|
||||
" -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n"
|
||||
" audio data in \"file.wav\", retrieving the named \"output\", or output\n"
|
||||
" number \"outputno\" (the first output by default) and dumping it to\n"
|
||||
" standard output, or to \"outfile.txt\" if the -o option is given.\n\n"
|
||||
" \"pluginlibrary\" should be a library name, not a file path; the\n"
|
||||
" standard Vamp library search path will be used to locate it. If\n"
|
||||
" a file path is supplied, the directory part(s) will be ignored.\n\n"
|
||||
" " << name << " -l\n\n"
|
||||
" -- List the plugin libraries and Vamp plugins in the library search path.\n\n"
|
||||
" " << name << " -p\n\n"
|
||||
" -- Print out the Vamp library search path.\n\n"
|
||||
" " << name << " -v\n\n"
|
||||
" -- Display version information only.\n\n"
|
||||
<< endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *scooter = argv[0];
|
||||
char *name = 0;
|
||||
while (scooter && *scooter) {
|
||||
if (*scooter == '/' || *scooter == '\\') name = ++scooter;
|
||||
else ++scooter;
|
||||
}
|
||||
if (!name || !*name) name = argv[0];
|
||||
|
||||
if (argc < 2) usage(name);
|
||||
|
||||
if (argc == 2) {
|
||||
|
||||
if (!strcmp(argv[1], "-v")) {
|
||||
|
||||
cout << "Simple Vamp plugin host version: " << HOST_VERSION << endl
|
||||
<< "Vamp API version: " << VAMP_API_VERSION << endl
|
||||
<< "Vamp SDK version: " << VAMP_SDK_VERSION << endl;
|
||||
return 0;
|
||||
|
||||
} else if (!strcmp(argv[1], "-l")) {
|
||||
|
||||
printPluginPath(true);
|
||||
enumeratePlugins();
|
||||
return 0;
|
||||
|
||||
} else if (!strcmp(argv[1], "-p")) {
|
||||
|
||||
printPluginPath(false);
|
||||
return 0;
|
||||
|
||||
} else usage(name);
|
||||
}
|
||||
|
||||
if (argc < 3) usage(name);
|
||||
|
||||
string soname = argv[1];
|
||||
string wavname = argv[2];
|
||||
string plugid = "";
|
||||
string output = "";
|
||||
int outputNo = -1;
|
||||
string outfilename;
|
||||
|
||||
if (argc >= 4) {
|
||||
|
||||
int idx = 3;
|
||||
|
||||
if (isdigit(*argv[idx])) {
|
||||
outputNo = atoi(argv[idx++]);
|
||||
}
|
||||
|
||||
if (argc == idx + 2) {
|
||||
if (!strcmp(argv[idx], "-o")) {
|
||||
outfilename = argv[idx+1];
|
||||
} else usage(name);
|
||||
} else if (argc != idx) {
|
||||
(usage(name));
|
||||
}
|
||||
}
|
||||
|
||||
cerr << endl << name << ": Running..." << endl;
|
||||
|
||||
cerr << "Reading file: \"" << wavname << "\", writing to ";
|
||||
if (outfilename == "") {
|
||||
cerr << "standard output" << endl;
|
||||
} else {
|
||||
cerr << "\"" << outfilename << "\"" << endl;
|
||||
}
|
||||
|
||||
string::size_type sep = soname.find(':');
|
||||
|
||||
if (sep != string::npos) {
|
||||
plugid = soname.substr(sep + 1);
|
||||
soname = soname.substr(0, sep);
|
||||
|
||||
sep = plugid.find(':');
|
||||
if (sep != string::npos) {
|
||||
output = plugid.substr(sep + 1);
|
||||
plugid = plugid.substr(0, sep);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugid == "") {
|
||||
usage(name);
|
||||
}
|
||||
|
||||
if (output != "" && outputNo != -1) {
|
||||
usage(name);
|
||||
}
|
||||
|
||||
if (output == "" && outputNo == -1) {
|
||||
outputNo = 0;
|
||||
}
|
||||
|
||||
return runPlugin(name, soname, plugid, output, outputNo,
|
||||
wavname, outfilename);
|
||||
}
|
||||
|
||||
|
||||
int runPlugin(string myname, string soname, string id,
|
||||
string output, int outputNo, string wavname,
|
||||
string outfilename)
|
||||
{
|
||||
PluginLoader *loader = PluginLoader::getInstance();
|
||||
|
||||
PluginLoader::PluginKey key = loader->composePluginKey(soname, id);
|
||||
|
||||
SNDFILE *sndfile;
|
||||
SF_INFO sfinfo;
|
||||
memset(&sfinfo, 0, sizeof(SF_INFO));
|
||||
|
||||
sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo);
|
||||
if (!sndfile) {
|
||||
cerr << myname << ": ERROR: Failed to open input file \""
|
||||
<< wavname << "\": " << sf_strerror(sndfile) << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ofstream *out = 0;
|
||||
if (outfilename != "") {
|
||||
out = new ofstream(outfilename.c_str(), ios::out);
|
||||
if (!*out) {
|
||||
cerr << myname << ": ERROR: Failed to open output file \""
|
||||
<< outfilename << "\" for writing" << endl;
|
||||
delete out;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Vamp::Plugin *plugin = loader->loadPlugin
|
||||
(key, sfinfo.samplerate, PluginLoader::ADAPT_ALL);
|
||||
if (!plugin) {
|
||||
cerr << myname << ": ERROR: Failed to load plugin \"" << id
|
||||
<< "\" from library \"" << soname << "\"" << endl;
|
||||
sf_close(sndfile);
|
||||
if (out) {
|
||||
out->close();
|
||||
delete out;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
|
||||
|
||||
int blockSize = plugin->getPreferredBlockSize();
|
||||
int stepSize = plugin->getPreferredStepSize();
|
||||
|
||||
if (blockSize == 0) blockSize = 1024;
|
||||
if (stepSize == 0) {
|
||||
if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) {
|
||||
stepSize = blockSize/2;
|
||||
} else {
|
||||
stepSize = blockSize;
|
||||
}
|
||||
}
|
||||
|
||||
int channels = sfinfo.channels;
|
||||
|
||||
float *filebuf = new float[blockSize * channels];
|
||||
float **plugbuf = new float*[channels];
|
||||
for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
|
||||
|
||||
cerr << "Using block size = " << blockSize << ", step size = "
|
||||
<< stepSize << endl;
|
||||
|
||||
int minch = plugin->getMinChannelCount();
|
||||
int maxch = plugin->getMaxChannelCount();
|
||||
cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
|
||||
cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
|
||||
|
||||
Vamp::Plugin::OutputList outputs = plugin->getOutputDescriptors();
|
||||
Vamp::Plugin::OutputDescriptor od;
|
||||
|
||||
int returnValue = 1;
|
||||
int progress = 0;
|
||||
|
||||
if (outputs.empty()) {
|
||||
cerr << "ERROR: Plugin has no outputs!" << endl;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (outputNo < 0) {
|
||||
|
||||
for (size_t oi = 0; oi < outputs.size(); ++oi) {
|
||||
if (outputs[oi].identifier == output) {
|
||||
outputNo = oi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outputNo < 0) {
|
||||
cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
|
||||
goto done;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (int(outputs.size()) <= outputNo) {
|
||||
cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
od = outputs[outputNo];
|
||||
cerr << "Output is: \"" << od.identifier << "\"" << endl;
|
||||
|
||||
if (!plugin->initialise(channels, stepSize, blockSize)) {
|
||||
cerr << "ERROR: Plugin initialise (channels = " << channels
|
||||
<< ", stepSize = " << stepSize << ", blockSize = "
|
||||
<< blockSize << ") failed." << endl;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sfinfo.frames; i += stepSize) {
|
||||
|
||||
int count;
|
||||
|
||||
if (sf_seek(sndfile, i, SEEK_SET) < 0) {
|
||||
cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
|
||||
cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int c = 0; c < channels; ++c) {
|
||||
int j = 0;
|
||||
while (j < count) {
|
||||
plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
|
||||
++j;
|
||||
}
|
||||
while (j < blockSize) {
|
||||
plugbuf[c][j] = 0.0f;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
printFeatures
|
||||
(i, sfinfo.samplerate, outputNo, plugin->process
|
||||
(plugbuf, Vamp::RealTime::frame2RealTime(i, sfinfo.samplerate)),
|
||||
out);
|
||||
|
||||
int pp = progress;
|
||||
progress = lrintf((float(i) / sfinfo.frames) * 100.f);
|
||||
if (progress != pp && out) {
|
||||
cerr << "\r" << progress << "%";
|
||||
}
|
||||
}
|
||||
if (out) cerr << "\rDone" << endl;
|
||||
|
||||
printFeatures(sfinfo.frames, sfinfo.samplerate, outputNo,
|
||||
plugin->getRemainingFeatures(), out);
|
||||
|
||||
returnValue = 0;
|
||||
|
||||
done:
|
||||
delete plugin;
|
||||
if (out) {
|
||||
out->close();
|
||||
delete out;
|
||||
}
|
||||
sf_close(sndfile);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void
|
||||
printPluginPath(bool verbose)
|
||||
{
|
||||
if (verbose) {
|
||||
cout << "\nVamp plugin search path: ";
|
||||
}
|
||||
|
||||
vector<string> path = Vamp::PluginHostAdapter::getPluginPath();
|
||||
for (size_t i = 0; i < path.size(); ++i) {
|
||||
if (verbose) {
|
||||
cout << "[" << path[i] << "]";
|
||||
} else {
|
||||
cout << path[i] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) cout << endl;
|
||||
}
|
||||
|
||||
void
|
||||
enumeratePlugins()
|
||||
{
|
||||
PluginLoader *loader = PluginLoader::getInstance();
|
||||
|
||||
cout << "\nVamp plugin libraries found in search path:" << endl;
|
||||
|
||||
std::vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
|
||||
typedef std::multimap<std::string, PluginLoader::PluginKey>
|
||||
LibraryMap;
|
||||
LibraryMap libraryMap;
|
||||
|
||||
for (size_t i = 0; i < plugins.size(); ++i) {
|
||||
std::string path = loader->getLibraryPathForPlugin(plugins[i]);
|
||||
libraryMap.insert(LibraryMap::value_type(path, plugins[i]));
|
||||
}
|
||||
|
||||
std::string prevPath = "";
|
||||
int index = 0;
|
||||
|
||||
for (LibraryMap::iterator i = libraryMap.begin();
|
||||
i != libraryMap.end(); ++i) {
|
||||
|
||||
std::string path = i->first;
|
||||
PluginLoader::PluginKey key = i->second;
|
||||
|
||||
if (path != prevPath) {
|
||||
prevPath = path;
|
||||
index = 0;
|
||||
cout << "\n " << path << ":" << endl;
|
||||
}
|
||||
|
||||
Vamp::Plugin *plugin = loader->loadPlugin(key, 48000);
|
||||
if (plugin) {
|
||||
|
||||
char c = char('A' + index);
|
||||
if (c > 'Z') c = char('a' + (index - 26));
|
||||
|
||||
cout << " [" << c << "] [v"
|
||||
<< plugin->getVampApiVersion() << "] "
|
||||
<< plugin->getName() << ", \""
|
||||
<< plugin->getIdentifier() << "\"" << " ["
|
||||
<< plugin->getMaker() << "]" << endl;
|
||||
|
||||
PluginLoader::PluginCategoryHierarchy category =
|
||||
loader->getPluginCategory(key);
|
||||
if (!category.empty()) {
|
||||
cout << " ";
|
||||
for (size_t ci = 0; ci < category.size(); ++ci) {
|
||||
cout << " > " << category[ci];
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if (plugin->getDescription() != "") {
|
||||
cout << " - " << plugin->getDescription() << endl;
|
||||
}
|
||||
|
||||
Vamp::Plugin::OutputList outputs =
|
||||
plugin->getOutputDescriptors();
|
||||
|
||||
if (outputs.size() > 1) {
|
||||
for (size_t j = 0; j < outputs.size(); ++j) {
|
||||
cout << " (" << j << ") "
|
||||
<< outputs[j].name << ", \""
|
||||
<< outputs[j].identifier << "\"" << endl;
|
||||
if (outputs[j].description != "") {
|
||||
cout << " - "
|
||||
<< outputs[j].description << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++index;
|
||||
|
||||
delete plugin;
|
||||
}
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void
|
||||
printFeatures(int frame, int sr, int output,
|
||||
Vamp::Plugin::FeatureSet features, ofstream *out)
|
||||
{
|
||||
for (unsigned int i = 0; i < features[output].size(); ++i) {
|
||||
|
||||
Vamp::RealTime rt = Vamp::RealTime::frame2RealTime(frame, sr);
|
||||
|
||||
if (features[output][i].hasTimestamp) {
|
||||
rt = features[output][i].timestamp;
|
||||
}
|
||||
|
||||
(out ? *out : cout) << rt.toString() << ":";
|
||||
|
||||
for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
|
||||
(out ? *out : cout) << " " << features[output][i].values[j];
|
||||
}
|
||||
|
||||
(out ? *out : cout) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
405
libs/vamp-sdk/vamp-sdk/Plugin.h
Normal file
405
libs/vamp-sdk/vamp-sdk/Plugin.h
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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_PLUGIN_H_
|
||||
#define _VAMP_PLUGIN_H_
|
||||
|
||||
#include "PluginBase.h"
|
||||
#include "RealTime.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
/**
|
||||
* \class Plugin Plugin.h <vamp-sdk/Plugin.h>
|
||||
*
|
||||
* Vamp::Plugin is a base class for plugin instance classes
|
||||
* that provide feature extraction from audio or related data.
|
||||
*
|
||||
* In most cases, the input will be audio and the output will be a
|
||||
* stream of derived data at a lower sampling resolution than the
|
||||
* input.
|
||||
*
|
||||
* Note that this class inherits several abstract methods from
|
||||
* PluginBase. These must be implemented by the subclass.
|
||||
*
|
||||
*
|
||||
* PLUGIN LIFECYCLE
|
||||
*
|
||||
* Feature extraction plugins are managed differently from real-time
|
||||
* plugins (such as VST effects). The main difference is that the
|
||||
* parameters for a feature extraction plugin are configured before
|
||||
* the plugin is used, and do not change during use.
|
||||
*
|
||||
* 1. Host constructs the plugin, passing it the input sample rate.
|
||||
* The plugin may do basic initialisation, but should not do anything
|
||||
* computationally expensive at this point. You must make sure your
|
||||
* plugin is cheap to construct, otherwise you'll seriously affect the
|
||||
* startup performance of almost all hosts. If you have serious
|
||||
* initialisation to do, the proper place is in initialise() (step 5).
|
||||
*
|
||||
* 2. Host may query the plugin's available outputs.
|
||||
*
|
||||
* 3. Host queries programs and parameter descriptors, and may set
|
||||
* some or all of them. Parameters that are not explicitly set should
|
||||
* take their default values as specified in the parameter descriptor.
|
||||
* When a program is set, the parameter values may change and the host
|
||||
* will re-query them to check.
|
||||
*
|
||||
* 4. Host queries the preferred step size, block size and number of
|
||||
* channels. These may all vary depending on the parameter values.
|
||||
* (Note however that you cannot make the number of distinct outputs
|
||||
* dependent on parameter values.)
|
||||
*
|
||||
* 5. Plugin is properly initialised with a call to initialise. This
|
||||
* fixes the step size, block size, and number of channels, as well as
|
||||
* all of the parameter and program settings. If the values passed in
|
||||
* to initialise do not match the plugin's advertised preferred values
|
||||
* from step 4, the plugin may refuse to initialise and return false
|
||||
* (although if possible it should accept the new values). Any
|
||||
* computationally expensive setup code should take place here.
|
||||
*
|
||||
* 6. Host finally checks the number of values, resolution, extents
|
||||
* etc per output (which may vary depending on the number of channels,
|
||||
* step size and block size as well as the parameter values).
|
||||
*
|
||||
* 7. Host will repeatedly call the process method to pass in blocks
|
||||
* of input data. This method may return features extracted from that
|
||||
* data (if the plugin is causal).
|
||||
*
|
||||
* 8. Host will call getRemainingFeatures exactly once, after all the
|
||||
* input data has been processed. This may return any non-causal or
|
||||
* leftover features.
|
||||
*
|
||||
* 9. At any point after initialise was called, the host may
|
||||
* optionally call the reset method and restart processing. (This
|
||||
* does not mean it can change the parameters, which are fixed from
|
||||
* initialise until destruction.)
|
||||
*
|
||||
* A plugin does not need to handle the case where setParameter or
|
||||
* selectProgram is called after initialise has been called. It's the
|
||||
* host's responsibility not to do that. Similarly, the plugin may
|
||||
* safely assume that initialise is called no more than once.
|
||||
*/
|
||||
|
||||
class Plugin : public PluginBase
|
||||
{
|
||||
public:
|
||||
virtual ~Plugin() { }
|
||||
|
||||
/**
|
||||
* Initialise a plugin to prepare it for use with the given number
|
||||
* of input channels, step size (window increment, in sample
|
||||
* frames) and block size (window size, in sample frames).
|
||||
*
|
||||
* The input sample rate should have been already specified at
|
||||
* construction time.
|
||||
*
|
||||
* Return true for successful initialisation, false if the number
|
||||
* of input channels, step size and/or block size cannot be
|
||||
* supported.
|
||||
*/
|
||||
virtual bool initialise(size_t inputChannels,
|
||||
size_t stepSize,
|
||||
size_t blockSize) = 0;
|
||||
|
||||
/**
|
||||
* Reset the plugin after use, to prepare it for another clean
|
||||
* run. Not called for the first initialisation (i.e. initialise
|
||||
* must also do a reset).
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
|
||||
enum InputDomain { TimeDomain, FrequencyDomain };
|
||||
|
||||
/**
|
||||
* Get the plugin's required input domain. If this is TimeDomain,
|
||||
* the samples provided to the process() function (below) will be
|
||||
* in the time domain, as for a traditional audio processing
|
||||
* plugin. If this is FrequencyDomain, the host will carry out a
|
||||
* windowed FFT of size equal to the negotiated block size on the
|
||||
* data before passing the frequency bin data in to process().
|
||||
* The plugin does not get to choose the window type -- the host
|
||||
* will either let the user do so, or will use a Hanning window.
|
||||
*/
|
||||
virtual InputDomain getInputDomain() const = 0;
|
||||
|
||||
/**
|
||||
* Get the preferred block size (window size -- the number of
|
||||
* sample frames passed in each block to the process() function).
|
||||
* This should be called before initialise().
|
||||
*
|
||||
* A plugin that can handle any block size may return 0. The
|
||||
* final block size will be set in the initialise() call.
|
||||
*/
|
||||
virtual size_t getPreferredBlockSize() const { return 0; }
|
||||
|
||||
/**
|
||||
* Get the preferred step size (window increment -- the distance
|
||||
* in sample frames between the start frames of consecutive blocks
|
||||
* passed to the process() function) for the plugin. This should
|
||||
* be called before initialise().
|
||||
*
|
||||
* A plugin may return 0 if it has no particular interest in the
|
||||
* step size. In this case, the host should make the step size
|
||||
* equal to the block size if the plugin is accepting input in the
|
||||
* time domain. If the plugin is accepting input in the frequency
|
||||
* domain, the host may use any step size. The final step size
|
||||
* will be set in the initialise() call.
|
||||
*/
|
||||
virtual size_t getPreferredStepSize() const { return 0; }
|
||||
|
||||
/**
|
||||
* Get the minimum supported number of input channels.
|
||||
*/
|
||||
virtual size_t getMinChannelCount() const { return 1; }
|
||||
|
||||
/**
|
||||
* Get the maximum supported number of input channels.
|
||||
*/
|
||||
virtual size_t getMaxChannelCount() const { return 1; }
|
||||
|
||||
struct OutputDescriptor
|
||||
{
|
||||
/**
|
||||
* The name of the output, in computer-usable form. Should be
|
||||
* reasonably short and without whitespace or punctuation, using
|
||||
* the characters [a-zA-Z0-9_] only.
|
||||
* Example: "zero_crossing_count"
|
||||
*/
|
||||
std::string identifier;
|
||||
|
||||
/**
|
||||
* The human-readable name of the output.
|
||||
* Example: "Zero Crossing Counts"
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* A human-readable short text describing the output. May be
|
||||
* empty if the name has said it all already.
|
||||
* Example: "The number of zero crossing points per processing block"
|
||||
*/
|
||||
std::string description;
|
||||
|
||||
/**
|
||||
* The unit of the output, in human-readable form.
|
||||
*/
|
||||
std::string unit;
|
||||
|
||||
/**
|
||||
* True if the output has the same number of values per sample
|
||||
* for every output sample. Outputs for which this is false
|
||||
* are unlikely to be very useful in a general-purpose host.
|
||||
*/
|
||||
bool hasFixedBinCount;
|
||||
|
||||
/**
|
||||
* The number of values per result of the output. Undefined
|
||||
* if hasFixedBinCount is false. If this is zero, the output
|
||||
* is point data (i.e. only the time of each output is of
|
||||
* interest, the value list will be empty).
|
||||
*/
|
||||
size_t binCount;
|
||||
|
||||
/**
|
||||
* The (human-readable) names of each of the bins, if
|
||||
* appropriate. This is always optional.
|
||||
*/
|
||||
std::vector<std::string> binNames;
|
||||
|
||||
/**
|
||||
* True if the results in each output bin fall within a fixed
|
||||
* numeric range (minimum and maximum values). Undefined if
|
||||
* binCount is zero.
|
||||
*/
|
||||
bool hasKnownExtents;
|
||||
|
||||
/**
|
||||
* Minimum value of the results in the output. Undefined if
|
||||
* hasKnownExtents is false or binCount is zero.
|
||||
*/
|
||||
float minValue;
|
||||
|
||||
/**
|
||||
* Maximum value of the results in the output. Undefined if
|
||||
* hasKnownExtents is false or binCount is zero.
|
||||
*/
|
||||
float maxValue;
|
||||
|
||||
/**
|
||||
* True if the output values are quantized to a particular
|
||||
* resolution. Undefined if binCount is zero.
|
||||
*/
|
||||
bool isQuantized;
|
||||
|
||||
/**
|
||||
* Quantization resolution of the output values (e.g. 1.0 if
|
||||
* they are all integers). Undefined if isQuantized is false
|
||||
* or binCount is zero.
|
||||
*/
|
||||
float quantizeStep;
|
||||
|
||||
enum SampleType {
|
||||
|
||||
/// Results from each process() align with that call's block start
|
||||
OneSamplePerStep,
|
||||
|
||||
/// Results are evenly spaced in time (sampleRate specified below)
|
||||
FixedSampleRate,
|
||||
|
||||
/// Results are unevenly spaced and have individual timestamps
|
||||
VariableSampleRate
|
||||
};
|
||||
|
||||
/**
|
||||
* Positioning in time of the output results.
|
||||
*/
|
||||
SampleType sampleType;
|
||||
|
||||
/**
|
||||
* Sample rate of the output results, as samples per second.
|
||||
* Undefined if sampleType is OneSamplePerStep.
|
||||
*
|
||||
* If sampleType is VariableSampleRate and this value is
|
||||
* non-zero, then it may be used to calculate a resolution for
|
||||
* the output (i.e. the "duration" of each sample, in time,
|
||||
* will be 1/sampleRate seconds). It's recommended to set
|
||||
* this to zero if that behaviour is not desired.
|
||||
*/
|
||||
float sampleRate;
|
||||
};
|
||||
|
||||
typedef std::vector<OutputDescriptor> OutputList;
|
||||
|
||||
/**
|
||||
* Get the outputs of this plugin. An output's index in this list
|
||||
* is used as its numeric index when looking it up in the
|
||||
* FeatureSet returned from the process() call.
|
||||
*/
|
||||
virtual OutputList getOutputDescriptors() const = 0;
|
||||
|
||||
struct Feature
|
||||
{
|
||||
/**
|
||||
* True if an output feature has its own timestamp. This is
|
||||
* mandatory if the output has VariableSampleRate, and is
|
||||
* likely to be disregarded otherwise.
|
||||
*/
|
||||
bool hasTimestamp;
|
||||
|
||||
/**
|
||||
* Timestamp of the output feature. This is mandatory if the
|
||||
* output has VariableSampleRate, and is likely to be
|
||||
* disregarded otherwise. Undefined if hasTimestamp is false.
|
||||
*/
|
||||
RealTime timestamp;
|
||||
|
||||
/**
|
||||
* Results for a single sample of this feature. If the output
|
||||
* hasFixedBinCount, there must be the same number of values
|
||||
* as the output's binCount count.
|
||||
*/
|
||||
std::vector<float> values;
|
||||
|
||||
/**
|
||||
* Label for the sample of this feature.
|
||||
*/
|
||||
std::string label;
|
||||
};
|
||||
|
||||
typedef std::vector<Feature> FeatureList;
|
||||
typedef std::map<int, FeatureList> FeatureSet; // key is output no
|
||||
|
||||
/**
|
||||
* Process a single block of input data.
|
||||
*
|
||||
* If the plugin's inputDomain is TimeDomain, inputBuffers will
|
||||
* point to one array of floats per input channel, and each of
|
||||
* these arrays will contain blockSize consecutive audio samples
|
||||
* (the host will zero-pad as necessary). The timestamp will be
|
||||
* the real time in seconds of the start of the supplied block of
|
||||
* samples.
|
||||
*
|
||||
* If the plugin's inputDomain is FrequencyDomain, inputBuffers
|
||||
* will point to one array of floats per input channel, and each
|
||||
* of these arrays will contain blockSize/2+1 consecutive pairs of
|
||||
* real and imaginary component floats corresponding to bins
|
||||
* 0..(blockSize/2) of the FFT output. That is, bin 0 (the first
|
||||
* pair of floats) contains the DC output, up to bin blockSize/2
|
||||
* which contains the Nyquist-frequency output. There will
|
||||
* therefore be blockSize+2 floats per channel in total. The
|
||||
* timestamp will be the real time in seconds of the centre of the
|
||||
* FFT input window (i.e. the very first block passed to process
|
||||
* might contain the FFT of half a block of zero samples and the
|
||||
* first half-block of the actual data, with a timestamp of zero).
|
||||
*
|
||||
* Return any features that have become available after this
|
||||
* process call. (These do not necessarily have to fall within
|
||||
* the process block, except for OneSamplePerStep outputs.)
|
||||
*/
|
||||
virtual FeatureSet process(const float *const *inputBuffers,
|
||||
RealTime timestamp) = 0;
|
||||
|
||||
/**
|
||||
* After all blocks have been processed, calculate and return any
|
||||
* remaining features derived from the complete input.
|
||||
*/
|
||||
virtual FeatureSet getRemainingFeatures() = 0;
|
||||
|
||||
/**
|
||||
* Used to distinguish between Vamp::Plugin and other potential
|
||||
* sibling subclasses of PluginBase. Do not reimplement this
|
||||
* function in your subclass.
|
||||
*/
|
||||
virtual std::string getType() const { return "Feature Extraction Plugin"; }
|
||||
|
||||
protected:
|
||||
Plugin(float inputSampleRate) :
|
||||
m_inputSampleRate(inputSampleRate) { }
|
||||
|
||||
float m_inputSampleRate;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
851
libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp
Normal file
851
libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp
Normal file
|
|
@ -0,0 +1,851 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 "PluginAdapter.h"
|
||||
|
||||
//#define DEBUG_PLUGIN_ADAPTER 1
|
||||
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
class PluginAdapterBase::Impl
|
||||
{
|
||||
public:
|
||||
Impl(PluginAdapterBase *);
|
||||
~Impl();
|
||||
|
||||
const VampPluginDescriptor *getDescriptor();
|
||||
|
||||
protected:
|
||||
PluginAdapterBase *m_base;
|
||||
|
||||
static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc,
|
||||
float inputSampleRate);
|
||||
|
||||
static void vampCleanup(VampPluginHandle handle);
|
||||
|
||||
static int vampInitialise(VampPluginHandle handle, unsigned int channels,
|
||||
unsigned int stepSize, unsigned int blockSize);
|
||||
|
||||
static void vampReset(VampPluginHandle handle);
|
||||
|
||||
static float vampGetParameter(VampPluginHandle handle, int param);
|
||||
static void vampSetParameter(VampPluginHandle handle, int param, float value);
|
||||
|
||||
static unsigned int vampGetCurrentProgram(VampPluginHandle handle);
|
||||
static void vampSelectProgram(VampPluginHandle handle, unsigned int program);
|
||||
|
||||
static unsigned int vampGetPreferredStepSize(VampPluginHandle handle);
|
||||
static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle);
|
||||
static unsigned int vampGetMinChannelCount(VampPluginHandle handle);
|
||||
static unsigned int vampGetMaxChannelCount(VampPluginHandle handle);
|
||||
|
||||
static unsigned int vampGetOutputCount(VampPluginHandle handle);
|
||||
|
||||
static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle,
|
||||
unsigned int i);
|
||||
|
||||
static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
|
||||
|
||||
static VampFeatureList *vampProcess(VampPluginHandle handle,
|
||||
const float *const *inputBuffers,
|
||||
int sec,
|
||||
int nsec);
|
||||
|
||||
static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
|
||||
|
||||
static void vampReleaseFeatureSet(VampFeatureList *fs);
|
||||
|
||||
void cleanup(Plugin *plugin);
|
||||
void checkOutputMap(Plugin *plugin);
|
||||
unsigned int getOutputCount(Plugin *plugin);
|
||||
VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
|
||||
unsigned int i);
|
||||
VampFeatureList *process(Plugin *plugin,
|
||||
const float *const *inputBuffers,
|
||||
int sec, int nsec);
|
||||
VampFeatureList *getRemainingFeatures(Plugin *plugin);
|
||||
VampFeatureList *convertFeatures(Plugin *plugin,
|
||||
const Plugin::FeatureSet &features);
|
||||
|
||||
// maps both plugins and descriptors to adapters
|
||||
typedef std::map<const void *, Impl *> AdapterMap;
|
||||
static AdapterMap *m_adapterMap;
|
||||
static Impl *lookupAdapter(VampPluginHandle);
|
||||
|
||||
bool m_populated;
|
||||
VampPluginDescriptor m_descriptor;
|
||||
Plugin::ParameterList m_parameters;
|
||||
Plugin::ProgramList m_programs;
|
||||
|
||||
typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
|
||||
OutputMap m_pluginOutputs;
|
||||
|
||||
std::map<Plugin *, VampFeatureList *> m_fs;
|
||||
std::map<Plugin *, std::vector<size_t> > m_fsizes;
|
||||
std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes;
|
||||
void resizeFS(Plugin *plugin, int n);
|
||||
void resizeFL(Plugin *plugin, int n, size_t sz);
|
||||
void resizeFV(Plugin *plugin, int n, int j, size_t sz);
|
||||
};
|
||||
|
||||
PluginAdapterBase::PluginAdapterBase()
|
||||
{
|
||||
m_impl = new Impl(this);
|
||||
}
|
||||
|
||||
PluginAdapterBase::~PluginAdapterBase()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
const VampPluginDescriptor *
|
||||
PluginAdapterBase::getDescriptor()
|
||||
{
|
||||
return m_impl->getDescriptor();
|
||||
}
|
||||
|
||||
PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
|
||||
m_base(base),
|
||||
m_populated(false)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
const VampPluginDescriptor *
|
||||
PluginAdapterBase::Impl::getDescriptor()
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl;
|
||||
#endif
|
||||
|
||||
if (m_populated) return &m_descriptor;
|
||||
|
||||
Plugin *plugin = m_base->createPlugin(48000);
|
||||
|
||||
if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
|
||||
std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
|
||||
<< "Plugin object API version "
|
||||
<< plugin->getVampApiVersion()
|
||||
<< " does not match actual API version "
|
||||
<< VAMP_API_VERSION << std::endl;
|
||||
delete plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_parameters = plugin->getParameterDescriptors();
|
||||
m_programs = plugin->getPrograms();
|
||||
|
||||
m_descriptor.vampApiVersion = plugin->getVampApiVersion();
|
||||
m_descriptor.identifier = strdup(plugin->getIdentifier().c_str());
|
||||
m_descriptor.name = strdup(plugin->getName().c_str());
|
||||
m_descriptor.description = strdup(plugin->getDescription().c_str());
|
||||
m_descriptor.maker = strdup(plugin->getMaker().c_str());
|
||||
m_descriptor.pluginVersion = plugin->getPluginVersion();
|
||||
m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
|
||||
|
||||
m_descriptor.parameterCount = m_parameters.size();
|
||||
m_descriptor.parameters = (const VampParameterDescriptor **)
|
||||
malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < m_parameters.size(); ++i) {
|
||||
VampParameterDescriptor *desc = (VampParameterDescriptor *)
|
||||
malloc(sizeof(VampParameterDescriptor));
|
||||
desc->identifier = strdup(m_parameters[i].identifier.c_str());
|
||||
desc->name = strdup(m_parameters[i].name.c_str());
|
||||
desc->description = strdup(m_parameters[i].description.c_str());
|
||||
desc->unit = strdup(m_parameters[i].unit.c_str());
|
||||
desc->minValue = m_parameters[i].minValue;
|
||||
desc->maxValue = m_parameters[i].maxValue;
|
||||
desc->defaultValue = m_parameters[i].defaultValue;
|
||||
desc->isQuantized = m_parameters[i].isQuantized;
|
||||
desc->quantizeStep = m_parameters[i].quantizeStep;
|
||||
desc->valueNames = 0;
|
||||
if (desc->isQuantized && !m_parameters[i].valueNames.empty()) {
|
||||
desc->valueNames = (const char **)
|
||||
malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *));
|
||||
for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) {
|
||||
desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str());
|
||||
}
|
||||
desc->valueNames[m_parameters[i].valueNames.size()] = 0;
|
||||
}
|
||||
m_descriptor.parameters[i] = desc;
|
||||
}
|
||||
|
||||
m_descriptor.programCount = m_programs.size();
|
||||
m_descriptor.programs = (const char **)
|
||||
malloc(m_programs.size() * sizeof(const char *));
|
||||
|
||||
for (i = 0; i < m_programs.size(); ++i) {
|
||||
m_descriptor.programs[i] = strdup(m_programs[i].c_str());
|
||||
}
|
||||
|
||||
if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
|
||||
m_descriptor.inputDomain = vampFrequencyDomain;
|
||||
} else {
|
||||
m_descriptor.inputDomain = vampTimeDomain;
|
||||
}
|
||||
|
||||
m_descriptor.instantiate = vampInstantiate;
|
||||
m_descriptor.cleanup = vampCleanup;
|
||||
m_descriptor.initialise = vampInitialise;
|
||||
m_descriptor.reset = vampReset;
|
||||
m_descriptor.getParameter = vampGetParameter;
|
||||
m_descriptor.setParameter = vampSetParameter;
|
||||
m_descriptor.getCurrentProgram = vampGetCurrentProgram;
|
||||
m_descriptor.selectProgram = vampSelectProgram;
|
||||
m_descriptor.getPreferredStepSize = vampGetPreferredStepSize;
|
||||
m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize;
|
||||
m_descriptor.getMinChannelCount = vampGetMinChannelCount;
|
||||
m_descriptor.getMaxChannelCount = vampGetMaxChannelCount;
|
||||
m_descriptor.getOutputCount = vampGetOutputCount;
|
||||
m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
|
||||
m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
|
||||
m_descriptor.process = vampProcess;
|
||||
m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
|
||||
m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
|
||||
|
||||
if (!m_adapterMap) {
|
||||
m_adapterMap = new AdapterMap;
|
||||
}
|
||||
(*m_adapterMap)[&m_descriptor] = this;
|
||||
|
||||
delete plugin;
|
||||
|
||||
m_populated = true;
|
||||
return &m_descriptor;
|
||||
}
|
||||
|
||||
PluginAdapterBase::Impl::~Impl()
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl;
|
||||
#endif
|
||||
|
||||
if (!m_populated) return;
|
||||
|
||||
free((void *)m_descriptor.identifier);
|
||||
free((void *)m_descriptor.name);
|
||||
free((void *)m_descriptor.description);
|
||||
free((void *)m_descriptor.maker);
|
||||
free((void *)m_descriptor.copyright);
|
||||
|
||||
for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
|
||||
const VampParameterDescriptor *desc = m_descriptor.parameters[i];
|
||||
free((void *)desc->identifier);
|
||||
free((void *)desc->name);
|
||||
free((void *)desc->description);
|
||||
free((void *)desc->unit);
|
||||
if (desc->valueNames) {
|
||||
for (unsigned int j = 0; desc->valueNames[j]; ++j) {
|
||||
free((void *)desc->valueNames[j]);
|
||||
}
|
||||
free((void *)desc->valueNames);
|
||||
}
|
||||
}
|
||||
free((void *)m_descriptor.parameters);
|
||||
|
||||
for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
|
||||
free((void *)m_descriptor.programs[i]);
|
||||
}
|
||||
free((void *)m_descriptor.programs);
|
||||
|
||||
if (m_adapterMap) {
|
||||
|
||||
m_adapterMap->erase(&m_descriptor);
|
||||
|
||||
if (m_adapterMap->empty()) {
|
||||
delete m_adapterMap;
|
||||
m_adapterMap = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PluginAdapterBase::Impl *
|
||||
PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
if (!m_adapterMap) return 0;
|
||||
AdapterMap::const_iterator i = m_adapterMap->find(handle);
|
||||
if (i == m_adapterMap->end()) return 0;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
VampPluginHandle
|
||||
PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
|
||||
float inputSampleRate)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
if (!m_adapterMap) {
|
||||
m_adapterMap = new AdapterMap();
|
||||
}
|
||||
|
||||
if (m_adapterMap->find(desc) == m_adapterMap->end()) {
|
||||
std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Impl *adapter = (*m_adapterMap)[desc];
|
||||
if (desc != &adapter->m_descriptor) return 0;
|
||||
|
||||
Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate);
|
||||
if (plugin) {
|
||||
(*m_adapterMap)[plugin] = adapter;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl;
|
||||
#endif
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) {
|
||||
delete ((Plugin *)handle);
|
||||
return;
|
||||
}
|
||||
adapter->cleanup(((Plugin *)handle));
|
||||
}
|
||||
|
||||
int
|
||||
PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle,
|
||||
unsigned int channels,
|
||||
unsigned int stepSize,
|
||||
unsigned int blockSize)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
bool result = ((Plugin *)handle)->initialise
|
||||
(channels, stepSize, blockSize);
|
||||
return result ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
((Plugin *)handle)->reset();
|
||||
}
|
||||
|
||||
float
|
||||
PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
|
||||
int param)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) return 0.0;
|
||||
Plugin::ParameterList &list = adapter->m_parameters;
|
||||
return ((Plugin *)handle)->getParameter(list[param].identifier);
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
|
||||
int param, float value)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) return;
|
||||
Plugin::ParameterList &list = adapter->m_parameters;
|
||||
((Plugin *)handle)->setParameter(list[param].identifier, value);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) return 0;
|
||||
Plugin::ProgramList &list = adapter->m_programs;
|
||||
std::string program = ((Plugin *)handle)->getCurrentProgram();
|
||||
for (unsigned int i = 0; i < list.size(); ++i) {
|
||||
if (list[i] == program) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
|
||||
unsigned int program)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) return;
|
||||
Plugin::ProgramList &list = adapter->m_programs;
|
||||
((Plugin *)handle)->selectProgram(list[program]);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return ((Plugin *)handle)->getPreferredStepSize();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return ((Plugin *)handle)->getPreferredBlockSize();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return ((Plugin *)handle)->getMinChannelCount();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return ((Plugin *)handle)->getMaxChannelCount();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
|
||||
// std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl;
|
||||
|
||||
if (!adapter) return 0;
|
||||
return adapter->getOutputCount((Plugin *)handle);
|
||||
}
|
||||
|
||||
VampOutputDescriptor *
|
||||
PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
|
||||
unsigned int i)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
|
||||
// std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl;
|
||||
|
||||
if (!adapter) return 0;
|
||||
return adapter->getOutputDescriptor((Plugin *)handle, i);
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
if (desc->identifier) free((void *)desc->identifier);
|
||||
if (desc->name) free((void *)desc->name);
|
||||
if (desc->description) free((void *)desc->description);
|
||||
if (desc->unit) free((void *)desc->unit);
|
||||
if (desc->hasFixedBinCount && desc->binNames) {
|
||||
for (unsigned int i = 0; i < desc->binCount; ++i) {
|
||||
if (desc->binNames[i]) {
|
||||
free((void *)desc->binNames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (desc->binNames) free((void *)desc->binNames);
|
||||
free((void *)desc);
|
||||
}
|
||||
|
||||
VampFeatureList *
|
||||
PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle,
|
||||
const float *const *inputBuffers,
|
||||
int sec,
|
||||
int nsec)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) return 0;
|
||||
return adapter->process((Plugin *)handle,
|
||||
inputBuffers, sec, nsec);
|
||||
}
|
||||
|
||||
VampFeatureList *
|
||||
PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
Impl *adapter = lookupAdapter(handle);
|
||||
if (!adapter) return 0;
|
||||
return adapter->getRemainingFeatures((Plugin *)handle);
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
|
||||
{
|
||||
#ifdef DEBUG_PLUGIN_ADAPTER
|
||||
std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::cleanup(Plugin *plugin)
|
||||
{
|
||||
if (m_fs.find(plugin) != m_fs.end()) {
|
||||
size_t outputCount = 0;
|
||||
if (m_pluginOutputs[plugin]) {
|
||||
outputCount = m_pluginOutputs[plugin]->size();
|
||||
}
|
||||
VampFeatureList *list = m_fs[plugin];
|
||||
for (unsigned int i = 0; i < outputCount; ++i) {
|
||||
for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
|
||||
if (list[i].features[j].label) {
|
||||
free(list[i].features[j].label);
|
||||
}
|
||||
if (list[i].features[j].values) {
|
||||
free(list[i].features[j].values);
|
||||
}
|
||||
}
|
||||
if (list[i].features) free(list[i].features);
|
||||
}
|
||||
m_fs.erase(plugin);
|
||||
m_fsizes.erase(plugin);
|
||||
m_fvsizes.erase(plugin);
|
||||
}
|
||||
|
||||
if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
|
||||
delete m_pluginOutputs[plugin];
|
||||
m_pluginOutputs.erase(plugin);
|
||||
}
|
||||
|
||||
if (m_adapterMap) {
|
||||
m_adapterMap->erase(plugin);
|
||||
|
||||
if (m_adapterMap->empty()) {
|
||||
delete m_adapterMap;
|
||||
m_adapterMap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delete ((Plugin *)plugin);
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
|
||||
{
|
||||
if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() ||
|
||||
!m_pluginOutputs[plugin]) {
|
||||
m_pluginOutputs[plugin] = new Plugin::OutputList
|
||||
(plugin->getOutputDescriptors());
|
||||
// std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
|
||||
{
|
||||
checkOutputMap(plugin);
|
||||
return m_pluginOutputs[plugin]->size();
|
||||
}
|
||||
|
||||
VampOutputDescriptor *
|
||||
PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
|
||||
unsigned int i)
|
||||
{
|
||||
checkOutputMap(plugin);
|
||||
Plugin::OutputDescriptor &od =
|
||||
(*m_pluginOutputs[plugin])[i];
|
||||
|
||||
VampOutputDescriptor *desc = (VampOutputDescriptor *)
|
||||
malloc(sizeof(VampOutputDescriptor));
|
||||
|
||||
desc->identifier = strdup(od.identifier.c_str());
|
||||
desc->name = strdup(od.name.c_str());
|
||||
desc->description = strdup(od.description.c_str());
|
||||
desc->unit = strdup(od.unit.c_str());
|
||||
desc->hasFixedBinCount = od.hasFixedBinCount;
|
||||
desc->binCount = od.binCount;
|
||||
|
||||
if (od.hasFixedBinCount && od.binCount > 0) {
|
||||
desc->binNames = (const char **)
|
||||
malloc(od.binCount * sizeof(const char *));
|
||||
|
||||
for (unsigned int i = 0; i < od.binCount; ++i) {
|
||||
if (i < od.binNames.size()) {
|
||||
desc->binNames[i] = strdup(od.binNames[i].c_str());
|
||||
} else {
|
||||
desc->binNames[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
desc->binNames = 0;
|
||||
}
|
||||
|
||||
desc->hasKnownExtents = od.hasKnownExtents;
|
||||
desc->minValue = od.minValue;
|
||||
desc->maxValue = od.maxValue;
|
||||
desc->isQuantized = od.isQuantized;
|
||||
desc->quantizeStep = od.quantizeStep;
|
||||
|
||||
switch (od.sampleType) {
|
||||
case Plugin::OutputDescriptor::OneSamplePerStep:
|
||||
desc->sampleType = vampOneSamplePerStep; break;
|
||||
case Plugin::OutputDescriptor::FixedSampleRate:
|
||||
desc->sampleType = vampFixedSampleRate; break;
|
||||
case Plugin::OutputDescriptor::VariableSampleRate:
|
||||
desc->sampleType = vampVariableSampleRate; break;
|
||||
}
|
||||
|
||||
desc->sampleRate = od.sampleRate;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
VampFeatureList *
|
||||
PluginAdapterBase::Impl::process(Plugin *plugin,
|
||||
const float *const *inputBuffers,
|
||||
int sec, int nsec)
|
||||
{
|
||||
// std::cerr << "PluginAdapterBase::Impl::process" << std::endl;
|
||||
RealTime rt(sec, nsec);
|
||||
checkOutputMap(plugin);
|
||||
return convertFeatures(plugin, plugin->process(inputBuffers, rt));
|
||||
}
|
||||
|
||||
VampFeatureList *
|
||||
PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
|
||||
{
|
||||
// std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl;
|
||||
checkOutputMap(plugin);
|
||||
return convertFeatures(plugin, plugin->getRemainingFeatures());
|
||||
}
|
||||
|
||||
VampFeatureList *
|
||||
PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
|
||||
const Plugin::FeatureSet &features)
|
||||
{
|
||||
int lastN = -1;
|
||||
|
||||
int outputCount = 0;
|
||||
if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
|
||||
|
||||
resizeFS(plugin, outputCount);
|
||||
VampFeatureList *fs = m_fs[plugin];
|
||||
|
||||
for (Plugin::FeatureSet::const_iterator fi = features.begin();
|
||||
fi != features.end(); ++fi) {
|
||||
|
||||
int n = fi->first;
|
||||
|
||||
// std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl;
|
||||
|
||||
if (n >= int(outputCount)) {
|
||||
std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n > lastN + 1) {
|
||||
for (int i = lastN + 1; i < n; ++i) {
|
||||
fs[i].featureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const Plugin::FeatureList &fl = fi->second;
|
||||
|
||||
size_t sz = fl.size();
|
||||
if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
|
||||
fs[n].featureCount = sz;
|
||||
|
||||
for (size_t j = 0; j < sz; ++j) {
|
||||
|
||||
// std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl;
|
||||
|
||||
VampFeature *feature = &fs[n].features[j];
|
||||
|
||||
feature->hasTimestamp = fl[j].hasTimestamp;
|
||||
feature->sec = fl[j].timestamp.sec;
|
||||
feature->nsec = fl[j].timestamp.nsec;
|
||||
feature->valueCount = fl[j].values.size();
|
||||
|
||||
if (feature->label) free(feature->label);
|
||||
|
||||
if (fl[j].label.empty()) {
|
||||
feature->label = 0;
|
||||
} else {
|
||||
feature->label = strdup(fl[j].label.c_str());
|
||||
}
|
||||
|
||||
if (feature->valueCount > m_fvsizes[plugin][n][j]) {
|
||||
resizeFV(plugin, n, j, feature->valueCount);
|
||||
}
|
||||
|
||||
for (unsigned int k = 0; k < feature->valueCount; ++k) {
|
||||
// std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl;
|
||||
feature->values[k] = fl[j].values[k];
|
||||
}
|
||||
}
|
||||
|
||||
lastN = n;
|
||||
}
|
||||
|
||||
if (lastN == -1) return 0;
|
||||
|
||||
if (int(outputCount) > lastN + 1) {
|
||||
for (int i = lastN + 1; i < int(outputCount); ++i) {
|
||||
fs[i].featureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
|
||||
{
|
||||
// std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
|
||||
|
||||
int i = m_fsizes[plugin].size();
|
||||
if (i >= n) return;
|
||||
|
||||
// std::cerr << "resizing from " << i << std::endl;
|
||||
|
||||
m_fs[plugin] = (VampFeatureList *)realloc
|
||||
(m_fs[plugin], n * sizeof(VampFeatureList));
|
||||
|
||||
while (i < n) {
|
||||
m_fs[plugin][i].featureCount = 0;
|
||||
m_fs[plugin][i].features = 0;
|
||||
m_fsizes[plugin].push_back(0);
|
||||
m_fvsizes[plugin].push_back(std::vector<size_t>());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
|
||||
{
|
||||
// std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
|
||||
// << sz << ")" << std::endl;
|
||||
|
||||
size_t i = m_fsizes[plugin][n];
|
||||
if (i >= sz) return;
|
||||
|
||||
// std::cerr << "resizing from " << i << std::endl;
|
||||
|
||||
m_fs[plugin][n].features = (VampFeature *)realloc
|
||||
(m_fs[plugin][n].features, sz * sizeof(VampFeature));
|
||||
|
||||
while (m_fsizes[plugin][n] < sz) {
|
||||
m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0;
|
||||
m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0;
|
||||
m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0;
|
||||
m_fvsizes[plugin][n].push_back(0);
|
||||
m_fsizes[plugin][n]++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
|
||||
{
|
||||
// std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
|
||||
// << j << ", " << sz << ")" << std::endl;
|
||||
|
||||
size_t i = m_fvsizes[plugin][n][j];
|
||||
if (i >= sz) return;
|
||||
|
||||
// std::cerr << "resizing from " << i << std::endl;
|
||||
|
||||
m_fs[plugin][n].features[j].values = (float *)realloc
|
||||
(m_fs[plugin][n].features[j].values, sz * sizeof(float));
|
||||
|
||||
m_fvsizes[plugin][n][j] = sz;
|
||||
}
|
||||
|
||||
PluginAdapterBase::Impl::AdapterMap *
|
||||
PluginAdapterBase::Impl::m_adapterMap = 0;
|
||||
|
||||
}
|
||||
|
||||
117
libs/vamp-sdk/vamp-sdk/PluginAdapter.h
Normal file
117
libs/vamp-sdk/vamp-sdk/PluginAdapter.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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_PLUGIN_ADAPTER_H_
|
||||
#define _VAMP_PLUGIN_ADAPTER_H_
|
||||
|
||||
#include <vamp/vamp.h>
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
/**
|
||||
* \class PluginAdapterBase PluginAdapter.h <vamp-sdk/PluginAdapter.h>
|
||||
*
|
||||
* PluginAdapter and PluginAdapterBase provide a wrapper class that a
|
||||
* plugin library can use to make its C++ Vamp::Plugin objects
|
||||
* available through the Vamp C API.
|
||||
*
|
||||
* Almost all Vamp plugin libraries will want to make use of this. To
|
||||
* do so, all they need to do is declare a PluginAdapter<T> for each
|
||||
* plugin class T in their library. It's very simple, and you need to
|
||||
* know absolutely nothing about how it works in order to use it.
|
||||
* Just cut and paste from an existing plugin's discovery function.
|
||||
* \see vampGetPluginDescriptor
|
||||
*/
|
||||
|
||||
class PluginAdapterBase
|
||||
{
|
||||
public:
|
||||
virtual ~PluginAdapterBase();
|
||||
|
||||
/**
|
||||
* Return a VampPluginDescriptor describing the plugin that is
|
||||
* wrapped by this adapter.
|
||||
*/
|
||||
const VampPluginDescriptor *getDescriptor();
|
||||
|
||||
protected:
|
||||
PluginAdapterBase();
|
||||
|
||||
virtual Plugin *createPlugin(float inputSampleRate) = 0;
|
||||
|
||||
class Impl;
|
||||
Impl *m_impl;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class PluginAdapter PluginAdapter.h <vamp-sdk/PluginAdapter.h>
|
||||
*
|
||||
* PluginAdapter turns a PluginAdapterBase into a specific wrapper for
|
||||
* a particular plugin implementation.
|
||||
*
|
||||
* See PluginAdapterBase.
|
||||
*/
|
||||
|
||||
template <typename P>
|
||||
class PluginAdapter : public PluginAdapterBase
|
||||
{
|
||||
public:
|
||||
PluginAdapter() : PluginAdapterBase() { }
|
||||
virtual ~PluginAdapter() { }
|
||||
|
||||
protected:
|
||||
Plugin *createPlugin(float inputSampleRate) {
|
||||
P *p = new P(inputSampleRate);
|
||||
Plugin *plugin = dynamic_cast<Plugin *>(p);
|
||||
if (!plugin) {
|
||||
std::cerr << "ERROR: PluginAdapter::createPlugin: "
|
||||
<< "Template type is not a plugin!"
|
||||
<< std::endl;
|
||||
delete p;
|
||||
return 0;
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
252
libs/vamp-sdk/vamp-sdk/PluginBase.h
Normal file
252
libs/vamp-sdk/vamp-sdk/PluginBase.h
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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_PLUGIN_BASE_H_
|
||||
#define _VAMP_PLUGIN_BASE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define VAMP_SDK_VERSION "1.1"
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
/**
|
||||
* A base class for plugins with optional configurable parameters,
|
||||
* programs, etc. The Vamp::Plugin is derived from this, and
|
||||
* individual Vamp plugins should derive from that.
|
||||
*
|
||||
* This class does not provide the necessary interfaces to instantiate
|
||||
* or run a plugin. It only specifies an interface for retrieving
|
||||
* those controls that the host may wish to show to the user for
|
||||
* editing. It could meaningfully be subclassed by real-time plugins
|
||||
* or other sorts of plugin as well as Vamp plugins.
|
||||
*/
|
||||
|
||||
class PluginBase
|
||||
{
|
||||
public:
|
||||
virtual ~PluginBase() { }
|
||||
|
||||
/**
|
||||
* Get the Vamp API compatibility level of the plugin.
|
||||
*/
|
||||
virtual unsigned int getVampApiVersion() const { return 1; }
|
||||
|
||||
/**
|
||||
* Get the computer-usable name of the plugin. This should be
|
||||
* reasonably short and contain no whitespace or punctuation
|
||||
* characters. It may only contain the characters [a-zA-Z0-9_].
|
||||
* This is the authoritative way for a program to identify a
|
||||
* plugin within a given library.
|
||||
*
|
||||
* This text may be visible to the user, but it should not be the
|
||||
* main text used to identify a plugin to the user (that will be
|
||||
* the name, below).
|
||||
*
|
||||
* Example: "zero_crossings"
|
||||
*/
|
||||
virtual std::string getIdentifier() const = 0;
|
||||
|
||||
/**
|
||||
* Get a human-readable name or title of the plugin. This
|
||||
* should be brief and self-contained, as it may be used to
|
||||
* identify the plugin to the user in isolation (i.e. without also
|
||||
* showing the plugin's "identifier").
|
||||
*
|
||||
* Example: "Zero Crossings"
|
||||
*/
|
||||
virtual std::string getName() const = 0;
|
||||
|
||||
/**
|
||||
* Get a human-readable description for the plugin, typically
|
||||
* a line of text that may optionally be displayed in addition
|
||||
* to the plugin's "name". May be empty if the name has said
|
||||
* it all already.
|
||||
*
|
||||
* Example: "Detect and count zero crossing points"
|
||||
*/
|
||||
virtual std::string getDescription() const = 0;
|
||||
|
||||
/**
|
||||
* Get the name of the author or vendor of the plugin in
|
||||
* human-readable form. This should be a short identifying text,
|
||||
* as it may be used to label plugins from the same source in a
|
||||
* menu or similar.
|
||||
*/
|
||||
virtual std::string getMaker() const = 0;
|
||||
|
||||
/**
|
||||
* Get the copyright statement or licensing summary for the
|
||||
* plugin. This can be an informative text, without the same
|
||||
* presentation constraints as mentioned for getMaker above.
|
||||
*/
|
||||
virtual std::string getCopyright() const = 0;
|
||||
|
||||
/**
|
||||
* Get the version number of the plugin.
|
||||
*/
|
||||
virtual int getPluginVersion() const = 0;
|
||||
|
||||
|
||||
struct ParameterDescriptor
|
||||
{
|
||||
/**
|
||||
* The name of the parameter, in computer-usable form. Should
|
||||
* be reasonably short, and may only contain the characters
|
||||
* [a-zA-Z0-9_].
|
||||
*/
|
||||
std::string identifier;
|
||||
|
||||
/**
|
||||
* The human-readable name of the parameter.
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* A human-readable short text describing the parameter. May be
|
||||
* empty if the name has said it all already.
|
||||
*/
|
||||
std::string description;
|
||||
|
||||
/**
|
||||
* The unit of the parameter, in human-readable form.
|
||||
*/
|
||||
std::string unit;
|
||||
|
||||
/**
|
||||
* The minimum value of the parameter.
|
||||
*/
|
||||
float minValue;
|
||||
|
||||
/**
|
||||
* The maximum value of the parameter.
|
||||
*/
|
||||
float maxValue;
|
||||
|
||||
/**
|
||||
* The default value of the parameter. The plugin should
|
||||
* ensure that parameters have this value on initialisation
|
||||
* (i.e. the host is not required to explicitly set parameters
|
||||
* if it wants to use their default values).
|
||||
*/
|
||||
float defaultValue;
|
||||
|
||||
/**
|
||||
* True if the parameter values are quantized to a particular
|
||||
* resolution.
|
||||
*/
|
||||
bool isQuantized;
|
||||
|
||||
/**
|
||||
* Quantization resolution of the parameter values (e.g. 1.0
|
||||
* if they are all integers). Undefined if isQuantized is
|
||||
* false.
|
||||
*/
|
||||
float quantizeStep;
|
||||
|
||||
/**
|
||||
* Names for the quantized values. If isQuantized is true,
|
||||
* this may either be empty or contain one string for each of
|
||||
* the quantize steps from minValue up to maxValue inclusive.
|
||||
* Undefined if isQuantized is false.
|
||||
*
|
||||
* If these names are provided, they should be shown to the
|
||||
* user in preference to the values themselves. The user may
|
||||
* never see the actual numeric values unless they are also
|
||||
* encoded in the names.
|
||||
*/
|
||||
std::vector<std::string> valueNames;
|
||||
};
|
||||
|
||||
typedef std::vector<ParameterDescriptor> ParameterList;
|
||||
|
||||
/**
|
||||
* Get the controllable parameters of this plugin.
|
||||
*/
|
||||
virtual ParameterList getParameterDescriptors() const {
|
||||
return ParameterList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a named parameter. The argument is the identifier
|
||||
* field from that parameter's descriptor.
|
||||
*/
|
||||
virtual float getParameter(std::string) const { return 0.0; }
|
||||
|
||||
/**
|
||||
* Set a named parameter. The first argument is the identifier field
|
||||
* from that parameter's descriptor.
|
||||
*/
|
||||
virtual void setParameter(std::string, float) { }
|
||||
|
||||
|
||||
typedef std::vector<std::string> ProgramList;
|
||||
|
||||
/**
|
||||
* Get the program settings available in this plugin. A program
|
||||
* is a named shorthand for a set of parameter values; changing
|
||||
* the program may cause the plugin to alter the values of its
|
||||
* published parameters (and/or non-public internal processing
|
||||
* parameters). The host should re-read the plugin's parameter
|
||||
* values after setting a new program.
|
||||
*
|
||||
* The programs must have unique names.
|
||||
*/
|
||||
virtual ProgramList getPrograms() const { return ProgramList(); }
|
||||
|
||||
/**
|
||||
* Get the current program.
|
||||
*/
|
||||
virtual std::string getCurrentProgram() const { return ""; }
|
||||
|
||||
/**
|
||||
* Select a program. (If the given program name is not one of the
|
||||
* available programs, do nothing.)
|
||||
*/
|
||||
virtual void selectProgram(std::string) { }
|
||||
|
||||
/**
|
||||
* Get the type of plugin. This is to be implemented by the
|
||||
* immediate subclass, not by actual plugins. Do not attempt to
|
||||
* implement this in plugin code.
|
||||
*/
|
||||
virtual std::string getType() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
418
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
Normal file
418
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 "PluginHostAdapter.h"
|
||||
|
||||
namespace Vamp
|
||||
{
|
||||
|
||||
PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
|
||||
float inputSampleRate) :
|
||||
Plugin(inputSampleRate),
|
||||
m_descriptor(descriptor)
|
||||
{
|
||||
// std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
|
||||
m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
|
||||
if (!m_handle) {
|
||||
// std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
PluginHostAdapter::~PluginHostAdapter()
|
||||
{
|
||||
// std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
|
||||
if (m_handle) m_descriptor->cleanup(m_handle);
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
PluginHostAdapter::getPluginPath()
|
||||
{
|
||||
std::vector<std::string> path;
|
||||
std::string envPath;
|
||||
|
||||
char *cpath = getenv("VAMP_PATH");
|
||||
if (cpath) envPath = cpath;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATH_SEPARATOR ';'
|
||||
#define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
|
||||
#else
|
||||
#define PATH_SEPARATOR ':'
|
||||
#ifdef __APPLE__
|
||||
#define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
|
||||
#else
|
||||
#define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (envPath == "") {
|
||||
envPath = DEFAULT_VAMP_PATH;
|
||||
char *chome = getenv("HOME");
|
||||
if (chome) {
|
||||
std::string home(chome);
|
||||
std::string::size_type f;
|
||||
while ((f = envPath.find("$HOME")) != std::string::npos &&
|
||||
f < envPath.length()) {
|
||||
envPath.replace(f, 5, home);
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
char *cpfiles = getenv("ProgramFiles");
|
||||
if (!cpfiles) cpfiles = "C:\\Program Files";
|
||||
std::string pfiles(cpfiles);
|
||||
std::string::size_type f;
|
||||
while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
|
||||
f < envPath.length()) {
|
||||
envPath.replace(f, 14, pfiles);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string::size_type index = 0, newindex = 0;
|
||||
|
||||
while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
|
||||
path.push_back(envPath.substr(index, newindex - index));
|
||||
index = newindex + 1;
|
||||
}
|
||||
|
||||
path.push_back(envPath.substr(index));
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginHostAdapter::initialise(size_t channels,
|
||||
size_t stepSize,
|
||||
size_t blockSize)
|
||||
{
|
||||
if (!m_handle) return false;
|
||||
return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
void
|
||||
PluginHostAdapter::reset()
|
||||
{
|
||||
if (!m_handle) return;
|
||||
m_descriptor->reset(m_handle);
|
||||
}
|
||||
|
||||
PluginHostAdapter::InputDomain
|
||||
PluginHostAdapter::getInputDomain() const
|
||||
{
|
||||
if (m_descriptor->inputDomain == vampFrequencyDomain) {
|
||||
return FrequencyDomain;
|
||||
} else {
|
||||
return TimeDomain;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginHostAdapter::getVampApiVersion() const
|
||||
{
|
||||
return m_descriptor->vampApiVersion;
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginHostAdapter::getIdentifier() const
|
||||
{
|
||||
return m_descriptor->identifier;
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginHostAdapter::getName() const
|
||||
{
|
||||
return m_descriptor->name;
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginHostAdapter::getDescription() const
|
||||
{
|
||||
return m_descriptor->description;
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginHostAdapter::getMaker() const
|
||||
{
|
||||
return m_descriptor->maker;
|
||||
}
|
||||
|
||||
int
|
||||
PluginHostAdapter::getPluginVersion() const
|
||||
{
|
||||
return m_descriptor->pluginVersion;
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginHostAdapter::getCopyright() const
|
||||
{
|
||||
return m_descriptor->copyright;
|
||||
}
|
||||
|
||||
PluginHostAdapter::ParameterList
|
||||
PluginHostAdapter::getParameterDescriptors() const
|
||||
{
|
||||
ParameterList list;
|
||||
for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
||||
const VampParameterDescriptor *spd = m_descriptor->parameters[i];
|
||||
ParameterDescriptor pd;
|
||||
pd.identifier = spd->identifier;
|
||||
pd.name = spd->name;
|
||||
pd.description = spd->description;
|
||||
pd.unit = spd->unit;
|
||||
pd.minValue = spd->minValue;
|
||||
pd.maxValue = spd->maxValue;
|
||||
pd.defaultValue = spd->defaultValue;
|
||||
pd.isQuantized = spd->isQuantized;
|
||||
pd.quantizeStep = spd->quantizeStep;
|
||||
if (pd.isQuantized && spd->valueNames) {
|
||||
for (unsigned int j = 0; spd->valueNames[j]; ++j) {
|
||||
pd.valueNames.push_back(spd->valueNames[j]);
|
||||
}
|
||||
}
|
||||
list.push_back(pd);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
float
|
||||
PluginHostAdapter::getParameter(std::string param) const
|
||||
{
|
||||
if (!m_handle) return 0.0;
|
||||
|
||||
for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
||||
if (param == m_descriptor->parameters[i]->identifier) {
|
||||
return m_descriptor->getParameter(m_handle, i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
PluginHostAdapter::setParameter(std::string param,
|
||||
float value)
|
||||
{
|
||||
if (!m_handle) return;
|
||||
|
||||
for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
||||
if (param == m_descriptor->parameters[i]->identifier) {
|
||||
m_descriptor->setParameter(m_handle, i, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PluginHostAdapter::ProgramList
|
||||
PluginHostAdapter::getPrograms() const
|
||||
{
|
||||
ProgramList list;
|
||||
|
||||
for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
|
||||
list.push_back(m_descriptor->programs[i]);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginHostAdapter::getCurrentProgram() const
|
||||
{
|
||||
if (!m_handle) return "";
|
||||
|
||||
int pn = m_descriptor->getCurrentProgram(m_handle);
|
||||
return m_descriptor->programs[pn];
|
||||
}
|
||||
|
||||
void
|
||||
PluginHostAdapter::selectProgram(std::string program)
|
||||
{
|
||||
if (!m_handle) return;
|
||||
|
||||
for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
|
||||
if (program == m_descriptor->programs[i]) {
|
||||
m_descriptor->selectProgram(m_handle, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginHostAdapter::getPreferredStepSize() const
|
||||
{
|
||||
if (!m_handle) return 0;
|
||||
return m_descriptor->getPreferredStepSize(m_handle);
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginHostAdapter::getPreferredBlockSize() const
|
||||
{
|
||||
if (!m_handle) return 0;
|
||||
return m_descriptor->getPreferredBlockSize(m_handle);
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginHostAdapter::getMinChannelCount() const
|
||||
{
|
||||
if (!m_handle) return 0;
|
||||
return m_descriptor->getMinChannelCount(m_handle);
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginHostAdapter::getMaxChannelCount() const
|
||||
{
|
||||
if (!m_handle) return 0;
|
||||
return m_descriptor->getMaxChannelCount(m_handle);
|
||||
}
|
||||
|
||||
PluginHostAdapter::OutputList
|
||||
PluginHostAdapter::getOutputDescriptors() const
|
||||
{
|
||||
OutputList list;
|
||||
if (!m_handle) {
|
||||
// std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
|
||||
return list;
|
||||
}
|
||||
|
||||
unsigned int count = m_descriptor->getOutputCount(m_handle);
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
|
||||
OutputDescriptor d;
|
||||
d.identifier = sd->identifier;
|
||||
d.name = sd->name;
|
||||
d.description = sd->description;
|
||||
d.unit = sd->unit;
|
||||
d.hasFixedBinCount = sd->hasFixedBinCount;
|
||||
d.binCount = sd->binCount;
|
||||
if (d.hasFixedBinCount) {
|
||||
for (unsigned int j = 0; j < sd->binCount; ++j) {
|
||||
d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
|
||||
}
|
||||
}
|
||||
d.hasKnownExtents = sd->hasKnownExtents;
|
||||
d.minValue = sd->minValue;
|
||||
d.maxValue = sd->maxValue;
|
||||
d.isQuantized = sd->isQuantized;
|
||||
d.quantizeStep = sd->quantizeStep;
|
||||
|
||||
switch (sd->sampleType) {
|
||||
case vampOneSamplePerStep:
|
||||
d.sampleType = OutputDescriptor::OneSamplePerStep; break;
|
||||
case vampFixedSampleRate:
|
||||
d.sampleType = OutputDescriptor::FixedSampleRate; break;
|
||||
case vampVariableSampleRate:
|
||||
d.sampleType = OutputDescriptor::VariableSampleRate; break;
|
||||
}
|
||||
|
||||
d.sampleRate = sd->sampleRate;
|
||||
|
||||
list.push_back(d);
|
||||
|
||||
m_descriptor->releaseOutputDescriptor(sd);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
PluginHostAdapter::FeatureSet
|
||||
PluginHostAdapter::process(const float *const *inputBuffers,
|
||||
RealTime timestamp)
|
||||
{
|
||||
FeatureSet fs;
|
||||
if (!m_handle) return fs;
|
||||
|
||||
int sec = timestamp.sec;
|
||||
int nsec = timestamp.nsec;
|
||||
|
||||
VampFeatureList *features = m_descriptor->process(m_handle,
|
||||
inputBuffers,
|
||||
sec, nsec);
|
||||
|
||||
convertFeatures(features, fs);
|
||||
m_descriptor->releaseFeatureSet(features);
|
||||
return fs;
|
||||
}
|
||||
|
||||
PluginHostAdapter::FeatureSet
|
||||
PluginHostAdapter::getRemainingFeatures()
|
||||
{
|
||||
FeatureSet fs;
|
||||
if (!m_handle) return fs;
|
||||
|
||||
VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle);
|
||||
|
||||
convertFeatures(features, fs);
|
||||
m_descriptor->releaseFeatureSet(features);
|
||||
return fs;
|
||||
}
|
||||
|
||||
void
|
||||
PluginHostAdapter::convertFeatures(VampFeatureList *features,
|
||||
FeatureSet &fs)
|
||||
{
|
||||
if (!features) return;
|
||||
|
||||
unsigned int outputs = m_descriptor->getOutputCount(m_handle);
|
||||
|
||||
for (unsigned int i = 0; i < outputs; ++i) {
|
||||
|
||||
VampFeatureList &list = features[i];
|
||||
|
||||
if (list.featureCount > 0) {
|
||||
|
||||
for (unsigned int j = 0; j < list.featureCount; ++j) {
|
||||
|
||||
Feature feature;
|
||||
feature.hasTimestamp = list.features[j].hasTimestamp;
|
||||
feature.timestamp = RealTime(list.features[j].sec,
|
||||
list.features[j].nsec);
|
||||
|
||||
for (unsigned int k = 0; k < list.features[j].valueCount; ++k) {
|
||||
feature.values.push_back(list.features[j].values[k]);
|
||||
}
|
||||
|
||||
if (list.features[j].label) {
|
||||
feature.label = list.features[j].label;
|
||||
}
|
||||
|
||||
fs[i].push_back(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
117
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h
Normal file
117
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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_PLUGIN_HOST_ADAPTER_H_
|
||||
#define _VAMP_PLUGIN_HOST_ADAPTER_H_
|
||||
|
||||
#include <vamp/vamp.h>
|
||||
#include <vamp-sdk/Plugin.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
/**
|
||||
* \class PluginHostAdapter PluginHostAdapter.h <vamp-sdk/PluginHostAdapter.h>
|
||||
*
|
||||
* PluginHostAdapter is a wrapper class that a Vamp host can use to
|
||||
* make the C-language VampPluginDescriptor object appear as a C++
|
||||
* Vamp::Plugin object.
|
||||
*
|
||||
* The Vamp API is defined in vamp/vamp.h as a C API. The C++ objects
|
||||
* used for convenience by plugins and hosts actually communicate
|
||||
* using the C low-level API, but the details of this communication
|
||||
* are handled seamlessly by the Vamp SDK implementation provided the
|
||||
* plugin and host use the proper C++ wrapper objects.
|
||||
*
|
||||
* See also PluginAdapter, the plugin-side wrapper that makes a C++
|
||||
* plugin object available using the C query API.
|
||||
*/
|
||||
|
||||
class PluginHostAdapter : public Plugin
|
||||
{
|
||||
public:
|
||||
PluginHostAdapter(const VampPluginDescriptor *descriptor,
|
||||
float inputSampleRate);
|
||||
virtual ~PluginHostAdapter();
|
||||
|
||||
static std::vector<std::string> getPluginPath();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
void reset();
|
||||
|
||||
InputDomain getInputDomain() const;
|
||||
|
||||
unsigned int getVampApiVersion() const;
|
||||
std::string getIdentifier() const;
|
||||
std::string getName() const;
|
||||
std::string getDescription() const;
|
||||
std::string getMaker() const;
|
||||
int getPluginVersion() const;
|
||||
std::string getCopyright() const;
|
||||
|
||||
ParameterList getParameterDescriptors() const;
|
||||
float getParameter(std::string) const;
|
||||
void setParameter(std::string, float);
|
||||
|
||||
ProgramList getPrograms() const;
|
||||
std::string getCurrentProgram() const;
|
||||
void selectProgram(std::string);
|
||||
|
||||
size_t getPreferredStepSize() const;
|
||||
size_t getPreferredBlockSize() const;
|
||||
|
||||
size_t getMinChannelCount() const;
|
||||
size_t getMaxChannelCount() const;
|
||||
|
||||
OutputList getOutputDescriptors() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||
|
||||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
void convertFeatures(VampFeatureList *, FeatureSet &);
|
||||
|
||||
const VampPluginDescriptor *m_descriptor;
|
||||
VampPluginHandle m_handle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
254
libs/vamp-sdk/vamp-sdk/RealTime.cpp
Normal file
254
libs/vamp-sdk/vamp-sdk/RealTime.cpp
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 is a modified version of a source file from the
|
||||
Rosegarden MIDI and audio sequencer and notation editor.
|
||||
This file copyright 2000-2006 Chris Cannam.
|
||||
Relicensed by the author as detailed above.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if (__GNUC__ < 3)
|
||||
#include <strstream>
|
||||
#define stringstream strstream
|
||||
#else
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
#include "RealTime.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
// A RealTime consists of two ints that must be at least 32 bits each.
|
||||
// A signed 32-bit int can store values exceeding +/- 2 billion. This
|
||||
// means we can safely use our lower int for nanoseconds, as there are
|
||||
// 1 billion nanoseconds in a second and we need to handle double that
|
||||
// because of the implementations of addition etc that we use.
|
||||
//
|
||||
// The maximum valid RealTime on a 32-bit system is somewhere around
|
||||
// 68 years: 999999999 nanoseconds longer than the classic Unix epoch.
|
||||
|
||||
#define ONE_BILLION 1000000000
|
||||
|
||||
RealTime::RealTime(int s, int n) :
|
||||
sec(s), nsec(n)
|
||||
{
|
||||
if (sec == 0) {
|
||||
while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; }
|
||||
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; }
|
||||
} else {
|
||||
while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; }
|
||||
while (nsec < 0) { nsec += ONE_BILLION; --sec; }
|
||||
}
|
||||
}
|
||||
|
||||
RealTime
|
||||
RealTime::fromSeconds(double sec)
|
||||
{
|
||||
return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION + 0.5));
|
||||
}
|
||||
|
||||
RealTime
|
||||
RealTime::fromMilliseconds(int msec)
|
||||
{
|
||||
return RealTime(msec / 1000, (msec % 1000) * 1000000);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
RealTime
|
||||
RealTime::fromTimeval(const struct timeval &tv)
|
||||
{
|
||||
return RealTime(tv.tv_sec, tv.tv_usec * 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const RealTime &rt)
|
||||
{
|
||||
if (rt < RealTime::zeroTime) {
|
||||
out << "-";
|
||||
} else {
|
||||
out << " ";
|
||||
}
|
||||
|
||||
int s = (rt.sec < 0 ? -rt.sec : rt.sec);
|
||||
int n = (rt.nsec < 0 ? -rt.nsec : rt.nsec);
|
||||
|
||||
out << s << ".";
|
||||
|
||||
int nn(n);
|
||||
if (nn == 0) out << "00000000";
|
||||
else while (nn < (ONE_BILLION / 10)) {
|
||||
out << "0";
|
||||
nn *= 10;
|
||||
}
|
||||
|
||||
out << n << "R";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string
|
||||
RealTime::toString() const
|
||||
{
|
||||
std::stringstream out;
|
||||
out << *this;
|
||||
|
||||
#if (__GNUC__ < 3)
|
||||
out << std::ends;
|
||||
#endif
|
||||
|
||||
std::string s = out.str();
|
||||
|
||||
// remove trailing R
|
||||
return s.substr(0, s.length() - 1);
|
||||
}
|
||||
|
||||
std::string
|
||||
RealTime::toText(bool fixedDp) const
|
||||
{
|
||||
if (*this < RealTime::zeroTime) return "-" + (-*this).toText();
|
||||
|
||||
std::stringstream out;
|
||||
|
||||
if (sec >= 3600) {
|
||||
out << (sec / 3600) << ":";
|
||||
}
|
||||
|
||||
if (sec >= 60) {
|
||||
out << (sec % 3600) / 60 << ":";
|
||||
}
|
||||
|
||||
if (sec >= 10) {
|
||||
out << ((sec % 60) / 10);
|
||||
}
|
||||
|
||||
out << (sec % 10);
|
||||
|
||||
int ms = msec();
|
||||
|
||||
if (ms != 0) {
|
||||
out << ".";
|
||||
out << (ms / 100);
|
||||
ms = ms % 100;
|
||||
if (ms != 0) {
|
||||
out << (ms / 10);
|
||||
ms = ms % 10;
|
||||
} else if (fixedDp) {
|
||||
out << "0";
|
||||
}
|
||||
if (ms != 0) {
|
||||
out << ms;
|
||||
} else if (fixedDp) {
|
||||
out << "0";
|
||||
}
|
||||
} else if (fixedDp) {
|
||||
out << ".000";
|
||||
}
|
||||
|
||||
#if (__GNUC__ < 3)
|
||||
out << std::ends;
|
||||
#endif
|
||||
|
||||
std::string s = out.str();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
RealTime
|
||||
RealTime::operator/(int d) const
|
||||
{
|
||||
int secdiv = sec / d;
|
||||
int secrem = sec % d;
|
||||
|
||||
double nsecdiv = (double(nsec) + ONE_BILLION * double(secrem)) / d;
|
||||
|
||||
return RealTime(secdiv, int(nsecdiv + 0.5));
|
||||
}
|
||||
|
||||
double
|
||||
RealTime::operator/(const RealTime &r) const
|
||||
{
|
||||
double lTotal = double(sec) * ONE_BILLION + double(nsec);
|
||||
double rTotal = double(r.sec) * ONE_BILLION + double(r.nsec);
|
||||
|
||||
if (rTotal == 0) return 0.0;
|
||||
else return lTotal/rTotal;
|
||||
}
|
||||
|
||||
long
|
||||
RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate)
|
||||
{
|
||||
if (time < zeroTime) return -realTime2Frame(-time, sampleRate);
|
||||
|
||||
// We like integers. The last term is always zero unless the
|
||||
// sample rate is greater than 1MHz, but hell, you never know...
|
||||
|
||||
long frame =
|
||||
time.sec * sampleRate +
|
||||
(time.msec() * sampleRate) / 1000 +
|
||||
((time.usec() - 1000 * time.msec()) * sampleRate) / 1000000 +
|
||||
((time.nsec - 1000 * time.usec()) * sampleRate) / 1000000000;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
RealTime
|
||||
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)(((float(frame) * 1000000) / long(sampleRate)) * 1000);
|
||||
return rt;
|
||||
}
|
||||
|
||||
const RealTime RealTime::zeroTime(0,0);
|
||||
|
||||
}
|
||||
154
libs/vamp-sdk/vamp-sdk/RealTime.h
Normal file
154
libs/vamp-sdk/vamp-sdk/RealTime.h
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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 is a modified version of a source file from the
|
||||
Rosegarden MIDI and audio sequencer and notation editor.
|
||||
This file copyright 2000-2006 Chris Cannam.
|
||||
Relicensed by the author as detailed above.
|
||||
*/
|
||||
|
||||
#ifndef _VAMP_REAL_TIME_H_
|
||||
#define _VAMP_REAL_TIME_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifndef _WIN32
|
||||
struct timeval;
|
||||
#endif
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
/**
|
||||
* \class RealTime RealTime.h <vamp-sdk/RealTime.h>
|
||||
*
|
||||
* RealTime represents time values to nanosecond precision
|
||||
* with accurate arithmetic and frame-rate conversion functions.
|
||||
*/
|
||||
|
||||
struct RealTime
|
||||
{
|
||||
int sec;
|
||||
int nsec;
|
||||
|
||||
int usec() const { return nsec / 1000; }
|
||||
int msec() const { return nsec / 1000000; }
|
||||
|
||||
RealTime(): sec(0), nsec(0) {}
|
||||
RealTime(int s, int n);
|
||||
|
||||
RealTime(const RealTime &r) :
|
||||
sec(r.sec), nsec(r.nsec) { }
|
||||
|
||||
static RealTime fromSeconds(double sec);
|
||||
static RealTime fromMilliseconds(int msec);
|
||||
|
||||
#ifndef _WIN32
|
||||
static RealTime fromTimeval(const struct timeval &);
|
||||
#endif
|
||||
|
||||
RealTime &operator=(const RealTime &r) {
|
||||
sec = r.sec; nsec = r.nsec; return *this;
|
||||
}
|
||||
|
||||
RealTime operator+(const RealTime &r) const {
|
||||
return RealTime(sec + r.sec, nsec + r.nsec);
|
||||
}
|
||||
RealTime operator-(const RealTime &r) const {
|
||||
return RealTime(sec - r.sec, nsec - r.nsec);
|
||||
}
|
||||
RealTime operator-() const {
|
||||
return RealTime(-sec, -nsec);
|
||||
}
|
||||
|
||||
bool operator <(const RealTime &r) const {
|
||||
if (sec == r.sec) return nsec < r.nsec;
|
||||
else return sec < r.sec;
|
||||
}
|
||||
|
||||
bool operator >(const RealTime &r) const {
|
||||
if (sec == r.sec) return nsec > r.nsec;
|
||||
else return sec > r.sec;
|
||||
}
|
||||
|
||||
bool operator==(const RealTime &r) const {
|
||||
return (sec == r.sec && nsec == r.nsec);
|
||||
}
|
||||
|
||||
bool operator!=(const RealTime &r) const {
|
||||
return !(r == *this);
|
||||
}
|
||||
|
||||
bool operator>=(const RealTime &r) const {
|
||||
if (sec == r.sec) return nsec >= r.nsec;
|
||||
else return sec >= r.sec;
|
||||
}
|
||||
|
||||
bool operator<=(const RealTime &r) const {
|
||||
if (sec == r.sec) return nsec <= r.nsec;
|
||||
else return sec <= r.sec;
|
||||
}
|
||||
|
||||
RealTime operator/(int d) const;
|
||||
|
||||
// Find the fractional difference between times
|
||||
//
|
||||
double operator/(const RealTime &r) const;
|
||||
|
||||
// Return a human-readable debug-type string to full precision
|
||||
// (probably not a format to show to a user directly)
|
||||
//
|
||||
std::string toString() const;
|
||||
|
||||
// Return a user-readable string to the nearest millisecond
|
||||
// in a form like HH:MM:SS.mmm
|
||||
//
|
||||
std::string toText(bool fixedDp = false) const;
|
||||
|
||||
// Convenience functions for handling sample frames
|
||||
//
|
||||
static long realTime2Frame(const RealTime &r, unsigned int sampleRate);
|
||||
static RealTime frame2RealTime(long frame, unsigned int sampleRate);
|
||||
|
||||
static const RealTime zeroTime;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const RealTime &rt);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
120
libs/vamp-sdk/vamp-sdk/doc-overview
Normal file
120
libs/vamp-sdk/vamp-sdk/doc-overview
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
/** \mainpage Vamp Plugin SDK
|
||||
|
||||
\section about About Vamp
|
||||
|
||||
Vamp is an API for C and C++ plugins that process sampled audio data
|
||||
to produce descriptive output (measurements or semantic observations).
|
||||
Find more information at http://www.vamp-plugins.org/ .
|
||||
|
||||
Although the official API for Vamp plugins is defined in C for maximum
|
||||
binary compatibility, we strongly recommend using the provided C++
|
||||
classes in the SDK to implement your own plugins and hosts.
|
||||
|
||||
\section plugins For Plugins
|
||||
|
||||
Plugins should subclass Vamp::Plugin, and then use a
|
||||
Vamp::PluginAdapter to expose the correct C API for the plugin. Read
|
||||
the documentation for Vamp::PluginBase and Vamp::Plugin before
|
||||
starting.
|
||||
|
||||
Plugins should be compiled and linked into dynamic libraries using the
|
||||
usual convention for your platform, and should link (preferably
|
||||
statically) with -lvamp-sdk. Any number of plugins can reside in a
|
||||
single dynamic library. See plugins.cpp in the example plugins
|
||||
directory for the sort of code that will need to accompany your plugin
|
||||
class or classes, to make it possible for a host to look up your
|
||||
plugins properly.
|
||||
|
||||
The following example plugins are provided:
|
||||
|
||||
- ZeroCrossing calculates the positions and density of zero-crossing
|
||||
points in an audio waveform.
|
||||
|
||||
- SpectralCentroid calculates the centre of gravity of the frequency
|
||||
domain representation of each block of audio.
|
||||
|
||||
- AmplitudeFollower is an implementation of SuperCollider's
|
||||
amplitude-follower algorithm as a simple Vamp plugin.
|
||||
|
||||
- PercussionOnsetDetector estimates the locations of percussive
|
||||
onsets using a simple method described in "Drum Source Separation
|
||||
using Percussive Feature Detection and Spectral Modulation" by Dan
|
||||
Barry, Derry Fitzgerald, Eugene Coyle and Bob Lawlor, ISSC 2005.
|
||||
|
||||
\section hosts For Hosts
|
||||
|
||||
Hosts will normally use a Vamp::PluginHostAdapter to convert each
|
||||
plugin's exposed C API back into a useful Vamp::Plugin C++ object.
|
||||
|
||||
Starting with version 1.1 of the Vamp SDK, there are several classes
|
||||
in the Vamp::HostExt namespace that aim to make the host's life as
|
||||
easy as possible:
|
||||
|
||||
- Vamp::HostExt::PluginLoader provides a very simple interface for a
|
||||
host to discover, load, and find out category information about the
|
||||
available plugins. Most "casual" Vamp hosts will probably want to
|
||||
use this class.
|
||||
|
||||
- Vamp::HostExt::PluginInputDomainAdapter provides a simple means for
|
||||
hosts to handle plugins that expect frequency-domain input, without
|
||||
having to convert the input themselves.
|
||||
|
||||
- Vamp::HostExt::PluginChannelAdapter provides a simple means for
|
||||
hosts to use plugins that do not necessarily support the same number
|
||||
of audio channels as they have available, without having to apply a
|
||||
channel management / mixdown policy themselves.
|
||||
|
||||
The PluginLoader class can also use the input domain and channel
|
||||
adapters automatically to make the entire conversion process
|
||||
transparent to the host if required.
|
||||
|
||||
Hosts should link with -lvamp-hostsdk.
|
||||
|
||||
(The following notes in this section are mostly relevant for
|
||||
developers that are not using the HostExt classes, or that wish to
|
||||
know more about the policy they implement.)
|
||||
|
||||
The Vamp API does not officially specify how to load plugin libraries
|
||||
or where to find them. However, the SDK does include a function
|
||||
(Vamp::PluginHostAdapter::getPluginPath()) that returns a recommended
|
||||
directory search path that hosts may use for plugin libraries.
|
||||
|
||||
Our suggestion for a host is to search each directory in this path for
|
||||
.DLL (on Windows), .so (on Linux, Solaris, BSD etc) or .dylib (on
|
||||
OS/X) files, then to load each one and perform a dynamic name lookup
|
||||
on the vampGetPluginDescriptor function to enumerate the plugins in
|
||||
the library. The example host has some code that may help, but this
|
||||
operation will necessarily be system-dependent.
|
||||
|
||||
Vamp also has an informal convention for sorting plugins into
|
||||
functional categories. In addition to the library file itself, a
|
||||
plugin library may install a category file with the same name as the
|
||||
library but .cat extension. The existence and format of this file are
|
||||
not specified by the Vamp API, but by convention the file may contain
|
||||
lines of the format
|
||||
|
||||
\code
|
||||
vamp:pluginlibrary:pluginname::General Category > Specific Category
|
||||
\endcode
|
||||
|
||||
which a host may read and use to assign plugins a location within a
|
||||
category tree for display to the user. The expectation is that
|
||||
advanced users may also choose to set up their own preferred category
|
||||
trees, which is why this information is not queried as part of the
|
||||
Vamp API itself.
|
||||
|
||||
There is an example host in the "host" directory from which code may
|
||||
be drawn.
|
||||
|
||||
\section license License
|
||||
|
||||
This plugin SDK is freely redistributable under a "new-style BSD"
|
||||
licence. See the file COPYING for more details. In short, you may
|
||||
modify and redistribute the SDK and example plugins within any
|
||||
commercial or non-commercial, proprietary or open-source plugin or
|
||||
application under almost any conditions, with no obligation to provide
|
||||
source code, provided you retain the original copyright note.
|
||||
|
||||
|
||||
*/
|
||||
228
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp
Normal file
228
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/* -*- 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-2007 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 "PluginChannelAdapter.h"
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
class PluginChannelAdapter::Impl
|
||||
{
|
||||
public:
|
||||
Impl(Plugin *plugin);
|
||||
~Impl();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||
|
||||
protected:
|
||||
Plugin *m_plugin;
|
||||
size_t m_blockSize;
|
||||
size_t m_inputChannels;
|
||||
size_t m_pluginChannels;
|
||||
float **m_buffer;
|
||||
const float **m_forwardPtrs;
|
||||
};
|
||||
|
||||
PluginChannelAdapter::PluginChannelAdapter(Plugin *plugin) :
|
||||
PluginWrapper(plugin)
|
||||
{
|
||||
m_impl = new Impl(plugin);
|
||||
}
|
||||
|
||||
PluginChannelAdapter::~PluginChannelAdapter()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginChannelAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
return m_impl->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
||||
PluginChannelAdapter::FeatureSet
|
||||
PluginChannelAdapter::process(const float *const *inputBuffers,
|
||||
RealTime timestamp)
|
||||
{
|
||||
return m_impl->process(inputBuffers, timestamp);
|
||||
}
|
||||
|
||||
PluginChannelAdapter::Impl::Impl(Plugin *plugin) :
|
||||
m_plugin(plugin),
|
||||
m_blockSize(0),
|
||||
m_inputChannels(0),
|
||||
m_pluginChannels(0),
|
||||
m_buffer(0),
|
||||
m_forwardPtrs(0)
|
||||
{
|
||||
}
|
||||
|
||||
PluginChannelAdapter::Impl::~Impl()
|
||||
{
|
||||
// the adapter will delete the plugin
|
||||
|
||||
if (m_buffer) {
|
||||
if (m_inputChannels > m_pluginChannels) {
|
||||
delete[] m_buffer[0];
|
||||
} else {
|
||||
for (size_t i = 0; i < m_pluginChannels - m_inputChannels; ++i) {
|
||||
delete[] m_buffer[i];
|
||||
}
|
||||
}
|
||||
delete[] m_buffer;
|
||||
m_buffer = 0;
|
||||
}
|
||||
|
||||
if (m_forwardPtrs) {
|
||||
delete[] m_forwardPtrs;
|
||||
m_forwardPtrs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PluginChannelAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
m_blockSize = blockSize;
|
||||
|
||||
size_t minch = m_plugin->getMinChannelCount();
|
||||
size_t maxch = m_plugin->getMaxChannelCount();
|
||||
|
||||
m_inputChannels = channels;
|
||||
|
||||
if (m_inputChannels < minch) {
|
||||
|
||||
m_forwardPtrs = new const float *[minch];
|
||||
|
||||
if (m_inputChannels > 1) {
|
||||
// We need a set of zero-valued buffers to add to the
|
||||
// forwarded pointers
|
||||
m_buffer = new float*[minch - channels];
|
||||
for (size_t i = 0; i < minch; ++i) {
|
||||
m_buffer[i] = new float[blockSize];
|
||||
for (size_t j = 0; j < blockSize; ++j) {
|
||||
m_buffer[i][j] = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_pluginChannels = minch;
|
||||
|
||||
std::cerr << "PluginChannelAdapter::initialise: expanding " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl;
|
||||
|
||||
} else if (m_inputChannels > maxch) {
|
||||
|
||||
// We only need m_buffer if we are mixing down to a single
|
||||
// channel -- otherwise we can just forward the same float* as
|
||||
// passed in to process(), expecting the excess to be ignored
|
||||
|
||||
if (maxch == 1) {
|
||||
m_buffer = new float *[1];
|
||||
m_buffer[0] = new float[blockSize];
|
||||
|
||||
std::cerr << "PluginChannelAdapter::initialise: mixing " << m_inputChannels << " to mono for plugin" << std::endl;
|
||||
|
||||
} else {
|
||||
|
||||
std::cerr << "PluginChannelAdapter::initialise: reducing " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl;
|
||||
}
|
||||
|
||||
m_pluginChannels = maxch;
|
||||
|
||||
} else {
|
||||
|
||||
std::cerr << "PluginChannelAdapter::initialise: accepting given number of channels (" << m_inputChannels << ")" << std::endl;
|
||||
m_pluginChannels = m_inputChannels;
|
||||
}
|
||||
|
||||
return m_plugin->initialise(m_pluginChannels, stepSize, blockSize);
|
||||
}
|
||||
|
||||
PluginChannelAdapter::FeatureSet
|
||||
PluginChannelAdapter::Impl::process(const float *const *inputBuffers,
|
||||
RealTime timestamp)
|
||||
{
|
||||
// std::cerr << "PluginChannelAdapter::process: " << m_inputChannels << " -> " << m_pluginChannels << " channels" << std::endl;
|
||||
|
||||
if (m_inputChannels < m_pluginChannels) {
|
||||
|
||||
if (m_inputChannels == 1) {
|
||||
for (size_t i = 0; i < m_pluginChannels; ++i) {
|
||||
m_forwardPtrs[i] = inputBuffers[0];
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < m_inputChannels; ++i) {
|
||||
m_forwardPtrs[i] = inputBuffers[i];
|
||||
}
|
||||
for (size_t i = m_inputChannels; i < m_pluginChannels; ++i) {
|
||||
m_forwardPtrs[i] = m_buffer[i - m_inputChannels];
|
||||
}
|
||||
}
|
||||
|
||||
return m_plugin->process(m_forwardPtrs, timestamp);
|
||||
|
||||
} else if (m_inputChannels > m_pluginChannels) {
|
||||
|
||||
if (m_pluginChannels == 1) {
|
||||
for (size_t j = 0; j < m_blockSize; ++j) {
|
||||
m_buffer[0][j] = inputBuffers[0][j];
|
||||
}
|
||||
for (size_t i = 1; i < m_inputChannels; ++i) {
|
||||
for (size_t j = 0; j < m_blockSize; ++j) {
|
||||
m_buffer[0][j] += inputBuffers[i][j];
|
||||
}
|
||||
}
|
||||
for (size_t j = 0; j < m_blockSize; ++j) {
|
||||
m_buffer[0][j] /= m_inputChannels;
|
||||
}
|
||||
return m_plugin->process(m_buffer, timestamp);
|
||||
} else {
|
||||
return m_plugin->process(inputBuffers, timestamp);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
return m_plugin->process(inputBuffers, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
128
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h
Normal file
128
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/* -*- 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-2007 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_PLUGIN_CHANNEL_ADAPTER_H_
|
||||
#define _VAMP_PLUGIN_CHANNEL_ADAPTER_H_
|
||||
|
||||
#include "PluginWrapper.h"
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
/**
|
||||
* \class PluginChannelAdapter PluginChannelAdapter.h <vamp-sdk/hostext/PluginChannelAdapter.h>
|
||||
*
|
||||
* PluginChannelAdapter is a Vamp plugin adapter that implements a
|
||||
* policy for management of plugins that expect a different number of
|
||||
* input channels from the number actually available in the source
|
||||
* audio data.
|
||||
*
|
||||
* A host using PluginChannelAdapter may ignore the getMinChannelCount
|
||||
* and getMaxChannelCount reported by the plugin, and still expect the
|
||||
* plugin to run.
|
||||
*
|
||||
* PluginChannelAdapter implements the following policy:
|
||||
*
|
||||
* - If the plugin supports the provided number of channels directly,
|
||||
* PluginChannelAdapter will just run the plugin as normal.
|
||||
*
|
||||
* - If the plugin only supports exactly one channel but more than
|
||||
* one channel is provided, PluginChannelAdapter will use the mean of
|
||||
* the channels. This ensures that the resulting values remain
|
||||
* within the same magnitude range as expected for mono data.
|
||||
*
|
||||
* - If the plugin requires more than one channel but exactly one is
|
||||
* provided, the provided channel will be duplicated across all the
|
||||
* plugin input channels.
|
||||
*
|
||||
* If none of the above apply:
|
||||
*
|
||||
* - If the plugin requires more channels than are provided, the
|
||||
* minimum acceptable number of channels will be produced by adding
|
||||
* empty (zero valued) channels to those provided.
|
||||
*
|
||||
* - If the plugin requires fewer channels than are provided, the
|
||||
* maximum acceptable number of channels will be produced by
|
||||
* discarding the excess channels.
|
||||
*
|
||||
* Hosts requiring a different channel policy from the above will need
|
||||
* to implement it themselves, instead of using PluginChannelAdapter.
|
||||
*
|
||||
* Note that PluginChannelAdapter does not override the minimum and
|
||||
* maximum channel counts returned by the wrapped plugin. The host
|
||||
* will need to be aware that it is using a PluginChannelAdapter, and
|
||||
* be prepared to ignore these counts as necessary. (This contrasts
|
||||
* with the approach used in PluginInputDomainAdapter, which aims to
|
||||
* make the host completely unaware of which underlying input domain
|
||||
* is in fact in use.)
|
||||
*
|
||||
* (The rationale for this is that a host may wish to use the
|
||||
* PluginChannelAdapter but still discriminate in some way on the
|
||||
* basis of the number of channels actually supported. For example, a
|
||||
* simple stereo audio host may prefer to reject plugins that require
|
||||
* more than two channels on the grounds that doesn't actually
|
||||
* understand what they are for, rather than allow the channel adapter
|
||||
* to make a potentially meaningless channel conversion for them.)
|
||||
*
|
||||
* In every respect other than its management of channels, the
|
||||
* PluginChannelAdapter behaves identically to the plugin that it
|
||||
* wraps. The wrapped plugin will be deleted when the wrapper is
|
||||
* deleted.
|
||||
*
|
||||
* \note This class was introduced in version 1.1 of the Vamp plugin SDK.
|
||||
*/
|
||||
|
||||
class PluginChannelAdapter : public PluginWrapper
|
||||
{
|
||||
public:
|
||||
PluginChannelAdapter(Plugin *plugin); // I take ownership of plugin
|
||||
virtual ~PluginChannelAdapter();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||
|
||||
protected:
|
||||
class Impl;
|
||||
Impl *m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
458
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
Normal file
458
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
Normal file
|
|
@ -0,0 +1,458 @@
|
|||
/* -*- 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-2007 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 "PluginInputDomainAdapter.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
class PluginInputDomainAdapter::Impl
|
||||
{
|
||||
public:
|
||||
Impl(Plugin *plugin, float inputSampleRate);
|
||||
~Impl();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
|
||||
size_t getPreferredStepSize() const;
|
||||
size_t getPreferredBlockSize() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||
|
||||
protected:
|
||||
Plugin *m_plugin;
|
||||
float m_inputSampleRate;
|
||||
size_t m_channels;
|
||||
size_t m_blockSize;
|
||||
float **m_freqbuf;
|
||||
double *m_ri;
|
||||
double *m_ro;
|
||||
double *m_io;
|
||||
|
||||
void fft(unsigned int n, bool inverse,
|
||||
double *ri, double *ii, double *ro, double *io);
|
||||
|
||||
size_t makeBlockSizeAcceptable(size_t) const;
|
||||
};
|
||||
|
||||
PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) :
|
||||
PluginWrapper(plugin)
|
||||
{
|
||||
m_impl = new Impl(plugin, m_inputSampleRate);
|
||||
}
|
||||
|
||||
PluginInputDomainAdapter::~PluginInputDomainAdapter()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInputDomainAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
return m_impl->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
||||
Plugin::InputDomain
|
||||
PluginInputDomainAdapter::getInputDomain() const
|
||||
{
|
||||
return TimeDomain;
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginInputDomainAdapter::getPreferredStepSize() const
|
||||
{
|
||||
return m_impl->getPreferredStepSize();
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginInputDomainAdapter::getPreferredBlockSize() const
|
||||
{
|
||||
return m_impl->getPreferredBlockSize();
|
||||
}
|
||||
|
||||
Plugin::FeatureSet
|
||||
PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime timestamp)
|
||||
{
|
||||
return m_impl->process(inputBuffers, timestamp);
|
||||
}
|
||||
|
||||
PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
|
||||
m_plugin(plugin),
|
||||
m_inputSampleRate(inputSampleRate),
|
||||
m_channels(0),
|
||||
m_blockSize(0),
|
||||
m_freqbuf(0)
|
||||
{
|
||||
}
|
||||
|
||||
PluginInputDomainAdapter::Impl::~Impl()
|
||||
{
|
||||
// the adapter will delete the plugin
|
||||
|
||||
if (m_channels > 0) {
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
delete[] m_freqbuf[c];
|
||||
}
|
||||
delete[] m_freqbuf;
|
||||
delete[] m_ri;
|
||||
delete[] m_ro;
|
||||
delete[] m_io;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
if (m_plugin->getInputDomain() == TimeDomain) {
|
||||
|
||||
m_blockSize = blockSize;
|
||||
m_channels = channels;
|
||||
|
||||
return m_plugin->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
||||
if (blockSize < 2) {
|
||||
std::cerr << "ERROR: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: blocksize < 2 not supported" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockSize & (blockSize-1)) {
|
||||
std::cerr << "ERROR: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_channels > 0) {
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
delete[] m_freqbuf[c];
|
||||
}
|
||||
delete[] m_freqbuf;
|
||||
delete[] m_ri;
|
||||
delete[] m_ro;
|
||||
delete[] m_io;
|
||||
}
|
||||
|
||||
m_blockSize = blockSize;
|
||||
m_channels = channels;
|
||||
|
||||
m_freqbuf = new float *[m_channels];
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
m_freqbuf[c] = new float[m_blockSize + 2];
|
||||
}
|
||||
m_ri = new double[m_blockSize];
|
||||
m_ro = new double[m_blockSize];
|
||||
m_io = new double[m_blockSize];
|
||||
|
||||
return m_plugin->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginInputDomainAdapter::Impl::getPreferredStepSize() const
|
||||
{
|
||||
size_t step = m_plugin->getPreferredStepSize();
|
||||
|
||||
if (step == 0 && (m_plugin->getInputDomain() == FrequencyDomain)) {
|
||||
step = getPreferredBlockSize() / 2;
|
||||
}
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginInputDomainAdapter::Impl::getPreferredBlockSize() const
|
||||
{
|
||||
size_t block = m_plugin->getPreferredBlockSize();
|
||||
|
||||
if (m_plugin->getInputDomain() == FrequencyDomain) {
|
||||
if (block == 0) {
|
||||
block = 1024;
|
||||
} else {
|
||||
block = makeBlockSizeAcceptable(block);
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
|
||||
{
|
||||
if (blockSize < 2) {
|
||||
|
||||
std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: blocksize < 2 not" << std::endl
|
||||
<< "supported, increasing from " << blockSize << " to 2" << std::endl;
|
||||
blockSize = 2;
|
||||
|
||||
} else if (blockSize & (blockSize-1)) {
|
||||
|
||||
// not a power of two, can't handle that with our current 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: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl;
|
||||
blockSize = nearest;
|
||||
}
|
||||
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
// for some visual studii apparently
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979232846
|
||||
#endif
|
||||
|
||||
Plugin::FeatureSet
|
||||
PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
||||
RealTime timestamp)
|
||||
{
|
||||
if (m_plugin->getInputDomain() == TimeDomain) {
|
||||
return m_plugin->process(inputBuffers, timestamp);
|
||||
}
|
||||
|
||||
// The timestamp supplied should be (according to the Vamp::Plugin
|
||||
// spec) the time of the start of the time-domain input block.
|
||||
// However, we want to pass to the plugin an FFT output calculated
|
||||
// from the block of samples _centred_ on that timestamp.
|
||||
//
|
||||
// We have two options:
|
||||
//
|
||||
// 1. Buffer the input, calculating the fft of the values at the
|
||||
// passed-in block minus blockSize/2 rather than starting at the
|
||||
// passed-in block. So each time we call process on the plugin,
|
||||
// we are passing in the same timestamp as was passed to our own
|
||||
// process plugin, but not (the frequency domain representation
|
||||
// of) the same set of samples. Advantages: avoids confusion in
|
||||
// the host by ensuring the returned values have timestamps
|
||||
// comparable with that passed in to this function (in fact this
|
||||
// is pretty much essential for one-value-per-block outputs);
|
||||
// consistent with hosts such as SV that deal with the
|
||||
// frequency-domain transform themselves. Disadvantages: means
|
||||
// making the not necessarily correct assumption that the samples
|
||||
// preceding the first official block are all zero (or some other
|
||||
// known value).
|
||||
//
|
||||
// 2. Increase the passed-in timestamps by half the blocksize. So
|
||||
// when we call process, we are passing in the frequency domain
|
||||
// representation of the same set of samples as passed to us, but
|
||||
// with a different timestamp. Advantages: simplicity; avoids
|
||||
// iffy assumption mentioned above. Disadvantages: inconsistency
|
||||
// with SV in cases where stepSize != blockSize/2; potential
|
||||
// confusion arising from returned timestamps being calculated
|
||||
// from the adjusted input timestamps rather than the original
|
||||
// ones (and inaccuracy where the returned timestamp is implied,
|
||||
// as in one-value-per-block).
|
||||
//
|
||||
// Neither way is ideal, but I don't think either is strictly
|
||||
// incorrect either. I think this is just a case where the same
|
||||
// plugin can legitimately produce differing results from the same
|
||||
// input data, depending on how that data is packaged.
|
||||
//
|
||||
// We'll go for option 2, adjusting the timestamps. Note in
|
||||
// particular that this means some results can differ from those
|
||||
// produced by SV.
|
||||
|
||||
// std::cerr << "PluginInputDomainAdapter: sampleRate " << m_inputSampleRate << ", blocksize " << m_blockSize << ", adjusting time from " << timestamp;
|
||||
|
||||
timestamp = timestamp + RealTime::frame2RealTime
|
||||
(m_blockSize/2, int(m_inputSampleRate + 0.5));
|
||||
|
||||
// std::cerr << " to " << timestamp << std::endl;
|
||||
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
|
||||
for (size_t i = 0; i < m_blockSize; ++i) {
|
||||
// Hanning window
|
||||
m_ri[i] = double(inputBuffers[c][i])
|
||||
* (0.50 - 0.50 * cos((2 * M_PI * i)
|
||||
/ m_blockSize));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_blockSize/2; ++i) {
|
||||
// FFT shift
|
||||
double value = m_ri[i];
|
||||
m_ri[i] = m_ri[i + m_blockSize/2];
|
||||
m_ri[i + m_blockSize/2] = value;
|
||||
}
|
||||
|
||||
fft(m_blockSize, false, m_ri, 0, m_ro, m_io);
|
||||
|
||||
for (size_t i = 0; i <= m_blockSize/2; ++i) {
|
||||
m_freqbuf[c][i * 2] = m_ro[i];
|
||||
m_freqbuf[c][i * 2 + 1] = m_io[i];
|
||||
}
|
||||
}
|
||||
|
||||
return m_plugin->process(m_freqbuf, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse,
|
||||
double *ri, 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;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int tableSize = 0;
|
||||
static int *table = 0;
|
||||
|
||||
if (tableSize != n) {
|
||||
|
||||
delete[] table;
|
||||
|
||||
table = new int[n];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
tableSize = n;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ai[2] = sm2;
|
||||
ai[1] = sm1;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
103
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h
Normal file
103
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- 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-2007 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_PLUGIN_INPUT_DOMAIN_ADAPTER_H_
|
||||
#define _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_
|
||||
|
||||
#include "PluginWrapper.h"
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
/**
|
||||
* \class PluginInputDomainAdapter PluginInputDomainAdapter.h <vamp-sdk/hostext/PluginInputDomainAdapter.h>
|
||||
*
|
||||
* PluginInputDomainAdapter is a Vamp plugin adapter that converts
|
||||
* time-domain input into frequency-domain input for plugins that need
|
||||
* it. This permits a host to use time- and frequency-domain plugins
|
||||
* interchangeably without needing to handle the conversion itself.
|
||||
*
|
||||
* This adapter uses a basic Hanning windowed FFT that supports
|
||||
* power-of-two block sizes only. If a frequency domain plugin
|
||||
* requests a non-power-of-two blocksize, the adapter will adjust it
|
||||
* to a nearby power of two instead. Thus, getPreferredBlockSize()
|
||||
* will always return a power of two if the wrapped plugin is a
|
||||
* frequency domain one. If the plugin doesn't accept the adjusted
|
||||
* power of two block size, initialise() will fail.
|
||||
*
|
||||
* The adapter provides no way for the host to discover whether the
|
||||
* underlying plugin is actually a time or frequency domain plugin
|
||||
* (except that if the preferred block size is not a power of two, it
|
||||
* must be a time domain plugin).
|
||||
*
|
||||
* The FFT implementation is simple and self-contained, but unlikely
|
||||
* to be the fastest available: a host can usually do better if it
|
||||
* cares enough.
|
||||
*
|
||||
* In every respect other than its input domain handling, the
|
||||
* PluginInputDomainAdapter behaves identically to the plugin that it
|
||||
* wraps. The wrapped plugin will be deleted when the wrapper is
|
||||
* deleted.
|
||||
*
|
||||
* \note This class was introduced in version 1.1 of the Vamp plugin SDK.
|
||||
*/
|
||||
|
||||
class PluginInputDomainAdapter : public PluginWrapper
|
||||
{
|
||||
public:
|
||||
PluginInputDomainAdapter(Plugin *plugin); // I take ownership of plugin
|
||||
virtual ~PluginInputDomainAdapter();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
|
||||
InputDomain getInputDomain() const;
|
||||
|
||||
size_t getPreferredStepSize() const;
|
||||
size_t getPreferredBlockSize() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||
|
||||
protected:
|
||||
class Impl;
|
||||
Impl *m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
601
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
Normal file
601
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
Normal file
|
|
@ -0,0 +1,601 @@
|
|||
/* -*- 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-2007 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-sdk/PluginHostAdapter.h"
|
||||
#include "PluginLoader.h"
|
||||
#include "PluginInputDomainAdapter.h"
|
||||
#include "PluginChannelAdapter.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <cctype> // tolower
|
||||
|
||||
#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;
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
class PluginLoader::Impl
|
||||
{
|
||||
public:
|
||||
Impl();
|
||||
virtual ~Impl();
|
||||
|
||||
PluginKeyList listPlugins();
|
||||
|
||||
Plugin *loadPlugin(PluginKey key,
|
||||
float inputSampleRate,
|
||||
int adapterFlags);
|
||||
|
||||
PluginKey composePluginKey(string libraryName, string identifier);
|
||||
|
||||
PluginCategoryHierarchy getPluginCategory(PluginKey key);
|
||||
|
||||
string getLibraryPathForPlugin(PluginKey key);
|
||||
|
||||
protected:
|
||||
class PluginDeletionNotifyAdapter : public PluginWrapper {
|
||||
public:
|
||||
PluginDeletionNotifyAdapter(Plugin *plugin, Impl *loader);
|
||||
virtual ~PluginDeletionNotifyAdapter();
|
||||
protected:
|
||||
Impl *m_loader;
|
||||
};
|
||||
|
||||
virtual void pluginDeleted(PluginDeletionNotifyAdapter *adapter);
|
||||
|
||||
map<PluginKey, string> m_pluginLibraryNameMap;
|
||||
bool m_allPluginsEnumerated;
|
||||
void enumeratePlugins(PluginKey forPlugin = "");
|
||||
|
||||
map<PluginKey, PluginCategoryHierarchy> m_taxonomy;
|
||||
void generateTaxonomy();
|
||||
|
||||
map<Plugin *, void *> m_pluginLibraryHandleMap;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
PluginLoader *
|
||||
PluginLoader::m_instance = 0;
|
||||
|
||||
PluginLoader::PluginLoader()
|
||||
{
|
||||
m_impl = new Impl();
|
||||
}
|
||||
|
||||
PluginLoader::~PluginLoader()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
PluginLoader *
|
||||
PluginLoader::getInstance()
|
||||
{
|
||||
if (!m_instance) m_instance = new PluginLoader();
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
vector<PluginLoader::PluginKey>
|
||||
PluginLoader::listPlugins()
|
||||
{
|
||||
return m_impl->listPlugins();
|
||||
}
|
||||
|
||||
Plugin *
|
||||
PluginLoader::loadPlugin(PluginKey key,
|
||||
float inputSampleRate,
|
||||
int adapterFlags)
|
||||
{
|
||||
return m_impl->loadPlugin(key, inputSampleRate, adapterFlags);
|
||||
}
|
||||
|
||||
PluginLoader::PluginKey
|
||||
PluginLoader::composePluginKey(string libraryName, string identifier)
|
||||
{
|
||||
return m_impl->composePluginKey(libraryName, identifier);
|
||||
}
|
||||
|
||||
PluginLoader::PluginCategoryHierarchy
|
||||
PluginLoader::getPluginCategory(PluginKey key)
|
||||
{
|
||||
return m_impl->getPluginCategory(key);
|
||||
}
|
||||
|
||||
string
|
||||
PluginLoader::getLibraryPathForPlugin(PluginKey key)
|
||||
{
|
||||
return m_impl->getLibraryPathForPlugin(key);
|
||||
}
|
||||
|
||||
PluginLoader::Impl::Impl() :
|
||||
m_allPluginsEnumerated(false)
|
||||
{
|
||||
}
|
||||
|
||||
PluginLoader::Impl::~Impl()
|
||||
{
|
||||
}
|
||||
|
||||
vector<PluginLoader::PluginKey>
|
||||
PluginLoader::Impl::listPlugins()
|
||||
{
|
||||
if (!m_allPluginsEnumerated) enumeratePlugins();
|
||||
|
||||
vector<PluginKey> plugins;
|
||||
for (map<PluginKey, string>::iterator mi = m_pluginLibraryNameMap.begin();
|
||||
mi != m_pluginLibraryNameMap.end(); ++mi) {
|
||||
plugins.push_back(mi->first);
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
void
|
||||
PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin)
|
||||
{
|
||||
vector<string> path = PluginHostAdapter::getPluginPath();
|
||||
|
||||
string libraryName, identifier;
|
||||
if (forPlugin != "") {
|
||||
if (!decomposePluginKey(forPlugin, libraryName, identifier)) {
|
||||
std::cerr << "WARNING: Vamp::HostExt::PluginLoader: Invalid plugin key \""
|
||||
<< forPlugin << "\" in enumerate" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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 != "") {
|
||||
// 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)lookupInLibrary
|
||||
(handle, "vampGetPluginDescriptor");
|
||||
|
||||
if (!fn) {
|
||||
unloadLibrary(handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
const VampPluginDescriptor *descriptor = 0;
|
||||
|
||||
while ((descriptor = fn(VAMP_API_VERSION, index))) {
|
||||
++index;
|
||||
if (identifier != "") {
|
||||
if (descriptor->identifier != identifier) continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
unloadLibrary(handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (forPlugin == "") m_allPluginsEnumerated = true;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
return basename + ":" + identifier;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginLoader::Impl::decomposePluginKey(PluginKey key,
|
||||
string &libraryName,
|
||||
string &identifier)
|
||||
{
|
||||
string::size_type ki = key.find(':');
|
||||
if (ki == string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
libraryName = key.substr(0, ki);
|
||||
identifier = key.substr(ki + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
PluginLoader::PluginCategoryHierarchy
|
||||
PluginLoader::Impl::getPluginCategory(PluginKey plugin)
|
||||
{
|
||||
if (m_taxonomy.empty()) generateTaxonomy();
|
||||
if (m_taxonomy.find(plugin) == m_taxonomy.end()) {
|
||||
return PluginCategoryHierarchy();
|
||||
}
|
||||
return m_taxonomy[plugin];
|
||||
}
|
||||
|
||||
string
|
||||
PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin)
|
||||
{
|
||||
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
|
||||
if (m_allPluginsEnumerated) return "";
|
||||
enumeratePlugins(plugin);
|
||||
}
|
||||
if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
|
||||
return "";
|
||||
}
|
||||
return m_pluginLibraryNameMap[plugin];
|
||||
}
|
||||
|
||||
Plugin *
|
||||
PluginLoader::Impl::loadPlugin(PluginKey key,
|
||||
float inputSampleRate, int adapterFlags)
|
||||
{
|
||||
string libname, identifier;
|
||||
if (!decomposePluginKey(key, libname, identifier)) {
|
||||
std::cerr << "Vamp::HostExt::PluginLoader: Invalid plugin key \""
|
||||
<< key << "\" in loadPlugin" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
string fullPath = getLibraryPathForPlugin(key);
|
||||
if (fullPath == "") return 0;
|
||||
|
||||
void *handle = loadLibrary(fullPath);
|
||||
if (!handle) return 0;
|
||||
|
||||
VampGetPluginDescriptorFunction fn =
|
||||
(VampGetPluginDescriptorFunction)lookupInLibrary
|
||||
(handle, "vampGetPluginDescriptor");
|
||||
|
||||
if (!fn) {
|
||||
unloadLibrary(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
const VampPluginDescriptor *descriptor = 0;
|
||||
|
||||
while ((descriptor = fn(VAMP_API_VERSION, index))) {
|
||||
|
||||
if (string(descriptor->identifier) == identifier) {
|
||||
|
||||
Vamp::PluginHostAdapter *plugin =
|
||||
new Vamp::PluginHostAdapter(descriptor, inputSampleRate);
|
||||
|
||||
Plugin *adapter = new PluginDeletionNotifyAdapter(plugin, this);
|
||||
|
||||
m_pluginLibraryHandleMap[adapter] = handle;
|
||||
|
||||
if (adapterFlags & ADAPT_INPUT_DOMAIN) {
|
||||
if (adapter->getInputDomain() == Plugin::FrequencyDomain) {
|
||||
adapter = new PluginInputDomainAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
if (adapterFlags & ADAPT_CHANNEL_COUNT) {
|
||||
adapter = new PluginChannelAdapter(adapter);
|
||||
}
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
cerr << "Vamp::HostExt::PluginLoader: Plugin \""
|
||||
<< identifier << "\" not found in library \""
|
||||
<< fullPath << "\"" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PluginLoader::Impl::generateTaxonomy()
|
||||
{
|
||||
// cerr << "PluginLoader::Impl::generateTaxonomy" << endl;
|
||||
|
||||
vector<string> path = PluginHostAdapter::getPluginPath();
|
||||
string libfragment = "/lib/";
|
||||
vector<string> catpath;
|
||||
|
||||
string suffix = "cat";
|
||||
|
||||
for (vector<string>::iterator i = path.begin();
|
||||
i != path.end(); ++i) {
|
||||
|
||||
// It doesn't matter that we're using literal forward-slash in
|
||||
// this bit, as it's only relevant if the path contains
|
||||
// "/lib/", which is only meaningful and only plausible on
|
||||
// systems with forward-slash delimiters
|
||||
|
||||
string dir = *i;
|
||||
string::size_type li = dir.find(libfragment);
|
||||
|
||||
if (li != string::npos) {
|
||||
catpath.push_back
|
||||
(dir.substr(0, li)
|
||||
+ "/share/"
|
||||
+ dir.substr(li + libfragment.length()));
|
||||
}
|
||||
|
||||
catpath.push_back(dir);
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
|
||||
for (vector<string>::iterator i = catpath.begin();
|
||||
i != catpath.end(); ++i) {
|
||||
|
||||
vector<string> files = listFiles(*i, suffix);
|
||||
|
||||
for (vector<string>::iterator fi = files.begin();
|
||||
fi != files.end(); ++fi) {
|
||||
|
||||
string filepath = splicePath(*i, *fi);
|
||||
ifstream is(filepath.c_str(), ifstream::in | ifstream::binary);
|
||||
|
||||
if (is.fail()) {
|
||||
// cerr << "failed to open: " << filepath << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// cerr << "opened: " << filepath << endl;
|
||||
|
||||
while (!!is.getline(buffer, 1024)) {
|
||||
|
||||
string line(buffer);
|
||||
|
||||
// cerr << "line = " << line << endl;
|
||||
|
||||
string::size_type di = line.find("::");
|
||||
if (di == string::npos) continue;
|
||||
|
||||
string id = line.substr(0, di);
|
||||
string encodedCat = line.substr(di + 2);
|
||||
|
||||
if (id.substr(0, 5) != "vamp:") continue;
|
||||
id = id.substr(5);
|
||||
|
||||
while (encodedCat.length() >= 1 &&
|
||||
encodedCat[encodedCat.length()-1] == '\r') {
|
||||
encodedCat = encodedCat.substr(0, encodedCat.length()-1);
|
||||
}
|
||||
|
||||
// cerr << "id = " << id << ", cat = " << encodedCat << endl;
|
||||
|
||||
PluginCategoryHierarchy category;
|
||||
string::size_type ai;
|
||||
while ((ai = encodedCat.find(" > ")) != string::npos) {
|
||||
category.push_back(encodedCat.substr(0, ai));
|
||||
encodedCat = encodedCat.substr(ai + 3);
|
||||
}
|
||||
if (encodedCat != "") category.push_back(encodedCat);
|
||||
|
||||
m_taxonomy[id] = category;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
PluginLoader::Impl::loadLibrary(string path)
|
||||
{
|
||||
void *handle = 0;
|
||||
#ifdef _WIN32
|
||||
handle = LoadLibrary(path.c_str());
|
||||
if (!handle) {
|
||||
cerr << "Vamp::HostExt::PluginLoader: Unable to load library \""
|
||||
<< path << "\"" << endl;
|
||||
}
|
||||
#else
|
||||
handle = dlopen(path.c_str(), RTLD_LAZY);
|
||||
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;
|
||||
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);
|
||||
|
||||
#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_type & DT_REG) || !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);
|
||||
m_pluginLibraryHandleMap.erase(adapter);
|
||||
}
|
||||
|
||||
PluginLoader::Impl::PluginDeletionNotifyAdapter::PluginDeletionNotifyAdapter(Plugin *plugin,
|
||||
Impl *loader) :
|
||||
PluginWrapper(plugin),
|
||||
m_loader(loader)
|
||||
{
|
||||
}
|
||||
|
||||
PluginLoader::Impl::PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter()
|
||||
{
|
||||
// We need to delete the plugin before calling pluginDeleted, as
|
||||
// the delete call may require calling through to the descriptor
|
||||
// (for e.g. cleanup) but pluginDeleted may unload the required
|
||||
// library for the call. To prevent a double deletion when our
|
||||
// parent's destructor runs (after this one), be sure to set
|
||||
// m_plugin to 0 after deletion.
|
||||
delete m_plugin;
|
||||
m_plugin = 0;
|
||||
|
||||
if (m_loader) m_loader->pluginDeleted(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
218
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h
Normal file
218
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/* -*- 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-2007 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_PLUGIN_LOADER_H_
|
||||
#define _VAMP_PLUGIN_LOADER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "PluginWrapper.h"
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
class Plugin;
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
/**
|
||||
* \class PluginLoader PluginLoader.h <vamp-sdk/hostext/PluginLoader.h>
|
||||
*
|
||||
* Vamp::HostExt::PluginLoader is a convenience class for discovering
|
||||
* and loading Vamp plugins using the typical plugin-path, library
|
||||
* naming, and categorisation conventions described in the Vamp SDK
|
||||
* documentation. This class is intended to greatly simplify the task
|
||||
* of becoming a Vamp plugin host for any C++ application.
|
||||
*
|
||||
* Hosts are not required by the Vamp specification to use the same
|
||||
* plugin search path and naming conventions as implemented by this
|
||||
* class, and are certainly not required to use this actual class.
|
||||
* But we do strongly recommend it.
|
||||
*
|
||||
* \note This class was introduced in version 1.1 of the Vamp plugin SDK.
|
||||
*/
|
||||
|
||||
class PluginLoader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Obtain a pointer to the singleton instance of PluginLoader.
|
||||
* Use this to obtain your loader object.
|
||||
*/
|
||||
static PluginLoader *getInstance();
|
||||
|
||||
/**
|
||||
* PluginKey is a string type that is used to identify a plugin
|
||||
* uniquely within the scope of "the current system". It consists
|
||||
* of the lower-cased base name of the plugin library, a colon
|
||||
* separator, and the identifier string for the plugin. It is
|
||||
* only meaningful in the context of a given plugin path (the one
|
||||
* returned by PluginHostAdapter::getPluginPath()).
|
||||
*
|
||||
* Use composePluginKey() to construct a plugin key from a known
|
||||
* plugin library name and identifier.
|
||||
*
|
||||
* Note: the fact that the library component of the key is
|
||||
* lower-cased implies that library names are matched
|
||||
* case-insensitively by the PluginLoader class, regardless of the
|
||||
* case sensitivity of the underlying filesystem. (Plugin
|
||||
* identifiers _are_ case sensitive, however.) Also, it is not
|
||||
* possible to portably extract a working library name from a
|
||||
* plugin key, as the result may fail on case-sensitive
|
||||
* filesystems. Use getLibraryPathForPlugin() instead.
|
||||
*/
|
||||
typedef std::string PluginKey;
|
||||
|
||||
/**
|
||||
* PluginKeyList is a sequence of plugin keys, such as returned by
|
||||
* listPlugins().
|
||||
*/
|
||||
typedef std::vector<PluginKey> PluginKeyList;
|
||||
|
||||
/**
|
||||
* PluginCategoryHierarchy is a sequence of general->specific
|
||||
* category names, as may be associated with a single plugin.
|
||||
* This sequence describes the location of a plugin within a
|
||||
* category forest, containing the human-readable names of the
|
||||
* plugin's category tree root, followed by each of the nodes down
|
||||
* to the leaf containing the plugin.
|
||||
*
|
||||
* \see getPluginCategory()
|
||||
*/
|
||||
typedef std::vector<std::string> PluginCategoryHierarchy;
|
||||
|
||||
/**
|
||||
* Search for all available Vamp plugins, and return a list of
|
||||
* them in the order in which they were found.
|
||||
*/
|
||||
PluginKeyList listPlugins();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* does not want to cater for complex features.
|
||||
*
|
||||
* The available flags are:
|
||||
*
|
||||
* ADAPT_INPUT_DOMAIN - If the plugin expects frequency domain
|
||||
* input, wrap it in a PluginInputDomainAdapter that automatically
|
||||
* converts the plugin to one that expects time-domain input.
|
||||
* This enables a host to accommodate time- and frequency-domain
|
||||
* plugins without needing to do any conversion itself.
|
||||
*
|
||||
* ADAPT_CHANNEL_COUNT - Wrap the plugin in a PluginChannelAdapter
|
||||
* to handle any mismatch between the number of channels of audio
|
||||
* the plugin can handle and the number available in the host.
|
||||
* This enables a host to use plugins that may require the input
|
||||
* to be mixed down to mono, etc., without having to worry about
|
||||
* doing that itself.
|
||||
*
|
||||
* ADAPT_ALL - Perform all available adaptations, where meaningful.
|
||||
*
|
||||
* See PluginInputDomainAdapter and PluginChannelAdapter for more
|
||||
* details of the classes that the loader may use if these flags
|
||||
* are set.
|
||||
*/
|
||||
enum AdapterFlags {
|
||||
ADAPT_INPUT_DOMAIN = 0x01,
|
||||
ADAPT_CHANNEL_COUNT = 0x02,
|
||||
ADAPT_ALL = 0xff
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a Vamp plugin, given its identifying key. If the plugin
|
||||
* could not be loaded, returns 0.
|
||||
*
|
||||
* The returned plugin should be deleted (using the standard C++
|
||||
* delete keyword) after use.
|
||||
*
|
||||
* \param adapterFlags a bitwise OR of the values in the AdapterFlags
|
||||
* enumeration, indicating under which circumstances an adapter should be
|
||||
* used to wrap the original plugin. If adapterFlags is 0, no
|
||||
* optional adapters will be used. Otherwise, the returned plugin
|
||||
* may be of an adapter class type which will behave identically
|
||||
* to the original plugin, apart from any particular features
|
||||
* implemented by the adapter itself.
|
||||
*
|
||||
* \see AdapterFlags, PluginInputDomainAdapter, PluginChannelAdapter
|
||||
*/
|
||||
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
|
||||
* loadPlugin().
|
||||
*/
|
||||
PluginKey composePluginKey(std::string libraryName,
|
||||
std::string identifier);
|
||||
|
||||
/**
|
||||
* Return the category hierarchy for a Vamp plugin, given its
|
||||
* identifying key.
|
||||
*
|
||||
* If the plugin has no category information, return an empty
|
||||
* hierarchy.
|
||||
*
|
||||
* \see PluginCategoryHierarchy
|
||||
*/
|
||||
PluginCategoryHierarchy getPluginCategory(PluginKey plugin);
|
||||
|
||||
/**
|
||||
* Return the file path of the dynamic library from which the
|
||||
* given plugin will be loaded (if available).
|
||||
*/
|
||||
std::string getLibraryPathForPlugin(PluginKey plugin);
|
||||
|
||||
protected:
|
||||
PluginLoader();
|
||||
virtual ~PluginLoader();
|
||||
|
||||
class Impl;
|
||||
Impl *m_impl;
|
||||
|
||||
static PluginLoader *m_instance;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
201
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp
Normal file
201
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/* -*- 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-2007 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 "PluginWrapper.h"
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
class PluginRateExtractor : public Plugin
|
||||
{
|
||||
public:
|
||||
PluginRateExtractor() : Plugin(0) { }
|
||||
float getRate() const { return m_inputSampleRate; }
|
||||
};
|
||||
|
||||
PluginWrapper::PluginWrapper(Plugin *plugin) :
|
||||
Plugin(((PluginRateExtractor *)plugin)->getRate()),
|
||||
m_plugin(plugin)
|
||||
{
|
||||
}
|
||||
|
||||
PluginWrapper::~PluginWrapper()
|
||||
{
|
||||
delete m_plugin;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginWrapper::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
return m_plugin->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
||||
void
|
||||
PluginWrapper::reset()
|
||||
{
|
||||
m_plugin->reset();
|
||||
}
|
||||
|
||||
Plugin::InputDomain
|
||||
PluginWrapper::getInputDomain() const
|
||||
{
|
||||
return m_plugin->getInputDomain();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PluginWrapper::getVampApiVersion() const
|
||||
{
|
||||
return m_plugin->getVampApiVersion();
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginWrapper::getIdentifier() const
|
||||
{
|
||||
return m_plugin->getIdentifier();
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginWrapper::getName() const
|
||||
{
|
||||
return m_plugin->getName();
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginWrapper::getDescription() const
|
||||
{
|
||||
return m_plugin->getDescription();
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginWrapper::getMaker() const
|
||||
{
|
||||
return m_plugin->getMaker();
|
||||
}
|
||||
|
||||
int
|
||||
PluginWrapper::getPluginVersion() const
|
||||
{
|
||||
return m_plugin->getPluginVersion();
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginWrapper::getCopyright() const
|
||||
{
|
||||
return m_plugin->getCopyright();
|
||||
}
|
||||
|
||||
PluginBase::ParameterList
|
||||
PluginWrapper::getParameterDescriptors() const
|
||||
{
|
||||
return m_plugin->getParameterDescriptors();
|
||||
}
|
||||
|
||||
float
|
||||
PluginWrapper::getParameter(std::string parameter) const
|
||||
{
|
||||
return m_plugin->getParameter(parameter);
|
||||
}
|
||||
|
||||
void
|
||||
PluginWrapper::setParameter(std::string parameter, float value)
|
||||
{
|
||||
m_plugin->setParameter(parameter, value);
|
||||
}
|
||||
|
||||
PluginBase::ProgramList
|
||||
PluginWrapper::getPrograms() const
|
||||
{
|
||||
return m_plugin->getPrograms();
|
||||
}
|
||||
|
||||
std::string
|
||||
PluginWrapper::getCurrentProgram() const
|
||||
{
|
||||
return m_plugin->getCurrentProgram();
|
||||
}
|
||||
|
||||
void
|
||||
PluginWrapper::selectProgram(std::string program)
|
||||
{
|
||||
m_plugin->selectProgram(program);
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginWrapper::getPreferredStepSize() const
|
||||
{
|
||||
return m_plugin->getPreferredStepSize();
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginWrapper::getPreferredBlockSize() const
|
||||
{
|
||||
return m_plugin->getPreferredBlockSize();
|
||||
}
|
||||
|
||||
size_t
|
||||
PluginWrapper::getMinChannelCount() const
|
||||
{
|
||||
return m_plugin->getMinChannelCount();
|
||||
}
|
||||
|
||||
size_t PluginWrapper::getMaxChannelCount() const
|
||||
{
|
||||
return m_plugin->getMaxChannelCount();
|
||||
}
|
||||
|
||||
Plugin::OutputList
|
||||
PluginWrapper::getOutputDescriptors() const
|
||||
{
|
||||
return m_plugin->getOutputDescriptors();
|
||||
}
|
||||
|
||||
Plugin::FeatureSet
|
||||
PluginWrapper::process(const float *const *inputBuffers, RealTime timestamp)
|
||||
{
|
||||
return m_plugin->process(inputBuffers, timestamp);
|
||||
}
|
||||
|
||||
Plugin::FeatureSet
|
||||
PluginWrapper::getRemainingFeatures()
|
||||
{
|
||||
return m_plugin->getRemainingFeatures();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
106
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h
Normal file
106
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- 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-2007 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_PLUGIN_WRAPPER_H_
|
||||
#define _VAMP_PLUGIN_WRAPPER_H_
|
||||
|
||||
#include <vamp-sdk/Plugin.h>
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
||||
/**
|
||||
* \class PluginWrapper PluginWrapper.h <vamp-sdk/hostext/PluginWrapper.h>
|
||||
*
|
||||
* PluginWrapper is a simple base class for adapter plugins. It takes
|
||||
* a pointer to a "to be wrapped" Vamp plugin on construction, and
|
||||
* provides implementations of all the Vamp plugin methods that simply
|
||||
* delegate through to the wrapped plugin. A subclass can therefore
|
||||
* override only the methods that are meaningful for the particular
|
||||
* adapter.
|
||||
*
|
||||
* \note This class was introduced in version 1.1 of the Vamp plugin SDK.
|
||||
*/
|
||||
|
||||
class PluginWrapper : public Plugin
|
||||
{
|
||||
public:
|
||||
virtual ~PluginWrapper();
|
||||
|
||||
bool initialise(size_t channels, size_t stepSize, size_t blockSize);
|
||||
void reset();
|
||||
|
||||
InputDomain getInputDomain() const;
|
||||
|
||||
unsigned int getVampApiVersion() const;
|
||||
std::string getIdentifier() const;
|
||||
std::string getName() const;
|
||||
std::string getDescription() const;
|
||||
std::string getMaker() const;
|
||||
int getPluginVersion() const;
|
||||
std::string getCopyright() const;
|
||||
|
||||
ParameterList getParameterDescriptors() const;
|
||||
float getParameter(std::string) const;
|
||||
void setParameter(std::string, float);
|
||||
|
||||
ProgramList getPrograms() const;
|
||||
std::string getCurrentProgram() const;
|
||||
void selectProgram(std::string);
|
||||
|
||||
size_t getPreferredStepSize() const;
|
||||
size_t getPreferredBlockSize() const;
|
||||
|
||||
size_t getMinChannelCount() const;
|
||||
size_t getMaxChannelCount() const;
|
||||
|
||||
OutputList getOutputDescriptors() const;
|
||||
|
||||
FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
|
||||
|
||||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
PluginWrapper(Plugin *plugin); // I take ownership of plugin
|
||||
Plugin *m_plugin;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
9
libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in
Normal file
9
libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
dlname='%LINK_ABI%'
|
||||
library_names='%LIBNAME% %LINK_ABI% %LINK_DEV%'
|
||||
old_library='%STATIC%'
|
||||
dependency_libs=''
|
||||
current=2
|
||||
age=0
|
||||
revision=0
|
||||
installed=yes
|
||||
libdir='%LIBS%'
|
||||
9
libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in
Normal file
9
libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
dlname='%LINK_ABI%'
|
||||
library_names='%LIBNAME% %LINK_ABI% %LINK_DEV%'
|
||||
old_library='%STATIC%'
|
||||
dependency_libs=''
|
||||
current=1
|
||||
age=1
|
||||
revision=0
|
||||
installed=yes
|
||||
libdir='%LIBS%'
|
||||
10
libs/vamp-sdk/vamp-sdk/vamp-hostsdk.pc.in
Normal file
10
libs/vamp-sdk/vamp-sdk/vamp-hostsdk.pc.in
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
prefix=%PREFIX%
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: vamp-hostsdk
|
||||
Version: 1.1.0
|
||||
Description: Development library for Vamp audio analysis plugin hosts
|
||||
Libs: -L${libdir} -lvamp-hostsdk
|
||||
Cflags: -I${includedir}
|
||||
10
libs/vamp-sdk/vamp-sdk/vamp-sdk.pc.in
Normal file
10
libs/vamp-sdk/vamp-sdk/vamp-sdk.pc.in
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
prefix=%PREFIX%
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: vamp-sdk
|
||||
Version: 1.1.0
|
||||
Description: Development library for Vamp audio analysis plugins
|
||||
Libs: -L${libdir} -lvamp-sdk
|
||||
Cflags: -I${includedir}
|
||||
339
libs/vamp-sdk/vamp/vamp.h
Normal file
339
libs/vamp-sdk/vamp/vamp.h
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/* -*- 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 Chris Cannam.
|
||||
|
||||
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_HEADER_INCLUDED
|
||||
#define VAMP_HEADER_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Plugin API version. This is incremented when a change is made that
|
||||
* changes the binary layout of the descriptor records. When this
|
||||
* happens, there should be a mechanism for retaining compatibility
|
||||
* with older hosts and/or plugins.
|
||||
*
|
||||
* See also the vampApiVersion field in the plugin descriptor, and the
|
||||
* hostApiVersion argument to the vampGetPluginDescriptor function.
|
||||
*/
|
||||
#define VAMP_API_VERSION 1
|
||||
|
||||
/**
|
||||
* C language API for Vamp plugins.
|
||||
*
|
||||
* This is the formal plugin API for Vamp. Plugin authors may prefer
|
||||
* to use the C++ classes provided in the Vamp plugin SDK, instead of
|
||||
* using this API directly. There is an adapter class provided that
|
||||
* makes C++ plugins available using this C API with relatively little
|
||||
* work, and the C++ headers are more thoroughly documented.
|
||||
*
|
||||
* IMPORTANT: The comments in this file summarise the purpose of each
|
||||
* of the declared fields and functions, but do not provide a complete
|
||||
* guide to their permitted values and expected usage. Please refer
|
||||
* to the C++ headers in the Vamp plugin SDK for further details and
|
||||
* plugin lifecycle documentation.
|
||||
*/
|
||||
|
||||
typedef struct _VampParameterDescriptor
|
||||
{
|
||||
/** 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. */
|
||||
const char *name;
|
||||
|
||||
/** Human-readable short text about the parameter. May be translatable. */
|
||||
const char *description;
|
||||
|
||||
/** Human-readable unit of the parameter. */
|
||||
const char *unit;
|
||||
|
||||
/** Minimum value. */
|
||||
float minValue;
|
||||
|
||||
/** Maximum value. */
|
||||
float maxValue;
|
||||
|
||||
/** Default value. Plugin is responsible for setting this on initialise. */
|
||||
float defaultValue;
|
||||
|
||||
/** 1 if parameter values are quantized to a particular resolution. */
|
||||
int isQuantized;
|
||||
|
||||
/** Quantization resolution, if isQuantized. */
|
||||
float quantizeStep;
|
||||
|
||||
/** Human-readable names of the values, if isQuantized. May be NULL. */
|
||||
const char **valueNames;
|
||||
|
||||
} VampParameterDescriptor;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/** Each process call returns results aligned with call's block start. */
|
||||
vampOneSamplePerStep,
|
||||
|
||||
/** Returned results are evenly spaced at samplerate specified below. */
|
||||
vampFixedSampleRate,
|
||||
|
||||
/** Returned results have their own individual timestamps. */
|
||||
vampVariableSampleRate
|
||||
|
||||
} VampSampleType;
|
||||
|
||||
typedef struct _VampOutputDescriptor
|
||||
{
|
||||
/** 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. */
|
||||
const char *name;
|
||||
|
||||
/** Human-readable short text about the output. May be translatable. */
|
||||
const char *description;
|
||||
|
||||
/** Human-readable name of the unit of the output. */
|
||||
const char *unit;
|
||||
|
||||
/** 1 if output has equal number of values for each returned result. */
|
||||
int hasFixedBinCount;
|
||||
|
||||
/** Number of values per result, if hasFixedBinCount. */
|
||||
unsigned int binCount;
|
||||
|
||||
/** Names of returned value bins, if hasFixedBinCount. May be NULL. */
|
||||
const char **binNames;
|
||||
|
||||
/** 1 if each returned value falls within the same fixed min/max range. */
|
||||
int hasKnownExtents;
|
||||
|
||||
/** Minimum value for a returned result in any bin, if hasKnownExtents. */
|
||||
float minValue;
|
||||
|
||||
/** Maximum value for a returned result in any bin, if hasKnownExtents. */
|
||||
float maxValue;
|
||||
|
||||
/** 1 if returned results are quantized to a particular resolution. */
|
||||
int isQuantized;
|
||||
|
||||
/** Quantization resolution for returned results, if isQuantized. */
|
||||
float quantizeStep;
|
||||
|
||||
/** Time positioning method for returned results (see VampSampleType). */
|
||||
VampSampleType sampleType;
|
||||
|
||||
/** Sample rate of returned results, if sampleType is vampFixedSampleRate.
|
||||
"Resolution" of result, if sampleType is vampVariableSampleRate. */
|
||||
float sampleRate;
|
||||
|
||||
} VampOutputDescriptor;
|
||||
|
||||
typedef struct _VampFeature
|
||||
{
|
||||
/** 1 if the feature has a timestamp (i.e. if vampVariableSampleRate). */
|
||||
int hasTimestamp;
|
||||
|
||||
/** Seconds component of timestamp. */
|
||||
int sec;
|
||||
|
||||
/** Nanoseconds component of timestamp. */
|
||||
int nsec;
|
||||
|
||||
/** Number of values. Must be binCount if hasFixedBinCount. */
|
||||
unsigned int valueCount;
|
||||
|
||||
/** Values for this returned sample. */
|
||||
float *values;
|
||||
|
||||
/** Label for this returned sample. May be NULL. */
|
||||
char *label;
|
||||
|
||||
} VampFeature;
|
||||
|
||||
typedef struct _VampFeatureList
|
||||
{
|
||||
/** Number of features in this feature list. */
|
||||
unsigned int featureCount;
|
||||
|
||||
/** Features in this feature list. May be NULL if featureCount is zero. */
|
||||
VampFeature *features;
|
||||
|
||||
} VampFeatureList;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
vampTimeDomain,
|
||||
vampFrequencyDomain
|
||||
|
||||
} VampInputDomain;
|
||||
|
||||
typedef void *VampPluginHandle;
|
||||
|
||||
typedef struct _VampPluginDescriptor
|
||||
{
|
||||
/** API version with which this descriptor is compatible. */
|
||||
unsigned int vampApiVersion;
|
||||
|
||||
/** 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. */
|
||||
const char *name;
|
||||
|
||||
/** Human-readable short text about the plugin. May be translatable. */
|
||||
const char *description;
|
||||
|
||||
/** Human-readable name of plugin's author or vendor. */
|
||||
const char *maker;
|
||||
|
||||
/** Version number of the plugin. */
|
||||
int pluginVersion;
|
||||
|
||||
/** Human-readable summary of copyright or licensing for plugin. */
|
||||
const char *copyright;
|
||||
|
||||
/** Number of parameter inputs. */
|
||||
unsigned int parameterCount;
|
||||
|
||||
/** Fixed descriptors for parameter inputs. */
|
||||
const VampParameterDescriptor **parameters;
|
||||
|
||||
/** Number of programs. */
|
||||
unsigned int programCount;
|
||||
|
||||
/** Fixed names for programs. */
|
||||
const char **programs;
|
||||
|
||||
/** Preferred input domain for audio input (time or frequency). */
|
||||
VampInputDomain inputDomain;
|
||||
|
||||
/** Create and return a new instance of this plugin. */
|
||||
VampPluginHandle (*instantiate)(const struct _VampPluginDescriptor *,
|
||||
float inputSampleRate);
|
||||
|
||||
/** Destroy an instance of this plugin. */
|
||||
void (*cleanup)(VampPluginHandle);
|
||||
|
||||
/** Initialise an instance following parameter configuration. */
|
||||
int (*initialise)(VampPluginHandle,
|
||||
unsigned int inputChannels,
|
||||
unsigned int stepSize,
|
||||
unsigned int blockSize);
|
||||
|
||||
/** Reset an instance, ready to use again on new input data. */
|
||||
void (*reset)(VampPluginHandle);
|
||||
|
||||
/** Get a parameter value. */
|
||||
float (*getParameter)(VampPluginHandle, int);
|
||||
|
||||
/** Set a parameter value. May only be called before initialise. */
|
||||
void (*setParameter)(VampPluginHandle, int, float);
|
||||
|
||||
/** Get the current program (if programCount > 0). */
|
||||
unsigned int (*getCurrentProgram)(VampPluginHandle);
|
||||
|
||||
/** Set the current program. May only be called before initialise. */
|
||||
void (*selectProgram)(VampPluginHandle, unsigned int);
|
||||
|
||||
/** Get the plugin's preferred processing window increment in samples. */
|
||||
unsigned int (*getPreferredStepSize)(VampPluginHandle);
|
||||
|
||||
/** Get the plugin's preferred processing window size in samples. */
|
||||
unsigned int (*getPreferredBlockSize)(VampPluginHandle);
|
||||
|
||||
/** Get the minimum number of input channels this plugin can handle. */
|
||||
unsigned int (*getMinChannelCount)(VampPluginHandle);
|
||||
|
||||
/** Get the maximum number of input channels this plugin can handle. */
|
||||
unsigned int (*getMaxChannelCount)(VampPluginHandle);
|
||||
|
||||
/** Get the number of feature outputs (distinct sets of results). */
|
||||
unsigned int (*getOutputCount)(VampPluginHandle);
|
||||
|
||||
/** Get a descriptor for a given feature output. Returned pointer
|
||||
is valid only until next call to getOutputDescriptor for this
|
||||
handle, or releaseOutputDescriptor for this descriptor. Host
|
||||
must call releaseOutputDescriptor after use. */
|
||||
VampOutputDescriptor *(*getOutputDescriptor)(VampPluginHandle,
|
||||
unsigned int);
|
||||
|
||||
/** Destroy a descriptor for a feature output. */
|
||||
void (*releaseOutputDescriptor)(VampOutputDescriptor *);
|
||||
|
||||
/** Process an input block and return a set of features. Returned
|
||||
pointer is valid only until next call to process,
|
||||
getRemainingFeatures, or cleanup for this handle, or
|
||||
releaseFeatureSet for this feature set. Host must call
|
||||
releaseFeatureSet after use. */
|
||||
VampFeatureList *(*process)(VampPluginHandle,
|
||||
const float *const *inputBuffers,
|
||||
int sec,
|
||||
int nsec);
|
||||
|
||||
/** Return any remaining features at the end of processing. */
|
||||
VampFeatureList *(*getRemainingFeatures)(VampPluginHandle);
|
||||
|
||||
/** Release a feature set returned from process or getRemainingFeatures. */
|
||||
void (*releaseFeatureSet)(VampFeatureList *);
|
||||
|
||||
} VampPluginDescriptor;
|
||||
|
||||
/** Get the descriptor for a given plugin index in this library.
|
||||
Return NULL if the index is outside the range of valid indices for
|
||||
this plugin library.
|
||||
|
||||
The hostApiVersion argument tells the library code the highest
|
||||
Vamp API version supported by the host. The function should
|
||||
return a plugin descriptor compatible with the highest API version
|
||||
supported by the library that is no higher than that supported by
|
||||
the host. Provided the descriptor has the correct vampApiVersion
|
||||
field for its actual compatibility level, the host should be able
|
||||
to do the right thing with it: use it if possible, discard it
|
||||
otherwise.
|
||||
*/
|
||||
const VampPluginDescriptor *vampGetPluginDescriptor
|
||||
(unsigned int hostApiVersion, unsigned int index);
|
||||
|
||||
/** Function pointer type for vampGetPluginDescriptor. */
|
||||
typedef const VampPluginDescriptor *(*VampGetPluginDescriptorFunction)
|
||||
(unsigned int, unsigned int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
10
libs/vamp-sdk/vamp/vamp.pc.in
Normal file
10
libs/vamp-sdk/vamp/vamp.pc.in
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
prefix=%PREFIX%
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: vamp
|
||||
Version: 1.0
|
||||
Description: An API for audio analysis and feature extraction plugins
|
||||
Libs:
|
||||
Cflags: -I${includedir}
|
||||
Loading…
Add table
Add a link
Reference in a new issue