changeset 11:4610f2b8477d

added pyRealTime object impl to host
author fazekasgy
date Mon, 16 Jun 2008 09:44:48 +0000
parents 8e9fbe4dc94d
children 095df80af751
files host/Makefile host/README host/pyRealTime.cpp host/pyRealTime.h
diffstat 4 files changed, 524 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host/Makefile	Mon Jun 16 09:44:48 2008 +0000
@@ -0,0 +1,24 @@
+CFLAGS		:= -O2 -Wall -I/usr/include/python2.5 -I/usr/include/vamp-sdk/hostext/ -I/usr/include/vamp-sdk/ -I/Users/Shared/Development/vampy-host-experiments/
+CXXFLAGS	:= -O2 -Wall -I/usr/include/python2.5 -I/usr/include/vamp-sdk/hostext/ -I/usr/include/vamp-sdk/ -I/Users/Shared/Development/vampy-host-experiments/
+LDFLAGS		:= -dynamiclib -lpython2.5 /usr/lib/libvamp-hostsdk.a
+
+
+all: pyRealTime.so 
+# all: pyRealTime.so vampyhost.so 
+
+
+pyRealTime.a: pyRealTime.o  
+	ar r $@ pyRealTime.o
+
+pyRealTime.so: pyRealTime.o
+	g++ -shared $^ -o $@ $(LDFLAGS) 
+
+vampyhost.so: vampyhost.o pyRealTime.a
+	g++ -o $@ -shared $^ $(LDFLAGS)
+
+
+clean:	
+	rm *.o
+	rm *.so
+	rm *.a	
+		
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host/README	Mon Jun 16 09:44:48 2008 +0000
@@ -0,0 +1,22 @@
+
+This is the place for Vampy-host.
+For now there is one object: pyRealTime which implements a wrapper around Vamp::RealTime.
+
+Using pyRealTime:
+
+(1) Compile: make pyRealTime.so
+(2) Test it in Python: 
+
+>>>import pyRealTime
+>>>from pyRealTime import *
+>>> dir(pyRealTime)
+['__doc__', '__file__', '__name__', 'frame2RealTime', 'realtime']
+>>>t = realtime(2,0)
+>>>t.sec
+2
+>>>t.nsec
+0
+>>> dir(realtime())
+['test', 'toFloat', 'toFrame', 'toText', 'values']
+>>> frame2RealTime(22050*10,22050).values()
+(10, 0)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host/pyRealTime.cpp	Mon Jun 16 09:44:48 2008 +0000
@@ -0,0 +1,434 @@
+/*
+
+This module exposes a Type Object wrapping VAMP::RealTime
+together with module level functions to create 
+new pyRealTime objects from frame count, samplerate or sec,nsec tuples.
+
+A small API is provided for the C/C++ programmer and relevant
+functions are exposed to Python.
+
+TODO: implement number protocol (i.e. wrap arithmetic operators) 
+partly done
+
+*/
+
+#include <Python.h>
+#include <pyRealTime.h>
+#include "vamp-sdk/Plugin.h"
+#include <string>
+
+using namespace std;
+using namespace Vamp;
+
+using Vamp::Plugin;
+using Vamp::RealTime;
+
+/*						REAL-TIME TYPE OBJECT						*/
+
+
+/* Documentation for our new module */
+PyDoc_STRVAR(module_doc,
+"This module is a thin wrapper around VAMP::RealTime.");
+
+
+/*					 RealTime Object's Methods 					*/ 
+//Note: these are internals, not exposed by the module but the object
+
+/* Returns a Tuple containing sec and nsec values */
+static PyObject *
+RealTime_values(RealTimeObject *self)
+{
+	return Py_BuildValue("(ii)",
+	self->rt->sec,self->rt->nsec);
+}
+
+/* Returns a Text representation */
+static PyObject *
+RealTime_toText(RealTimeObject *self, PyObject *args)
+{
+	return Py_BuildValue("s",
+	self->rt->toText().c_str());
+}
+
+/* String representation called by e.g. str(realtime), print realtime*/
+static PyObject *
+RealTime_repr(PyObject *self)
+{
+	return Py_BuildValue("s",
+	((RealTimeObject*)self)->rt->toString().c_str());
+}
+
+
+/* Frame representation */
+static PyObject *
+RealTime_toFrame(PyObject *self, PyObject *args)
+{
+	unsigned int samplerate;
+	
+	if ( !PyArg_ParseTuple(args, "I:realtime.toFrame object ", 
+	(unsigned int *) &samplerate )) {
+		PyErr_SetString(PyExc_ValueError, 
+		"Sample Rate Required.");
+		return NULL;
+	}
+	
+	return Py_BuildValue("k", 
+	RealTime::realTime2Frame( 
+	*(const RealTime*) ((RealTimeObject*)self)->rt, 
+	(unsigned int) samplerate));
+}
+
+/* Conversion of realtime to a double precision floating point value */
+/* ...in Python called by e.g. float(realtime) */
+static PyObject *
+RealTime_float(PyObject *s)
+{
+	double drt = ((double) ((RealTimeObject*)s)->rt->sec + 
+	(double)((double) ((RealTimeObject*)s)->rt->nsec)/1000000000);
+	return PyFloat_FromDouble(drt);	
+}
+
+/* test */
+static PyObject *
+RealTime_test(PyObject *self)
+{
+
+	long frame = 100;
+	unsigned int sampleRate = 22050;
+	
+	const RealTime t = RealTime::frame2RealTime(frame,sampleRate);
+	long back = RealTime::realTime2Frame(t,sampleRate);
+	cerr << "Reverse Conversion: " << back << endl;
+
+	return Py_BuildValue("s",
+	((RealTimeObject*)self)->rt->toString().c_str());
+}
+
+
+/* Type object's (RealTime) methods table */
+static PyMethodDef RealTime_methods[] = {
+
+	{"toText",	(PyCFunction)RealTime_toText,	METH_NOARGS,
+		PyDoc_STR("toText() -> Return a user-readable string to the nearest millisecond in a form like HH:MM:SS.mmm")},
+
+	{"values",	(PyCFunction)RealTime_values,	METH_NOARGS,
+		PyDoc_STR("values() -> Tuple of sec,nsec representation.")},
+
+	{"toFrame",	(PyCFunction)RealTime_toFrame,	METH_VARARGS,
+		PyDoc_STR("frame(samplerate) -> Sample count for given sample rate.")},
+
+	{"toFloat",	(PyCFunction)RealTime_float,	METH_NOARGS,
+		PyDoc_STR("float() -> Floating point representation.")},
+
+	{"test",	(PyCFunction)RealTime_test,	METH_VARARGS,
+		PyDoc_STR("test() -> .")},
+	
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+
+/* Function to set basic attributes */
+static int
+RealTime_setattr(RealTimeObject *self, char *name, PyObject *value)
+{
+
+	if ( !string(name).compare("sec")) { 
+		self->rt->sec= (int) PyInt_AS_LONG(value);
+		return 0;
+	}
+
+	if ( !string(name).compare("nsec")) { 
+		self->rt->nsec= (int) PyInt_AS_LONG(value);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Function to get basic attributes */
+static PyObject *
+RealTime_getattr(RealTimeObject *self, char *name)
+{
+
+	if ( !string(name).compare("sec") ) { 
+		return PyInt_FromSsize_t(
+		(Py_ssize_t) self->rt->sec); 
+	} 
+
+	if ( !string(name).compare("nsec") ) { 
+		return PyInt_FromSsize_t(
+		(Py_ssize_t) self->rt->nsec); 
+	} 
+
+	return Py_FindMethod(RealTime_methods, 
+	(PyObject *)self, name);
+}
+
+
+/* DESTRUCTOR: delete type object */
+static void
+RealTimeObject_dealloc(RealTimeObject *self)
+{
+	delete self->rt; 	//delete the C object
+	PyObject_Del(self); //delete the Python object
+}
+
+/*					 Number Protocol 					*/
+
+
+static PyObject *
+RealTime_add(PyObject *s, PyObject *w)
+{
+
+	RealTimeObject *result = 
+    PyObject_New(RealTimeObject, &RealTime_Type); 
+	if (result == NULL) return NULL;
+
+	result->rt = new RealTime::RealTime(
+	*((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
+	return (PyObject*)result;
+}
+
+static PyObject *
+RealTime_subtract(PyObject *s, PyObject *w)
+{
+
+	RealTimeObject *result = 
+    PyObject_New(RealTimeObject, &RealTime_Type); 
+	if (result == NULL) return NULL;
+
+	result->rt = new RealTime::RealTime(
+	*((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
+	return (PyObject*)result;
+}
+
+
+static PyNumberMethods realtime_as_number = {
+	RealTime_add,			/*nb_add*/
+	RealTime_subtract,		/*nb_subtract*/
+	0,						/*nb_multiply*/
+	0,				 		/*nb_divide*/
+    0,						/*nb_remainder*/
+    0,      	            /*nb_divmod*/
+    0,                   	/*nb_power*/
+    0,                  	/*nb_neg*/
+    0,                		/*nb_pos*/
+    0,                  	/*(unaryfunc)array_abs,*/
+    0,                    	/*nb_nonzero*/
+    0,                    	/*nb_invert*/
+    0,       				/*nb_lshift*/
+    0,      				/*nb_rshift*/
+    0,      				/*nb_and*/
+    0,      				/*nb_xor*/
+    0,       				/*nb_or*/
+    0,                      /*nb_coerce*/
+    0,						/*nb_int*/
+    0,				        /*nb_long*/
+    (unaryfunc)RealTime_float,             /*nb_float*/
+    0,               		/*nb_oct*/
+    0,               		/*nb_hex*/
+};
+
+/*					 pyRealTime TypeObject 					*/
+
+
+/* Doc:: 10.3 Type Objects */
+/* static */ PyTypeObject RealTime_Type = {
+	/* The ob_type field must be initialized in the module init function
+	 * to be portable to Windows without using C++. */
+	PyObject_HEAD_INIT(NULL)
+	0,						/*ob_size*/
+	"pyRealTime.realtime",				/*tp_name*/
+	sizeof(RealTimeObject),	/*tp_basicsize*/
+	sizeof(RealTime),		/*tp_itemsize*/
+	/*	 	methods	 	*/
+	(destructor)RealTimeObject_dealloc, /*tp_dealloc*/
+	0,						/*tp_print*/
+	(getattrfunc)RealTime_getattr, /*tp_getattr*/
+	(setattrfunc)RealTime_setattr, /*tp_setattr*/
+	0,						/*tp_compare*/
+	RealTime_repr,			/*tp_repr*/
+	&realtime_as_number,	/*tp_as_number*/
+	0,						/*tp_as_sequence*/
+	0,						/*tp_as_mapping*/
+	0,						/*tp_hash*/
+	0,//(ternaryfunc)RealTime_new,                      /*tp_call*/
+    0,                      /*tp_str*/
+    0,                      /*tp_getattro*/
+    0,                      /*tp_setattro*/
+    0,                      /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+    0,                      /*tp_doc*/
+    0,                      /*tp_traverse*/
+    0,                      /*tp_clear*/
+    0,                      /*tp_richcompare*/
+    0,                      /*tp_weaklistoffset*/
+    0,                      /*tp_iter*/
+    0,                      /*tp_iternext*/
+    RealTime_methods,       /*tp_methods*/ //TypeObject Methods
+    0,                      /*tp_members*/
+    0,                      /*tp_getset*/
+    0,                      /*tp_base*/
+    0,                      /*tp_dict*/
+    0,                      /*tp_descr_get*/
+    0,                      /*tp_descr_set*/
+    0,                      /*tp_dictoffset*/
+    0,                      /*tp_init*/
+    0,                      /*tp_alloc*/
+    0,                      /*tp_new*/
+    0,			            /*tp_free*/
+    0,                      /*tp_is_gc*/
+};
+
+
+/*		 Remaining Functions Exposed by the MODULE 					*/
+
+
+/* New RealTime object from Frame (with given samplerate) */
+/*static*/ PyObject *
+RealTime_frame2RealTime(PyObject *ignored, PyObject *args)
+{
+
+	long frame;
+	unsigned int sampleRate;
+
+	if (!PyArg_ParseTuple(args, "lI:realtime.fame2RealTime ", 
+	&frame, 
+	&sampleRate))
+		return NULL;
+	/*Doc:: 5.5 Parsing arguments and building values*/
+
+	RealTimeObject *self;
+	self = PyObject_New(RealTimeObject, &RealTime_Type); 
+	if (self == NULL)
+		return NULL;
+
+	self->rt = new RealTime::RealTime(
+	RealTime::frame2RealTime(frame,sampleRate));
+
+	return (PyObject *) self;
+}
+
+/* New RealTime object from sec and nsec */
+/*static*/ PyObject *
+RealTime_new(PyObject *ignored, PyObject *args)
+{
+
+	unsigned int sec = 0;
+	unsigned int nsec = 0;
+	double unary = 0;
+	const char *fmt = NULL;
+
+	/*Doc:: 5.5 Parsing arguments and building values*/
+	if (
+		
+	!PyArg_ParseTuple(args, "|sd:realtime.new ", 
+	(const char *) &fmt, 
+	(double *) &unary) 	&&
+
+	!PyArg_ParseTuple(args, "|II:realtime.new ", 
+	(unsigned int*) &sec, 
+	(unsigned int*) &nsec) 
+		
+	) { 
+		PyErr_SetString(PyExc_TypeError, 
+		"RealTime initialised with wrong arguments.");
+		return NULL; }
+
+	PyErr_Clear();
+
+	RealTimeObject *self = 
+	PyObject_New(RealTimeObject, &RealTime_Type); 
+	if (self == NULL) return NULL;
+
+	self->rt = NULL;
+
+	if (sec == 0 && nsec == 0 && fmt == 0) 
+		self->rt = new RealTime::RealTime();
+	else if (fmt == 0)
+		self->rt = new RealTime::RealTime(sec,nsec);
+	else { 
+
+		if (!string(fmt).compare("float") ||
+			!string(fmt).compare("seconds"))  
+			self->rt = new RealTime::RealTime( 
+			RealTime::fromSeconds((double) unary)); 
+
+		if (!string(fmt).compare("milliseconds")) {
+			self->rt = new RealTime::RealTime( 
+			RealTime::fromSeconds((double) unary / 1000.0)); }
+	}
+
+	if (!self->rt) { 
+		PyErr_SetString(PyExc_TypeError, 
+		"RealTime initialised with wrong arguments.");
+		return NULL; 
+	}
+
+	return (PyObject *) self;
+}
+
+
+/* pyRealTime Module's methods table */
+static PyMethodDef Module_methods[] = {
+
+	{"frame2RealTime",	(PyCFunction)RealTime_frame2RealTime,	METH_VARARGS,
+		PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")},
+
+	{"realtime",	RealTime_new,		METH_VARARGS,
+		PyDoc_STR("realtime() -> returns new RealTime object")},
+	
+	{NULL,		NULL}		/* sentinel */
+};
+
+
+/*				 PyRealTime C API functions 					*/
+
+
+
+/*RealTime from PyRealTime*/
+RealTime*
+PyRealTime_AsPointer (PyObject *self) { 
+
+	RealTimeObject *s = (RealTimeObject*) self; 
+
+	if (!PyRealTime_Check(s)) {
+		PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
+		cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
+		return NULL; }
+	return s->rt; };
+
+/*PyRealTime from RealTime*/
+PyObject* 
+PyRealTime_FromRealTime(Vamp::RealTime *rt) {
+
+	RealTimeObject *self =
+	PyObject_New(RealTimeObject, &RealTime_Type); 
+	if (self == NULL) return NULL;
+
+	self->rt = new RealTime::RealTime(*rt);
+	return (PyObject*) self;
+}
+
+
+/* Module initialization (includes extern "C" {...}) */
+PyMODINIT_FUNC
+initpyRealTime(void)
+{
+	PyObject *m;
+
+	/* Finalize the type object including setting type of the new type
+	 * object; doing it here is required for portability to Windows 
+	 * without requiring C++. */
+	if (PyType_Ready(&RealTime_Type) < 0)
+		return;
+
+	/* Create the module and add the functions */
+	m = Py_InitModule3("pyRealTime", Module_methods, module_doc);
+	if (m == NULL)
+		return;
+
+//	PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host/pyRealTime.h	Mon Jun 16 09:44:48 2008 +0000
@@ -0,0 +1,44 @@
+#ifndef _PYREALTIME_H_
+#define _PYREALTIME_H_
+
+#include "vamp-sdk/Plugin.h"
+
+/* RealTime Type Object's structure    */
+/* Doc:: 10.2 Common Object Structures */
+typedef struct {
+		PyObject_HEAD
+		/*PyObject	*rt_attrs;*/
+		Vamp::RealTime::RealTime *rt;
+} RealTimeObject; 
+
+PyAPI_DATA(PyTypeObject) RealTime_Type;
+
+#define PyRealTime_CheckExact(v)	((v)->ob_type == &RealTime_Type)
+#define PyRealTime_Check(v) PyObject_TypeCheck(v, &RealTime_Type)
+
+/* pyRealTime C API functions */
+//	Example from Python's stringobject.h
+// 	PyAPI_FUNC(PyObject *) PyString_FromString(const char *);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+PyAPI_FUNC(PyObject *) 
+PyRealTime_FromRealTime(Vamp::RealTime *rt);
+
+PyAPI_FUNC(Vamp::RealTime::RealTime *) 
+PyRealTime_AsPointer (PyObject *self);
+
+/* PyRealTime Module functions */
+
+PyAPI_FUNC(PyObject *)
+RealTime_new(PyObject *ignored, PyObject *args);
+
+PyAPI_FUNC(PyObject *)
+RealTime_frame2RealTime(PyObject *ignored, PyObject *args);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _PYREALTIME_H_ */