Changeset 388 for python/vendor/current/Modules/sunaudiodev.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Modules/sunaudiodev.c
r2 r388 24 24 25 25 typedef struct { 26 27 int x_fd;/* The open file */28 int x_icount;/* # samples read */29 int x_ocount;/* # samples written */30 int x_isctl;/* True if control device */31 26 PyObject_HEAD 27 int x_fd; /* The open file */ 28 int x_icount; /* # samples read */ 29 int x_ocount; /* # samples written */ 30 int x_isctl; /* True if control device */ 31 32 32 } sadobject; 33 33 34 34 typedef struct { 35 36 35 PyObject_HEAD 36 audio_info_t ai; 37 37 } sadstatusobject; 38 38 39 39 static PyTypeObject Sadtype; 40 40 static PyTypeObject Sadstatustype; 41 static sadstatusobject *sads_alloc(void); 41 static sadstatusobject *sads_alloc(void); /* Forward */ 42 42 43 43 static PyObject *SunAudioError; 44 44 45 #define is_sadobject(v) 46 #define is_sadstatusobject(v) 45 #define is_sadobject(v) (Py_TYPE(v) == &Sadtype) 46 #define is_sadstatusobject(v) (Py_TYPE(v) == &Sadstatustype) 47 47 48 48 … … 50 50 newsadobject(PyObject *args) 51 51 { 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 52 sadobject *xp; 53 int fd; 54 char *mode; 55 int imode; 56 char* basedev; 57 char* ctldev; 58 char* opendev; 59 60 /* Check arg for r/w/rw */ 61 if (!PyArg_ParseTuple(args, "s", &mode)) 62 return NULL; 63 if (strcmp(mode, "r") == 0) 64 imode = 0; 65 else if (strcmp(mode, "w") == 0) 66 imode = 1; 67 else if (strcmp(mode, "rw") == 0) 68 imode = 2; 69 else if (strcmp(mode, "control") == 0) 70 imode = -1; 71 else { 72 PyErr_SetString(SunAudioError, 73 "Mode should be one of 'r', 'w', 'rw' or 'control'"); 74 return NULL; 75 } 76 77 /* Open the correct device. The base device name comes from the 78 * AUDIODEV environment variable first, then /dev/audio. The 79 * control device tacks "ctl" onto the base device name. 80 */ 81 basedev = getenv("AUDIODEV"); 82 if (!basedev) 83 basedev = "/dev/audio"; 84 ctldev = PyMem_NEW(char, strlen(basedev) + 4); 85 if (!ctldev) { 86 PyErr_NoMemory(); 87 return NULL; 88 } 89 strcpy(ctldev, basedev); 90 strcat(ctldev, "ctl"); 91 92 if (imode < 0) { 93 opendev = ctldev; 94 fd = open(ctldev, 2); 95 } 96 else { 97 opendev = basedev; 98 fd = open(basedev, imode); 99 } 100 if (fd < 0) { 101 PyErr_SetFromErrnoWithFilename(SunAudioError, opendev); 102 PyMem_DEL(ctldev); 103 return NULL; 104 } 105 PyMem_DEL(ctldev); 106 107 /* Create and initialize the object */ 108 xp = PyObject_New(sadobject, &Sadtype); 109 if (xp == NULL) { 110 close(fd); 111 return NULL; 112 } 113 xp->x_fd = fd; 114 xp->x_icount = xp->x_ocount = 0; 115 xp->x_isctl = (imode < 0); 116 117 return xp; 118 118 } 119 119 … … 123 123 sad_dealloc(sadobject *xp) 124 124 { 125 126 125 close(xp->x_fd); 126 PyObject_Del(xp); 127 127 } 128 128 … … 130 130 sad_read(sadobject *self, PyObject *args) 131 131 { 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 132 int size, count; 133 char *cp; 134 PyObject *rv; 135 136 if (!PyArg_ParseTuple(args, "i:read", &size)) 137 return NULL; 138 rv = PyString_FromStringAndSize(NULL, size); 139 if (rv == NULL) 140 return NULL; 141 142 if (!(cp = PyString_AsString(rv))) 143 goto finally; 144 145 count = read(self->x_fd, cp, size); 146 if (count < 0) { 147 PyErr_SetFromErrno(SunAudioError); 148 goto finally; 149 } 150 150 #if 0 151 152 153 154 155 156 157 #endif 158 159 151 /* TBD: why print this message if you can handle the condition? 152 * assume it's debugging info which we can just as well get rid 153 * of. in any case this message should *not* be using printf! 154 */ 155 if (count != size) 156 printf("sunaudio: funny read rv %d wtd %d\n", count, size); 157 #endif 158 self->x_icount += count; 159 return rv; 160 160 161 161 finally: 162 163 162 Py_DECREF(rv); 163 return NULL; 164 164 } 165 165 … … 167 167 sad_write(sadobject *self, PyObject *args) 168 168 { 169 170 171 172 173 174 175 176 177 178 179 169 char *cp; 170 int count, size; 171 172 if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) 173 return NULL; 174 175 count = write(self->x_fd, cp, size); 176 if (count < 0) { 177 PyErr_SetFromErrno(SunAudioError); 178 return NULL; 179 } 180 180 #if 0 181 182 183 #endif 184 185 186 187 181 if (count != size) 182 printf("sunaudio: funny write rv %d wanted %d\n", count, size); 183 #endif 184 self->x_ocount += count; 185 186 Py_INCREF(Py_None); 187 return Py_None; 188 188 } 189 189 … … 191 191 sad_getinfo(sadobject *self) 192 192 { 193 194 195 196 197 198 199 200 201 202 203 193 sadstatusobject *rv; 194 195 if (!(rv = sads_alloc())) 196 return NULL; 197 198 if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) { 199 PyErr_SetFromErrno(SunAudioError); 200 Py_DECREF(rv); 201 return NULL; 202 } 203 return (PyObject *)rv; 204 204 } 205 205 … … 207 207 sad_setinfo(sadobject *self, sadstatusobject *arg) 208 208 { 209 210 211 212 213 214 215 216 217 218 219 209 if (!is_sadstatusobject(arg)) { 210 PyErr_SetString(PyExc_TypeError, 211 "Must be sun audio status object"); 212 return NULL; 213 } 214 if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) { 215 PyErr_SetFromErrno(SunAudioError); 216 return NULL; 217 } 218 Py_INCREF(Py_None); 219 return Py_None; 220 220 } 221 221 … … 223 223 sad_ibufcount(sadobject *self) 224 224 { 225 226 227 228 229 230 231 225 audio_info_t ai; 226 227 if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) { 228 PyErr_SetFromErrno(SunAudioError); 229 return NULL; 230 } 231 return PyInt_FromLong(ai.record.samples - self->x_icount); 232 232 } 233 233 … … 235 235 sad_obufcount(sadobject *self) 236 236 { 237 238 239 240 241 242 243 244 245 246 247 237 audio_info_t ai; 238 239 if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) { 240 PyErr_SetFromErrno(SunAudioError); 241 return NULL; 242 } 243 /* x_ocount is in bytes, whereas play.samples is in frames */ 244 /* we want frames */ 245 return PyInt_FromLong(self->x_ocount / (ai.play.channels * 246 ai.play.precision / 8) - 247 ai.play.samples); 248 248 } 249 249 … … 251 251 sad_drain(sadobject *self) 252 252 { 253 254 255 256 257 258 253 if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) { 254 PyErr_SetFromErrno(SunAudioError); 255 return NULL; 256 } 257 Py_INCREF(Py_None); 258 return Py_None; 259 259 } 260 260 … … 263 263 sad_getdev(sadobject *self) 264 264 { 265 266 267 268 269 270 271 265 struct audio_device ad; 266 267 if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) { 268 PyErr_SetFromErrno(SunAudioError); 269 return NULL; 270 } 271 return Py_BuildValue("(sss)", ad.name, ad.version, ad.config); 272 272 } 273 273 #endif … … 276 276 sad_flush(sadobject *self) 277 277 { 278 279 280 281 282 283 278 if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) { 279 PyErr_SetFromErrno(SunAudioError); 280 return NULL; 281 } 282 Py_INCREF(Py_None); 283 return Py_None; 284 284 } 285 285 … … 287 287 sad_close(sadobject *self) 288 288 { 289 290 291 292 293 294 295 289 290 if (self->x_fd >= 0) { 291 close(self->x_fd); 292 self->x_fd = -1; 293 } 294 Py_INCREF(Py_None); 295 return Py_None; 296 296 } 297 297 … … 299 299 sad_fileno(sadobject *self) 300 300 { 301 301 return PyInt_FromLong(self->x_fd); 302 302 } 303 303 304 304 305 305 static PyMethodDef sad_methods[] = { 306 { "read",(PyCFunction)sad_read, METH_VARARGS },307 { "write",(PyCFunction)sad_write, METH_VARARGS },308 { "ibufcount",(PyCFunction)sad_ibufcount, METH_NOARGS },309 { "obufcount",(PyCFunction)sad_obufcount, METH_NOARGS },306 { "read", (PyCFunction)sad_read, METH_VARARGS }, 307 { "write", (PyCFunction)sad_write, METH_VARARGS }, 308 { "ibufcount", (PyCFunction)sad_ibufcount, METH_NOARGS }, 309 { "obufcount", (PyCFunction)sad_obufcount, METH_NOARGS }, 310 310 #define CTL_METHODS 4 311 { "getinfo",(PyCFunction)sad_getinfo, METH_NOARGS },312 { "setinfo",(PyCFunction)sad_setinfo, METH_O},313 { "drain",(PyCFunction)sad_drain, METH_NOARGS },314 { "flush",(PyCFunction)sad_flush, METH_NOARGS },311 { "getinfo", (PyCFunction)sad_getinfo, METH_NOARGS }, 312 { "setinfo", (PyCFunction)sad_setinfo, METH_O}, 313 { "drain", (PyCFunction)sad_drain, METH_NOARGS }, 314 { "flush", (PyCFunction)sad_flush, METH_NOARGS }, 315 315 #ifdef SOLARIS 316 { "getdev",(PyCFunction)sad_getdev, METH_NOARGS },317 #endif 318 { "close",(PyCFunction)sad_close, METH_NOARGS },319 320 {NULL, NULL}/* sentinel */316 { "getdev", (PyCFunction)sad_getdev, METH_NOARGS }, 317 #endif 318 { "close", (PyCFunction)sad_close, METH_NOARGS }, 319 { "fileno", (PyCFunction)sad_fileno, METH_NOARGS }, 320 {NULL, NULL} /* sentinel */ 321 321 }; 322 322 … … 324 324 sad_getattr(sadobject *xp, char *name) 325 325 { 326 327 328 329 330 326 if (xp->x_isctl) 327 return Py_FindMethod(sad_methods+CTL_METHODS, 328 (PyObject *)xp, name); 329 else 330 return Py_FindMethod(sad_methods, (PyObject *)xp, name); 331 331 } 332 332 … … 335 335 static sadstatusobject * 336 336 sads_alloc(void) { 337 337 return PyObject_New(sadstatusobject, &Sadstatustype); 338 338 } 339 339 … … 341 341 sads_dealloc(sadstatusobject *xp) 342 342 { 343 343 PyMem_DEL(xp); 344 344 } 345 345 346 346 #define OFF(x) offsetof(audio_info_t,x) 347 347 static struct memberlist sads_ml[] = { 348 { "i_sample_rate", T_UINT,OFF(record.sample_rate) },349 { "i_channels", T_UINT,OFF(record.channels) },350 { "i_precision", T_UINT,OFF(record.precision) },351 { "i_encoding", T_UINT,OFF(record.encoding) },352 { "i_gain", T_UINT,OFF(record.gain) },353 { "i_port", T_UINT,OFF(record.port) },354 { "i_samples", T_UINT,OFF(record.samples) },355 { "i_eof", T_UINT,OFF(record.eof) },356 { "i_pause", T_UBYTE,OFF(record.pause) },357 { "i_error", T_UBYTE,OFF(record.error) },358 { "i_waiting", T_UBYTE,OFF(record.waiting) },359 { "i_open", T_UBYTE, OFF(record.open) ,RO},360 { "i_active", T_UBYTE, OFF(record.active) ,RO},348 { "i_sample_rate", T_UINT, OFF(record.sample_rate) }, 349 { "i_channels", T_UINT, OFF(record.channels) }, 350 { "i_precision", T_UINT, OFF(record.precision) }, 351 { "i_encoding", T_UINT, OFF(record.encoding) }, 352 { "i_gain", T_UINT, OFF(record.gain) }, 353 { "i_port", T_UINT, OFF(record.port) }, 354 { "i_samples", T_UINT, OFF(record.samples) }, 355 { "i_eof", T_UINT, OFF(record.eof) }, 356 { "i_pause", T_UBYTE, OFF(record.pause) }, 357 { "i_error", T_UBYTE, OFF(record.error) }, 358 { "i_waiting", T_UBYTE, OFF(record.waiting) }, 359 { "i_open", T_UBYTE, OFF(record.open) , RO}, 360 { "i_active", T_UBYTE, OFF(record.active) , RO}, 361 361 #ifdef SOLARIS 362 { "i_buffer_size", T_UINT,OFF(record.buffer_size) },363 { "i_balance", T_UBYTE,OFF(record.balance) },364 { "i_avail_ports", T_UINT,OFF(record.avail_ports) },365 #endif 366 367 { "o_sample_rate", T_UINT,OFF(play.sample_rate) },368 { "o_channels", T_UINT,OFF(play.channels) },369 { "o_precision", T_UINT,OFF(play.precision) },370 { "o_encoding", T_UINT,OFF(play.encoding) },371 { "o_gain", T_UINT,OFF(play.gain) },372 { "o_port", T_UINT,OFF(play.port) },373 { "o_samples", T_UINT,OFF(play.samples) },374 { "o_eof", T_UINT,OFF(play.eof) },375 { "o_pause", T_UBYTE,OFF(play.pause) },376 { "o_error", T_UBYTE,OFF(play.error) },377 { "o_waiting", T_UBYTE,OFF(play.waiting) },378 { "o_open", T_UBYTE, OFF(play.open) ,RO},379 { "o_active", T_UBYTE, OFF(play.active) ,RO},362 { "i_buffer_size", T_UINT, OFF(record.buffer_size) }, 363 { "i_balance", T_UBYTE, OFF(record.balance) }, 364 { "i_avail_ports", T_UINT, OFF(record.avail_ports) }, 365 #endif 366 367 { "o_sample_rate", T_UINT, OFF(play.sample_rate) }, 368 { "o_channels", T_UINT, OFF(play.channels) }, 369 { "o_precision", T_UINT, OFF(play.precision) }, 370 { "o_encoding", T_UINT, OFF(play.encoding) }, 371 { "o_gain", T_UINT, OFF(play.gain) }, 372 { "o_port", T_UINT, OFF(play.port) }, 373 { "o_samples", T_UINT, OFF(play.samples) }, 374 { "o_eof", T_UINT, OFF(play.eof) }, 375 { "o_pause", T_UBYTE, OFF(play.pause) }, 376 { "o_error", T_UBYTE, OFF(play.error) }, 377 { "o_waiting", T_UBYTE, OFF(play.waiting) }, 378 { "o_open", T_UBYTE, OFF(play.open) , RO}, 379 { "o_active", T_UBYTE, OFF(play.active) , RO}, 380 380 #ifdef SOLARIS 381 { "o_buffer_size", T_UINT,OFF(play.buffer_size) },382 { "o_balance", T_UBYTE,OFF(play.balance) },383 { "o_avail_ports", T_UINT,OFF(play.avail_ports) },384 #endif 385 386 { "monitor_gain", T_UINT,OFF(monitor_gain) },387 381 { "o_buffer_size", T_UINT, OFF(play.buffer_size) }, 382 { "o_balance", T_UBYTE, OFF(play.balance) }, 383 { "o_avail_ports", T_UINT, OFF(play.avail_ports) }, 384 #endif 385 386 { "monitor_gain", T_UINT, OFF(monitor_gain) }, 387 { NULL, 0, 0}, 388 388 }; 389 389 … … 391 391 sads_getattr(sadstatusobject *xp, char *name) 392 392 { 393 393 return PyMember_Get((char *)&xp->ai, sads_ml, name); 394 394 } 395 395 … … 398 398 { 399 399 400 401 402 403 404 405 400 if (v == NULL) { 401 PyErr_SetString(PyExc_TypeError, 402 "can't delete sun audio status attributes"); 403 return -1; 404 } 405 return PyMember_Set((char *)&xp->ai, sads_ml, name, v); 406 406 } 407 407 … … 410 410 411 411 static PyTypeObject Sadtype = { 412 413 "sunaudiodev.sun_audio_device",/*tp_name*/414 sizeof(sadobject),/*tp_size*/415 0,/*tp_itemsize*/416 417 (destructor)sad_dealloc,/*tp_dealloc*/418 0,/*tp_print*/419 (getattrfunc)sad_getattr,/*tp_getattr*/420 0,/*tp_setattr*/421 0,/*tp_compare*/422 0,/*tp_repr*/412 PyVarObject_HEAD_INIT(&PyType_Type, 0) 413 "sunaudiodev.sun_audio_device", /*tp_name*/ 414 sizeof(sadobject), /*tp_size*/ 415 0, /*tp_itemsize*/ 416 /* methods */ 417 (destructor)sad_dealloc, /*tp_dealloc*/ 418 0, /*tp_print*/ 419 (getattrfunc)sad_getattr, /*tp_getattr*/ 420 0, /*tp_setattr*/ 421 0, /*tp_compare*/ 422 0, /*tp_repr*/ 423 423 }; 424 424 425 425 static PyTypeObject Sadstatustype = { 426 427 428 sizeof(sadstatusobject),/*tp_size*/429 0,/*tp_itemsize*/430 431 (destructor)sads_dealloc,/*tp_dealloc*/432 0,/*tp_print*/433 (getattrfunc)sads_getattr,/*tp_getattr*/434 (setattrfunc)sads_setattr,/*tp_setattr*/435 0,/*tp_compare*/436 0,/*tp_repr*/426 PyVarObject_HEAD_INIT(&PyType_Type, 0) 427 "sunaudiodev.sun_audio_device_status", /*tp_name*/ 428 sizeof(sadstatusobject), /*tp_size*/ 429 0, /*tp_itemsize*/ 430 /* methods */ 431 (destructor)sads_dealloc, /*tp_dealloc*/ 432 0, /*tp_print*/ 433 (getattrfunc)sads_getattr, /*tp_getattr*/ 434 (setattrfunc)sads_setattr, /*tp_setattr*/ 435 0, /*tp_compare*/ 436 0, /*tp_repr*/ 437 437 }; 438 438 /* ------------------------------------------------------------------- */ … … 441 441 sadopen(PyObject *self, PyObject *args) 442 442 { 443 444 } 445 443 return (PyObject *)newsadobject(args); 444 } 445 446 446 static PyMethodDef sunaudiodev_methods[] = { 447 447 { "open", sadopen, METH_VARARGS }, … … 452 452 initsunaudiodev(void) 453 453 { 454 455 456 457 458 459 460 461 462 463 464 465 466 467 } 454 PyObject *m, *d; 455 456 if (PyErr_WarnPy3k("the sunaudiodev module has been removed in " 457 "Python 3.0", 2) < 0) 458 return; 459 460 m = Py_InitModule("sunaudiodev", sunaudiodev_methods); 461 if (m == NULL) 462 return; 463 d = PyModule_GetDict(m); 464 SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL); 465 if (SunAudioError) 466 PyDict_SetItemString(d, "error", SunAudioError); 467 }
Note:
See TracChangeset
for help on using the changeset viewer.