fazekasgy@37: Chris@79: Vampy is a wrapper for the Vamp audio analysis plugin API. fazekasgy@58: (http://www.vamp-plugins.org/) It allows for writing Vamp fazekasgy@58: plugins in Python. fazekasgy@37: fazekasgy@38: fazekasgy@37: WHAT IS IT FOR? fazekasgy@58: fazekasgy@58: Vamp is an audio analysis and feature extraction plugin system fazekasgy@58: with a C/C++ Application Programming Interface (API). fazekasgy@58: fazekasgy@58: Typical applications of Vamp plugins include visualisation, using cannam@101: a host such as Sonic Visualiser (https://www.sonicvisualiser.org/), fazekasgy@58: or batch feature extraction from audio, using Sonic Annotator cannam@101: (https://vamp-plugins.org/sonic-annotator). fazekasgy@58: fazekasgy@58: Vamp plugins are typically written in C++. Although currently fazekasgy@58: available plugin hosts are valuable tools in audio research, Chris@66: the long and tedious development cycle of plugins does not fazekasgy@58: support quick prototyping of feature extraction algorithms. fazekasgy@58: Learning the extra skills needed for plugin development or using fazekasgy@58: scientific libraries available for C and C++ is often outside fazekasgy@58: the interest of audio researches typically using MATLAB or other fazekasgy@58: high-level development environments. fazekasgy@37: fazekasgy@58: This package aims at easing Vamp plugin development, prototyping fazekasgy@58: or deployment by using the high-level Python scripting language. fazekasgy@37: fazekasgy@37: fazekasgy@37: WHY PYTHON? fazekasgy@58: Chris@93: The Python programming language is extremely popular in the Chris@93: scientific community. Besides being a high-productivity Chris@93: interpreted language, it has extensions for scientific Chris@93: computing such as Numpy, an efficient numerical library and Chris@93: SciPy, a collection of Python modules for signal processing, Chris@93: linear algebra, statistics and machine learning ... Chris@93: (www.SciPy.org). These packages together with matplotlib Chris@93: (http://matplotlib.sourceforge.net/) provide similar Chris@93: capabilities to most commercial modelling environments. As a Chris@93: further advantage, Python is a general purpose language which Chris@93: also supports the functional programming style. fazekasgy@37: fazekasgy@58: fazekasgy@58: HOW DOES IT WORK? fazekasgy@58: fazekasgy@58: Vampy acts like a bridge between a Vamp plugin host application fazekasgy@58: and Python scripts. It translates host function calls to Python fazekasgy@58: interpreter calls and converts Python data types to C++ and Vamp fazekasgy@58: defined data structures. fazekasgy@58: fazekasgy@58: Vampy is distributed and can be installed like any other ordinary fazekasgy@58: Vamp plugin. When it is installed, any appropriately structured fazekasgy@58: Python script in its script directory will be presented to fazekasgy@58: host programs as if they were native Vamp plugins written in C++. fazekasgy@58: fazekasgy@58: Vampy embeds the Python interpreter dynamically, and also extends fazekasgy@58: it with data types defined by the Vamp C++ API, all within a fazekasgy@58: single shared library. fazekasgy@58: Chris@111: Chris@111: WHAT'S NEW IN THIS RELEASE? Chris@111: Chris@111: See the file CHANGELOG for details of changes in this release Chris@111: (and previous releases) of Vampy. Chris@111: fazekasgy@58: fazekasgy@58: OBTAINING VAMPY: fazekasgy@58: Chris@93: Vampy is a free, cross platform, open source package. The Chris@93: source code is available from its repository at Chris@93: https://code.soundsoftware.ac.uk/projects/vampy. fazekasgy@58: Chris@93: * Binary distributions are available for Windows, macOS, and Chris@93: Linux. fazekasgy@58: Chris@93: * The source code can be obtained using the Mercurial command: Chris@93: hg clone https://code.soundsoftware.ac.uk/hg/vampy fazekasgy@58: fazekasgy@58: fazekasgy@58: DEPENDENCIES: fazekasgy@58: Chris@66: * Vampy requires Python 2.7. fazekasgy@58: Chris@93: Note that Vampy does not support Python 3 at all at this Chris@93: point. Note also that on a Mac in normal circumstances Vampy cannam@101: expects to use the system installation of Python, so plugins cannam@101: that you write should be tested using the system Python. fazekasgy@58: Chris@93: * Vampy supports Numpy 1.1 or greater. fazekasgy@58: Chris@93: Using Numpy is optional, however writing plugins in pure Chris@93: Python typically results in significantly slower processing. fazekasgy@58: fazekasgy@58: fazekasgy@58: BUILDING VAMPY: fazekasgy@58: fazekasgy@58: It is advised to use a binary distribution if available for fazekasgy@58: your platform and Python/Numpy versions before attempting to fazekasgy@58: compile it from source. If you decide to do so, please use the fazekasgy@58: make files provided. Make sure the correct include locations fazekasgy@58: are set for Python, Numpy, and the Vamp plugin SDK. fazekasgy@58: fazekasgy@58: fazekasgy@58: COMPILER OPTIONS: fazekasgy@58: fazekasgy@58: HAVE_NUMPY : compile with Numpy array interface support fazekasgy@58: fazekasgy@58: NUMPY_SHORTVERSION : set to the minimum version of Numpy you have, fazekasgy@58: as a floating-point value; the default is 1.1, which should be fazekasgy@58: OK for using the plugin with Numpy 1.1, 1.2 and 1.3 fazekasgy@58: fazekasgy@58: simple debugging (for developers): fazekasgy@58: _DEBUG : print more detailed messages while Vampy is in use fazekasgy@58: _DEBUG_VALUES : print all converted values to stderr Chris@67: Chris@67: (But note that basic debug messages are compiled in already, and Chris@67: will be displayed if the environment variable VAMPY_VERBOSE is set.) fazekasgy@37: fazekasgy@38: fazekasgy@58: USING VAMPY: fazekasgy@38: Chris@66: (1) Make sure you have Python 2.7 installed and you fazekasgy@58: have a recent Vamp plugin host application. fazekasgy@58: (e.g. Sonic Visualier) fazekasgy@38: fazekasgy@58: (2) Download a version of Vampy compatible with your fazekasgy@58: operating system and Python distribution. fazekasgy@58: fazekasgy@58: (3) Unzip the package and copy the shared library fazekasgy@58: (Windows: vampy.dll, Linux: vampy.so, MacOS: vampy.dylib) fazekasgy@58: to your Vamp plugin path. fazekasgy@58: fazekasgy@58: (4) Copy the example plugins (.py files) from the fazekasgy@58: 'Example VamPy plugins' directory to the same place. fazekasgy@58: (without the example directory itself) fazekasgy@58: fazekasgy@58: (5) If you are familiar with Python, it is straightforward fazekasgy@58: to start writing your own plugins by following these examples. fazekasgy@58: fazekasgy@58: Note: The interpreter automatically generates a compiled version fazekasgy@58: of each plugin when their source file is first imported. This fazekasgy@58: file can be distributed alone is so desired. Compiled or compiled fazekasgy@58: and optimised versions of a plugin can also be obtained using the fazekasgy@58: 'py_compile' standard library module. (Note that Python byte fazekasgy@58: compiled binaries are easier to reverse than C++ binaries.) fazekasgy@58: fazekasgy@58: Some familiarity with the Vamp plugin SDK and Vamp Plugin fazekasgy@58: documentation is assumed before one would start writing a plugin fazekasgy@58: using Vampy. Only the particularities of Vampy plugins are fazekasgy@58: covered here. The Vamp plugin documentation is available at: fazekasgy@58: * http://www.vamp-plugins.org/code-doc/index.html fazekasgy@58: * http://www.vamp-plugins.org/guide.pdf fazekasgy@58: fazekasgy@58: fazekasgy@58: BASIC RULES: fazekasgy@58: fazekasgy@58: Only the Python scripts that follow some basic rules qualify as fazekasgy@58: Vampy plugins: fazekasgy@58: fazekasgy@58: (1) Each plugin must contain a single class with the fazekasgy@58: same name as the script file name. fazekasgy@58: fazekasgy@58: e.g. PyZeroCrossing.py -> class PyZeroCrossing fazekasgy@58: fazekasgy@58: (2) Vampy plugins have to be in a specific directory designated fazekasgy@58: to Vamp plugins. The exact location is platform specific. fazekasgy@58: Additionally, you can use the VAMPY_EXTPATH environment fazekasgy@58: variable to specify a separate path for Vampy plugins. fazekasgy@58: fazekasgy@58: (3) Vampy plugins can be used and distributed as Python scripts fazekasgy@58: (.py) or byte compiled Python binaries (.pyc / .pyo). fazekasgy@58: fazekasgy@58: When a script is present with the same name as a compiled fazekasgy@58: file on any of the valid paths, the script will be preferred. fazekasgy@58: fazekasgy@58: (4) Vampy may decide to reject some scripts after some basic fazekasgy@58: validation is performed: fazekasgy@58: fazekasgy@58: * Scripts with syntax errors in them are ignored. fazekasgy@58: fazekasgy@58: * Scripts not containing a class with the exact same name fazekasgy@58: as the file name are ignored. (Python is case sensitive!) fazekasgy@58: fazekasgy@58: * Scripts with the wrong number of arguments to the plugin fazekasgy@58: class's __init__() function will be avoided. Chris@93: Chris@93: * Scripts that redefine any of Vampy's standard type names Chris@93: will be avoided. fazekasgy@58: Chris@93: (5) Unknown scripts may cause undesired behaviour. fazekasgy@58: Don't put arbitrary Python scripts in your Vamp directory, fazekasgy@58: you may use a subdirectory for that. fazekasgy@58: fazekasgy@58: fazekasgy@58: PLUGIN ERRORS: fazekasgy@58: fazekasgy@58: Script validation is performed by the interpreter itself fazekasgy@58: using the same rules as module compilation. This means that fazekasgy@58: while most syntax errors will be noted when Vampy is first fazekasgy@58: used by a host, runtime errors can still occur during fazekasgy@58: execution. For example, a plugin calculating the dot product fazekasgy@58: of two vectors with different sizes will produce a runtime error. fazekasgy@58: Chris@93: Error messages from Vampy are printed on the standard error Chris@93: channel. fazekasgy@58: If you're using a graphical host (such as Sonic Visualiser) fazekasgy@58: you may start the application from a command line terminal Chris@93: in order to see these messages, or they may be forwarded by Chris@93: the host to its own debug log file. fazekasgy@58: fazekasgy@58: Exceptions: fazekasgy@58: fazekasgy@58: * Runtime errors occurring in the plugin's __init__() function fazekasgy@58: will prevent the host from loading the plugin. fazekasgy@58: fazekasgy@58: * Runtime errors in the plugin's initialise() function will fazekasgy@58: prevent the host from using the plugin. fazekasgy@58: fazekasgy@58: * Module level errors resulting from importing a non-existent fazekasgy@58: module or source file or an error occurring on an imported fazekasgy@58: module's source tree will prevent the plugin from loading. fazekasgy@58: fazekasgy@58: Any other error, including those during the process will fazekasgy@58: only be noted on the terminal output. Processing errors will fazekasgy@58: generally result in a blank screen or no results displayed by fazekasgy@58: graphical hosts. fazekasgy@58: fazekasgy@58: fazekasgy@58: EXTENSION MODULE: fazekasgy@58: fazekasgy@58: Vampy extends Python with some useful data types defined fazekasgy@58: by the Vamp plugin API. This extension module is embedded fazekasgy@58: into the Vampy shared library, therefore it doesn't need fazekasgy@58: to be installed separately. However, it works very similarly fazekasgy@58: to any third party Python extension within a Vampy plugin. fazekasgy@58: fazekasgy@58: You may import the extension in the usual manner using fazekasgy@58: " import vampy " and " from vampy import * ". (Note that fazekasgy@58: currently the extension module is not available as a fazekasgy@58: separate package, therefore this will only work if the fazekasgy@58: plugin is executed by Vampy within a usual host context.) fazekasgy@58: fazekasgy@58: You can use any standard Python statement involving fazekasgy@58: modules such as " dir(vampy) " to print the names exported fazekasgy@58: by the module. The use of the extension in entirely optional, fazekasgy@58: however its use is strongly advised for the following reasons: fazekasgy@58: fazekasgy@58: * Using the module hides the mapping between Python and fazekasgy@58: C++ data types and provides improved plugin portability. fazekasgy@58: fazekasgy@58: * Returning types exported by the module is often faster. fazekasgy@58: fazekasgy@58: * In future releases its use may become mandatory. fazekasgy@58: fazekasgy@58: fazekasgy@58: PROCESS INTERFACES: fazekasgy@58: fazekasgy@58: Most computationally intensive processing takes place in fazekasgy@58: the plugin's process() method. This method has two arguments, fazekasgy@58: (besides the 'self' argument mandatory in all Python class methods). fazekasgy@58: fazekasgy@58: * The fist argument is used to pass audio samples (in time fazekasgy@58: domain plugins) or frequency samples (complex FFT output) fazekasgy@58: in frequency domain plugins. This argument is always a fazekasgy@58: Python list object where each element of the list corresponds fazekasgy@58: to an audio channel. (The length of this list can not be zero.) fazekasgy@58: The actual element types contained in this list depends fazekasgy@58: on the domain type of the plugin (time/frequency domain) and fazekasgy@58: the selected process interface. (explained below) fazekasgy@58: fazekasgy@58: * The second argument is the time stamp of the processing fazekasgy@58: block passed to the plugin. This time stamp is either fazekasgy@58: a long integer corresponding to a sample number, or a fazekasgy@58: RealTime data type exposed by the vampy module. fazekasgy@58: The use of the time stamp is different in time and frequency fazekasgy@58: domain plugins. Please refer to the Vamp plugin documentation fazekasgy@58: for more details. fazekasgy@58: fazekasgy@58: Vampy supports three interfaces to process() function. fazekasgy@58: The interface type can be selected using the flags indicated fazekasgy@58: next to the process name below. The detailed use of these fazekasgy@58: flags will be explained later. fazekasgy@58: fazekasgy@58: INTERFACE TYPES: fazekasgy@58: fazekasgy@58: (1) Legacy interface (default, slowest): fazekasgy@58: fazekasgy@58: Vampy passes a Python List of List of values to the fazekasgy@58: plugin corresponding to each audio channel, and the fazekasgy@58: time or frequency domain samples of each channel: fazekasgy@58: fazekasgy@58: * Audio samples are passed as an N element list fazekasgy@58: of floating point values in time domain plugins, fazekasgy@58: (where N equals to the block size parameter of the plugin). fazekasgy@58: fazekasgy@58: * Frequency Domain plugins are passed an N element list fazekasgy@58: of complex numbers, where N = (blockSize/2) + 1. This list fazekasgy@58: includes the DC and the Nyquist frequency FFT oputputs. fazekasgy@58: fazekasgy@58: Note: This is the only available interface which can be used fazekasgy@58: without Numpy or a compatible numerical library. fazekasgy@58: fazekasgy@58: (2) Buffer interface (vf_BUFFER, fast): fazekasgy@58: fazekasgy@58: * Both time and frequency domain plugins are passed a list fazekasgy@58: of shared memory buffer objects where each buffer corresponds fazekasgy@58: to an audio channel. The length of these buffers is blockSize fazekasgy@58: in time domain plugins and blockSize+2 in frequency domain fazekasgy@58: plugins. The easiest way to access the data in the buffers fazekasgy@58: is the use of Numpy's frombuffer() command. See the Numpy fazekasgy@58: documentation or the Vampy example plugins for more details. fazekasgy@58: fazekasgy@58: Note that this interface is very similar to how the data is fazekasgy@58: passed to Vamp plugins in C++. fazekasgy@58: fazekasgy@58: (3) Numpy Array interface (vf_ARRAY, fast): fazekasgy@58: fazekasgy@58: Vampy passes a list of Numpy arrays to the process() fazekasgy@58: corresponding to each audio channel. fazekasgy@58: fazekasgy@58: * Time Domain plugins are passed an array of numpy.float32 fazekasgy@58: values where the array size is N = blockSize. fazekasgy@58: fazekasgy@58: * Frequency Domain plugins are passed an array of fazekasgy@58: numpy.complex64 values where the size N = (blockSize/2) + 1. fazekasgy@58: fazekasgy@58: fazekasgy@58: RETURNING VALUES: fazekasgy@58: fazekasgy@58: Python is a dynamically typed language, which means fazekasgy@58: that the programmer is not forced to declare variable fazekasgy@58: types strictly and specifically, they can be decided fazekasgy@58: or changed at runtime. This leads to different programming fazekasgy@58: styles compared to using statically typed languages such fazekasgy@58: as C++. The Vamp API is declared using C++ and expects fazekasgy@58: statically declared types returned by the plugin. fazekasgy@58: This leads to difficulties to the Python programmer, and fazekasgy@58: requires a detailed knowledge of the API which otherwise fazekasgy@58: would be unnecessary. Vampy relaxes this requirement by fazekasgy@58: using a runtime type inference mechanism. fazekasgy@58: fazekasgy@58: Vampy can convert just about any suitable Python data fazekasgy@58: object to the appropriate C++ data type expected by a fazekasgy@58: Vamp plugin host. This includes Numpy data types such as fazekasgy@58: numpy.float32 or a Numpy array. The type conversion is fazekasgy@58: dynamic and it is decided based on the plugin context and fazekasgy@58: the expected data type defined by the Vamp plugin API fazekasgy@58: in that context. This mechanism also takes advantage of the fazekasgy@58: higher level Python number, sequence and mapping protocols. fazekasgy@58: fazekasgy@58: For example if the Vamp API expects a floating point value, fazekasgy@58: any returned Python object will be attempted to cast fazekasgy@58: to a floating point value first and returned to the host. fazekasgy@58: If the value can not be converted, an error message is fazekasgy@58: displayed. fazekasgy@58: fazekasgy@58: Similarly, any returned value will be converted to a vector of fazekasgy@58: the appropriate element type when the expected return type is fazekasgy@58: a sequence of values. This allows the programmer to omit fazekasgy@58: unnecessary conversions, when, for example, a one element fazekasgy@58: list (vector) would be returned. fazekasgy@58: fazekasgy@58: The type conversion can be controlled specifically for fazekasgy@58: each plugin. Vampy supports the use case of prototyping fazekasgy@58: C++ Vamp plugins in Python by using a more strict type fazekasgy@58: conversion mechanism which would issue an error message fazekasgy@58: if the Python object does not correspond to a C++ type fazekasgy@58: according to a strict one-to-one mapping. This mapping fazekasgy@58: can be briefly outlined as follows: fazekasgy@58: fazekasgy@58: * numerical types require direct correspondence fazekasgy@58: between Python and C++ types when available fazekasgy@58: e.g. C++ float -> Python float fazekasgy@58: fazekasgy@58: * Data structures defined in the Vamp Plugin API require fazekasgy@58: a type exported be the vampy extension module. fazekasgy@58: Vamp::FeatureSet() -> vampy.FeatureSet() fazekasgy@58: Vamp::RealTime() -> vampy.RealTime() fazekasgy@58: fazekasgy@58: The strict type conversion method can be selected using fazekasgy@58: the Vampy flag: vf_STRICT (explained in the FLAGS section). fazekasgy@58: fazekasgy@58: fazekasgy@58: TIME STAMPS : fazekasgy@58: fazekasgy@58: Vamp uses RealTime time stamps to indicate the position of fazekasgy@58: a processing block passed to the plugin, or the position of fazekasgy@58: any returned features relative to the start of the audio. fazekasgy@58: RealTime uses two integer values to represent time values fazekasgy@58: to nanosecond precision. Vampy provides a Python compatible fazekasgy@58: representation of this this type which can be imported and fazekasgy@58: used in any Vampy plugin. fazekasgy@58: fazekasgy@58: * Vampy RealTime objects can be initialised using integers fazekasgy@58: corresponding to second and nanosecond values, or seconds (floats). fazekasgy@58: e.g.: fazekasgy@58: timestamp1 = RealTime(2,0) fazekasgy@58: timestamp2 = RealTime('seconds',2.123) fazekasgy@58: fazekasgy@58: Please note that only the following methods are available: fazekasgy@58: fazekasgy@58: * values() : returns a tuple of integers (sec,nsec) fazekasgy@58: * toFloat() : return a floating point representation (in seconds) fazekasgy@58: * toFrame(samplerate) : convert to frame fazekasgy@58: (sample number) given the audio sample rate fazekasgy@58: * toString() : human readable string representation fazekasgy@58: * a limited set of arithmetic operators (+,-) fazekasgy@58: fazekasgy@58: Additionally Vampy provides a function to convert frame fazekasgy@58: counts (in audio samples) to RealTime: fazekasgy@58: fazekasgy@58: timestamp = frame2RealTime(frameCount,inputSampleRate) fazekasgy@58: fazekasgy@58: For the detailed use of time stamps, refer to the Vamp plugin fazekasgy@58: documentation. i.e. Section 5, "Sample Types and Timestamps" fazekasgy@58: in the Vamp plugin guide, and the Vamp SDK documentation: fazekasgy@58: http://vamp-plugins.org/code-doc/classVamp_1_1Plugin.html fazekasgy@58: on how time stamps are used in process calls. fazekasgy@58: fazekasgy@58: Note: The support for RealTime time stamps is new in this fazekasgy@58: version of Vampy. Vampy 1 used long integer sample counts fazekasgy@58: instead. This is still accepted for backward compatibility, fazekasgy@58: but the use of RealTime is encouraged whenever possible. fazekasgy@58: By default sample counts are used, please set the falg: fazekasgy@58: vf_REALTIME to obtain RealTime time stamps in process calls. fazekasgy@58: fazekasgy@58: fazekasgy@58: VAMPY FLAGS : fazekasgy@58: fazekasgy@58: The execution of Vampy plugins can be controlled using a set fazekasgy@58: of flags. (Each control flag is prefixed by vf_) fazekasgy@58: fazekasgy@58: vf_NULL : zero value, default for Vampy version 1 behaviour fazekasgy@38: vf_DEBUG : print debug messages to standard error fazekasgy@58: vf_STRICT : strict type conversion (follows the C++ API more closely) fazekasgy@38: vf_QUIT : quit the host process on hard errors fazekasgy@38: vf_REALTIME : use RealTime time stamps fazekasgy@58: vf_BUFFER : use the Numpy Buffer interface fazekasgy@58: vf_ARRAY : use the numpy Array interface fazekasgy@38: vf_DEFAULT_V2 : default Vampy version 2 behaviour fazekasgy@58: (equals to setting: vf_ARRAY | vf_REALTIME) fazekasgy@38: fazekasgy@58: The use of flags is optional. The default behaviour is that fazekasgy@58: of Vampy version 1. fazekasgy@38: fazekasgy@38: To set the flags, place a variable called 'vampy_flags' in fazekasgy@38: your plugin class's __init__() function. fazekasgy@38: fazekasgy@38: Example: fazekasgy@38: fazekasgy@38: class PyMFCC(melScaling): fazekasgy@38: def __init__(self,inputSampleRate): fazekasgy@38: self.vampy_flags = vf_DEBUG | vf_ARRAY | vf_REALTIME fazekasgy@38: fazekasgy@38: fazekasgy@38: ENVIRONMENT VARIABLES: fazekasgy@38: Chris@67: Vampy recognises these optional environment variables: Chris@67: Chris@67: VAMPY_VERBOSE if set at all, print out debug info to stderr Chris@67: fazekasgy@38: VAMPY_COMPILED=1 recognise byte compiled python plugins (default) fazekasgy@38: VAMPY_COMPILED=0 ignore them cannam@57: fazekasgy@38: VAMPY_EXTPATH: if given, searches this path for vampy plugins. fazekasgy@58: This is useful if you want to keep your python plugins fazekasgy@58: separate. Only a single absolute path name is recognised. fazekasgy@58: fazekasgy@58: Example: fazekasgy@58: export VAMPY_EXTPATH="/Users/Shared/Development/vampy-path" cannam@57: cannam@57: VAMPY_PYLIB: path to the Python shared library to be preloaded cannam@57: before scripts are run. The preload is necessary on some cannam@57: systems to support plugins that load additional Python modules. cannam@57: Vampy will attempt to preload the right library by default, but cannam@57: it sometimes fails; if so, set this variable to override it. fazekasgy@37: cannam@50: fazekasgy@37: HISTORY: fazekasgy@37: fazekasgy@38: v1: fazekasgy@51: * added support for Numpy arrays in processN() fazekasgy@58: * framecount is now passed also to legacy process() fazekasgy@58: and fixed resulting bugs in the PyZeroCrossing plugin fazekasgy@38: * added two examples which use Frequency Domain input in processN() fazekasgy@38: fazekasgy@38: v2.0: fazekasgy@58: * complete rewrite using generic functions for fazekasgy@58: implementing full error checking on Python/C API calls fazekasgy@58: * added extension module; fazekasgy@58: supports RealTime and other Vamp type wrappers fazekasgy@58: enables a much more readable syntax fazekasgy@51: * added Numpy Array interface fazekasgy@51: * added flags fazekasgy@38: * added environment variables fazekasgy@58: * recognise byte compiled python scripts fazekasgy@58: * new example plugin PyMFCC fazekasgy@58: * modified all examples for the new syntax fazekasgy@58: * bug fix: Nyquist frequency FFT output is now passed correctly fazekasgy@58: fazekasgy@58: fazekasgy@58: TODO: fazekasgy@58: * Vamp 'programs' not implemented fazekasgy@58: * support multiple classes per script in scanner fazekasgy@58: * implement missing methods of vampy.RealTime type fazekasgy@58: fazekasgy@38: cannam@50: LICENCE: cannam@50: cannam@50: VamPy is distributed under a "new-style BSD" license; see the cannam@50: file COPYING for details. You may modify and redistribute it cannam@50: within any commercial or non-commercial, proprietary or cannam@50: open-source context. VamPy imposes no limitation on how you cannam@50: may choose to license your own plugin scripts. Note that cannam@50: these happen to be the same terms as the Vamp SDK itself. cannam@50: cannam@50: VamPy was written by Gyorgy Fazekas at the Centre for Digital cannam@50: Music, Queen Mary University of London. cannam@50: Copyright 2008-2009 Gyorgy Fazekas. Chris@93: Copyright 2008-2019 Queen Mary University of London. fazekasgy@38: fazekasgy@38: