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