comparison PyTypeInterface.cpp @ 37:27bab3a16c9a vampy2final

new branch Vampy2final
author fazekasgy
date Mon, 05 Oct 2009 11:28:00 +0000
parents
children 94d09b4027aa
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
14 #ifdef HAVE_NUMPY
15 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API
16 #define NO_IMPORT_ARRAY
17 #include "numpy/arrayobject.h"
18 #endif
19
20 #include "PyTypeInterface.h"
21 #include "PyRealTime.h"
22 #include "PyExtensionModule.h"
23 #include <math.h>
24 #include <float.h>
25 #include <limits.h>
26 #ifndef SIZE_T_MAX
27 #define SIZE_T_MAX ((size_t) -1)
28 #endif
29
30 using std::string;
31 using std::vector;
32 using std::cerr;
33 using std::endl;
34 using std::map;
35
36 static std::map<std::string, o::eOutDescriptors> outKeys;
37 static std::map<std::string, p::eParmDescriptors> parmKeys;
38 static std::map<std::string, eSampleTypes> sampleKeys;
39 static std::map<std::string, eFeatureFields> ffKeys;
40 static bool isMapInitialised = false;
41
42 /* Note: NO FUNCTION IN THIS CLASS SHOULD ALTER REFERENCE COUNTS
43 (EXCEPT FOR TEMPORARY PYTHON OBJECTS)! */
44
45 PyTypeInterface::PyTypeInterface() :
46 m_strict(false),
47 m_error(false),
48 error(m_error) // const public reference for easy access
49 {
50 }
51
52 PyTypeInterface::~PyTypeInterface()
53 {
54 }
55
56 /// floating point numbers (TODO: check numpy.float128)
57 float
58 PyTypeInterface::PyValue_To_Float(PyObject* pyValue) const
59 {
60 // convert float
61 if (pyValue && PyFloat_Check(pyValue))
62 //TODO: check for limits here (same on most systems)
63 return (float) PyFloat_AS_DOUBLE(pyValue);
64
65 if (pyValue == NULL)
66 {
67 setValueError("Error while converting float object.",m_strict);
68 return 0.0;
69 }
70
71 // in strict mode we will not try harder
72 if (m_strict) {
73 setValueError("Strict conversion error: object is not float.",m_strict);
74 return 0.0;
75 }
76
77 // convert other objects supporting the number protocol
78 if (PyNumber_Check(pyValue))
79 {
80 PyObject* pyFloat = PyNumber_Float(pyValue); // new ref
81 if (!pyFloat)
82 {
83 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
84 setValueError("Error while converting " + PyValue_Get_TypeName(pyValue) + " object to float.",m_strict);
85 return 0.0;
86 }
87 float rValue = (float) PyFloat_AS_DOUBLE(pyFloat);
88 Py_DECREF(pyFloat);
89 return rValue;
90 }
91 /*
92 // convert other objects supporting the number protocol
93 if (PyNumber_Check(pyValue))
94 {
95 // PEP353: Py_ssize_t is size_t but signed !
96 // This will work up to numpy.float64
97 Py_ssize_t rValue = PyNumber_AsSsize_t(pyValue,NULL);
98 if (PyErr_Occurred())
99 {
100 PyErr_Print(); PyErr_Clear();
101 setValueError("Error while converting integer object.",m_strict);
102 return 0.0;
103 }
104 if (rValue > (Py_ssize_t)FLT_MAX || rValue < (Py_ssize_t)FLT_MIN)
105 {
106 setValueError("Overflow error. Object can not be converted to float.",m_strict);
107 return 0.0;
108 }
109 return (float) rValue;
110 }
111 */
112 // convert string
113 if (PyString_Check(pyValue))
114 {
115 PyObject* pyFloat = PyFloat_FromString(pyValue,NULL);
116 if (!pyFloat)
117 {
118 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
119 setValueError("String value can not be converted to float.",m_strict);
120 return 0.0;
121 }
122 float rValue = (float) PyFloat_AS_DOUBLE(pyFloat);
123 if (PyErr_Occurred())
124 {
125 PyErr_Print(); PyErr_Clear();
126 Py_CLEAR(pyFloat);
127 setValueError("Error while converting float object.",m_strict);
128 return 0.0;
129 }
130 Py_DECREF(pyFloat);
131 return rValue;
132 }
133
134 // convert the first element of any iterable sequence (for convenience and backwards compatibility)
135 if (PySequence_Check(pyValue) and PySequence_Size(pyValue) > 0)
136 {
137 PyObject* item = PySequence_GetItem(pyValue,0);
138 if (item)
139 {
140 float rValue = this->PyValue_To_Float(item);
141 if (!m_error) {
142 Py_DECREF(item);
143 return rValue;
144 } else {
145 Py_CLEAR(item);
146 std::string msg = "Could not convert sequence element to float. ";
147 setValueError(msg,m_strict);
148 return 0.0;
149 }
150 }
151 }
152
153 // give up
154 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
155 std::string msg = "Conversion from " + PyValue_Get_TypeName(pyValue) + " to float is not possible.";
156 setValueError(msg,m_strict);
157 #ifdef _DEBUG
158 cerr << "PyTypeInterface::PyValue_To_Float failed. " << msg << endl;
159 #endif
160 return 0.0;
161 }
162
163 /// size_t (unsigned integer types)
164 size_t
165 PyTypeInterface::PyValue_To_Size_t(PyObject* pyValue) const
166 {
167 // convert objects supporting the number protocol
168 if (PyNumber_Check(pyValue))
169 {
170 if (m_strict && !PyInt_Check(pyValue) && !PyLong_Check(pyValue))
171 setValueError("Strict conversion error: object is not integer type.",m_strict);
172 // Note: this function handles Bool,Int,Long,Float
173 // speed is not critical in the use of this type by Vamp
174 // PEP353: Py_ssize_t is size_t but signed !
175 Py_ssize_t rValue = PyInt_AsSsize_t(pyValue);
176 if (PyErr_Occurred())
177 {
178 PyErr_Print(); PyErr_Clear();
179 setValueError("Error while converting integer object.",m_strict);
180 return 0;
181 }
182 if ((unsigned long)rValue > SIZE_T_MAX || (unsigned long)rValue < 0)
183 {
184 setValueError("Overflow error. Object can not be converted to size_t.",m_strict);
185 return 0;
186 }
187 return (size_t) rValue;
188 }
189
190 // in strict mode we will not try harder and throw an exception
191 // then the caller should decide what to do with it
192 if (m_strict) {
193 setValueError("Strict conversion error: object is not integer.",m_strict);
194 return 0;
195 }
196
197 // convert string
198 if (PyString_Check(pyValue))
199 {
200 PyObject* pyLong = PyNumber_Long(pyValue);
201 if (!pyLong)
202 {
203 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
204 setValueError("String object can not be converted to size_t.",m_strict);
205 return 0;
206 }
207 size_t rValue = this->PyValue_To_Size_t(pyLong);
208 if (!m_error) {
209 Py_DECREF(pyLong);
210 return rValue;
211 } else {
212 Py_CLEAR(pyLong);
213 setValueError ("Error converting string to size_t.",m_strict);
214 return 0;
215 }
216 }
217
218 // convert the first element of iterable sequences
219 if (PySequence_Check(pyValue) and PySequence_Size(pyValue) > 0)
220 {
221 PyObject* item = PySequence_GetItem(pyValue,0);
222 if (item)
223 {
224 size_t rValue = this->PyValue_To_Size_t(item);
225 if (!m_error) {
226 Py_DECREF(item);
227 return rValue;
228 } else {
229 Py_CLEAR(item);
230 setValueError("Could not convert sequence element to size_t. ",m_strict);
231 return 0;
232 }
233 }
234 }
235
236 // give up
237 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
238 std::string msg = "Conversion from " + this->PyValue_Get_TypeName(pyValue) + " to size_t is not possible.";
239 setValueError(msg,m_strict);
240 #ifdef _DEBUG
241 cerr << "PyTypeInterface::PyValue_To_Size_t failed. " << msg << endl;
242 #endif
243 return 0;
244 }
245
246 /// long and int
247 long
248 PyTypeInterface::PyValue_To_Long(PyObject* pyValue) const
249 {
250 // most common case: convert int (faster)
251 if (pyValue && PyInt_Check(pyValue)) {
252 // if the object is not NULL and verified, this macro just extracts the value.
253 return PyInt_AS_LONG(pyValue);
254 }
255
256 // long
257 if (PyLong_Check(pyValue)) {
258 long rValue = PyLong_AsLong(pyValue);
259 if (PyErr_Occurred()) {
260 PyErr_Print(); PyErr_Clear();
261 setValueError("Error while converting long object.",m_strict);
262 return 0;
263 }
264 return rValue;
265 }
266
267 if (m_strict) {
268 setValueError("Strict conversion error: object is not integer or long integer.",m_strict);
269 return 0;
270 }
271
272 // convert all objects supporting the number protocol
273 if (PyNumber_Check(pyValue))
274 {
275 // Note: this function handles Bool,Int,Long,Float
276 // PEP353: Py_ssize_t is size_t but signed !
277 Py_ssize_t rValue = PyInt_AsSsize_t(pyValue);
278 if (PyErr_Occurred())
279 {
280 PyErr_Print(); PyErr_Clear();
281 setValueError("Error while converting integer object.",m_strict);
282 return 0;
283 }
284 if (rValue > LONG_MAX || rValue < LONG_MIN)
285 {
286 setValueError("Overflow error. Object can not be converted to size_t.",m_strict);
287 return 0;
288 }
289 return (long) rValue;
290 }
291
292 // convert string
293 if (PyString_Check(pyValue))
294 {
295 PyObject* pyLong = PyNumber_Long(pyValue);
296 if (!pyLong)
297 {
298 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
299 setValueError("String object can not be converted to long.",m_strict);
300 return 0;
301 }
302 long rValue = this->PyValue_To_Long(pyLong);
303 if (!m_error) {
304 Py_DECREF(pyLong);
305 return rValue;
306 } else {
307 Py_CLEAR(pyLong);
308 setValueError ("Error converting string to long.",m_strict);
309 return 0;
310 }
311 }
312
313 // convert the first element of iterable sequences
314 if (PySequence_Check(pyValue) and PySequence_Size(pyValue) > 0)
315 {
316 PyObject* item = PySequence_GetItem(pyValue,0);
317 if (item)
318 {
319 size_t rValue = this->PyValue_To_Long(item);
320 if (!m_error) {
321 Py_DECREF(item);
322 return rValue;
323 } else {
324 Py_CLEAR(item);
325 setValueError("Could not convert sequence element to long. ",m_strict);
326 return 0;
327 }
328 }
329 }
330
331 // give up
332 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
333 std::string msg = "Conversion from " + this->PyValue_Get_TypeName(pyValue) + " to long is not possible.";
334 setValueError(msg,m_strict);
335 #ifdef _DEBUG
336 cerr << "PyTypeInterface::PyValue_To_Long failed. " << msg << endl;
337 #endif
338 return 0;
339 }
340
341
342 bool
343 PyTypeInterface::PyValue_To_Bool(PyObject* pyValue) const
344 {
345 // convert objects supporting the number protocol
346 // Note: PyBool is a subclass of PyInt
347 if (PyNumber_Check(pyValue))
348 {
349 if (m_strict && !PyBool_Check(pyValue))
350 setValueError
351 ("Strict conversion error: object is not boolean type.",m_strict);
352
353 // Note: this function handles Bool,Int,Long,Float
354 Py_ssize_t rValue = PyInt_AsSsize_t(pyValue);
355 if (PyErr_Occurred())
356 {
357 PyErr_Print(); PyErr_Clear();
358 setValueError ("Error while converting boolean object.",m_strict);
359 }
360 if (rValue != 1 && rValue != 0)
361 {
362 setValueError ("Overflow error. Object can not be converted to boolean.",m_strict);
363 }
364 return (bool) rValue;
365 }
366
367 if (m_strict) {
368 setValueError ("Strict conversion error: object is not numerical type.",m_strict);
369 return false;
370 }
371
372 // convert iterables: the rule is the same as in the interpreter:
373 // empty sequence evaluates to False, anything else is True
374 if (PySequence_Check(pyValue))
375 {
376 return PySequence_Size(pyValue)?true:false;
377 }
378
379 // give up
380 if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
381 std::string msg = "Conversion from " + this->PyValue_Get_TypeName(pyValue) + " to boolean is not possible.";
382 setValueError(msg,m_strict);
383 #ifdef _DEBUG
384 cerr << "PyTypeInterface::PyValue_To_Bool failed. " << msg << endl;
385 #endif
386 return false;
387 }
388
389 /// string and objects that support .__str__()
390 /// TODO: check unicode objects
391 std::string
392 PyTypeInterface::PyValue_To_String(PyObject* pyValue) const
393 {
394 // convert string
395 if (PyString_Check(pyValue))
396 {
397 char *cstr = PyString_AS_STRING(pyValue);
398 if (!cstr)
399 {
400 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
401 setValueError("Error while converting string object.",m_strict);
402 return std::string();
403 }
404 return std::string(cstr);
405 }
406 // TODO: deal with unicode here (argh!)
407
408 // in strict mode we will not try harder
409 if (m_strict) {
410 setValueError("Strict conversion error: object is not string.",m_strict);
411 return std::string();
412 }
413
414 // accept None as empty string
415 if (pyValue == Py_None) return std::string();
416
417 // convert list or tuple: empties are turned into empty strings conventionally
418 if (PyList_Check(pyValue) || PyTuple_Check(pyValue))
419 {
420 if (!PySequence_Size(pyValue)) return std::string();
421 PyObject* item = PySequence_GetItem(pyValue,0);
422 if (item)
423 {
424 std::string rValue = this->PyValue_To_String(item);
425 if (!m_error) {
426 Py_DECREF(item);
427 return rValue;
428 } else {
429 Py_CLEAR(item);
430 setValueError("Could not convert sequence element to string.",m_strict);
431 return std::string();
432 }
433 }
434 }
435
436 // convert any other object that has .__str__() or .__repr__()
437 PyObject* pyString = PyObject_Str(pyValue);
438 if (pyString && !PyErr_Occurred())
439 {
440 std::string rValue = this->PyValue_To_String(pyString);
441 if (!m_error) {
442 Py_DECREF(pyString);
443 return rValue;
444 } else {
445 Py_CLEAR(pyString);
446 std::string msg = "Object " + this->PyValue_Get_TypeName(pyValue) +" can not be represented as string. ";
447 setValueError (msg,m_strict);
448 return std::string();
449 }
450 }
451
452 // give up
453 PyErr_Print(); PyErr_Clear();
454 std::string msg = "Conversion from " + this->PyValue_Get_TypeName(pyValue) + " to string is not possible.";
455 setValueError(msg,m_strict);
456 #ifdef _DEBUG
457 cerr << "PyTypeInterface::PyValue_To_String failed. " << msg << endl;
458 #endif
459 return std::string();
460 }
461
462 /* C Values to Py Values */
463
464
465 PyObject*
466 PyTypeInterface::PyValue_From_CValue(const char* cValue) const
467 {
468 // returns new reference
469 #ifdef _DEBUG
470 if (!cValue) {
471 std::string msg = "PyTypeInterface::PyValue_From_CValue: Null pointer encountered while converting from const char* .";
472 cerr << msg << endl;
473 setValueError(msg,m_strict);
474 return NULL;
475 }
476 #endif
477 PyObject *pyValue = PyString_FromString(cValue);
478 if (!pyValue)
479 {
480 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
481 setValueError("Error while converting from char* or string.",m_strict);
482 #ifdef _DEBUG
483 cerr << "PyTypeInterface::PyValue_From_CValue: Interpreter failed to convert from const char*" << endl;
484 #endif
485 return NULL;
486 }
487 return pyValue;
488 }
489
490 PyObject*
491 PyTypeInterface::PyValue_From_CValue(size_t cValue) const
492 {
493 // returns new reference
494 PyObject *pyValue = PyInt_FromSsize_t((Py_ssize_t)cValue);
495 if (!pyValue)
496 {
497 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
498 setValueError("Error while converting from size_t.",m_strict);
499 #ifdef _DEBUG
500 cerr << "PyTypeInterface::PyValue_From_CValue: Interpreter failed to convert from size_t" << endl;
501 #endif
502 return NULL;
503 }
504 return pyValue;
505 }
506
507 PyObject*
508 PyTypeInterface::PyValue_From_CValue(double cValue) const
509 {
510 // returns new reference
511 PyObject *pyValue = PyFloat_FromDouble(cValue);
512 if (!pyValue)
513 {
514 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
515 setValueError("Error while converting from float or double.",m_strict);
516 #ifdef _DEBUG
517 cerr << "PyTypeInterface::PyValue_From_CValue: Interpreter failed to convert from float or double" << endl;
518 #endif
519 return NULL;
520 }
521 return pyValue;
522 }
523
524 PyObject*
525 PyTypeInterface::PyValue_From_CValue(bool cValue) const
526 {
527 // returns new reference
528 PyObject *pyValue = PyBool_FromLong((long)cValue);
529 if (!pyValue)
530 {
531 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
532 setValueError("Error while converting from bool.",m_strict);
533 #ifdef _DEBUG
534 cerr << "PyTypeInterface::PyValue_From_CValue: Interpreter failed to convert from bool" << endl;
535 #endif
536 return NULL;
537 }
538 return pyValue;
539 }
540
541
542 /* Sequence Types to C++ Types */
543
544 //convert Python list to C++ vector of strings
545 std::vector<std::string>
546 PyTypeInterface::PyValue_To_StringVector (PyObject *pyList) const
547 {
548
549 std::vector<std::string> Output;
550 std::string ListElement;
551 PyObject *pyString = NULL;
552
553 if (PyList_Check(pyList)) {
554
555 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyList); ++i) {
556 //Get next list item (Borrowed Reference)
557 pyString = PyList_GET_ITEM(pyList,i);
558 ListElement = (string) PyString_AsString(PyObject_Str(pyString));
559 Output.push_back(ListElement);
560 }
561 return Output;
562 }
563 #ifdef _DEBUG
564 cerr << "PyTypeInterface::PyValue_To_StringVector: Warning: Value is not list of strings." << endl;
565 #endif
566
567 /// Assume a single value that can be casted as string
568 /// this allows to write e.g. Feature.label = 5.2 instead of ['5.2']
569 Output.push_back(PyValue_To_String(pyList));
570 if (m_error) {
571 std::string msg = "Value is not list of strings nor can be casted as string. ";
572 setValueError(msg,m_strict);
573 #ifdef _DEBUG
574 cerr << "PyTypeInterface::PyValue_To_StringVector failed. " << msg << endl;
575 #endif
576 }
577 return Output;
578 }
579
580 //convert PyFeature.value (typically a list or numpy array) to C++ vector of floats
581 std::vector<float>
582 PyTypeInterface::PyValue_To_FloatVector (PyObject *pyValue) const
583 {
584
585 #ifdef HAVE_NUMPY
586 // there are four types of values we may receive from a numpy process:
587 // * a python scalar,
588 // * an array scalar, (e.g. numpy.float32)
589 // * an array with nd = 0 (0D array)
590 // * an array with nd > 0
591
592 /// check for scalars
593 if (PyArray_CheckScalar(pyValue) || PyFloat_Check(pyValue)) {
594
595 std::vector<float> Output;
596
597 // we rely on the behaviour the scalars are either floats
598 // or support the number protocol
599 // TODO: a potential optimisation is to handle them directly
600 Output.push_back(PyValue_To_Float(pyValue));
601 return Output;
602 }
603
604 /// numpy array
605 if (PyArray_CheckExact(pyValue))
606 return PyArray_To_FloatVector(pyValue);
607
608 #endif
609
610 /// python list of floats (backward compatible)
611 if (PyList_Check(pyValue)) {
612 return PyList_To_FloatVector(pyValue);
613 }
614
615 std::vector<float> Output;
616
617 /// finally assume a single value supporting the number protocol
618 /// this allows to write e.g. Feature.values = 5 instead of [5.00]
619 Output.push_back(PyValue_To_Float(pyValue));
620 if (m_error) {
621 std::string msg = "Value is not list or array of floats nor can be casted as float. ";
622 setValueError(msg,m_strict);
623 #ifdef _DEBUG
624 cerr << "PyTypeInterface::PyValue_To_FloatVector failed." << msg << endl;
625 #endif
626 }
627 return Output;
628 }
629
630 //convert a list of python floats
631 std::vector<float>
632 PyTypeInterface::PyList_To_FloatVector (PyObject *inputList) const
633 {
634 std::vector<float> Output;
635
636 #ifdef _DEBUG
637 // This is a low level function normally called from
638 // PyValue_To_FloatVector(). Checking for list is not required.
639 if (!PyList_Check(inputList)) {
640 std::string msg = "Value is not list.";
641 setValueError(msg,true);
642 cerr << "PyTypeInterface::PyList_To_FloatVector failed. " << msg << endl;
643 return Output;
644 }
645 #endif
646
647 float ListElement;
648 PyObject *pyFloat = NULL;
649 PyObject **pyObjectArray = PySequence_Fast_ITEMS(inputList);
650
651 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(inputList); ++i) {
652
653 // pyFloat = PyList_GET_ITEM(inputList,i);
654 pyFloat = pyObjectArray[i];
655
656 #ifdef _DEBUG
657 if (!pyFloat) {
658 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
659 cerr << "PyTypeInterface::PyList_To_FloatVector: Could not obtain list element: "
660 << i << " PyList_GetItem returned NULL! Skipping value." << endl;
661 continue;
662 }
663 #endif
664
665 // ListElement = (float) PyFloat_AS_DOUBLE(pyFloat);
666 ListElement = PyValue_To_Float(pyFloat);
667
668
669 #ifdef _DEBUG_VALUES
670 cerr << "value: " << ListElement << endl;
671 #endif
672 Output.push_back(ListElement);
673 }
674 return Output;
675 }
676
677 #ifdef HAVE_NUMPY
678 std::vector<float>
679 PyTypeInterface::PyArray_To_FloatVector (PyObject *pyValue) const
680 {
681 std::vector<float> Output;
682
683 #ifdef _DEBUG
684 // This is a low level function, normally called from
685 // PyValue_To_FloatVector(). Checking the array here is not required.
686 if (!PyArray_Check(pyValue)) {
687 std::string msg = "Object has no array interface.";
688 setValueError(msg,true);
689 cerr << "PyTypeInterface::PyArray_To_FloatVector failed. " << msg << endl;
690 return Output;
691 }
692 #endif
693
694 PyArrayObject* pyArray = (PyArrayObject*) pyValue;
695 PyArray_Descr* descr = pyArray->descr;
696
697 /// check raw data and descriptor pointers
698 if (pyArray->data == 0 || descr == 0) {
699 std::string msg = "NumPy array with NULL data or descriptor pointer encountered.";
700 setValueError(msg,m_strict);
701 #ifdef _DEBUG
702 cerr << "PyTypeInterface::PyArray_To_FloatVector failed. Error: " << msg << endl;
703 #endif
704 return Output;
705 }
706
707 /// check dimensions
708 if (pyArray->nd != 1) {
709 std::string msg = "NumPy array must be a one dimensional vector.";
710 setValueError(msg,m_strict);
711 #ifdef _DEBUG
712 cerr << "PyTypeInterface::PyArray_To_FloatVector failed. Error: " << msg << " Dims: " << (int) pyArray->nd << endl;
713 #endif
714 return Output;
715 }
716
717 #ifdef _DEBUG_VALUES
718 cerr << "PyTypeInterface::PyArray_To_FloatVector: Numpy array verified." << endl;
719 #endif
720
721 /// check strides (useful if array is not continuous)
722 size_t strides = *((size_t*) pyArray->strides);
723
724 /// convert the array
725 switch (descr->type_num)
726 {
727 case NPY_FLOAT : // dtype='float32'
728 return PyArray_Convert<float,float>(pyArray->data,pyArray->dimensions[0],strides);
729 case NPY_DOUBLE : // dtype='float64'
730 return PyArray_Convert<float,double>(pyArray->data,pyArray->dimensions[0],strides);
731 case NPY_INT : // dtype='int'
732 return PyArray_Convert<float,int>(pyArray->data,pyArray->dimensions[0],strides);
733 case NPY_LONG : // dtype='long'
734 return PyArray_Convert<float,long>(pyArray->data,pyArray->dimensions[0],strides);
735 default :
736 std::string msg = "Unsupported value type in NumPy array object.";
737 setValueError(msg,m_strict);
738 #ifdef _DEBUG
739 cerr << "PyTypeInterface::PyArray_To_FloatVector failed. Error: " << msg << endl;
740 #endif
741 return Output;
742 }
743 }
744 #endif
745
746
747 /// FeatureSet (an integer map of OutputLists)
748 Vamp::Plugin::FeatureSet
749 PyTypeInterface::PyValue_To_FeatureSet(PyObject* pyValue) const
750 {
751 Vamp::Plugin::FeatureSet rFeatureSet;
752
753 /// Convert PyFeatureSet
754 if (PyFeatureSet_CheckExact(pyValue)) {
755
756 Py_ssize_t pyPos = 0;
757 PyObject *pyKey, *pyDictValue; // Borrowed References
758 int key;
759 // bool it_error = false;
760
761 m_error = false;
762 while (PyDict_Next(pyValue, &pyPos, &pyKey, &pyDictValue))
763 {
764 key = (int) PyInt_AS_LONG(pyKey);
765 #ifdef _DEBUG_VALUES
766 cerr << "key: '" << key << "' value: '" << PyValue_To_String(pyDictValue) << "' " << endl;
767 #endif
768 // DictValue -> Vamp::FeatureList
769 PyValue_To_rValue(pyDictValue,rFeatureSet[key]);
770 if (m_error) {
771 // it_error = true;
772 lastError() << " in output number: " << key;
773 }
774 }
775 // if (it_error) m_error = true;
776 if (!m_errorQueue.empty()) {
777 setValueError("Error while converting FeatureSet.",m_strict);
778 }
779 return rFeatureSet;
780 }
781
782 /// Convert Python list (backward compatibility)
783 if (PyList_Check(pyValue)) {
784
785 PyObject *pyFeatureList; // This will be borrowed reference
786
787 //Parse Output List for each element (FeatureSet)
788 m_error = false;
789 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyValue); ++i) {
790 //Get i-th FeatureList (Borrowed Reference)
791 pyFeatureList = PyList_GET_ITEM(pyValue,i);
792 PyValue_To_rValue(pyFeatureList,rFeatureSet[i]);
793 if (m_error) {
794 lastError() << " in output number: " << i;
795 }
796 }
797 if (!m_errorQueue.empty()) m_error = true;
798 return rFeatureSet;
799 }
800
801 /// accept no return values
802 if (pyValue == Py_None) return rFeatureSet;
803
804 /// give up
805 std::string msg = "Unsupported return type. Expected list or vampy.FeatureSet(). ";
806 setValueError(msg,m_strict);
807 #ifdef _DEBUG
808 cerr << "PyTypeInterface::PyValue_To_FeatureSet failed. Error: " << msg << endl;
809 #endif
810 return rFeatureSet;
811 }
812
813 Vamp::RealTime
814 PyTypeInterface::PyValue_To_RealTime(PyObject* pyValue) const
815 {
816 // We accept integer sample counts (for backward compatibility)
817 // or PyRealTime objects and convert them to Vamp::RealTime
818
819 if (PyRealTime_CheckExact(pyValue))
820 {
821 /// just create a copy of the wrapped object
822 return Vamp::RealTime(*PyRealTime_AS_REALTIME(pyValue));
823 }
824
825 // assume integer sample count
826 long sampleCount = PyValue_To_Long(pyValue);
827 if (m_error) {
828 std::string msg = "Unexpected value passed as RealTime.\nMust be vampy.RealTime type or integer sample count.";
829 setValueError(msg,m_strict);
830 #ifdef _DEBUG
831 cerr << "PyTypeInterface::PyValue_To_RealTime failed. " << msg << endl;
832 #endif
833 return Vamp::RealTime();
834 }
835
836 #ifdef _DEBUG_VALUES
837 Vamp::RealTime rt =
838 Vamp::RealTime::frame2RealTime(sampleCount,m_inputSampleRate );
839 cerr << "RealTime: " << (long)sampleCount << ", ->" << rt.toString() << endl;
840 return rt;
841 #else
842 return Vamp::RealTime::frame2RealTime(sampleCount,m_inputSampleRate );
843 #endif
844
845 }
846
847 Vamp::Plugin::OutputDescriptor::SampleType
848 PyTypeInterface::PyValue_To_SampleType(PyObject* pyValue) const
849 {
850 /// convert simulated enum values
851 /// { OneSamplePerStep,FixedSampleRate,VariableSampleRate }
852 if (PyInt_CheckExact(pyValue)) {
853 long lst = PyInt_AS_LONG(pyValue);
854 if (lst<0 || lst>2) {
855 setValueError("Overflow error. SampleType has to be one of { OneSamplePerStep,FixedSampleRate,VariableSampleRate }\n(an integer in the range of 0..2) or a string value naming the type.",m_strict);
856 return Vamp::Plugin::OutputDescriptor::SampleType();
857 }
858 return (Vamp::Plugin::OutputDescriptor::SampleType) lst;
859 }
860
861 /// convert string (backward compatible)
862 if (PyString_CheckExact(pyValue)) {
863 Vamp::Plugin::OutputDescriptor::SampleType st;
864 st = (Vamp::Plugin::OutputDescriptor::SampleType) sampleKeys[PyValue_To_String(pyValue)];
865 if (m_error) {
866 std::string msg = "Unexpected value passed as SampleType. Must be one of { OneSamplePerStep,FixedSampleRate,VariableSampleRate }\n(an integer in the range of 0..2) or a string value naming the type.";
867 setValueError(msg,m_strict);
868 return Vamp::Plugin::OutputDescriptor::SampleType();
869 }
870 return st;
871 }
872
873 /// give up
874 std::string msg = "Unsupported return type. Expected one of { OneSamplePerStep,FixedSampleRate,VariableSampleRate }\n(an integer in the range of 0..2) or a string value naming the type.";
875 setValueError(msg,m_strict);
876 #ifdef _DEBUG
877 cerr << "PyTypeInterface::PyValue_To_SampleType failed. Error: " << msg << endl;
878 #endif
879 return Vamp::Plugin::OutputDescriptor::SampleType();
880 }
881
882 Vamp::Plugin::InputDomain
883 PyTypeInterface::PyValue_To_InputDomain(PyObject* pyValue) const
884 {
885 /// convert simulated enum values { TimeDomain,FrequencyDomain }
886 if (PyInt_CheckExact(pyValue)) {
887 long lst = PyInt_AS_LONG(pyValue);
888 if (lst!=0 && lst!=1) {
889 setValueError("Overflow error. InputDomain has to be one of { TimeDomain,FrequencyDomain }\n(an integer in the range of 0..1) or a string value naming the type.",m_strict);
890 return Vamp::Plugin::InputDomain();
891 }
892 return (Vamp::Plugin::InputDomain) lst;
893 }
894
895 /// convert string (backward compatible)
896 if (PyString_CheckExact(pyValue)) {
897 Vamp::Plugin::InputDomain id;
898 id = (PyValue_To_String(pyValue) == "FrequencyDomain")?Vamp::Plugin::FrequencyDomain:Vamp::Plugin::TimeDomain;
899 if (m_error)
900 {
901 std::string msg = "Unexpected value passed as SampleType. Must be one of { TimeDomain,FrequencyDomain }\n(an integer in the range of 0..1) or a string value naming the type.";
902 setValueError(msg,m_strict);
903 return Vamp::Plugin::InputDomain();
904 }
905 return id;
906 }
907
908 /// give up
909 std::string msg = "Unsupported return type. Expected one of { TimeDomain,FrequencyDomain }\n(an integer in the range of 0..1) or a string value naming the type.";
910 setValueError(msg,m_strict);
911 #ifdef _DEBUG
912 cerr << "PyTypeInterface::PyValue_To_InputDomain failed. Error: " << msg << endl;
913 #endif
914 return Vamp::Plugin::InputDomain();
915 }
916
917
918 /// OutputDescriptor
919 void
920 PyTypeInterface::SetValue(Vamp::Plugin::OutputDescriptor& od, std::string& key, PyObject* pyValue) const
921 {
922 switch (outKeys[key])
923 {
924 case o::not_found:
925 setValueError("Unknown key in Vamp OutputDescriptor",m_strict);
926 cerr << "Unknown key in Vamp OutputDescriptor: " << key << endl;
927 break;
928 case o::identifier:
929 _convert(pyValue,od.identifier);
930 break;
931 case o::name:
932 _convert(pyValue,od.name);
933 break;
934 case o::description:
935 _convert(pyValue,od.description);
936 break;
937 case o::unit:
938 _convert(pyValue,od.unit);
939 break;
940 case o::hasFixedBinCount:
941 _convert(pyValue,od.hasFixedBinCount);
942 break;
943 case o::binCount:
944 _convert(pyValue,od.binCount);
945 break;
946 case o::binNames:
947 _convert(pyValue,od.binNames);
948 break;
949 case o::hasKnownExtents:
950 _convert(pyValue,od.hasKnownExtents);
951 break;
952 case o::minValue:
953 _convert(pyValue,od.minValue);
954 break;
955 case o::maxValue:
956 _convert(pyValue,od.maxValue);
957 break;
958 case o::isQuantized:
959 _convert(pyValue,od.isQuantized);
960 break;
961 case o::quantizeStep:
962 _convert(pyValue,od.quantizeStep);
963 break;
964 case o::sampleType:
965 _convert(pyValue,od.sampleType);
966 break;
967 case o::sampleRate:
968 _convert(pyValue,od.sampleRate);
969 break;
970 case o::hasDuration:
971 _convert(pyValue,od.hasDuration);
972 break;
973 default:
974 setValueError("Unknown key in Vamp OutputDescriptor",m_strict);
975 cerr << "Invalid key in Vamp OutputDescriptor: " << key << endl;
976 }
977 }
978
979 /// ParameterDescriptor
980 void
981 PyTypeInterface::SetValue(Vamp::Plugin::ParameterDescriptor& pd, std::string& key, PyObject* pyValue) const
982 {
983 switch (parmKeys[key])
984 {
985 case p::not_found :
986 setValueError("Unknown key in Vamp ParameterDescriptor",m_strict);
987 cerr << "Unknown key in Vamp ParameterDescriptor: " << key << endl;
988 break;
989 case p::identifier:
990 _convert(pyValue,pd.identifier);
991 break;
992 case p::name:
993 _convert(pyValue,pd.name);
994 break;
995 case p::description:
996 _convert(pyValue,pd.description);
997 break;
998 case p::unit:
999 _convert(pyValue,pd.unit);
1000 break;
1001 case p::minValue:
1002 _convert(pyValue,pd.minValue);
1003 break;
1004 case p::maxValue:
1005 _convert(pyValue,pd.maxValue);
1006 break;
1007 case p::defaultValue:
1008 _convert(pyValue,pd.defaultValue);
1009 break;
1010 case p::isQuantized:
1011 _convert(pyValue,pd.isQuantized);
1012 break;
1013 case p::quantizeStep:
1014 _convert(pyValue,pd.quantizeStep);
1015 break;
1016 default :
1017 setValueError("Unknown key in Vamp ParameterDescriptor",m_strict);
1018 cerr << "Invalid key in Vamp ParameterDescriptor: " << key << endl;
1019 }
1020 }
1021
1022 /// Feature (it's like a Descriptor)
1023 bool
1024 PyTypeInterface::SetValue(Vamp::Plugin::Feature& feature, std::string& key, PyObject* pyValue) const
1025 {
1026 bool found = true;
1027 switch (ffKeys[key])
1028 {
1029 case unknown :
1030 setValueError("Unknown key in Vamp Feature",m_strict);
1031 cerr << "Unknown key in Vamp Feature: " << key << endl;
1032 found = false;
1033 break;
1034 case hasTimestamp:
1035 _convert(pyValue,feature.hasTimestamp);
1036 break;
1037 case timestamp:
1038 _convert(pyValue,feature.timestamp);
1039 break;
1040 case hasDuration:
1041 _convert(pyValue,feature.hasDuration);
1042 break;
1043 case duration:
1044 _convert(pyValue,feature.duration);
1045 break;
1046 case values:
1047 _convert(pyValue,feature.values);
1048 break;
1049 case label:
1050 _convert(pyValue,feature.label);
1051 break;
1052 default:
1053 setValueError("Unknown key in Vamp Feature",m_strict);
1054 found = false;
1055 }
1056 return found;
1057 }
1058
1059
1060 /* Error handling */
1061
1062 void
1063 PyTypeInterface::setValueError (std::string message, bool strict) const
1064 {
1065 m_error = true;
1066 m_errorQueue.push(ValueError(message,strict));
1067 }
1068
1069 /// return a reference to the last error or creates a new one.
1070 PyTypeInterface::ValueError&
1071 PyTypeInterface::lastError() const
1072 {
1073 m_error = false;
1074 if (!m_errorQueue.empty()) return m_errorQueue.back();
1075 else {
1076 m_errorQueue.push(ValueError("Type conversion error.",m_strict));
1077 return m_errorQueue.back();
1078 }
1079 }
1080
1081 /// helper function to iterate over the error message queue:
1082 /// pops the oldest item
1083 PyTypeInterface::ValueError
1084 PyTypeInterface::getError() const
1085 {
1086 if (!m_errorQueue.empty()) {
1087 PyTypeInterface::ValueError e = m_errorQueue.front();
1088 m_errorQueue.pop();
1089 if (m_errorQueue.empty()) m_error = false;
1090 return e;
1091 }
1092 else {
1093 m_error = false;
1094 return PyTypeInterface::ValueError();
1095 }
1096 }
1097
1098 /* Utilities */
1099
1100 /// get the type name of an object
1101 std::string
1102 PyTypeInterface::PyValue_Get_TypeName(PyObject* pyValue) const
1103 {
1104 PyObject *pyType = PyObject_Type(pyValue);
1105 if (!pyType)
1106 {
1107 cerr << "Warning: Object type name could not be found." << endl;
1108 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
1109 return std::string ("< unknown type >");
1110 }
1111 PyObject *pyString = PyObject_Str(pyType);
1112 if (!pyString)
1113 {
1114 cerr << "Warning: Object type name could not be found." << endl;
1115 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
1116 Py_CLEAR(pyType);
1117 return std::string ("< unknown type >");
1118 }
1119 char *cstr = PyString_AS_STRING(pyString);
1120 if (!cstr)
1121 {
1122 cerr << "Warning: Object type name could not be found." << endl;
1123 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
1124 Py_DECREF(pyType);
1125 Py_CLEAR(pyString);
1126 return std::string("< unknown type >");
1127 }
1128 Py_DECREF(pyType);
1129 Py_DECREF(pyString);
1130 return std::string(cstr);
1131
1132 }
1133
1134 bool
1135 PyTypeInterface::initMaps() const
1136 {
1137
1138 if (isMapInitialised) return true;
1139
1140 outKeys["identifier"] = o::identifier;
1141 outKeys["name"] = o::name;
1142 outKeys["description"] = o::description;
1143 outKeys["unit"] = o::unit;
1144 outKeys["hasFixedBinCount"] = o::hasFixedBinCount;
1145 outKeys["binCount"] = o::binCount;
1146 outKeys["binNames"] = o::binNames;
1147 outKeys["hasKnownExtents"] = o::hasKnownExtents;
1148 outKeys["minValue"] = o::minValue;
1149 outKeys["maxValue"] = o::maxValue;
1150 outKeys["isQuantized"] = o::isQuantized;
1151 outKeys["quantizeStep"] = o::quantizeStep;
1152 outKeys["sampleType"] = o::sampleType;
1153 outKeys["sampleRate"] = o::sampleRate;
1154 outKeys["hasDuration"] = o::hasDuration;
1155
1156 sampleKeys["OneSamplePerStep"] = OneSamplePerStep;
1157 sampleKeys["FixedSampleRate"] = FixedSampleRate;
1158 sampleKeys["VariableSampleRate"] = VariableSampleRate;
1159
1160 ffKeys["hasTimestamp"] = hasTimestamp;
1161 ffKeys["timestamp"] = timestamp; // this is the correct one
1162 ffKeys["timeStamp"] = timestamp; // backward compatible
1163 ffKeys["hasDuration"] = hasDuration;
1164 ffKeys["duration"] = duration;
1165 ffKeys["values"] = values;
1166 ffKeys["label"] = label;
1167
1168 parmKeys["identifier"] = p::identifier;
1169 parmKeys["name"] = p::name;
1170 parmKeys["description"] = p::description;
1171 parmKeys["unit"] = p::unit;
1172 parmKeys["minValue"] = p::minValue;
1173 parmKeys["maxValue"] = p::maxValue;
1174 parmKeys["defaultValue"] = p::defaultValue;
1175 parmKeys["isQuantized"] = p::isQuantized;
1176 parmKeys["quantizeStep"] = p::quantizeStep;
1177
1178 isMapInitialised = true;
1179 return true;
1180 }