Mercurial > hg > vampy-host
comparison PyTypeConversions.h @ 26:014c48d6f360
Now we know what we want from Vampy source, bring it in here again and lose the subrepo
author | Chris Cannam |
---|---|
date | Wed, 26 Nov 2014 09:48:35 +0000 |
parents | |
children | fb6519598734 |
comparison
equal
deleted
inserted
replaced
25:5379af6bef00 | 26:014c48d6f360 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 VampyHost | |
5 | |
6 Use Vamp audio analysis plugins in Python | |
7 | |
8 Gyorgy Fazekas and Chris Cannam | |
9 Centre for Digital Music, Queen Mary, University of London | |
10 Copyright 2008-2014 Queen Mary, University of London | |
11 | |
12 Permission is hereby granted, free of charge, to any person | |
13 obtaining a copy of this software and associated documentation | |
14 files (the "Software"), to deal in the Software without | |
15 restriction, including without limitation the rights to use, copy, | |
16 modify, merge, publish, distribute, sublicense, and/or sell copies | |
17 of the Software, and to permit persons to whom the Software is | |
18 furnished to do so, subject to the following conditions: | |
19 | |
20 The above copyright notice and this permission notice shall be | |
21 included in all copies or substantial portions of the Software. | |
22 | |
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
24 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
26 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR | |
27 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
28 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
29 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
30 | |
31 Except as contained in this notice, the names of the Centre for | |
32 Digital Music; Queen Mary, University of London; and the authors | |
33 shall not be used in advertising or otherwise to promote the sale, | |
34 use or other dealings in this Software without prior written | |
35 authorization. | |
36 */ | |
37 | |
38 /* | |
39 PyTypeConversions: Type safe conversion utilities between Python | |
40 types and basic C/C++ types. | |
41 */ | |
42 | |
43 #ifndef PY_TYPE_CONVERSIONS_H | |
44 #define PY_TYPE_CONVERSIONS_H | |
45 | |
46 #include <Python.h> | |
47 | |
48 #ifdef HAVE_NUMPY | |
49 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API | |
50 #define NO_IMPORT_ARRAY | |
51 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION | |
52 #include "numpy/arrayobject.h" | |
53 #endif | |
54 | |
55 #include <vector> | |
56 #include <queue> | |
57 #include <string> | |
58 #include <sstream> | |
59 #include <iostream> | |
60 | |
61 using std::cerr; | |
62 using std::endl; | |
63 | |
64 #ifdef HAVE_NUMPY | |
65 enum eArrayDataType { | |
66 dtype_float32 = (int) NPY_FLOAT, | |
67 dtype_complex64 = (int) NPY_CFLOAT | |
68 }; | |
69 #endif | |
70 | |
71 /* C++ mapping of PyNone Type */ | |
72 struct NoneType {}; | |
73 | |
74 // Data | |
75 class ValueError | |
76 { | |
77 public: | |
78 ValueError() {} | |
79 ValueError(std::string m, bool s) : message(m),strict(s) {} | |
80 std::string location; | |
81 std::string message; | |
82 bool strict; | |
83 std::string str() const { | |
84 return (location.empty()) ? message : message + "\nLocation: " + location;} | |
85 void print() const { cerr << str() << endl; } | |
86 template<typename V> ValueError &operator<< (const V& v) | |
87 { | |
88 std::ostringstream ss; | |
89 ss << v; | |
90 location += ss.str(); | |
91 return *this; | |
92 } | |
93 }; | |
94 | |
95 class PyTypeConversions | |
96 { | |
97 public: | |
98 PyTypeConversions(); | |
99 ~PyTypeConversions(); | |
100 | |
101 // Utilities | |
102 void setStrictTypingFlag(bool b) {m_strict = b;} | |
103 void setNumpyInstalled(bool b) {m_numpyInstalled = b;} | |
104 ValueError getError() const; | |
105 std::string PyValue_Get_TypeName(PyObject*) const; | |
106 | |
107 // Basic type conversion: Python to C++ | |
108 float PyValue_To_Float(PyObject*) const; | |
109 size_t PyValue_To_Size_t(PyObject*) const; | |
110 bool PyValue_To_Bool(PyObject*) const; | |
111 std::string PyValue_To_String(PyObject*) const; | |
112 long PyValue_To_Long(PyObject*) const; | |
113 // int PyValue_To_Int(PyObject* pyValue) const; | |
114 | |
115 // C++ to Python | |
116 PyObject *PyValue_From_CValue(const char*) const; | |
117 PyObject *PyValue_From_CValue(const std::string& x) const { return PyValue_From_CValue(x.c_str()); } | |
118 PyObject *PyValue_From_CValue(size_t) const; | |
119 PyObject *PyValue_From_CValue(double) const; | |
120 PyObject *PyValue_From_CValue(float x) const { return PyValue_From_CValue((double)x); } | |
121 PyObject *PyValue_From_CValue(bool) const; | |
122 | |
123 // Sequence types | |
124 std::vector<std::string> PyValue_To_StringVector (PyObject*) const; | |
125 std::vector<float> PyValue_To_FloatVector (PyObject*) const; | |
126 std::vector<float> PyList_To_FloatVector (PyObject*) const; | |
127 | |
128 PyObject *PyValue_From_StringVector(const std::vector<std::string> &) const; | |
129 | |
130 // Numpy types | |
131 #ifdef HAVE_NUMPY | |
132 std::vector<float> PyArray_To_FloatVector (PyObject *pyValue) const; | |
133 PyObject *FloatVector_To_PyArray(const std::vector<float> &) const; // Copying the data | |
134 #endif | |
135 | |
136 /// Convert DTYPE type 1D NumpyArray to std::vector<RET> | |
137 template<typename RET, typename DTYPE> | |
138 std::vector<RET> PyArray_Convert(void* raw_data_ptr, long length, size_t strides) const | |
139 { | |
140 std::vector<RET> rValue; | |
141 | |
142 /// check if the array is continuous, if not use strides info | |
143 if (sizeof(DTYPE)!=strides) { | |
144 #ifdef _DEBUG_VALUES | |
145 cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl; | |
146 #endif | |
147 char* data = (char*) raw_data_ptr; | |
148 for (long i = 0; i<length; ++i){ | |
149 rValue.push_back((RET)(*((DTYPE*)data))); | |
150 #ifdef _DEBUG_VALUES | |
151 cerr << "value: " << (RET)(*((DTYPE*)data)) << endl; | |
152 #endif | |
153 data+=strides; | |
154 } | |
155 return rValue; | |
156 } | |
157 | |
158 DTYPE* data = (DTYPE*) raw_data_ptr; | |
159 for (long i = 0; i<length; ++i){ | |
160 #ifdef _DEBUG_VALUES | |
161 cerr << "value: " << (RET)data[i] << endl; | |
162 #endif | |
163 rValue.push_back((RET)data[i]); | |
164 } | |
165 return rValue; | |
166 } | |
167 | |
168 /// this is a special case. numpy.float64 has an array conversions but no array descriptor | |
169 std::vector<float> PyArray0D_Convert(PyArrayInterface *ai) const | |
170 { | |
171 std::vector<float> rValue; | |
172 if ((ai->typekind) == *"f") | |
173 rValue.push_back((float)*(double*)(ai->data)); | |
174 else { | |
175 setValueError("Unsupported NumPy data type.",m_strict); | |
176 return rValue; | |
177 } | |
178 #ifdef _DEBUG_VALUES | |
179 cerr << "value: " << rValue[0] << endl; | |
180 #endif | |
181 return rValue; | |
182 } | |
183 | |
184 private: | |
185 bool m_strict; | |
186 mutable bool m_error; | |
187 mutable std::queue<ValueError> m_errorQueue; | |
188 bool m_numpyInstalled; | |
189 | |
190 void setValueError(std::string,bool) const; | |
191 ValueError& lastError() const; | |
192 | |
193 public: | |
194 const bool& error; | |
195 | |
196 }; | |
197 | |
198 #endif |