changeset 17:3893b76daf80

Type checking for process call, start on some tests
author Chris Cannam
date Mon, 24 Nov 2014 16:22:54 +0000
parents 7987e3123909
children 4b9adb4b532f
files .hgignore .hgsubstate test_metadata.py vampyhost.cpp vampyhost_exercise.py vampyhost_test.py
diffstat 6 files changed, 174 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Nov 24 14:39:56 2014 +0000
+++ b/.hgignore	Mon Nov 24 16:22:54 2014 +0000
@@ -4,3 +4,4 @@
 *.so
 *.dll
 *.dylib
+*.pyc
--- a/.hgsubstate	Mon Nov 24 14:39:56 2014 +0000
+++ b/.hgsubstate	Mon Nov 24 16:22:54 2014 +0000
@@ -1,1 +1,1 @@
-76355b91cd92c57633e72f680494a2f67740ba58 vampy
+e7d03f88ef43458d5e2954f8368d489e862f1a25 vampy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test_metadata.py	Mon Nov 24 16:22:54 2014 +0000
@@ -0,0 +1,26 @@
+
+import vampyhost as vh
+
+testPluginKey = "vamp-test-plugin:vamp-test-plugin"
+
+##!!! could use: plugin version
+
+def test_enumerate():
+    plugins = vh.enumeratePlugins()
+    if testPluginKey not in plugins:
+        print("Test plugin " + testPluginKey + " not installed or not returned by enumerate: can't run any tests without it")
+    assert testPluginKey in plugins
+
+def test_path():
+    path = vh.getPluginPath()
+    assert len(path) > 0
+
+def test_getlibrary():
+    lib = vh.getLibraryForPlugin(testPluginKey)
+    assert lib != ""
+
+def test_getoutputlist():
+    outputs = vh.getOutputList(testPluginKey)
+    assert len(outputs) == 8
+    assert "curve-vsr" in outputs
+    
--- a/vampyhost.cpp	Mon Nov 24 14:39:56 2014 +0000
+++ b/vampyhost.cpp	Mon Nov 24 16:22:54 2014 +0000
@@ -63,7 +63,6 @@
     size_t channels;
     size_t blockSize;
     size_t stepSize;
-    Vamp::Plugin::FeatureSet output;
 };
 
 /* MODULE HELPER FUNCTIONS */
@@ -267,9 +266,6 @@
     return pyPluginHandle;
 }
 
-
-/* INITIALISE PLUGIN */
-
 static PyObject *
 vampyhost_initialise(PyObject *self, PyObject *args)
 {
@@ -282,7 +278,7 @@
 			   (size_t) &blockSize))
     {
 	PyErr_SetString(PyExc_TypeError,
-			"Wrong input arguments: requires a valid plugin handle,channels,stepSize,blockSize.");
+			"initialise() takes plugin handle (object), channel count, step size, and block size arguments");
 	return 0;
     }
 
@@ -294,9 +290,9 @@
     pd->blockSize = blockSize;
 
     if (!pd->plugin->initialise(channels, stepSize, blockSize)) {
-        std::cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << std::endl;
+        cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << endl;
 	PyErr_SetString(PyExc_TypeError,
-			"Plugin initialization failed.");
+			"Plugin initialization failed");
 	return 0;
     }
 
@@ -305,8 +301,6 @@
     return Py_True;
 }
 
-/* RUN PROCESS */
-
 static PyObject *
 vampyhost_process(PyObject *self, PyObject *args)
 {
@@ -319,13 +313,18 @@
 			  &pyBuffer,			// Audio data
 			  &pyRealTime)) {		// TimeStamp
 	PyErr_SetString(PyExc_TypeError,
-			"Required: plugin handle, buffer, timestmap.");
+			"process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments");
 	return 0; }
 
     if (!PyRealTime_Check(pyRealTime)) {
 	PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
 	return 0; }
 
+    if (!PyList_Check(pyBuffer)) {
+	PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
+        return 0;
+    }
+
     PyPluginData *pd = getPluginData(pyPluginHandle);
     if (!pd) return 0;
 
@@ -336,15 +335,9 @@
     }
 
     int channels =  pd->channels;
-//    int blockSize = pd->blockSize;
-
-    if (!PyList_Check(pyBuffer)) {
-	PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
-        return 0;
-    }
 
     if (PyList_GET_SIZE(pyBuffer) != channels) {
-        std::cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << std::endl;
+        cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl;
 	PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
         return 0;
     }
@@ -353,21 +346,30 @@
 
     PyTypeConversions typeConv;
     typeConv.setNumpyInstalled(true);
+
+    cerr << "here!"  << endl;
     
     vector<vector<float> > data;
     for (int c = 0; c < channels; ++c) {
         PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
-        data.push_back(typeConv.PyArray_To_FloatVector(cbuf));
+        data.push_back(typeConv.PyValue_To_FloatVector(cbuf));
     }
     
     for (int c = 0; c < channels; ++c) {
+        if (data[c].size() != pd->blockSize) {
+            cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl;
+            PyErr_SetString(PyExc_TypeError, "Wrong number of samples");
+            return 0;
+        }
         inbuf[c] = &data[c][0];
     }
 
+    cerr << "no, here!"  << endl;
+
     RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
 
-    //Call process and store the output
-    pd->output = pd->plugin->process(inbuf, timeStamp);
+    // Call process and store the output
+    (void) pd->plugin->process(inbuf, timeStamp); //!!! return the output!
 
     /* TODO:  DO SOMETHONG WITH THE FEATURE SET HERE */
 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ...
@@ -378,9 +380,7 @@
 
 }
 
-/* GET / SET OUTPUT */
-
-//getOutput(plugin,outputNo)
+#ifdef NOPE
 static PyObject *
 vampyhost_getOutput(PyObject *self, PyObject *args) {
 
@@ -429,8 +429,8 @@
 // We have the block output in pd->output
 // FeatureSet[output] -> [Feature[x]] -> Feature.hasTimestamp = v
 // Vamp::Plugin::FeatureSet output; = pd->output
-// typedef std::vector<Feature> FeatureList;
-// typedef std::map<int, FeatureList> FeatureSet; // key is output no
+// typedef vector<Feature> FeatureList;
+// typedef map<int, FeatureList> FeatureSet; // key is output no
 
     // 	THIS IS FOR OUTPUT id LOOKUP LATER
     //     Plugin::OutputList outputs = plugin->getOutputDescriptors();
@@ -451,7 +451,7 @@
     //     }
 
 }
-
+#endif
 
 
 
@@ -486,8 +486,8 @@
     {"initialise",	vampyhost_initialise, METH_VARARGS,
      xx_foo_doc},
 
-    {"getOutput",	vampyhost_getOutput, METH_VARARGS,
-     xx_foo_doc},
+//    {"getOutput",	vampyhost_getOutput, METH_VARARGS,
+//     xx_foo_doc},
 
     /* Add RealTime Module Methods */
 /*
@@ -519,7 +519,6 @@
 
     if (PyType_Ready(&RealTime_Type) < 0)
 	return;
-//	PyModule_AddObject(m, "Real_Time", (PyObject *)&RealTime_Type);
 
     /* Create the module and add the functions */
     m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc);
@@ -527,6 +526,5 @@
 
     import_array();
 
-    // PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type);
-
+    PyModule_AddObject(m, "RealTime", (PyObject *)&RealTime_Type);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vampyhost_exercise.py	Mon Nov 24 16:22:54 2014 +0000
@@ -0,0 +1,117 @@
+
+import sys
+import os
+
+sys.path.append(os.getcwd())
+
+import scikits.audiolab as al;
+
+#from melscale import melscale
+#from melscale import initialize
+from pylab import *
+# from melscale import *
+from numpy import *
+from pylab import *
+from time import *
+
+from vampyhost import *
+import vampyhost
+import vampyhost as vh
+#import pyRealTime
+#from pyRealTime import *
+
+#deal with an audio file
+wavfile='test.wav'
+
+wavdata, samplerate, format = al.wavread(wavfile);
+
+print "samplerate: ",samplerate
+print "number of samples (frames): ",wavdata.size
+
+audio = wavdata.transpose()
+
+channels = audio.size
+print "channels: ",channels
+
+rt=realtime(4,70)
+
+#test RealTime Object
+for i in [0,1,2] :
+	if (i==0) : rtl=[]
+	rtl.append(realtime())
+	print ">>>>>RealTime's method: ", rtl[i].values()
+
+
+class feature_example():
+	def __init__(self):
+		self.hasTimestamp
+		self.timestamp
+		self.values
+		self.label
+
+pluginlist = vh.enumeratePlugins()
+for i,n in enumerate(pluginlist) : print i,":",n
+pluginKey=pluginlist[0]; # try the first plugin listed
+
+retval = vh.getLibraryPath(pluginKey)
+print pluginKey
+print retval
+
+print vh.getPluginCategory(pluginKey)
+print vh.getOutputList(pluginKey)
+handle = vh.loadPlugin(pluginKey,samplerate);
+print "\n\nPlugin handle: ",handle
+
+print "Output list of: ",pluginKey,"\n",vh.getOutputList(handle)
+print "Have ", len(audio), " channels in audio"
+
+#initialise: pluginhandle, channels, stepSize, blockSize
+if vh.initialise(handle,len(audio),1024,1024):
+	print "Initialise succeeded"
+else:
+	print "Initialise failed!"
+	exit(1)
+
+#!!! continue with this lark
+
+rt=frame2RealTime(100000,22050)
+print type(rt)
+
+out=vh.process(handle,list(audio),rt) ##!!! cast to list should not be necessary
+output = vh.getOutput(handle,1);
+
+print type(output)
+print output
+#print output[1].label
+
+print "_______________OUTPUT TYPE_________:",type(out)
+in_audio = frombuffer(audio,int16,-1,0)
+out_audio = frombuffer(out,float32,-1,0)
+subplot(211)
+plot(in_audio)
+subplot(212)
+plot(out_audio)
+
+show()
+#do some processing here
+
+#buffer is a multichannel frame or a numpy array containing samples
+#buffer = vh.frame(audiodata,stepSize,blockSize)
+
+#output = vh.process(handle,buffer)
+
+#output is a list of list of features
+
+vh.unloadPlugin(handle);
+vh.unloadPlugin(handle); # test if it chrashes...
+
+print vh.getOutputList(handle)
+
+#cases:
+#buffer = blockSize : evaluate
+#buffer > blockSize : enframe and zeropad
+#return:
+#oneSamplePerStep, FixedSamplerate : can return numpy array
+#variableSamplerate : list of featres only
+
+#print dir(vampyhost)
--- a/vampyhost_test.py	Mon Nov 24 14:39:56 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-
-import sys
-import os
-
-sys.path.append(os.getcwd())
-
-import scikits.audiolab as al;
-
-#from melscale import melscale
-#from melscale import initialize
-from pylab import *
-# from melscale import *
-from numpy import *
-from pylab import *
-from time import *
-
-from vampyhost import *
-import vampyhost
-import vampyhost as vh
-#import pyRealTime
-#from pyRealTime import *
-
-#deal with an audio file
-wavfile='test.wav'
-
-wavdata, samplerate, format = al.wavread(wavfile);
-
-print "samplerate: ",samplerate
-print "number of samples (frames): ",wavdata.size
-
-audio = wavdata.transpose()
-
-channels = audio.size
-print "channels: ",channels
-
-rt=realtime(4,70)
-
-#test RealTime Object
-for i in [0,1,2] :
-	if (i==0) : rtl=[]
-	rtl.append(realtime())
-	print ">>>>>RealTime's method: ", rtl[i].values()
-
-
-class feature_example():
-	def __init__(self):
-		self.hasTimestamp
-		self.timestamp
-		self.values
-		self.label
-
-pluginlist = vh.enumeratePlugins()
-for i,n in enumerate(pluginlist) : print i,":",n
-pluginKey=pluginlist[0]; # try the first plugin listed
-
-retval = vh.getLibraryPath(pluginKey)
-print pluginKey
-print retval
-
-print vh.getPluginCategory(pluginKey)
-print vh.getOutputList(pluginKey)
-handle = vh.loadPlugin(pluginKey,samplerate);
-print "\n\nPlugin handle: ",handle
-
-print "Output list of: ",pluginKey,"\n",vh.getOutputList(handle)
-print "Have ", len(audio), " channels in audio"
-
-#initialise: pluginhandle, channels, stepSize, blockSize
-if vh.initialise(handle,len(audio),1024,1024):
-	print "Initialise succeeded"
-else:
-	print "Initialise failed!"
-	exit(1)
-
-#!!! continue with this lark
-
-rt=frame2RealTime(100000,22050)
-print type(rt)
-
-out=vh.process(handle,list(audio),rt) ##!!! cast to list should not be necessary
-output = vh.getOutput(handle,1);
-
-print type(output)
-print output
-#print output[1].label
-
-print "_______________OUTPUT TYPE_________:",type(out)
-in_audio = frombuffer(audio,int16,-1,0)
-out_audio = frombuffer(out,float32,-1,0)
-subplot(211)
-plot(in_audio)
-subplot(212)
-plot(out_audio)
-
-show()
-#do some processing here
-
-#buffer is a multichannel frame or a numpy array containing samples
-#buffer = vh.frame(audiodata,stepSize,blockSize)
-
-#output = vh.process(handle,buffer)
-
-#output is a list of list of features
-
-vh.unloadPlugin(handle);
-vh.unloadPlugin(handle); # test if it chrashes...
-
-print vh.getOutputList(handle)
-
-#cases:
-#buffer = blockSize : evaluate
-#buffer > blockSize : enframe and zeropad
-#return:
-#oneSamplePerStep, FixedSamplerate : can return numpy array
-#variableSamplerate : list of featres only
-
-#print dir(vampyhost)