changeset 8:db72f98403b4 lf-numpy-arrays

Working on the code so that it accepts numpy n-dim arrays directly (output of scikits.audiolab). Not working for stereo.
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Thu, 14 Mar 2013 11:37:07 +0000
parents d29c25695f5e
children 703f52bf8a2e
files Makefile vampyhost.cpp vampyhost_test.py
diffstat 3 files changed, 114 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue Mar 12 18:20:06 2013 +0000
+++ b/Makefile	Thu Mar 14 11:37:07 2013 +0000
@@ -1,27 +1,25 @@
 
 PY_INCLUDE_PATH	:= /usr/include/python2.7
-NUMPY_INCLUDE_PATH := /usr/lib/python2.7/site-packages/numpy/core/include
+NUMPY_INCLUDE_PATH := /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/core/include
 
 CFLAGS		:= -O2 -fPIC -Wall -I$(PY_INCLUDE_PATH) -I$(NUMPY_INCLUDE_PATH) -I.
-CXXFLAGS	:= -O2 -fPIC -Wall -I$(PY_INCLUDE_PATH) -I$(NUMPY_INCLUDE_PATH) -I.
+CXXFLAGS	:= -O2 -fPIC -Wall -I$(PY_INCLUDE_PATH) -I$(NUMPY_INCLUDE_PATH) -I. -I../vamp-plugin-sdk
 
-LDFLAGS		:= -shared -lpython2.7 -lvamp-hostsdk
+LDFLAGS		:= -shared -L../vamp-plugin-sdk -lpython2.7 -lvamp-hostsdk
 #LDFLAGS		:= -dynamiclib -lpython2.5 /usr/lib/libvamp-hostsdk.a
 
+all: pyRealTime.so vampyhost.so
 
-all: pyRealTime.so vampyhost.so 
-
-pyRealTime.a: pyRealTime.o  
+pyRealTime.a: pyRealTime.o
 	ar r $@ pyRealTime.o
 
 pyRealTime.so: pyRealTime.o
-	g++ -shared $^ -o $@ $(LDFLAGS) 
+	g++ -shared $^ -o $@ $(LDFLAGS)
 
 vampyhost.so: vampyhost.o pyRealTime.a
 	g++ -o $@ -shared $^ $(LDFLAGS)
 
-
-clean:	
+clean:
 	rm *.o
 	rm *.so
-	rm *.a	
+	rm *.a
--- a/vampyhost.cpp	Tue Mar 12 18:20:06 2013 +0000
+++ b/vampyhost.cpp	Thu Mar 14 11:37:07 2013 +0000
@@ -483,12 +483,12 @@
 vampyhost_process(PyObject *self, PyObject *args)
 {
     PyObject *pyPluginHandle;
-    PyObject *pyBuffer;
+    PyArrayObject *pyBuffer;
     PyObject *pyRealTime;
 
     if (!PyArg_ParseTuple(args, "OOO",
 			  &pyPluginHandle,	// C object holding a pointer to a plugin and its descriptor
-			  &pyBuffer,			// Audio data
+			  &pyBuffer,			// Audio data (NumPy ndim array)
 			  &pyRealTime)) {		// TimeStamp
 	PyErr_SetString(PyExc_TypeError,
 			"Required: plugin handle, buffer, timestmap.");
@@ -502,48 +502,72 @@
     Plugin *plugin;
 
     if (!getPluginHandle(pyPluginHandle, &plugin, &key)) {
-	PyErr_SetString(PyExc_AttributeError,
-			"Invalid or already deleted plugin handle.");
-	return NULL;
+    PyErr_SetString(PyExc_AttributeError,
+            "Invalid or already deleted plugin handle.");
+    return NULL;
     }
 
     PyPluginDescriptor *pd = (PyPluginDescriptor*) key;
 
     if (!pd->isInitialised) {
-	PyErr_SetString(PyExc_StandardError,
-			"Plugin has not been initialised.");
-	return NULL; }
+    PyErr_SetString(PyExc_StandardError,
+            "Plugin has not been initialised.");
+    return NULL; }
 
     size_t channels =  pd->channels;
     size_t blockSize = pd->blockSize;
 
-    if (!PyList_Check(pyBuffer)) {
-	PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
+    if (!PyArray_Check(pyBuffer)) {
+        PyErr_SetString(PyExc_TypeError, "Argument is not a Numpy array.");
         return NULL;
     }
 
-    if (PyList_GET_SIZE(pyBuffer) != channels) {
-        std::cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << std::endl;
+    if (pyBuffer->nd != channels) {
+        cerr << "Wrong number of channels: got " << pyBuffer->nd << ", expected " << channels << endl;
 	PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
         return NULL;
     }
 
+    int n = pyBuffer->dimensions[0];
+    int m = pyBuffer->dimensions[1];
+
+    cout << "Kind :" << pyBuffer->descr->kind << endl;
+    cout << "Strides 0 :" << pyBuffer->strides[0] << endl;
+    cout << "Strides 1 :" << pyBuffer->strides[1] << endl;
+    cout << "Flags:" << pyBuffer->flags << endl;
+
     float **inbuf = new float *[channels];
+    cout << "Created inbuf with #channels: " << channels << endl;
 
     for (int c = 0; c < channels; ++c) {
-        PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
-        inbuf[c] = pyArrayToFloatArray(cbuf);
+
+        // cout << "[Host] Converting channel #" << c << endl;
+        // PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
+        // cout << "Ok1..." << endl;
+        // inbuf[c] = pyArrayToFloatArray(cbuf);
+
+        inbuf[c] = pyArrayToFloatArray((PyObject*) pyBuffer);
+
+        cout << "Ok2..." << endl;
+
         if (!inbuf[c]) {
             PyErr_SetString(PyExc_TypeError,"NumPy Array required for each channel in process input.");
             return NULL;
         }
+
+        cout << "[Host] Converted channel #" << c << endl;
+
     }
 
     RealTime timeStamp = *PyRealTime_AsPointer(pyRealTime);
 
+    cout << "[Host] Gonna call plugin->process" << endl;
+
     //Call process and store the output
     pd->output = plugin->process(inbuf, timeStamp);
 
+    cout << "[Host] Called plugin->process" << endl;
+
     /* TODO:  DO SOMETHONG WITH THE FEATURE SET HERE */
 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ...
 
@@ -553,8 +577,11 @@
     }
     delete[] inbuf;
 
+
+
+
+
     return NULL; //!!! Need to return actual features!
-
 }
 
 /* GET / SET OUTPUT */
@@ -706,6 +733,9 @@
     m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc);
     if (m == NULL) return;
 
+    // Numpy array library initialization function
+    import_array();
+
     // PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type);
 
 }
--- a/vampyhost_test.py	Tue Mar 12 18:20:06 2013 +0000
+++ b/vampyhost_test.py	Thu Mar 14 11:37:07 2013 +0000
@@ -1,57 +1,55 @@
-
 import sys
 import os
 
 sys.path.append(os.getcwd())
 
-import scikits.audiolab as al;
+import numpy as np
+print np.__version__
+
+import matplotlib.pyplot as plt
+import scikits.audiolab as al
+
+import vampyhost as vh
 
 #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'
+wavfile = 'test-mono.wav'
+# wavfile = '4sample-stereo-ny.wav'
 
-wavdata, samplerate, format = al.wavread(wavfile);
+af = al.Sndfile(wavfile)
 
-print "samplerate: ",samplerate
-print "number of samples (frames): ",wavdata.size
+nchannels = af.channels
 
-audio = wavdata.transpose()
+print "Samplerate: ", af.samplerate
+print "Number of channels: ", nchannels
+print "Number of samples (frames): ", af.nframes
 
-channels = audio.size
-print "channels: ",channels
-
-rt=realtime(4,70)
+rt = vh.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()
+for i in [0, 1, 2]:
+    if i == 0:
+        rtl = []
+    rtl.append(vh.realtime())
+    print ">>>>>RealTime's method: ", rtl[i].values()
 
 
 class feature_example():
-	def __init__(self):
-		self.hasTimestamp
-		self.timestamp
-		self.values
-		self.label
+    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
+for i, n in enumerate(pluginlist):
+    print i, ":", n
+
+pluginKey = pluginlist[0]  # try the first plugin listed
 
 retval = vh.getLibraryPath(pluginKey)
 print pluginKey
@@ -59,40 +57,48 @@
 
 print vh.getPluginCategory(pluginKey)
 print vh.getOutputList(pluginKey)
-handle = vh.loadPlugin(pluginKey,samplerate);
-print "\n\nPlugin handle: ",handle
+handle = vh.loadPlugin(pluginKey, af.samplerate)
 
-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"
+print "\n\nPlugin handle: ", handle
+print "Output list of: ", pluginKey, "\n", vh.getOutputList(handle)
+
+# initialise: pluginhandle, channels, stepSize, blockSize
+if vh.initialise(handle, nchannels, 1024, 1024):
+    print "Initialise succeeded"
 else:
-	print "Initialise failed!"
-	exit(1)
+    print "Initialise failed!"
+    exit(1)
 
-#!!! continue with this lark
+# should return a realtime object
+rt = vh.frame2RealTime(100000, 22050)
+print rt
 
-rt=frame2RealTime(100000,22050)
-print type(rt)
+assert type(rt) == type(vh.realtime())
 
-out=vh.process(handle,list(audio),rt) ##!!! cast to list should not be necessary
-output = vh.getOutput(handle,1);
+audio = af.read_frames(af.nframes)
+audio = np.transpose(audio)
+
+print "Gonna send", len(audio)
+
+out = vh.process(handle, audio, rt)
+print "OKEYDOKEY: Processed"
+
+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)
+print "_______________OUTPUT TYPE_________:", type(out)
+in_audio = np.frombuffer(audio, np.int16, -1, 0)
+out_audio = np.frombuffer(out, np.float32, -1, 0)
+plt.subplot(211)
+plt.plot(in_audio)
+plt.subplot(212)
+plt.plot(out_audio)
 
-show()
+plt.show()
 #do some processing here
 
 #buffer is a multichannel frame or a numpy array containing samples
@@ -102,8 +108,8 @@
 
 #output is a list of list of features
 
-vh.unloadPlugin(handle);
-vh.unloadPlugin(handle); # test if it chrashes...
+vh.unloadPlugin(handle)
+vh.unloadPlugin(handle)  # test if it chrashes...
 
 print vh.getOutputList(handle)