annotate PyFeature.cpp @ 63:577b251cad2f

applied patch to fix bug related to numpy version string parsing
author gyorgyf
date Sat, 05 Oct 2013 13:36:27 +0100
parents 27bab3a16c9a
children 5664fe298af2
rev   line source
fazekasgy@37 1 /*
fazekasgy@37 2
fazekasgy@37 3 * Vampy : This plugin is a wrapper around the Vamp plugin API.
fazekasgy@37 4 * It allows for writing Vamp plugins in Python.
fazekasgy@37 5
fazekasgy@37 6 * Centre for Digital Music, Queen Mary University of London.
fazekasgy@37 7 * Copyright (C) 2008-2009 Gyorgy Fazekas, QMUL. (See Vamp sources
fazekasgy@37 8 * for licence information.)
fazekasgy@37 9
fazekasgy@37 10 */
fazekasgy@37 11
fazekasgy@37 12 #include <Python.h>
fazekasgy@37 13 #include "PyExtensionModule.h"
fazekasgy@37 14 #include "PyFeature.h"
fazekasgy@37 15 #include "vamp-sdk/Plugin.h"
fazekasgy@37 16 #include <string>
fazekasgy@37 17
fazekasgy@37 18 using namespace std;
fazekasgy@37 19 using namespace Vamp;
fazekasgy@37 20 using Vamp::Plugin;
fazekasgy@37 21
fazekasgy@37 22 /* CONSTRUCTOR: New Feature object */
fazekasgy@37 23 static PyObject *
fazekasgy@37 24 Feature_new(PyTypeObject *type, PyObject *args, PyObject *kw)
fazekasgy@37 25 {
fazekasgy@37 26 // FeatureObject *self = PyObject_New(FeatureObject, &Feature_Type);
fazekasgy@37 27 FeatureObject *self = (FeatureObject*)type->tp_alloc(type, 0);
fazekasgy@37 28 if (self == NULL) return NULL;
fazekasgy@37 29 self->dict = PyDict_New();
fazekasgy@37 30 if (self->dict == NULL) return NULL;
fazekasgy@37 31
fazekasgy@37 32 /// 4 args max.: {values|self_copy},timestamp,duration,label
fazekasgy@37 33 if(args && PyTuple_GET_SIZE(args)>0) {
fazekasgy@37 34 int s = PyTuple_GET_SIZE(args);
fazekasgy@37 35 PyObject* arg0 = PyTuple_GET_ITEM(args,0);
fazekasgy@37 36 if (s == 1 && PyFeature_CheckExact(arg0))
fazekasgy@37 37 PyDict_Merge(self->dict,PyFeature_AS_DICT(arg0),0);
fazekasgy@37 38 else
fazekasgy@37 39 PyDict_SetItemString(self->dict, "values", arg0);
fazekasgy@37 40 if (s>1) {
fazekasgy@37 41 PyDict_SetItemString(self->dict, "timestamp", PyTuple_GET_ITEM(args,1));
fazekasgy@37 42 PyDict_SetItemString(self->dict, "hasTimestamp", Py_True);
fazekasgy@37 43 }
fazekasgy@37 44 if (s>2) {
fazekasgy@37 45 PyDict_SetItemString(self->dict, "duration", PyTuple_GET_ITEM(args,2));
fazekasgy@37 46 PyDict_SetItemString(self->dict, "hasDuration", Py_True);
fazekasgy@37 47 }
fazekasgy@37 48 if (s>3) {
fazekasgy@37 49 PyDict_SetItemString(self->dict, "label", PyTuple_GET_ITEM(args,3));
fazekasgy@37 50 }
fazekasgy@37 51 }
fazekasgy@37 52
fazekasgy@37 53 /// accept keyword arguments:
fazekasgy@37 54 /// e.g. Feature(values = theOutputArray)
fazekasgy@37 55 if (!kw || !PyDict_Size(kw)) return (PyObject *) self;
fazekasgy@37 56 PyDict_Merge(self->dict,kw,0);
fazekasgy@37 57
fazekasgy@37 58 static char *kwlist[] = {"timestamp", "hasTimestamp", "duration", "hasDuration", 0};
fazekasgy@37 59
fazekasgy@37 60 int i = 0;
fazekasgy@37 61 while (kwlist[i]) {
fazekasgy@37 62 char* name = kwlist[i];
fazekasgy@37 63 char* attr = kwlist[++i];
fazekasgy@37 64 i++;
fazekasgy@37 65 PyObject *key = PyString_FromString(name);
fazekasgy@37 66 if (!key) break;
fazekasgy@37 67 if (PyDict_Contains(kw,key)) {
fazekasgy@37 68 if (PyDict_SetItem(self->dict,PyString_FromString(attr),Py_True) != 0)
fazekasgy@37 69 PyErr_SetString(PyExc_TypeError,
fazekasgy@37 70 "Error: in keyword arguments of vampy.Feature().");
fazekasgy@37 71 }
fazekasgy@37 72 Py_DECREF(key);
fazekasgy@37 73 }
fazekasgy@37 74
fazekasgy@37 75 return (PyObject *) self;
fazekasgy@37 76 }
fazekasgy@37 77
fazekasgy@37 78 /* DESTRUCTOR: delete type object */
fazekasgy@37 79 static void
fazekasgy@37 80 FeatureObject_dealloc(FeatureObject *self)
fazekasgy@37 81 {
fazekasgy@37 82 Py_XDECREF(self->dict);
fazekasgy@37 83 self->ob_type->tp_free((PyObject*)self);
fazekasgy@37 84 }
fazekasgy@37 85
fazekasgy@37 86 /* Feature Object's Methods */
fazekasgy@37 87 //Feature objects have no callable methods
fazekasgy@37 88
fazekasgy@37 89 /* PyFeature methods implementing protocols */
fazekasgy@37 90 // these functions are called by the interpreter automatically
fazekasgy@37 91
fazekasgy@37 92 /* Set attributes */
fazekasgy@37 93 static int
fazekasgy@37 94 Feature_setattr(FeatureObject *self, char *name, PyObject *v)
fazekasgy@37 95 {
fazekasgy@37 96 if (v == NULL)
fazekasgy@37 97 {
fazekasgy@37 98 int rv = PyDict_DelItemString(self->dict, name);
fazekasgy@37 99 if (rv < 0)
fazekasgy@37 100 PyErr_SetString(PyExc_AttributeError,"non-existing Feature attribute");
fazekasgy@37 101 return rv;
fazekasgy@37 102 }
fazekasgy@37 103 else return PyDict_SetItemString(self->dict, name, v);
fazekasgy@37 104 }
fazekasgy@37 105
fazekasgy@37 106
fazekasgy@37 107 /* Get attributes */
fazekasgy@37 108 static PyObject *
fazekasgy@37 109 Feature_getattr(FeatureObject *self, char *name)
fazekasgy@37 110 {
fazekasgy@37 111 if (self->dict != NULL) {
fazekasgy@37 112 PyObject *v = PyDict_GetItemString(self->dict, name);
fazekasgy@37 113 if (v != NULL)
fazekasgy@37 114 {
fazekasgy@37 115 Py_INCREF(v);
fazekasgy@37 116 return v;
fazekasgy@37 117 }
fazekasgy@37 118 }
fazekasgy@37 119 return NULL;
fazekasgy@37 120 }
fazekasgy@37 121
fazekasgy@37 122 /* The problem with this is that we'd need to implement two-way
fazekasgy@37 123 conversions which is really unnecesary: The case for using
fazekasgy@37 124 a Vamp::Feature in Python for anything else than returning
fazekasgy@37 125 values is rather obscure. It's not really worth it. */
fazekasgy@37 126
fazekasgy@37 127 /* Set Attribute: Using wrapped Vamp::Feature
fazekasgy@37 128 static int
fazekasgy@37 129 Feature_setattr(FeatureObject *self, char *name, PyObject *value)
fazekasgy@37 130 {
fazekasgy@37 131 std::string key = std::string(name);
fazekasgy@37 132 if (self->ti.SetValue(*(self->feature),key,value)) return 0;
fazekasgy@37 133 else return -1;
fazekasgy@37 134 }*/
fazekasgy@37 135
fazekasgy@37 136 /* Get Attribute: Using wrapped Vamp::Feature
fazekasgy@37 137 static PyObject *
fazekasgy@37 138 Feature_getattr(FeatureObject *self, char *name)
fazekasgy@37 139 {
fazekasgy@37 140 std::string key = std::string(name);
fazekasgy@37 141 PyObject* pyValue;
fazekasgy@37 142 if (self->ti.GetValue(*(self->feature),key,pyValue))
fazekasgy@37 143 return pyValue;
fazekasgy@37 144 else return NULL;
fazekasgy@37 145 }*/
fazekasgy@37 146
fazekasgy@37 147 /*
fazekasgy@37 148 static int
fazekasgy@37 149 Feature_init(FeatureObject *self, PyObject *args, PyObject *kwds)
fazekasgy@37 150 {
fazekasgy@37 151 cerr << "FeatureObject Init called" << endl;
fazekasgy@37 152 return 0;
fazekasgy@37 153 }
fazekasgy@37 154
fazekasgy@37 155 PyObject*
fazekasgy@37 156 Feature_test(PyObject *self, PyObject *args, PyObject *kwds)
fazekasgy@37 157 {
fazekasgy@37 158 cerr << "FeatureObject TEST called" << endl;
fazekasgy@37 159 return self;
fazekasgy@37 160 }
fazekasgy@37 161 */
fazekasgy@37 162
fazekasgy@37 163 /* String representation */
fazekasgy@37 164 static PyObject *
fazekasgy@37 165 Feature_repr(PyObject *self)
fazekasgy@37 166 {
fazekasgy@37 167 FeatureObject* v = (FeatureObject*)self;
fazekasgy@37 168 if (v->dict) return PyDict_Type.tp_repr((PyObject *)v->dict);
fazekasgy@37 169 else return PyString_FromString("Feature()");
fazekasgy@37 170 }
fazekasgy@37 171
fazekasgy@37 172 #define Feature_alloc PyType_GenericAlloc
fazekasgy@37 173 #define Feature_free PyObject_Del
fazekasgy@37 174
fazekasgy@37 175
fazekasgy@37 176 /* FEATURE TYPE OBJECT */
fazekasgy@37 177
fazekasgy@37 178 PyTypeObject Feature_Type = {
fazekasgy@37 179 PyObject_HEAD_INIT(NULL)
fazekasgy@37 180 0, /*ob_size*/
fazekasgy@37 181 "vampy.Feature", /*tp_name*/
fazekasgy@37 182 sizeof(FeatureObject), /*tp_basicsize*/
fazekasgy@37 183 0, /*tp_itemsize*/
fazekasgy@37 184 (destructor)FeatureObject_dealloc, /*tp_dealloc*/
fazekasgy@37 185 0, /*tp_print*/
fazekasgy@37 186 (getattrfunc)Feature_getattr, /*tp_getattr*/
fazekasgy@37 187 (setattrfunc)Feature_setattr, /*tp_setattr*/
fazekasgy@37 188 0, /*tp_compare*/
fazekasgy@37 189 Feature_repr, /*tp_repr*/
fazekasgy@37 190 0, /*tp_as_number*/
fazekasgy@37 191 0, /*tp_as_sequence*/
fazekasgy@37 192 0, /*tp_as_mapping*/
fazekasgy@37 193 0, /*tp_hash*/
fazekasgy@37 194 0,//Feature_test, /*tp_call*/ // call on an instance
fazekasgy@37 195 0, /*tp_str*/
fazekasgy@37 196 0, /*tp_getattro*/
fazekasgy@37 197 0, /*tp_setattro*/
fazekasgy@37 198 0, /*tp_as_buffer*/
fazekasgy@37 199 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
fazekasgy@37 200 0, /*tp_doc*/
fazekasgy@37 201 0, /*tp_traverse*/
fazekasgy@37 202 0, /*tp_clear*/
fazekasgy@37 203 0, /*tp_richcompare*/
fazekasgy@37 204 0, /*tp_weaklistoffset*/
fazekasgy@37 205 0, /*tp_iter*/
fazekasgy@37 206 0, /*tp_iternext*/
fazekasgy@37 207 0, /*tp_methods*/ //TypeObject Methods
fazekasgy@37 208 0, /*tp_members*/
fazekasgy@37 209 0, /*tp_getset*/
fazekasgy@37 210 0, /*tp_base*/
fazekasgy@37 211 0, /*tp_dict*/
fazekasgy@37 212 0, /*tp_descr_get*/
fazekasgy@37 213 0, /*tp_descr_set*/
fazekasgy@37 214 0, /*tp_dictoffset*/
fazekasgy@37 215 0,//(initproc)Feature_init, /*tp_init*/
fazekasgy@37 216 Feature_alloc, /*tp_alloc*/
fazekasgy@37 217 Feature_new, /*tp_new*/
fazekasgy@37 218 Feature_free, /*tp_free*/
fazekasgy@37 219 0, /*tp_is_gc*/
fazekasgy@37 220 };
fazekasgy@37 221
fazekasgy@37 222 /* PyRealTime C++ API */
fazekasgy@37 223
fazekasgy@37 224 /*Feature* from PyFeature
fazekasgy@37 225 const Vamp::Plugin::Feature*
fazekasgy@37 226 PyFeature_AsFeature (PyObject *self) {
fazekasgy@37 227
fazekasgy@37 228 FeatureObject *s = (FeatureObject*) self;
fazekasgy@37 229
fazekasgy@37 230 if (!PyFeature_Check(s)) {
fazekasgy@37 231 PyErr_SetString(PyExc_TypeError, "Feature Object Expected.");
fazekasgy@37 232 cerr << "in call PyFeature_AsPointer(): Feature Object Expected. " << endl;
fazekasgy@37 233 return NULL; }
fazekasgy@37 234 return s->feature;
fazekasgy@37 235 };*/