changeset 58:62dcaa5fe6f8 vampy-2.0

Extended README, added .pyo support
author fazekasgy
date Sun, 11 Oct 2009 09:57:48 +0000
parents 87b9ea6fc7d0
children 93eddad99f3c
files PyPlugScanner.cpp PyPlugScanner.h PyRealTime.cpp README
diffstat 4 files changed, 487 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/PyPlugScanner.cpp	Fri Oct 09 14:35:08 2009 +0000
+++ b/PyPlugScanner.cpp	Sun Oct 11 09:57:48 2009 +0000
@@ -81,8 +81,10 @@
 
         /// recognise byte compiled plugins
 		if (getCompiled) {
-        	vector<string> compiled_files = listFiles(m_path[i],"pyc");
-			mergeFileLists(compiled_files,files);
+        	vector<string> pyc_files = listFiles(m_path[i],"pyc");
+        	vector<string> pyo_files = listFiles(m_path[i],"pyo");
+			mergeFileLists(pyc_files,pyo_files,".pyo");
+			mergeFileLists(pyo_files,files,".py");
 		}
 
         for (vector<string>::iterator fi = files.begin();
@@ -113,15 +115,15 @@
 /// them if they exist. Therefore, we prefer .py files, but we allow
 /// (relatively) closed source distributions by recognising .pyc files.
 void
-PyPlugScanner::mergeFileLists(vector<string> &pyc, vector<string> &py)
+PyPlugScanner::mergeFileLists(vector<string> &src, vector<string> &tg, string target_ext)
 {
-    for (vector<string>::iterator pycit = pyc.begin();
-    	pycit != pyc.end(); ++pycit) {
-			// cerr << *pycit;
-			string pyc_name = *pycit;
-			string py_name = pyc_name.substr(0,pyc_name.rfind('.')) + ".py";
-			vector<string>::iterator pyit = find (py.begin(), py.end(), py_name);
-			if (pyit == py.end()) py.push_back(pyc_name);
+    for (vector<string>::iterator srcit = src.begin();
+    	srcit != src.end(); ++srcit) {
+			// cerr << *srcit;
+			string src_name = *srcit;
+			string tg_name = src_name.substr(0,src_name.rfind('.')) + target_ext;
+			vector<string>::iterator tgit = find (tg.begin(), tg.end(), tg_name);
+			if (tgit == tg.end()) tg.push_back(src_name);
 	}
 	
 }
--- a/PyPlugScanner.h	Fri Oct 09 14:35:08 2009 +0000
+++ b/PyPlugScanner.h	Sun Oct 11 09:57:48 2009 +0000
@@ -67,7 +67,7 @@
 	PyPlugScanner();
 	PyObject *getScriptClass(std::string path, std::string classname);
 	std::vector<std::string> listFiles(std::string dir, std::string ext);
-	void mergeFileLists(std::vector<std::string> &s, std::vector<std::string> &t);
+	void mergeFileLists(std::vector<std::string> &src, std::vector<std::string> &tg, std::string target_ext);
 	
 	static bool m_hasInstance;
 	static PyPlugScanner *m_instance;
--- a/PyRealTime.cpp	Fri Oct 09 14:35:08 2009 +0000
+++ b/PyRealTime.cpp	Sun Oct 11 09:57:48 2009 +0000
@@ -205,9 +205,7 @@
 
 
 /*					 Number Protocol 					*/
-/// Only add and substract make sense, or what about the
-/// square root of Monday morning?
-/// Divide by integer maybe for durations?
+/// TODO: implement all methods available in Vamp::RealTime() objects
 
 static PyObject *
 RealTime_add(PyObject *s, PyObject *w)
--- a/README	Fri Oct 09 14:35:08 2009 +0000
+++ b/README	Sun Oct 11 09:57:48 2009 +0000
@@ -1,39 +1,123 @@
 
- * VamPy is an API wrapper for Vamp. It allows for writing Vamp 
-	plugins in Python with or without Numpy support.
+ *  Vampy is a wrapper for the Vamp audio analysis plugin API.
+	(http://www.vamp-plugins.org/) It allows for writing Vamp 
+	plugins in Python.
 
 
 WHAT IS IT FOR?
+
+	Vamp is an audio analysis and feature extraction plugin system 
+	with a C/C++ Application Programming Interface (API).
+
+	Typical applications of Vamp plugins include visualisation, using 
+	a host such as Sonic Visualiser (http://www.sonicvisualiser.org/),
+	or batch feature extraction from audio, using Sonic Annotator 
+	(http://www.omras2.org/SonicAnnotator).
+
+	Vamp plugins are typically written in C++. Although currently
+	available plugin hosts are valuable tools in audio research,
+    the long and tedious development cycle of plugins does not 
+	support quick prototyping of feature extraction algorithms.
+	Learning the extra skills needed for plugin development or using 
+	scientific libraries available for C and C++ is often outside 
+	the interest of audio researches typically using MATLAB or other
+	high-level development environments.
 	
-	This wrapper is for writing Vamp plugins in Python which 
-	can do the same as a native C++ plugin, plus a lot more if 
-	you're using advanced Python modules such as Numpy and Scipy.
+	This package aims at easing Vamp plugin development, prototyping 
+	or deployment by using the high-level Python scripting language.
 
-	This may be an easier way to get into Vamp development.
-	You can use it for prototyping your plugin before writing 
-	it in C++.
-	
 
 WHY PYTHON?
+	
+	The Python programming language is rapidly gaining popularity
+	in the scientific community. Besides being a high-productivity
+	interpreted language, it has extensions for scientific computing
+	such as Numpy, an efficient numerical library and SciPy, a 
+	collection of Python modules for signal processing, 
+	linear algebra, statistics and machine learning ... 
+	(www.SciPy.org). These packages together with matplotlib 
+	(http://matplotlib.sourceforge.net/) provide similar capabilities
+	to most commercial modelling environments. As a further advantage, 
+	Python is a general purpose language which also supports 
+	the functional programming style.	
 
-	Python is a general purpose high level scripting language.
-	It is interpreted, so you don't need to compile your plugins.
-	It has very high level libraries. e.g. you can stream audio 
-	from a Vampy plugin if you want to.
-	Supports functional programming. 
+
+HOW DOES IT WORK?
+
+	Vampy acts like a bridge between a Vamp plugin host application
+	and Python scripts. It translates host function calls to Python
+	interpreter calls and converts Python data types to C++ and Vamp
+	defined data structures. 
+	
+	Vampy is distributed and can be installed like any other ordinary 
+	Vamp plugin. When it is installed, any appropriately structured 
+	Python script in its script directory will be presented to 
+	host programs as if they were native Vamp plugins written in C++.
+	
+	Vampy embeds the Python interpreter dynamically, and also extends 
+	it with data types defined by the Vamp C++ API, all within a 
+	single shared library.
+
+	
+OBTAINING VAMPY:
+
+	Vampy is a free, cross platform, open source package. The source
+	code is available from the Vamp-Plugins subversion repository
+	on SourceForge. (http://vamp.svn.sourceforge.net/)
+	
+	* Binary distributions are available for Windows, Mac OS/X, 
+	Linux and Solaris Unix.
+
+	* The source code can be obtained using the SVN command:
+	svn co https://vamp.svn.sourceforge.net/svnroot/vamp/vamp-vampy vampy
+
+
+DEPENDENCIES:
+
+	* Vampy requires Python 2.5 or greater. 
+	
+	Note that Vampy does not support the new flavour of Python (3.x) 
+	which breaks language compatibility with the 2.x series.
+	
+	* Vampy supports Numpy 1.1. or greater. 
+	
+	Using Numpy is optional, however writing plugins in pure Python
+	results in significantly longer processing times.
+
+
+BUILDING VAMPY:
+
+	It is advised to use a binary distribution if available for
+	your platform and Python/Numpy versions before attempting to 
+	compile it from source. If you decide to do so, please use the 
+	make files provided. Make sure the correct include locations 
+	are set for Python, Numpy, and the Vamp plugin SDK.
+
+	
+COMPILER OPTIONS: 
+
+	HAVE_NUMPY : compile with Numpy array interface support
+
+	NUMPY_SHORTVERSION : set to the minimum version of Numpy you have, 
+		as a floating-point value; the default is 1.1, which should be 
+		OK for using the plugin with Numpy 1.1, 1.2 and 1.3
+
+	simple debugging (for developers):
+		_DEBUG : print more detailed messages while Vampy is in use
+		_DEBUG_VALUES : print all converted values to stderr
 
 
 UPDATES IN THIS VERSION (Vampy 2.0):
 
-	* Two-way Numpy Support
+	* More complete, two-way Numpy support
 	* Embedded extension module exposing Vamp defined names 
 		e.g. ParameterDescriptor. This allows easier porting to C++.
 	* Support RealTime time stamps
 	* Support byte compiled Python scripts (.pyc)
-	* Environment variables: VAMPY_COMPILED, VAMPY_EXTPATH
-	* Flags to control type conversion and error reporting for development
-	* Flexible type inference to take advantage of Python's loose typing
-	* Full error checking for all Python/C API calls
+	* Environment variables
+	* Flags to control how Vampy works with each plugin
+	* Flexible type inference to take advantage of dynamic typing
+	* More complete error checking for all Python/C API calls
 	* Various optimisations and speed-ups
 	
 	Vampy now supports two main use cases: 
@@ -42,42 +126,364 @@
 	hosts for e.g. batch processing or visualisation.
 	
 	Vampy provides an extension module which allows the use of
-	Vamp data types such as FeatureSet() or RealTime() in Vampy plugins. 
+	data types defined in the Vamp API; such as FeatureSet() or 
+	RealTime() in Vampy plugins. 
 
 
-HOW DOES IT WORK:
+BACKWARD COMPATIBILITY (Read this if you used Vampy 1):
+	
+	This is the second version of Vampy. It is largely compatible
+	with the previous version and it is able to run plugins 
+	written for it. However, due to some bug fixes in this release, 
+	it may be required to modify old plugins to work correctly 
+	with Vampy 2.0:
+	
+	* The size of the input buffers of frequency domain plugins 
+	are now longer by one element corresponding to the Nyquist
+	frequency output of the FFT. 
+	
+	* The legacy interface now uses complex numbers to pass the 
+	FFT output to frequency domain plugins in Vampy 2.0 instead 
+	of floating point values.
+	
+	* Consequently, the size of the input buffer for each 
+	audio channel is blockSize/2 + 1 if the legacy interface
+	is used and blockSize+2 if the buffer interface is used
+	in frequency domain plugins. Time domain plugins however
+	do not require any change.
+	
+	* Vampy 1 had two types of process interfaces; the legacy
+	and the buffer interface (for Numpy support). They were
+	selected based on the name of the process method.
+	A process() implementation used the legacy interface, 
+	a processN() implementation used the Numpy buffer interface.
+	This behaviour is retained for backward compatibility but
+	only if no flags are set. The use of processN() is now 
+	obsolete, since the standard process() implementation can 
+	be configured to use any of the available interfaces by 
+	setting the flags appropriately.
 
-	(1) Make sure you have Python (and Numpy) installed.
-	(2) Download Vampy and install it to your Vamp plugin path.
-		eg. /Library/Audio/Plug-Ins/Vamp
-	(3) Write some python plugins and copy them to the same place.
-	(4) Each plugin must contain a single class with the same name as your script file.
-		e.g. PyZeroCrossing.py -> calss PyZeroCrossing
-		-Scripts with syntax errors in them are ignored.
-		-Scripts not having the same class as the filename are ignored. (Python is case sensitive!)
-		-Other unknown scripts may cause a crash.  
-		(Don't put other python scripts in your Vamp directory.)
-	    Some example plugin scripts are provided in "Example VamPy plugins".
 
-FLAGS :
+USING VAMPY:	
 
-	You can use some flags to control Vampy. They are:
+	(1) Make sure you have Python 2.5 or greater installed and you
+		have a recent Vamp plugin host application. 
+		(e.g. Sonic Visualier)
 
-	vf_NULL : zero value, default for vampy version 1 behaviour
+	(2) Download a version of Vampy compatible with your
+		operating system and Python distribution.
+	
+	(3) Unzip the package and copy the shared library 
+		(Windows: vampy.dll, Linux: vampy.so, MacOS: vampy.dylib)
+		to your Vamp plugin path.
+		
+	(4) Copy the example plugins (.py files) from the 
+		'Example VamPy plugins' directory to the same place.
+		(without the example directory itself)
+
+	(5) If you are familiar with Python, it is straightforward 
+		to start writing your own plugins by following these examples.
+		
+	Note: The interpreter automatically generates a compiled version
+	of each plugin when their source file is first imported. This 
+	file can be distributed alone is so desired. Compiled or compiled 
+	and optimised versions of a plugin can also be obtained using the 
+	'py_compile' standard library module. (Note that Python byte 
+	compiled binaries are easier to reverse than C++ binaries.)
+	
+	Some familiarity with the Vamp plugin SDK and Vamp Plugin 
+	documentation is assumed before one would start writing a plugin
+	using Vampy. Only the particularities of Vampy plugins are 
+	covered here. The Vamp plugin documentation is available at:
+	* http://www.vamp-plugins.org/code-doc/index.html
+	* http://www.vamp-plugins.org/guide.pdf
+
+	
+BASIC RULES:
+
+	Only the Python scripts that follow some basic rules qualify as
+	Vampy plugins:
+	
+	(1) Each plugin must contain a single class with the 
+		same name as the script file name.
+		
+		e.g. PyZeroCrossing.py -> class PyZeroCrossing
+		
+	(2) Vampy plugins have to be in a specific directory designated
+		to Vamp plugins. The exact location is platform specific.
+		Additionally, you can use the VAMPY_EXTPATH environment
+		variable to specify a separate path for Vampy plugins.
+		
+	(3) Vampy plugins can be used and distributed as Python scripts 
+		(.py) or byte compiled Python binaries (.pyc / .pyo).
+		
+		When a script is present with the same name as a compiled
+		file on any of the valid paths, the script will be preferred.
+		
+	(4) Vampy may decide to reject some scripts after some basic
+		validation is performed:
+
+		* Scripts with syntax errors in them are ignored.
+		
+		* Scripts not containing a class with the exact same name 
+		as the file name are ignored. (Python is case sensitive!)
+		
+		* Scripts with the wrong number of arguments to the plugin 
+		class's __init__() function will be avoided.
+		
+	(5) Unknown scripts may cause undesired behaviour (or a crash).  
+		Don't put arbitrary Python scripts in your Vamp directory,
+		you may use a subdirectory for that.
+
+
+PLUGIN ERRORS:
+
+	Script validation is performed by the interpreter itself
+	using the same rules as module compilation. This means that
+	while most syntax errors will be noted when Vampy is first
+	used by a host, runtime errors can still occur during
+	execution. For example, a plugin calculating the dot product
+	of two vectors with different sizes will produce a runtime error.
+	
+	Error messages from Vampy are printed on the standard output.
+	If you're using a graphical host (such as Sonic Visualiser)
+	you may start the application from a command line terminal
+	in order to see these messages.
+		
+	Exceptions:
+		
+	* Runtime errors occurring in the plugin's __init__() function
+	will prevent the host from loading the plugin.  
+
+	* Runtime errors in the plugin's initialise() function will
+	prevent the host from using the plugin.
+		
+	* Module level errors resulting from importing a non-existent
+	module or source file or an error occurring on an imported
+	module's source tree will prevent the plugin from loading.
+
+	Any other error, including those during the process will
+	only be noted on the terminal output. Processing errors will
+	generally result in a blank screen or no results displayed by
+	graphical hosts.
+
+
+EXTENSION MODULE:
+
+	Vampy extends Python with some useful data types defined
+	by the Vamp plugin API. This extension module is embedded
+	into the Vampy shared library, therefore it doesn't need 
+	to be installed separately. However, it works very similarly 
+	to any third party Python extension within a Vampy plugin.
+	
+	You may import the extension in the usual manner using
+	" import vampy " and " from vampy import * ". (Note that
+	currently the extension module is not available as a 
+	separate package, therefore this will only work if the 
+	plugin is executed by Vampy within a usual host context.)
+	
+	You can use any standard Python statement involving 
+	modules such as " dir(vampy) " to print the names exported
+	by the module. The use of the extension in entirely optional,
+	however its use is strongly advised for the following reasons:
+
+	* Using the module hides the mapping between Python and
+	C++ data types and provides improved plugin portability.
+		
+	* Returning types exported by the module is often faster.
+		
+	* In future releases its use may become mandatory.
+
+
+PROCESS INTERFACES:
+
+	Most computationally intensive processing takes place in
+	the plugin's process() method. This method has two arguments,
+	(besides the 'self' argument mandatory in all Python class methods).
+	
+	* The fist argument is used to pass audio samples (in time 
+	domain plugins) or frequency samples (complex FFT output)
+	in frequency domain plugins. This argument is always a
+	Python list object where each element of the list corresponds
+	to an audio channel. (The length of this list can not be zero.)
+	The actual element types contained in this list depends
+	on the domain type of the plugin (time/frequency domain) and
+	the selected process interface. (explained below)
+	
+	* The second argument is the time stamp of the processing 
+	block passed to the plugin. This time stamp is either
+	a long integer corresponding to a sample number, or a
+	RealTime data type exposed by the vampy module.
+	The use of the time stamp is different in time and frequency
+	domain plugins. Please refer to the Vamp plugin documentation
+	for more details.
+	
+	Vampy supports three interfaces to process() function. 
+	The interface type can be selected using the flags indicated 
+	next to the process name below. The detailed use of these 
+	flags will be explained later.
+	
+	INTERFACE TYPES:
+	
+	(1) Legacy interface (default, slowest):
+	
+	Vampy passes a Python List of List of values to the 
+	plugin corresponding to each audio channel, and the 
+	time or frequency domain samples of each channel:
+	
+	* Audio samples are passed as an N element list 
+	of floating point values in time domain plugins,
+	(where N equals to the block size parameter of the plugin).
+
+	* Frequency Domain plugins are passed an N element list 
+	of complex numbers, where N = (blockSize/2) + 1. This list 
+	includes the DC and the Nyquist frequency FFT oputputs.
+	
+	Note: This is the only available interface which can be used 
+	without Numpy or a compatible numerical library.
+	
+	(2) Buffer interface (vf_BUFFER, fast):
+	
+	* Both time and frequency domain plugins are passed a list 
+	of shared memory buffer objects where each buffer corresponds
+	to an audio channel. The length of these buffers is blockSize
+	in time domain plugins and blockSize+2 in frequency domain
+	plugins. The easiest way to access the data in the buffers
+	is the use of Numpy's frombuffer() command. See the Numpy
+	documentation or the Vampy example plugins for more details.
+	
+	Note that this interface is very similar to how the data is
+	passed to Vamp plugins in C++.
+	
+	(3) Numpy Array interface (vf_ARRAY, fast):
+	
+	Vampy passes a list of Numpy arrays to the process() 
+	corresponding to each audio channel.
+	
+	* Time Domain plugins are passed an array of numpy.float32
+	values where the array size is N = blockSize.
+	
+	* Frequency Domain plugins are passed an array of 
+	numpy.complex64 values where the size N = (blockSize/2) + 1.
+
+
+RETURNING VALUES:
+
+	Python is a dynamically typed language, which means
+	that the programmer is not forced to declare variable 
+	types strictly and specifically, they can be decided 
+	or changed at runtime. This leads to different programming 
+	styles compared to using statically typed languages such 
+	as C++. The Vamp API is declared using C++ and expects 
+	statically declared types returned by the plugin.
+	This leads to difficulties to the Python programmer, and
+	requires a detailed knowledge of the API which otherwise
+	would be unnecessary. Vampy relaxes this requirement by
+	using a runtime type inference mechanism.
+	
+	Vampy can convert just about any suitable Python data
+	object to the appropriate C++ data type expected by a 
+	Vamp plugin host. This includes Numpy data types such as 
+	numpy.float32 or a Numpy array. The type conversion is 
+	dynamic and it is decided based on the plugin context and 
+	the expected data type defined by the Vamp plugin API 
+	in that context. This mechanism also takes advantage of the 
+	higher level Python number, sequence and mapping protocols.
+	
+	For example if the Vamp API expects a floating point value,
+	any returned Python object will be attempted to cast
+	to a floating point value first and returned to the host.
+	If the value can not be converted, an error message is 
+	displayed.
+	
+	Similarly, any returned value will be converted to a vector of 
+	the appropriate element type when the expected return type is 
+	a sequence of values. This allows the programmer to omit 
+	unnecessary conversions, when, for example, a one element 
+	list (vector) would be returned.
+	
+	The type conversion can be controlled specifically for
+	each plugin. Vampy supports the use case of prototyping
+	C++ Vamp plugins in Python by using a more strict type
+	conversion mechanism which would issue an error message
+	if the Python object does not correspond to a C++ type
+	according to a strict one-to-one mapping. This mapping
+	can be briefly outlined as follows:
+	
+	* numerical types require direct correspondence 
+	between Python and C++ types when available
+	e.g. C++ float -> Python float
+	
+	* Data structures defined in the Vamp Plugin API require
+	a type exported be the vampy extension module.
+	Vamp::FeatureSet() -> vampy.FeatureSet()
+	Vamp::RealTime() -> vampy.RealTime()
+	
+	The strict type conversion method can be selected using
+	the Vampy flag: vf_STRICT (explained in the FLAGS section).
+
+	
+TIME STAMPS :
+
+	Vamp uses RealTime time stamps to indicate the position of
+	a processing block passed to the plugin, or the position of
+	any returned features relative to the start of the audio.
+	RealTime uses two integer values to represent time values
+	to nanosecond precision. Vampy provides a Python compatible
+	representation of this this type which can be imported and 
+	used in any Vampy plugin. 
+	
+	* Vampy RealTime objects can be initialised using integers 
+	corresponding to second and nanosecond values, or seconds (floats).
+	e.g.: 
+		timestamp1 = RealTime(2,0) 
+		timestamp2 = RealTime('seconds',2.123)
+	
+	Please note that only the following methods are available:
+
+	* values() : returns a tuple of integers (sec,nsec) 
+	* toFloat() : return a floating point representation (in seconds)
+	* toFrame(samplerate) : convert to frame 
+		(sample number) given the audio sample rate
+	* toString() : human readable string representation
+	* a limited set of arithmetic operators (+,-)
+	
+	Additionally Vampy provides a function to convert frame
+	counts (in audio samples) to RealTime:
+	
+		timestamp = frame2RealTime(frameCount,inputSampleRate)
+		
+	For the detailed use of time stamps, refer to the Vamp plugin
+	documentation. i.e. Section 5, "Sample Types and Timestamps"
+	in the Vamp plugin guide, and the Vamp SDK documentation:
+	http://vamp-plugins.org/code-doc/classVamp_1_1Plugin.html
+	on how time stamps are used in process calls.
+	
+	Note: The support for RealTime time stamps is new in this 
+	version of Vampy. Vampy 1 used long integer sample counts
+	instead. This is still accepted for backward compatibility,
+	but the use of RealTime is encouraged whenever possible.
+	By default sample counts are used, please set the falg:
+	vf_REALTIME to obtain RealTime time stamps in process calls. 
+
+		
+VAMPY FLAGS :
+
+	The execution of Vampy plugins can be controlled using a set
+	of flags. (Each control flag is prefixed by vf_)
+
+	vf_NULL : zero value, default for Vampy version 1 behaviour
 	vf_DEBUG : print debug messages to standard error
-	vf_STRICT : more strict type conversion (follows the C++ API more closely)
+	vf_STRICT : strict type conversion (follows the C++ API more closely)
 	vf_QUIT : quit the host process on hard errors
 	vf_REALTIME : use RealTime time stamps
-	vf_BUFFER : use the Numpy buffer interface to 
-				pass time/frequency domain samples to the python process
-
-	vf_ARRAY : use the numpy Array interface directly
-
+	vf_BUFFER : use the Numpy Buffer interface 
+	vf_ARRAY : use the numpy Array interface
 	vf_DEFAULT_V2 : default Vampy version 2 behaviour 
-					(= vf_ARRAY | vf_REALTIME)
+		(equals to setting: vf_ARRAY | vf_REALTIME)
 					
-	The use of these flags is optional. The default behaviour is
-	that of Vampy version 1.
+	The use of flags is optional. The default behaviour is that 
+	of Vampy version 1.
 	
 	To set the flags, place a variable called 'vampy_flags' in
 	your plugin class's __init__() function.
@@ -97,11 +503,11 @@
 	VAMPY_COMPILED=0 ignore them 
 
 	VAMPY_EXTPATH: if given, searches this path for vampy plugins.
-	(This is useful if you want to keep your python plugins separate.)
-	Only a single absolute path name is recognised.
-	
-	  Example:
-	  export VAMPY_EXTPATH="/Users/Shared/Development/vampy-path"
+		This is useful if you want to keep your python plugins 
+		separate. Only a single absolute path name is recognised.
+		
+		Example:
+	  	export VAMPY_EXTPATH="/Users/Shared/Development/vampy-path"
 
 	VAMPY_PYLIB: path to the Python shared library to be preloaded
         before scripts are run.  The preload is necessary on some
@@ -109,46 +515,35 @@
         Vampy will attempt to preload the right library by default, but
         it sometimes fails; if so, set this variable to override it.
 
-	
-COMPILING AND LINKING:
-	
-	Please use the make files provided.
-	Make sure the correct include locations are provided for
-	Python, Numpy, and the Vamp plugin SDK.
-
-	
-COMPILER OPTIONS: 
-
-	HAVE_NUMPY : compile with Numpy array interface support
-
-	NUMPY_SHORTVERSION : set to the minimum version of Numpy you have, as
- 	  a floating-point value; the default is 1.1, which should be OK for
-	  use with Numpy 1.1, 1.2 and 1.3
-
-	for developers:
-	_DEBUG : print very detailed messages and logs while Vampy is in use
-	_DEBUG_VALUES : print all converted values to stderr
-
-
-TODO:	
-	* Vamp 'programs' not implemented
-	* support multiple classes per script in scanner
-
 
 HISTORY:
 
 	v1:
 	* added support for Numpy arrays in processN()
-	* framecount is now passed also to legacy process() and fixed resulting bugs in the PyZeroCrossing plugin
+	* framecount is now passed also to legacy process() 
+		and fixed resulting bugs in the PyZeroCrossing plugin
 	* added two examples which use Frequency Domain input in processN()
 
 	v2.0:
-	* complete rewrite (using generic functions implementing full error checking)
-	* added extension module : support RealTime and other Vamp type wrappers
+	* complete rewrite using generic functions for 
+		implementing full error checking on Python/C API calls
+	* added extension module; 
+		supports RealTime and other Vamp type wrappers
+		enables a much more readable syntax
 	* added Numpy Array interface
 	* added flags
 	* added environment variables
-	* recognise byte compiled python scripts
+	* recognise byte compiled python scripts 
+	* new example plugin PyMFCC
+	* modified all examples for the new syntax
+	* bug fix: Nyquist frequency FFT output is now passed correctly
+
+	
+TODO:	
+	* Vamp 'programs' not implemented
+	* support multiple classes per script in scanner
+	* implement missing methods of vampy.RealTime type
+
 	
 LICENCE: