annotate PyRealTime.cpp @ 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 e1e54546d5fd
rev   line source
Chris@26 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@26 2
Chris@26 3 /*
Chris@26 4 VampyHost
Chris@26 5
Chris@26 6 Use Vamp audio analysis plugins in Python
Chris@26 7
Chris@26 8 Gyorgy Fazekas and Chris Cannam
Chris@26 9 Centre for Digital Music, Queen Mary, University of London
Chris@26 10 Copyright 2008-2014 Queen Mary, University of London
Chris@26 11
Chris@26 12 Permission is hereby granted, free of charge, to any person
Chris@26 13 obtaining a copy of this software and associated documentation
Chris@26 14 files (the "Software"), to deal in the Software without
Chris@26 15 restriction, including without limitation the rights to use, copy,
Chris@26 16 modify, merge, publish, distribute, sublicense, and/or sell copies
Chris@26 17 of the Software, and to permit persons to whom the Software is
Chris@26 18 furnished to do so, subject to the following conditions:
Chris@26 19
Chris@26 20 The above copyright notice and this permission notice shall be
Chris@26 21 included in all copies or substantial portions of the Software.
Chris@26 22
Chris@26 23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@26 24 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@26 25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@26 26 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
Chris@26 27 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@26 28 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@26 29 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@26 30
Chris@26 31 Except as contained in this notice, the names of the Centre for
Chris@26 32 Digital Music; Queen Mary, University of London; and the authors
Chris@26 33 shall not be used in advertising or otherwise to promote the sale,
Chris@26 34 use or other dealings in this Software without prior written
Chris@26 35 authorization.
Chris@26 36 */
Chris@26 37
Chris@26 38 #include <Python.h>
Chris@26 39 #include "PyRealTime.h"
Chris@26 40 #include "vamp-sdk/Plugin.h"
Chris@26 41 #include <string>
Chris@26 42
Chris@26 43 using namespace std;
Chris@26 44 using namespace Vamp;
Chris@26 45 using Vamp::Plugin;
Chris@26 46 using Vamp::RealTime;
Chris@26 47
Chris@26 48 /* CONSTRUCTOR: New RealTime object from sec and nsec */
Chris@26 49 static PyObject*
Chris@26 50 RealTime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Chris@26 51 {
Chris@26 52 unsigned int sec = 0;
Chris@26 53 unsigned int nsec = 0;
Chris@26 54 double unary = 0;
Chris@26 55 const char *fmt = NULL;
Chris@26 56
Chris@26 57 if (
Chris@26 58 /// new RealTime from ('format',float) e.g. ('seconds',2.34123)
Chris@26 59 !PyArg_ParseTuple(args, "|sd:RealTime.new ",
Chris@26 60 (const char *) &fmt,
Chris@26 61 (double *) &unary) &&
Chris@26 62
Chris@26 63 /// new RealTime from (sec{int},nsec{int}) e.g. (2,34)
Chris@26 64 !PyArg_ParseTuple(args, "|II:RealTime.new ",
Chris@26 65 (unsigned int*) &sec,
Chris@26 66 (unsigned int*) &nsec)
Chris@26 67
Chris@26 68 ) {
Chris@26 69 PyErr_SetString(PyExc_TypeError,
Chris@26 70 "RealTime initialised with wrong arguments.");
Chris@26 71 return NULL;
Chris@26 72 }
Chris@26 73
Chris@26 74 // PyErr_Clear();
Chris@26 75
Chris@26 76 // RealTimeObject *self = PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 77 RealTimeObject *self = (RealTimeObject*)type->tp_alloc(type, 0);
Chris@26 78
Chris@26 79 if (self == NULL) return NULL;
Chris@26 80
Chris@26 81 self->rt = NULL;
Chris@26 82
Chris@26 83 if (sec == 0 && nsec == 0 && fmt == 0)
Chris@26 84 self->rt = new RealTime();
Chris@26 85 else if (fmt == 0)
Chris@26 86 self->rt = new RealTime(sec,nsec);
Chris@26 87 else {
Chris@26 88 /// new RealTime from seconds or milliseconds: i.e. >>>RealTime('seconds',12.3)
Chris@26 89 if (!string(fmt).compare("float") ||
Chris@26 90 !string(fmt).compare("seconds"))
Chris@26 91 self->rt = new RealTime(
Chris@26 92 RealTime::fromSeconds((double) unary));
Chris@26 93
Chris@26 94 if (!string(fmt).compare("milliseconds")) {
Chris@26 95 self->rt = new RealTime(
Chris@26 96 RealTime::fromSeconds((double) unary / 1000.0)); }
Chris@26 97 }
Chris@26 98
Chris@26 99 if (!self->rt) {
Chris@26 100 PyErr_SetString(PyExc_TypeError,
Chris@26 101 "RealTime initialised with wrong arguments.");
Chris@26 102 return NULL;
Chris@26 103 }
Chris@26 104
Chris@26 105 return (PyObject *) self;
Chris@26 106 }
Chris@26 107
Chris@26 108 /* DESTRUCTOR: delete type object */
Chris@26 109 static void
Chris@26 110 RealTimeObject_dealloc(RealTimeObject *self)
Chris@26 111 {
Chris@26 112 if (self->rt) delete self->rt; //delete the C object
Chris@26 113 PyObject_Del(self); //delete the Python object (original)
Chris@26 114 /// this requires PyType_Ready() which fills ob_type
Chris@26 115 // self->ob_type->tp_free((PyObject*)self);
Chris@26 116 }
Chris@26 117
Chris@26 118 /* RealTime Object's Methods */
Chris@26 119 //these are internals not exposed by the module but the object
Chris@26 120
Chris@26 121 /* Returns a Tuple containing sec and nsec values */
Chris@26 122 static PyObject *
Chris@26 123 RealTime_values(RealTimeObject *self)
Chris@26 124 {
Chris@26 125 return Py_BuildValue("(ii)",self->rt->sec,self->rt->nsec);
Chris@26 126 }
Chris@26 127
Chris@26 128 /* Returns a Text representation */
Chris@26 129 static PyObject *
Chris@26 130 RealTime_toString(RealTimeObject *self, PyObject *args)
Chris@26 131 {
Chris@26 132 return Py_BuildValue("s",self->rt->toText().c_str());
Chris@26 133 }
Chris@26 134
Chris@26 135 /* Frame representation */
Chris@26 136 static PyObject *
Chris@26 137 RealTime_toFrame(PyObject *self, PyObject *args)
Chris@26 138 {
Chris@26 139 unsigned int samplerate;
Chris@26 140
Chris@26 141 if ( !PyArg_ParseTuple(args, "I:realtime.toFrame object ",
Chris@26 142 (unsigned int *) &samplerate )) {
Chris@26 143 PyErr_SetString(PyExc_ValueError,"Integer Sample Rate Required.");
Chris@26 144 return NULL;
Chris@26 145 }
Chris@26 146
Chris@26 147 return Py_BuildValue("k",
Chris@26 148 RealTime::realTime2Frame(
Chris@26 149 *(const RealTime*) ((RealTimeObject*)self)->rt,
Chris@26 150 (unsigned int) samplerate));
Chris@26 151 }
Chris@26 152
Chris@26 153 /* Conversion of realtime to a double precision floating point value */
Chris@26 154 /* ...in Python called by e.g. float(realtime) */
Chris@26 155 static PyObject *
Chris@26 156 RealTime_float(PyObject *s)
Chris@26 157 {
Chris@26 158 double drt = ((double) ((RealTimeObject*)s)->rt->sec +
Chris@26 159 (double)((double) ((RealTimeObject*)s)->rt->nsec)/1000000000);
Chris@26 160 return PyFloat_FromDouble(drt);
Chris@26 161 }
Chris@26 162
Chris@26 163
Chris@26 164 /* Type object's (RealTime) methods table */
Chris@26 165 static PyMethodDef RealTime_methods[] =
Chris@26 166 {
Chris@26 167 {"values", (PyCFunction)RealTime_values, METH_NOARGS,
Chris@26 168 PyDoc_STR("values() -> Tuple of sec,nsec representation.")},
Chris@26 169
Chris@26 170 {"toString", (PyCFunction)RealTime_toString, METH_NOARGS,
Chris@26 171 PyDoc_STR("toString() -> Return a user-readable string to the nearest millisecond in a form like HH:MM:SS.mmm")},
Chris@26 172
Chris@26 173 {"toFrame", (PyCFunction)RealTime_toFrame, METH_VARARGS,
Chris@26 174 PyDoc_STR("toFrame(samplerate) -> Sample count for given sample rate.")},
Chris@26 175
Chris@26 176 {"toFloat", (PyCFunction)RealTime_float, METH_NOARGS,
Chris@26 177 PyDoc_STR("toFloat() -> Floating point representation.")},
Chris@26 178
Chris@26 179 {NULL, NULL} /* sentinel */
Chris@26 180 };
Chris@26 181
Chris@26 182
Chris@26 183 /* Methods implementing protocols */
Chris@26 184 // these functions are called by the interpreter
Chris@26 185
Chris@26 186 /* Object Protocol */
Chris@26 187
Chris@26 188 static int
Chris@26 189 RealTime_setattr(RealTimeObject *self, char *name, PyObject *value)
Chris@26 190 {
Chris@26 191
Chris@26 192 if ( !string(name).compare("sec")) {
Chris@26 193 self->rt->sec= (int) PyInt_AS_LONG(value);
Chris@26 194 return 0;
Chris@26 195 }
Chris@26 196
Chris@26 197 if ( !string(name).compare("nsec")) {
Chris@26 198 self->rt->nsec= (int) PyInt_AS_LONG(value);
Chris@26 199 return 0;
Chris@26 200 }
Chris@26 201
Chris@26 202 return -1;
Chris@26 203 }
Chris@26 204
Chris@26 205 static PyObject *
Chris@26 206 RealTime_getattr(RealTimeObject *self, char *name)
Chris@26 207 {
Chris@26 208
Chris@26 209 if ( !string(name).compare("sec") ) {
Chris@26 210 return PyInt_FromSsize_t(
Chris@26 211 (Py_ssize_t) self->rt->sec);
Chris@26 212 }
Chris@26 213
Chris@26 214 if ( !string(name).compare("nsec") ) {
Chris@26 215 return PyInt_FromSsize_t(
Chris@26 216 (Py_ssize_t) self->rt->nsec);
Chris@26 217 }
Chris@26 218
Chris@26 219 return Py_FindMethod(RealTime_methods,
Chris@26 220 (PyObject *)self, name);
Chris@26 221 }
Chris@26 222
Chris@26 223 /* String representation called by e.g. str(realtime), print realtime*/
Chris@26 224 static PyObject *
Chris@26 225 RealTime_repr(PyObject *self)
Chris@26 226 {
Chris@26 227 return Py_BuildValue("s",
Chris@26 228 ((RealTimeObject*)self)->rt->toString().c_str());
Chris@26 229 }
Chris@26 230
Chris@26 231
Chris@26 232 /* Number Protocol */
Chris@26 233 /// TODO: implement all methods available in Vamp::RealTime() objects
Chris@26 234
Chris@26 235 static PyObject *
Chris@26 236 RealTime_add(PyObject *s, PyObject *w)
Chris@26 237 {
Chris@26 238 RealTimeObject *result =
Chris@26 239 PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 240 if (result == NULL) return NULL;
Chris@26 241
Chris@26 242 result->rt = new RealTime(
Chris@26 243 *((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
Chris@26 244 return (PyObject*)result;
Chris@26 245 }
Chris@26 246
Chris@26 247 static PyObject *
Chris@26 248 RealTime_subtract(PyObject *s, PyObject *w)
Chris@26 249 {
Chris@26 250 RealTimeObject *result =
Chris@26 251 PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 252 if (result == NULL) return NULL;
Chris@26 253
Chris@26 254 result->rt = new RealTime(
Chris@26 255 *((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
Chris@26 256 return (PyObject*)result;
Chris@26 257 }
Chris@26 258
Chris@26 259 static PyNumberMethods realtime_as_number =
Chris@26 260 {
Chris@26 261 RealTime_add, /*nb_add*/
Chris@26 262 RealTime_subtract, /*nb_subtract*/
Chris@26 263 0, /*nb_multiply*/
Chris@26 264 0, /*nb_divide*/
Chris@26 265 0, /*nb_remainder*/
Chris@26 266 0, /*nb_divmod*/
Chris@26 267 0, /*nb_power*/
Chris@26 268 0, /*nb_neg*/
Chris@26 269 0, /*nb_pos*/
Chris@26 270 0, /*(unaryfunc)array_abs,*/
Chris@26 271 0, /*nb_nonzero*/
Chris@26 272 0, /*nb_invert*/
Chris@26 273 0, /*nb_lshift*/
Chris@26 274 0, /*nb_rshift*/
Chris@26 275 0, /*nb_and*/
Chris@26 276 0, /*nb_xor*/
Chris@26 277 0, /*nb_or*/
Chris@26 278 0, /*nb_coerce*/
Chris@26 279 0, /*nb_int*/
Chris@26 280 0, /*nb_long*/
Chris@26 281 (unaryfunc)RealTime_float,/*nb_float*/
Chris@26 282 0, /*nb_oct*/
Chris@26 283 0, /*nb_hex*/
Chris@26 284 };
Chris@26 285
Chris@26 286 /* REAL-TIME TYPE OBJECT */
Chris@26 287
Chris@26 288 #define RealTime_alloc PyType_GenericAlloc
Chris@26 289 #define RealTime_free PyObject_Del
Chris@26 290
Chris@26 291 /* Doc:: 10.3 Type Objects */ /* static */
Chris@26 292 PyTypeObject RealTime_Type =
Chris@26 293 {
Chris@26 294 PyObject_HEAD_INIT(NULL)
Chris@26 295 0, /*ob_size*/
Chris@26 296 "vampy.RealTime", /*tp_name*/
Chris@26 297 sizeof(RealTimeObject), /*tp_basicsize*/
Chris@26 298 0,//sizeof(RealTime), /*tp_itemsize*/
Chris@26 299 /* methods */
Chris@26 300 (destructor)RealTimeObject_dealloc, /*tp_dealloc*/
Chris@26 301 0, /*tp_print*/
Chris@26 302 (getattrfunc)RealTime_getattr, /*tp_getattr*/
Chris@26 303 (setattrfunc)RealTime_setattr, /*tp_setattr*/
Chris@26 304 0, /*tp_compare*/
Chris@26 305 RealTime_repr, /*tp_repr*/
Chris@26 306 &realtime_as_number, /*tp_as_number*/
Chris@26 307 0, /*tp_as_sequence*/
Chris@26 308 0, /*tp_as_mapping*/
Chris@26 309 0, /*tp_hash*/
Chris@26 310 0,//(ternaryfunc)RealTime_new, /*tp_call*/
Chris@26 311 0, /*tp_str*/
Chris@26 312 0, /*tp_getattro*/
Chris@26 313 0, /*tp_setattro*/
Chris@26 314 0, /*tp_as_buffer*/
Chris@26 315 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Chris@26 316 "RealTime Object", /*tp_doc*/
Chris@26 317 0, /*tp_traverse*/
Chris@26 318 0, /*tp_clear*/
Chris@26 319 0, /*tp_richcompare*/
Chris@26 320 0, /*tp_weaklistoffset*/
Chris@26 321 0, /*tp_iter*/
Chris@26 322 0, /*tp_iternext*/
Chris@26 323 RealTime_methods, /*tp_methods*/ //TypeObject Methods
Chris@26 324 0, /*tp_members*/
Chris@26 325 0, /*tp_getset*/
Chris@26 326 0, /*tp_base*/
Chris@26 327 0, /*tp_dict*/
Chris@26 328 0, /*tp_descr_get*/
Chris@26 329 0, /*tp_descr_set*/
Chris@26 330 0, /*tp_dictoffset*/
Chris@26 331 0, /*tp_init*/
Chris@26 332 RealTime_alloc, /*tp_alloc*/
Chris@26 333 RealTime_new, /*tp_new*/
Chris@26 334 RealTime_free, /*tp_free*/
Chris@26 335 0, /*tp_is_gc*/
Chris@26 336 };
Chris@26 337
Chris@26 338
Chris@26 339
Chris@26 340 /* PyRealTime C++ API */
Chris@26 341
Chris@26 342 /*PyRealTime from RealTime*/
Chris@26 343 PyObject*
Chris@26 344 PyRealTime_FromRealTime(const Vamp::RealTime& rt) {
Chris@26 345
Chris@26 346 RealTimeObject *self =
Chris@26 347 PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 348 if (self == NULL) return NULL;
Chris@26 349
Chris@26 350 self->rt = new RealTime(rt);
Chris@26 351 return (PyObject*) self;
Chris@26 352 }
Chris@26 353
Chris@26 354 /*RealTime* from PyRealTime*/
Chris@26 355 const Vamp::RealTime*
Chris@26 356 PyRealTime_AsRealTime (PyObject *self) {
Chris@26 357
Chris@26 358 RealTimeObject *s = (RealTimeObject*) self;
Chris@26 359
Chris@26 360 if (!PyRealTime_Check(s)) {
Chris@26 361 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
Chris@26 362 cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
Chris@26 363 return NULL; }
Chris@26 364 return s->rt;
Chris@26 365 };
Chris@26 366