annotate native/PyRealTime.cpp @ 52:b56513f872a5

Move files into subdirs
author Chris Cannam
date Wed, 14 Jan 2015 08:30:47 +0000
parents PyRealTime.cpp@13dcfe8c7ed7
children c12589026ff4
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 "PyRealTime.h"
Chris@30 39
Chris@26 40 #include <string>
Chris@26 41
Chris@26 42 using namespace std;
Chris@26 43 using namespace Vamp;
Chris@26 44
Chris@26 45 /* CONSTRUCTOR: New RealTime object from sec and nsec */
Chris@26 46 static PyObject*
Chris@26 47 RealTime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Chris@26 48 {
Chris@26 49 unsigned int sec = 0;
Chris@26 50 unsigned int nsec = 0;
Chris@26 51 double unary = 0;
Chris@26 52 const char *fmt = NULL;
Chris@26 53
Chris@26 54 if (
Chris@39 55 /// new RealTime from ('format',float) e.g. ('seconds',2.34123)
Chris@39 56 !PyArg_ParseTuple(args, "|sd:RealTime.new ",
Chris@39 57 (const char *) &fmt,
Chris@39 58 (double *) &unary) &&
Chris@26 59
Chris@39 60 /// new RealTime from (sec{int},nsec{int}) e.g. (2,34)
Chris@39 61 !PyArg_ParseTuple(args, "|II:RealTime.new ",
Chris@39 62 (unsigned int*) &sec,
Chris@39 63 (unsigned int*) &nsec)
Chris@39 64
Chris@39 65 ) {
Chris@39 66 PyErr_SetString(PyExc_TypeError,
Chris@39 67 "RealTime initialised with wrong arguments.");
Chris@39 68 return NULL;
Chris@26 69 }
Chris@26 70
Chris@26 71 // PyErr_Clear();
Chris@26 72
Chris@26 73 // RealTimeObject *self = PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 74 RealTimeObject *self = (RealTimeObject*)type->tp_alloc(type, 0);
Chris@39 75
Chris@26 76 if (self == NULL) return NULL;
Chris@26 77
Chris@26 78 self->rt = NULL;
Chris@26 79
Chris@26 80 if (sec == 0 && nsec == 0 && fmt == 0)
Chris@39 81 self->rt = new RealTime();
Chris@26 82 else if (fmt == 0)
Chris@39 83 self->rt = new RealTime(sec,nsec);
Chris@26 84 else {
Chris@26 85 /// new RealTime from seconds or milliseconds: i.e. >>>RealTime('seconds',12.3)
Chris@39 86 if (!string(fmt).compare("float") ||
Chris@39 87 !string(fmt).compare("seconds"))
Chris@39 88 self->rt = new RealTime(
Chris@39 89 RealTime::fromSeconds((double) unary));
Chris@26 90
Chris@39 91 if (!string(fmt).compare("milliseconds")) {
Chris@39 92 self->rt = new RealTime(
Chris@39 93 RealTime::fromSeconds((double) unary / 1000.0)); }
Chris@26 94 }
Chris@26 95
Chris@26 96 if (!self->rt) {
Chris@39 97 PyErr_SetString(PyExc_TypeError,
Chris@39 98 "RealTime initialised with wrong arguments.");
Chris@39 99 return NULL;
Chris@26 100 }
Chris@26 101
Chris@26 102 return (PyObject *) self;
Chris@26 103 }
Chris@26 104
Chris@26 105 /* DESTRUCTOR: delete type object */
Chris@26 106 static void
Chris@26 107 RealTimeObject_dealloc(RealTimeObject *self)
Chris@26 108 {
Chris@39 109 if (self->rt) delete self->rt; //delete the C object
Chris@26 110 PyObject_Del(self); //delete the Python object (original)
Chris@26 111 /// this requires PyType_Ready() which fills ob_type
Chris@26 112 // self->ob_type->tp_free((PyObject*)self);
Chris@26 113 }
Chris@26 114
Chris@26 115 /* RealTime Object's Methods */
Chris@26 116 //these are internals not exposed by the module but the object
Chris@26 117
Chris@26 118 /* Returns a Tuple containing sec and nsec values */
Chris@26 119 static PyObject *
Chris@26 120 RealTime_values(RealTimeObject *self)
Chris@26 121 {
Chris@26 122 return Py_BuildValue("(ii)",self->rt->sec,self->rt->nsec);
Chris@26 123 }
Chris@26 124
Chris@26 125 /* Returns a Text representation */
Chris@26 126 static PyObject *
Chris@26 127 RealTime_toString(RealTimeObject *self, PyObject *args)
Chris@26 128 {
Chris@26 129 return Py_BuildValue("s",self->rt->toText().c_str());
Chris@26 130 }
Chris@26 131
Chris@26 132 /* Frame representation */
Chris@26 133 static PyObject *
Chris@26 134 RealTime_toFrame(PyObject *self, PyObject *args)
Chris@26 135 {
Chris@26 136 unsigned int samplerate;
Chris@39 137
Chris@26 138 if ( !PyArg_ParseTuple(args, "I:realtime.toFrame object ",
Chris@39 139 (unsigned int *) &samplerate )) {
Chris@39 140 PyErr_SetString(PyExc_ValueError,"Integer Sample Rate Required.");
Chris@39 141 return NULL;
Chris@26 142 }
Chris@39 143
Chris@26 144 return Py_BuildValue("k",
Chris@39 145 RealTime::realTime2Frame(
Chris@39 146 *(const RealTime*) ((RealTimeObject*)self)->rt,
Chris@39 147 (unsigned int) samplerate));
Chris@26 148 }
Chris@26 149
Chris@26 150 /* Conversion of realtime to a double precision floating point value */
Chris@26 151 /* ...in Python called by e.g. float(realtime) */
Chris@26 152 static PyObject *
Chris@26 153 RealTime_float(PyObject *s)
Chris@26 154 {
Chris@26 155 double drt = ((double) ((RealTimeObject*)s)->rt->sec +
Chris@39 156 (double)((double) ((RealTimeObject*)s)->rt->nsec)/1000000000);
Chris@39 157 return PyFloat_FromDouble(drt);
Chris@26 158 }
Chris@26 159
Chris@26 160
Chris@26 161 /* Type object's (RealTime) methods table */
Chris@26 162 static PyMethodDef RealTime_methods[] =
Chris@26 163 {
Chris@39 164 {"values", (PyCFunction)RealTime_values, METH_NOARGS,
Chris@26 165 PyDoc_STR("values() -> Tuple of sec,nsec representation.")},
Chris@26 166
Chris@39 167 {"toString", (PyCFunction)RealTime_toString, METH_NOARGS,
Chris@26 168 PyDoc_STR("toString() -> Return a user-readable string to the nearest millisecond in a form like HH:MM:SS.mmm")},
Chris@26 169
Chris@39 170 {"toFrame", (PyCFunction)RealTime_toFrame, METH_VARARGS,
Chris@26 171 PyDoc_STR("toFrame(samplerate) -> Sample count for given sample rate.")},
Chris@26 172
Chris@39 173 {"toFloat", (PyCFunction)RealTime_float, METH_NOARGS,
Chris@26 174 PyDoc_STR("toFloat() -> Floating point representation.")},
Chris@39 175
Chris@39 176 {NULL, NULL} /* sentinel */
Chris@26 177 };
Chris@26 178
Chris@26 179
Chris@26 180 /* Methods implementing protocols */
Chris@26 181 // these functions are called by the interpreter
Chris@26 182
Chris@26 183 /* Object Protocol */
Chris@26 184
Chris@26 185 static int
Chris@26 186 RealTime_setattr(RealTimeObject *self, char *name, PyObject *value)
Chris@26 187 {
Chris@26 188
Chris@26 189 if ( !string(name).compare("sec")) {
Chris@39 190 self->rt->sec= (int) PyInt_AS_LONG(value);
Chris@39 191 return 0;
Chris@26 192 }
Chris@26 193
Chris@26 194 if ( !string(name).compare("nsec")) {
Chris@39 195 self->rt->nsec= (int) PyInt_AS_LONG(value);
Chris@39 196 return 0;
Chris@26 197 }
Chris@26 198
Chris@26 199 return -1;
Chris@26 200 }
Chris@26 201
Chris@26 202 static PyObject *
Chris@26 203 RealTime_getattr(RealTimeObject *self, char *name)
Chris@26 204 {
Chris@26 205
Chris@26 206 if ( !string(name).compare("sec") ) {
Chris@39 207 return PyInt_FromSsize_t(
Chris@39 208 (Py_ssize_t) self->rt->sec);
Chris@26 209 }
Chris@26 210
Chris@26 211 if ( !string(name).compare("nsec") ) {
Chris@39 212 return PyInt_FromSsize_t(
Chris@39 213 (Py_ssize_t) self->rt->nsec);
Chris@26 214 }
Chris@26 215
Chris@26 216 return Py_FindMethod(RealTime_methods,
Chris@39 217 (PyObject *)self, name);
Chris@26 218 }
Chris@26 219
Chris@26 220 /* String representation called by e.g. str(realtime), print realtime*/
Chris@26 221 static PyObject *
Chris@26 222 RealTime_repr(PyObject *self)
Chris@26 223 {
Chris@26 224 return Py_BuildValue("s",
Chris@39 225 ((RealTimeObject*)self)->rt->toString().c_str());
Chris@26 226 }
Chris@26 227
Chris@26 228
Chris@26 229 /* Number Protocol */
Chris@26 230 /// TODO: implement all methods available in Vamp::RealTime() objects
Chris@26 231
Chris@26 232 static PyObject *
Chris@26 233 RealTime_add(PyObject *s, PyObject *w)
Chris@26 234 {
Chris@26 235 RealTimeObject *result =
Chris@39 236 PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 237 if (result == NULL) return NULL;
Chris@26 238
Chris@26 239 result->rt = new RealTime(
Chris@39 240 *((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
Chris@26 241 return (PyObject*)result;
Chris@26 242 }
Chris@26 243
Chris@26 244 static PyObject *
Chris@26 245 RealTime_subtract(PyObject *s, PyObject *w)
Chris@26 246 {
Chris@26 247 RealTimeObject *result =
Chris@39 248 PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 249 if (result == NULL) return NULL;
Chris@26 250
Chris@26 251 result->rt = new RealTime(
Chris@39 252 *((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
Chris@26 253 return (PyObject*)result;
Chris@26 254 }
Chris@26 255
Chris@26 256 static PyNumberMethods realtime_as_number =
Chris@26 257 {
Chris@39 258 RealTime_add, /*nb_add*/
Chris@39 259 RealTime_subtract, /*nb_subtract*/
Chris@39 260 0, /*nb_multiply*/
Chris@39 261 0, /*nb_divide*/
Chris@39 262 0, /*nb_remainder*/
Chris@39 263 0, /*nb_divmod*/
Chris@39 264 0, /*nb_power*/
Chris@39 265 0, /*nb_neg*/
Chris@39 266 0, /*nb_pos*/
Chris@39 267 0, /*(unaryfunc)array_abs,*/
Chris@39 268 0, /*nb_nonzero*/
Chris@39 269 0, /*nb_invert*/
Chris@39 270 0, /*nb_lshift*/
Chris@39 271 0, /*nb_rshift*/
Chris@39 272 0, /*nb_and*/
Chris@39 273 0, /*nb_xor*/
Chris@39 274 0, /*nb_or*/
Chris@26 275 0, /*nb_coerce*/
Chris@39 276 0, /*nb_int*/
Chris@39 277 0, /*nb_long*/
Chris@26 278 (unaryfunc)RealTime_float,/*nb_float*/
Chris@39 279 0, /*nb_oct*/
Chris@39 280 0, /*nb_hex*/
Chris@26 281 };
Chris@26 282
Chris@26 283 /* REAL-TIME TYPE OBJECT */
Chris@26 284
Chris@26 285 #define RealTime_alloc PyType_GenericAlloc
Chris@26 286 #define RealTime_free PyObject_Del
Chris@26 287
Chris@26 288 /* Doc:: 10.3 Type Objects */ /* static */
Chris@26 289 PyTypeObject RealTime_Type =
Chris@26 290 {
Chris@26 291 PyObject_HEAD_INIT(NULL)
Chris@39 292 0, /*ob_size*/
Chris@39 293 "vampy.RealTime", /*tp_name*/
Chris@39 294 sizeof(RealTimeObject), /*tp_basicsize*/
Chris@39 295 0, /*tp_itemsize*/
Chris@39 296 /* methods */
Chris@26 297 (destructor)RealTimeObject_dealloc, /*tp_dealloc*/
Chris@39 298 0, /*tp_print*/
Chris@26 299 (getattrfunc)RealTime_getattr, /*tp_getattr*/
Chris@26 300 (setattrfunc)RealTime_setattr, /*tp_setattr*/
Chris@39 301 0, /*tp_compare*/
Chris@39 302 RealTime_repr, /*tp_repr*/
Chris@39 303 &realtime_as_number, /*tp_as_number*/
Chris@39 304 0, /*tp_as_sequence*/
Chris@39 305 0, /*tp_as_mapping*/
Chris@39 306 0, /*tp_hash*/
Chris@39 307 0, /*tp_call*/
Chris@26 308 0, /*tp_str*/
Chris@26 309 0, /*tp_getattro*/
Chris@26 310 0, /*tp_setattro*/
Chris@26 311 0, /*tp_as_buffer*/
Chris@26 312 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Chris@39 313 "RealTime object, used for Vamp plugin timestamps.", /*tp_doc*/
Chris@26 314 0, /*tp_traverse*/
Chris@26 315 0, /*tp_clear*/
Chris@26 316 0, /*tp_richcompare*/
Chris@26 317 0, /*tp_weaklistoffset*/
Chris@26 318 0, /*tp_iter*/
Chris@26 319 0, /*tp_iternext*/
Chris@26 320 RealTime_methods, /*tp_methods*/ //TypeObject Methods
Chris@26 321 0, /*tp_members*/
Chris@26 322 0, /*tp_getset*/
Chris@26 323 0, /*tp_base*/
Chris@26 324 0, /*tp_dict*/
Chris@26 325 0, /*tp_descr_get*/
Chris@26 326 0, /*tp_descr_set*/
Chris@26 327 0, /*tp_dictoffset*/
Chris@26 328 0, /*tp_init*/
Chris@26 329 RealTime_alloc, /*tp_alloc*/
Chris@26 330 RealTime_new, /*tp_new*/
Chris@39 331 RealTime_free, /*tp_free*/
Chris@26 332 0, /*tp_is_gc*/
Chris@26 333 };
Chris@26 334
Chris@26 335
Chris@26 336
Chris@26 337 /* PyRealTime C++ API */
Chris@26 338
Chris@26 339 /*PyRealTime from RealTime*/
Chris@26 340 PyObject*
Chris@26 341 PyRealTime_FromRealTime(const Vamp::RealTime& rt) {
Chris@26 342
Chris@26 343 RealTimeObject *self =
Chris@39 344 PyObject_New(RealTimeObject, &RealTime_Type);
Chris@26 345 if (self == NULL) return NULL;
Chris@26 346
Chris@26 347 self->rt = new RealTime(rt);
Chris@26 348 return (PyObject*) self;
Chris@26 349 }
Chris@26 350
Chris@26 351 /*RealTime* from PyRealTime*/
Chris@26 352 const Vamp::RealTime*
Chris@26 353 PyRealTime_AsRealTime (PyObject *self) {
Chris@26 354
Chris@26 355 RealTimeObject *s = (RealTimeObject*) self;
Chris@26 356
Chris@26 357 if (!PyRealTime_Check(s)) {
Chris@39 358 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
Chris@39 359 cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
Chris@39 360 return NULL; }
Chris@26 361 return s->rt;
Chris@26 362 };
Chris@26 363