fork download
  1. /**
  2.  * PyAudio: Python Bindings for PortAudio.
  3.  *
  4.  * Copyright (c) 2006-2012 Hubert Pham
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person
  7.  * obtaining a copy of this software and associated documentation
  8.  * files (the "Software"), to deal in the Software without
  9.  * restriction, including without limitation the rights to use, copy,
  10.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  11.  * of the Software, and to permit persons to whom the Software is
  12.  * furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be
  15.  * included in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  21.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  22.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24.  * SOFTWARE.
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include "Python.h"
  29. #include "portaudio.h"
  30. #include "_portaudiomodule.h"
  31.  
  32.  
  33. #ifdef MACOSX
  34. #include "pa_mac_core.h"
  35. #endif
  36.  
  37. #define DEFAULT_FRAMES_PER_BUFFER 1024
  38. /* #define VERBOSE */
  39.  
  40. #define min(a,b) \
  41.   ({ __typeof__ (a) _a = (a); \
  42.   __typeof__ (b) _b = (b); \
  43.   _a < _b ? _a : _b; })
  44.  
  45. /************************************************************
  46.  *
  47.  * Table of Contents
  48.  *
  49.  * I. Exportable PortAudio Method Definitions
  50.  * II. Python Object Wrappers
  51.  * - PaDeviceInfo
  52.  * - PaHostInfo
  53.  * - PaStream
  54.  * III. PortAudio Method Implementations
  55.  * - Initialization/Termination
  56.  * - HostAPI
  57.  * - DeviceAPI
  58.  * - Stream Open/Close
  59.  * - Stream Start/Stop/Info
  60.  * - Stream Read/Write
  61.  * IV. Python Module Init
  62.  * - PaHostApiTypeId enum constants
  63.  *
  64.  ************************************************************/
  65.  
  66.  
  67. /************************************************************
  68.  *
  69.  * I. Exportable Python Methods
  70.  *
  71.  ************************************************************/
  72.  
  73. static PyMethodDef paMethods[] = {
  74.  
  75. /* version */
  76. {"get_version", pa_get_version, METH_VARARGS, "get version"},
  77. {"get_version_text", pa_get_version_text, METH_VARARGS,
  78. "get version text"},
  79.  
  80. /* inits */
  81. {"initialize", pa_initialize, METH_VARARGS, "initialize portaudio"},
  82. {"terminate", pa_terminate, METH_VARARGS, "terminate portaudio"},
  83.  
  84. /* host api */
  85. {"get_host_api_count", pa_get_host_api_count, METH_VARARGS,
  86. "get host API count"},
  87.  
  88. {"get_default_host_api", pa_get_default_host_api, METH_VARARGS,
  89. "get default host API index"},
  90.  
  91. {"host_api_type_id_to_host_api_index",
  92. pa_host_api_type_id_to_host_api_index, METH_VARARGS,
  93. "get default host API index"},
  94.  
  95. {"host_api_device_index_to_device_index",
  96. pa_host_api_device_index_to_device_index,
  97. METH_VARARGS,
  98. "get default host API index"},
  99.  
  100. {"get_host_api_info", pa_get_host_api_info, METH_VARARGS,
  101. "get host api information"},
  102.  
  103. /* device api */
  104. {"get_device_count", pa_get_device_count, METH_VARARGS,
  105. "get host API count"},
  106.  
  107. {"get_default_input_device", pa_get_default_input_device, METH_VARARGS,
  108. "get default input device index"},
  109.  
  110. {"get_default_output_device", pa_get_default_output_device, METH_VARARGS,
  111. "get default output device index"},
  112.  
  113. {"get_device_info", pa_get_device_info, METH_VARARGS,
  114. "get device information"},
  115.  
  116. /* stream open/close */
  117. {"open", (PyCFunction) pa_open, METH_VARARGS | METH_KEYWORDS,
  118. "open port audio stream"},
  119. {"close", pa_close, METH_VARARGS, "close port audio stream"},
  120. {"get_sample_size", pa_get_sample_size, METH_VARARGS,
  121. "get sample size of a format in bytes"},
  122. {"is_format_supported", (PyCFunction) pa_is_format_supported,
  123. METH_VARARGS | METH_KEYWORDS,
  124. "returns whether specified format is supported"},
  125.  
  126. /* stream start/stop */
  127. {"start_stream", pa_start_stream, METH_VARARGS, "starts port audio stream"},
  128. {"stop_stream", pa_stop_stream, METH_VARARGS, "stops port audio stream"},
  129. {"abort_stream", pa_abort_stream, METH_VARARGS, "aborts port audio stream"},
  130. {"is_stream_stopped", pa_is_stream_stopped, METH_VARARGS,
  131. "returns whether stream is stopped"},
  132. {"is_stream_active", pa_is_stream_active, METH_VARARGS,
  133. "returns whether stream is active"},
  134. {"get_stream_time", pa_get_stream_time, METH_VARARGS,
  135. "returns stream time"},
  136. {"get_stream_cpu_load", pa_get_stream_cpu_load, METH_VARARGS,
  137. "returns stream CPU load -- always 0 for blocking mode"},
  138.  
  139. /* stream read/write */
  140. {"write_stream", pa_write_stream, METH_VARARGS, "write to stream"},
  141. {"read_stream", pa_read_stream, METH_VARARGS, "read from stream"},
  142.  
  143. {"get_stream_write_available",
  144. pa_get_stream_write_available, METH_VARARGS,
  145. "get buffer available for writing"},
  146.  
  147. {"get_stream_read_available",
  148. pa_get_stream_read_available, METH_VARARGS,
  149. "get buffer available for reading"},
  150.  
  151. {NULL, NULL, 0, NULL}
  152. };
  153.  
  154.  
  155. /************************************************************
  156.  *
  157.  * II. Python Object Wrappers
  158.  *
  159.  ************************************************************/
  160.  
  161.  
  162. /*************************************************************
  163.  * PaDeviceInfo Type : Python object wrapper for PaDeviceInfo
  164.  *************************************************************/
  165.  
  166. typedef struct {
  167. PyObject_HEAD
  168. PaDeviceInfo *devInfo;
  169. } _pyAudio_paDeviceInfo;
  170.  
  171.  
  172. /* sepcific getters into the PaDeviceInfo struct */
  173.  
  174. static PyObject *
  175. _pyAudio_paDeviceInfo_get_structVersion(_pyAudio_paDeviceInfo *self,
  176. void *closure)
  177. {
  178. /* sanity check */
  179. if (!self->devInfo) {
  180. PyErr_SetString(PyExc_AttributeError,
  181. "No Device Info available");
  182. return NULL;
  183. }
  184.  
  185. return PyLong_FromLong(self->devInfo->structVersion);
  186. }
  187.  
  188. static PyObject *
  189. _pyAudio_paDeviceInfo_get_name(_pyAudio_paDeviceInfo *self,
  190. void *closure)
  191. {
  192. /* sanity check */
  193. if ((!self->devInfo) || (self->devInfo->name == NULL)) {
  194. PyErr_SetString(PyExc_AttributeError,
  195. "No Device Info available");
  196. return NULL;
  197. }
  198.  
  199. return PyBytes_FromString(self->devInfo->name);
  200. }
  201.  
  202. static PyObject *
  203. _pyAudio_paDeviceInfo_get_hostApi(_pyAudio_paDeviceInfo *self,
  204. void *closure)
  205. {
  206. /* sanity check */
  207. if (!self->devInfo) {
  208. PyErr_SetString(PyExc_AttributeError,
  209. "No Device Info available");
  210. return NULL;
  211. }
  212.  
  213. return PyLong_FromLong(self->devInfo->hostApi);
  214. }
  215.  
  216. static PyObject *
  217. _pyAudio_paDeviceInfo_get_maxInputChannels(_pyAudio_paDeviceInfo *self,
  218. void *closure)
  219. {
  220. /* sanity check */
  221. if (!self->devInfo) {
  222. PyErr_SetString(PyExc_AttributeError,
  223. "No Device Info available");
  224. return NULL;
  225. }
  226.  
  227. return PyLong_FromLong(self->devInfo->maxInputChannels);
  228. }
  229.  
  230. static PyObject *
  231. _pyAudio_paDeviceInfo_get_maxOutputChannels(_pyAudio_paDeviceInfo *self,
  232. void *closure)
  233. {
  234. /* sanity check */
  235. if (!self->devInfo) {
  236. PyErr_SetString(PyExc_AttributeError,
  237. "No Device Info available");
  238. return NULL;
  239. }
  240.  
  241. return PyLong_FromLong(self->devInfo->maxOutputChannels);
  242. }
  243.  
  244. static PyObject *
  245. _pyAudio_paDeviceInfo_get_defaultLowInputLatency(_pyAudio_paDeviceInfo *self,
  246. void *closure)
  247. {
  248. /* sanity check */
  249. if (!self->devInfo) {
  250. PyErr_SetString(PyExc_AttributeError,
  251. "No Device Info available");
  252. return NULL;
  253. }
  254.  
  255. return PyFloat_FromDouble(self->devInfo->defaultLowInputLatency);
  256. }
  257.  
  258. static PyObject *
  259. _pyAudio_paDeviceInfo_get_defaultLowOutputLatency(_pyAudio_paDeviceInfo *self,
  260. void *closure)
  261. {
  262. /* sanity check */
  263. if (!self->devInfo) {
  264. PyErr_SetString(PyExc_AttributeError,
  265. "No Device Info available");
  266. return NULL;
  267. }
  268.  
  269. return PyFloat_FromDouble(self->devInfo->defaultLowOutputLatency);
  270. }
  271.  
  272.  
  273. static PyObject *
  274. _pyAudio_paDeviceInfo_get_defaultHighInputLatency(_pyAudio_paDeviceInfo *self,
  275. void *closure)
  276. {
  277. /* sanity check */
  278. if (!self->devInfo) {
  279. PyErr_SetString(PyExc_AttributeError,
  280. "No Device Info available");
  281. return NULL;
  282. }
  283.  
  284. return PyFloat_FromDouble(self->devInfo->defaultHighInputLatency);
  285. }
  286.  
  287. static PyObject *
  288. _pyAudio_paDeviceInfo_get_defaultHighOutputLatency(_pyAudio_paDeviceInfo *self,
  289. void *closure)
  290. {
  291. /* sanity check */
  292. if (!self->devInfo) {
  293. PyErr_SetString(PyExc_AttributeError,
  294. "No Device Info available");
  295. return NULL;
  296. }
  297.  
  298. return PyFloat_FromDouble(self->devInfo->defaultHighOutputLatency);
  299. }
  300.  
  301. static PyObject *
  302. _pyAudio_paDeviceInfo_get_defaultSampleRate(_pyAudio_paDeviceInfo *self,
  303. void *closure)
  304. {
  305. /* sanity check */
  306. if (!self->devInfo) {
  307. PyErr_SetString(PyExc_AttributeError,
  308. "No Device Info available");
  309. return NULL;
  310. }
  311.  
  312. return PyFloat_FromDouble(self->devInfo->defaultSampleRate);
  313. }
  314.  
  315.  
  316.  
  317. static int
  318. _pyAudio_paDeviceInfo_antiset(_pyAudio_paDeviceInfo *self,
  319. PyObject *value,
  320. void *closure)
  321. {
  322. /* read-only: do not allow users to change values */
  323. PyErr_SetString(PyExc_AttributeError,
  324. "Fields read-only: cannot modify values");
  325. return -1;
  326. }
  327.  
  328. static PyGetSetDef _pyAudio_paDeviceInfo_getseters[] = {
  329. {"name",
  330. (getter) _pyAudio_paDeviceInfo_get_name,
  331. (setter) _pyAudio_paDeviceInfo_antiset,
  332. "device name",
  333. NULL},
  334.  
  335. {"structVersion",
  336. (getter) _pyAudio_paDeviceInfo_get_structVersion,
  337. (setter) _pyAudio_paDeviceInfo_antiset,
  338. "struct version",
  339. NULL},
  340.  
  341. {"hostApi",
  342. (getter) _pyAudio_paDeviceInfo_get_hostApi,
  343. (setter) _pyAudio_paDeviceInfo_antiset,
  344. "host api index",
  345. NULL},
  346.  
  347. {"maxInputChannels",
  348. (getter) _pyAudio_paDeviceInfo_get_maxInputChannels,
  349. (setter) _pyAudio_paDeviceInfo_antiset,
  350. "max input channels",
  351. NULL},
  352.  
  353. {"maxOutputChannels",
  354. (getter) _pyAudio_paDeviceInfo_get_maxOutputChannels,
  355. (setter) _pyAudio_paDeviceInfo_antiset,
  356. "max output channels",
  357. NULL},
  358.  
  359. {"defaultLowInputLatency",
  360. (getter) _pyAudio_paDeviceInfo_get_defaultLowInputLatency,
  361. (setter) _pyAudio_paDeviceInfo_antiset,
  362. "default low input latency",
  363. NULL},
  364.  
  365. {"defaultLowOutputLatency",
  366. (getter) _pyAudio_paDeviceInfo_get_defaultLowOutputLatency,
  367. (setter) _pyAudio_paDeviceInfo_antiset,
  368. "default low output latency",
  369. NULL},
  370.  
  371. {"defaultHighInputLatency",
  372. (getter) _pyAudio_paDeviceInfo_get_defaultHighInputLatency,
  373. (setter) _pyAudio_paDeviceInfo_antiset,
  374. "default high input latency",
  375. NULL},
  376.  
  377. {"defaultHighOutputLatency",
  378. (getter) _pyAudio_paDeviceInfo_get_defaultHighOutputLatency,
  379. (setter) _pyAudio_paDeviceInfo_antiset,
  380. "default high output latency",
  381. NULL},
  382.  
  383. {"defaultSampleRate",
  384. (getter) _pyAudio_paDeviceInfo_get_defaultSampleRate,
  385. (setter) _pyAudio_paDeviceInfo_antiset,
  386. "default sample rate",
  387. NULL},
  388.  
  389. {NULL}
  390. };
  391.  
  392. static void
  393. _pyAudio_paDeviceInfo_dealloc(_pyAudio_paDeviceInfo* self)
  394. {
  395. /* reset the pointer */
  396. self->devInfo = NULL;
  397.  
  398. /* free the object */
  399. Py_TYPE(self)->tp_free((PyObject*) self);
  400. }
  401.  
  402. static PyTypeObject _pyAudio_paDeviceInfoType = {
  403. PyVarObject_HEAD_INIT(NULL, 0)
  404. "_portaudio.paDeviceInfo", /*tp_name*/
  405. sizeof(_pyAudio_paDeviceInfo), /*tp_basicsize*/
  406. 0, /*tp_itemsize*/
  407. (destructor) _pyAudio_paDeviceInfo_dealloc, /*tp_dealloc*/
  408. 0, /*tp_print*/
  409. 0, /*tp_getattr*/
  410. 0, /*tp_setattr*/
  411. 0, /*tp_compare*/
  412. 0, /*tp_repr*/
  413. 0, /*tp_as_number*/
  414. 0, /*tp_as_sequence*/
  415. 0, /*tp_as_mapping*/
  416. 0, /*tp_hash */
  417. 0, /*tp_call*/
  418. 0, /*tp_str*/
  419. 0, /*tp_getattro*/
  420. 0, /*tp_setattro*/
  421. 0, /*tp_as_buffer*/
  422. Py_TPFLAGS_DEFAULT, /*tp_flags*/
  423. "Port Audio Device Info", /* tp_doc */
  424. 0, /* tp_traverse */
  425. 0, /* tp_clear */
  426. 0, /* tp_richcompare */
  427. 0, /* tp_weaklistoffset */
  428. 0, /* tp_iter */
  429. 0, /* tp_iternext */
  430. 0, /* tp_methods */
  431. 0, /* tp_members */
  432. _pyAudio_paDeviceInfo_getseters, /* tp_getset */
  433. 0, /* tp_base */
  434. 0, /* tp_dict */
  435. 0, /* tp_descr_get */
  436. 0, /* tp_descr_set */
  437. 0, /* tp_dictoffset */
  438. 0, /* tp_init */
  439. 0, /* tp_alloc */
  440. 0, /* tp_new */
  441. };
  442.  
  443. static _pyAudio_paDeviceInfo *
  444. _create_paDeviceInfo_object(void)
  445. {
  446. _pyAudio_paDeviceInfo *obj;
  447.  
  448. /* don't allow subclassing? */
  449. obj = (_pyAudio_paDeviceInfo *) PyObject_New(_pyAudio_paDeviceInfo,
  450. &_pyAudio_paDeviceInfoType);
  451.  
  452. /* obj = (_pyAudio_Stream*)
  453.   _pyAudio_StreamType.tp_alloc(&_pyAudio_StreamType, 0); */
  454. return obj;
  455. }
  456.  
  457.  
  458.  
  459.  
  460. /*************************************************************
  461.  * PaHostApi Info Python Object
  462.  *************************************************************/
  463.  
  464. typedef struct {
  465. PyObject_HEAD
  466. PaHostApiInfo *apiInfo;
  467. } _pyAudio_paHostApiInfo;
  468.  
  469. /* sepcific getters into the PaDeviceInfo struct */
  470.  
  471. static PyObject *
  472. _pyAudio_paHostApiInfo_get_structVersion(_pyAudio_paHostApiInfo *self,
  473. void *closure)
  474. {
  475. /* sanity check */
  476. if ((!self->apiInfo)) {
  477. PyErr_SetString(PyExc_AttributeError,
  478. "No HostApi Info available");
  479. return NULL;
  480. }
  481.  
  482. return PyLong_FromLong(self->apiInfo->structVersion);
  483. }
  484.  
  485. static PyObject *
  486. _pyAudio_paHostApiInfo_get_type(_pyAudio_paHostApiInfo *self,
  487. void *closure)
  488. {
  489. /* sanity check */
  490. if ((!self->apiInfo)) {
  491. PyErr_SetString(PyExc_AttributeError,
  492. "No HostApi Info available");
  493. return NULL;
  494. }
  495.  
  496. return PyLong_FromLong((long) self->apiInfo->type);
  497. }
  498.  
  499. static PyObject *
  500. _pyAudio_paHostApiInfo_get_name(_pyAudio_paHostApiInfo *self,
  501. void *closure)
  502. {
  503. /* sanity check */
  504. if ((!self->apiInfo) || (self->apiInfo->name == NULL)) {
  505. PyErr_SetString(PyExc_AttributeError,
  506. "No HostApi Info available");
  507. return NULL;
  508. }
  509.  
  510. return PyUnicode_FromString(self->apiInfo->name);
  511. }
  512.  
  513. static PyObject *
  514. _pyAudio_paHostApiInfo_get_deviceCount(_pyAudio_paHostApiInfo *self,
  515. void *closure)
  516. {
  517. /* sanity check */
  518. if ((!self->apiInfo)) {
  519. PyErr_SetString(PyExc_AttributeError,
  520. "No HostApi Info available");
  521. return NULL;
  522. }
  523.  
  524. return PyLong_FromLong(self->apiInfo->deviceCount);
  525. }
  526.  
  527. static PyObject *
  528. _pyAudio_paHostApiInfo_get_defaultInputDevice(_pyAudio_paHostApiInfo *self,
  529. void *closure)
  530. {
  531. /* sanity check */
  532. if ((!self->apiInfo)) {
  533. PyErr_SetString(PyExc_AttributeError,
  534. "No HostApi Info available");
  535. return NULL;
  536. }
  537.  
  538. return PyLong_FromLong(self->apiInfo->defaultInputDevice);
  539. }
  540.  
  541. static PyObject *
  542. _pyAudio_paHostApiInfo_get_defaultOutputDevice(_pyAudio_paHostApiInfo *self,
  543. void *closure)
  544. {
  545. /* sanity check */
  546. if ((!self->apiInfo)) {
  547. PyErr_SetString(PyExc_AttributeError,
  548. "No HostApi Info available");
  549. return NULL;
  550. }
  551.  
  552. return PyLong_FromLong(self->apiInfo->defaultOutputDevice);
  553. }
  554.  
  555. static int
  556. _pyAudio_paHostApiInfo_antiset(_pyAudio_paDeviceInfo *self,
  557. PyObject *value,
  558. void *closure)
  559. {
  560. /* read-only: do not allow users to change values */
  561. PyErr_SetString(PyExc_AttributeError,
  562. "Fields read-only: cannot modify values");
  563. return -1;
  564. }
  565.  
  566. static void
  567. _pyAudio_paHostApiInfo_dealloc(_pyAudio_paHostApiInfo* self)
  568. {
  569. /* reset the pointer */
  570. self->apiInfo = NULL;
  571.  
  572. /* free the object */
  573. Py_TYPE(self)->tp_free((PyObject*) self);
  574. }
  575.  
  576. static PyGetSetDef _pyAudio_paHostApiInfo_getseters[] = {
  577. {"name",
  578. (getter) _pyAudio_paHostApiInfo_get_name,
  579. (setter) _pyAudio_paHostApiInfo_antiset,
  580. "host api name",
  581. NULL},
  582.  
  583. {"structVersion",
  584. (getter) _pyAudio_paHostApiInfo_get_structVersion,
  585. (setter) _pyAudio_paHostApiInfo_antiset,
  586. "struct version",
  587. NULL},
  588.  
  589. {"type",
  590. (getter) _pyAudio_paHostApiInfo_get_type,
  591. (setter) _pyAudio_paHostApiInfo_antiset,
  592. "host api type",
  593. NULL},
  594.  
  595. {"deviceCount",
  596. (getter) _pyAudio_paHostApiInfo_get_deviceCount,
  597. (setter) _pyAudio_paHostApiInfo_antiset,
  598. "number of devices",
  599. NULL},
  600.  
  601. {"defaultInputDevice",
  602. (getter) _pyAudio_paHostApiInfo_get_defaultInputDevice,
  603. (setter) _pyAudio_paHostApiInfo_antiset,
  604. "default input device index",
  605. NULL},
  606.  
  607. {"defaultOutputDevice",
  608. (getter) _pyAudio_paHostApiInfo_get_defaultOutputDevice,
  609. (setter) _pyAudio_paDeviceInfo_antiset,
  610. "default output device index",
  611. NULL},
  612.  
  613. {NULL}
  614. };
  615.  
  616. static PyTypeObject _pyAudio_paHostApiInfoType = {
  617. PyVarObject_HEAD_INIT(NULL, 0)
  618. "_portaudio.paHostApiInfo", /*tp_name*/
  619. sizeof(_pyAudio_paHostApiInfo), /*tp_basicsize*/
  620. 0, /*tp_itemsize*/
  621. (destructor) _pyAudio_paHostApiInfo_dealloc, /*tp_dealloc*/
  622. 0, /*tp_print*/
  623. 0, /*tp_getattr*/
  624. 0, /*tp_setattr*/
  625. 0, /*tp_compare*/
  626. 0, /*tp_repr*/
  627. 0, /*tp_as_number*/
  628. 0, /*tp_as_sequence*/
  629. 0, /*tp_as_mapping*/
  630. 0, /*tp_hash */
  631. 0, /*tp_call*/
  632. 0, /*tp_str*/
  633. 0, /*tp_getattro*/
  634. 0, /*tp_setattro*/
  635. 0, /*tp_as_buffer*/
  636. Py_TPFLAGS_DEFAULT, /*tp_flags*/
  637. "Port Audio HostApi Info", /* tp_doc */
  638. 0, /* tp_traverse */
  639. 0, /* tp_clear */
  640. 0, /* tp_richcompare */
  641. 0, /* tp_weaklistoffset */
  642. 0, /* tp_iter */
  643. 0, /* tp_iternext */
  644. 0, /* tp_methods */
  645. 0, /* tp_members */
  646. _pyAudio_paHostApiInfo_getseters, /* tp_getset */
  647. 0, /* tp_base */
  648. 0, /* tp_dict */
  649. 0, /* tp_descr_get */
  650. 0, /* tp_descr_set */
  651. 0, /* tp_dictoffset */
  652. 0, /* tp_init */
  653. 0, /* tp_alloc */
  654. 0, /* tp_new */
  655. };
  656.  
  657. static _pyAudio_paHostApiInfo *
  658. _create_paHostApiInfo_object(void)
  659. {
  660. _pyAudio_paHostApiInfo *obj;
  661.  
  662. /* don't allow subclassing? */
  663. obj = (_pyAudio_paHostApiInfo *) PyObject_New(_pyAudio_paHostApiInfo,
  664. &_pyAudio_paHostApiInfoType);
  665. return obj;
  666. }
  667.  
  668. /*************************************************************
  669.  * Host-Specific Objects
  670.  *************************************************************/
  671.  
  672. /*************************************************************
  673.  * --> Mac OS X
  674.  *************************************************************/
  675.  
  676. #ifdef MACOSX
  677. typedef struct {
  678. PyObject_HEAD
  679. PaMacCoreStreamInfo *paMacCoreStreamInfo;
  680. int flags;
  681. SInt32 *channelMap;
  682. int channelMapSize;
  683. } _pyAudio_MacOSX_hostApiSpecificStreamInfo;
  684.  
  685. typedef _pyAudio_MacOSX_hostApiSpecificStreamInfo _pyAudio_Mac_HASSI;
  686.  
  687. static void
  688. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(_pyAudio_Mac_HASSI *self)
  689. {
  690. if (self->paMacCoreStreamInfo != NULL) {
  691. free(self->paMacCoreStreamInfo);
  692. self->paMacCoreStreamInfo = NULL;
  693. }
  694.  
  695. if (self->channelMap != NULL) {
  696. free(self->channelMap);
  697. self->channelMap = NULL;
  698. }
  699.  
  700. self->flags = paMacCorePlayNice;
  701. self->channelMapSize = 0;
  702. }
  703.  
  704. static void
  705. _pyAudio_MacOSX_hostApiSpecificStreamInfo_dealloc(_pyAudio_Mac_HASSI *self)
  706. {
  707. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(self);
  708. Py_TYPE(self)->tp_free((PyObject *) self);
  709. }
  710.  
  711. static int
  712. _pyAudio_MacOSX_hostApiSpecificStreamInfo_init(PyObject *_self,
  713. PyObject *args,
  714. PyObject *kwargs)
  715. {
  716. _pyAudio_Mac_HASSI *self = (_pyAudio_Mac_HASSI *) _self;
  717. PyObject *channel_map = NULL;
  718. int flags = paMacCorePlayNice;
  719.  
  720. static char *kwlist[] = {"flags", "channel_map", NULL};
  721.  
  722. if (! PyArg_ParseTupleAndKeywords(args, kwargs, "|iO", kwlist,
  723. &flags, &channel_map)) {
  724. return -1;
  725. }
  726.  
  727. // cleanup (just in case)
  728. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(self);
  729.  
  730. if (channel_map != NULL) {
  731. // ensure channel_map is an array
  732. if (! PyTuple_Check(channel_map)) {
  733. PyErr_SetString(PyExc_ValueError, "Channel map must be a tuple");
  734. return -1;
  735. }
  736.  
  737. // generate SInt32 channelMap
  738. self->channelMapSize = (int) PyTuple_Size(channel_map);
  739.  
  740. self->channelMap = (SInt32 *) malloc(sizeof(SInt32) * self->channelMapSize);
  741.  
  742. if (self->channelMap == NULL) {
  743. PyErr_SetString(PyExc_SystemError, "Out of memory");
  744. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(self);
  745. return -1;
  746. }
  747.  
  748. PyObject *element;
  749. int i;
  750. for (i = 0; i < self->channelMapSize; ++i) {
  751. element = PyTuple_GetItem(channel_map, i);
  752. if (element == NULL) {
  753. // error condition
  754. PyErr_SetString(PyExc_ValueError,
  755. "Internal error: out of bounds index");
  756. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(self);
  757. return -1;
  758. }
  759.  
  760. // make sure element is an integer
  761. if (!PyNumber_Check(element)) {
  762. PyErr_SetString(PyExc_ValueError,
  763. "Channel Map must consist of integer elements");
  764. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(self);
  765. return -1;
  766. }
  767.  
  768. PyObject *long_element = PyNumber_Long(element);
  769.  
  770. // OK, looks good
  771. self->channelMap[i] = (SInt32) PyLong_AsLong(long_element);
  772. Py_DECREF(long_element);
  773. }
  774. }
  775.  
  776. // malloc self->paMacCoreStreamInfo
  777. self->paMacCoreStreamInfo =
  778. (PaMacCoreStreamInfo *) malloc(sizeof(PaMacCoreStreamInfo));
  779.  
  780. if (self->paMacCoreStreamInfo == NULL) {
  781. PyErr_SetString(PyExc_SystemError, "Out of memeory");
  782. _pyAudio_MacOSX_hostApiSpecificStreamInfo_cleanup(self);
  783. return -1;
  784. }
  785.  
  786. PaMacCore_SetupStreamInfo(self->paMacCoreStreamInfo, flags);
  787.  
  788. if (self->channelMap) {
  789. PaMacCore_SetupChannelMap(self->paMacCoreStreamInfo,
  790. self->channelMap,
  791. self->channelMapSize);
  792. }
  793.  
  794. self->flags = flags;
  795.  
  796. return 0;
  797. }
  798.  
  799. static PyObject *
  800. _pyAudio_MacOSX_hostApiSpecificStreamInfo_get_flags(_pyAudio_Mac_HASSI *self,
  801. void *closure)
  802. {
  803. return PyLong_FromLong(self->flags);
  804. }
  805.  
  806. static PyObject *
  807. _pyAudio_MacOSX_hostApiSpecificStreamInfo_get_channel_map(
  808. _pyAudio_Mac_HASSI *self,
  809. void *closure)
  810. {
  811. if (self->channelMap == NULL || self->channelMapSize == 0) {
  812. Py_INCREF(Py_None);
  813. return Py_None;
  814. }
  815.  
  816. int i;
  817. PyObject *channelMapTuple = PyTuple_New(self->channelMapSize);
  818. for (i = 0; i < self->channelMapSize; ++i) {
  819. PyObject *element = PyLong_FromLong(self->channelMap[i]);
  820. if (!element) {
  821. PyErr_SetString(PyExc_SystemError, "Invalid channel map");
  822. return NULL;
  823. }
  824.  
  825. if (PyTuple_SetItem(channelMapTuple,
  826. i,
  827. PyLong_FromLong(self->channelMap[i]))) {
  828. // non-zero on error
  829. PyErr_SetString(PyExc_SystemError, "Can't create channel map.");
  830. return NULL;
  831. }
  832. }
  833. return channelMapTuple;
  834. }
  835.  
  836. static int
  837. _pyAudio_MacOSX_hostApiSpecificStreamInfo_antiset(_pyAudio_Mac_HASSI *self,
  838. PyObject *value,
  839. void *closure)
  840. {
  841. /* read-only: do not allow users to change values */
  842. PyErr_SetString(PyExc_AttributeError,
  843. "Fields read-only: cannot modify values");
  844. return -1;
  845. }
  846.  
  847. static PyGetSetDef _pyAudio_MacOSX_hostApiSpecificStreamInfo_getseters[] = {
  848. {"flags",
  849. (getter) _pyAudio_MacOSX_hostApiSpecificStreamInfo_get_flags,
  850. (setter) _pyAudio_MacOSX_hostApiSpecificStreamInfo_antiset,
  851. "flags",
  852. NULL},
  853.  
  854. {"channel_map",
  855. (getter) _pyAudio_MacOSX_hostApiSpecificStreamInfo_get_channel_map,
  856. (setter) _pyAudio_MacOSX_hostApiSpecificStreamInfo_antiset,
  857. "channel map",
  858. NULL},
  859.  
  860. {NULL}
  861. };
  862.  
  863. static PyTypeObject _pyAudio_MacOSX_hostApiSpecificStreamInfoType = {
  864. PyVarObject_HEAD_INIT(NULL, 0)
  865. "_portaudio.PaMacCoreStreamInfo", /*tp_name*/
  866. sizeof(_pyAudio_MacOSX_hostApiSpecificStreamInfo), /*tp_basicsize*/
  867. 0, /*tp_itemsize*/
  868. /*tp_dealloc*/
  869. (destructor) _pyAudio_MacOSX_hostApiSpecificStreamInfo_dealloc,
  870. 0, /*tp_print*/
  871. 0, /*tp_getattr*/
  872. 0, /*tp_setattr*/
  873. 0, /*tp_compare*/
  874. 0, /*tp_repr*/
  875. 0, /*tp_as_number*/
  876. 0, /*tp_as_sequence*/
  877. 0, /*tp_as_mapping*/
  878. 0, /*tp_hash */
  879. 0, /*tp_call*/
  880. 0, /*tp_str*/
  881. 0, /*tp_getattro*/
  882. 0, /*tp_setattro*/
  883. 0, /*tp_as_buffer*/
  884. Py_TPFLAGS_DEFAULT, /*tp_flags*/
  885. "Mac OS X Specific HostAPI configuration", /* tp_doc */
  886. 0, /* tp_traverse */
  887. 0, /* tp_clear */
  888. 0, /* tp_richcompare */
  889. 0, /* tp_weaklistoffset */
  890. 0, /* tp_iter */
  891. 0, /* tp_iternext */
  892. 0, /* tp_methods */
  893. 0, /* tp_members */
  894. _pyAudio_MacOSX_hostApiSpecificStreamInfo_getseters, /* tp_getset */
  895. 0, /* tp_base */
  896. 0, /* tp_dict */
  897. 0, /* tp_descr_get */
  898. 0, /* tp_descr_set */
  899. 0, /* tp_dictoffset */
  900. (int (*)(PyObject*, PyObject*, PyObject*))_pyAudio_MacOSX_hostApiSpecificStreamInfo_init, /* tp_init */
  901. 0, /* tp_alloc */
  902. 0, /* tp_new */
  903. };
  904. #endif
  905.  
  906.  
  907. /*************************************************************
  908.  * Stream Wrapper Python Object
  909.  *************************************************************/
  910.  
  911. typedef struct {
  912. PyObject *callback;
  913. long main_thread_id;
  914. unsigned int frame_size;
  915. } PyAudioCallbackContext;
  916.  
  917. typedef struct {
  918. PyObject_HEAD
  919. PaStream *stream;
  920. PaStreamParameters *inputParameters;
  921. PaStreamParameters *outputParameters;
  922.  
  923. /* include PaStreamInfo too! */
  924. PaStreamInfo *streamInfo;
  925.  
  926. /* context for callback */
  927. PyAudioCallbackContext *callbackContext;
  928.  
  929. int is_open;
  930. } _pyAudio_Stream;
  931.  
  932. static int
  933. _is_open(_pyAudio_Stream *obj) {
  934. return (obj) && (obj->is_open);
  935. }
  936.  
  937. static void
  938. _cleanup_Stream_object(_pyAudio_Stream *streamObject)
  939. {
  940. if (streamObject->stream != NULL) {
  941. Py_BEGIN_ALLOW_THREADS
  942. Pa_CloseStream(streamObject->stream);
  943. Py_END_ALLOW_THREADS
  944. streamObject->stream = NULL;
  945. }
  946.  
  947. if (streamObject->streamInfo)
  948. streamObject->streamInfo = NULL;
  949.  
  950. if (streamObject->inputParameters != NULL) {
  951. free(streamObject->inputParameters);
  952. streamObject->inputParameters = NULL;
  953. }
  954.  
  955. if (streamObject->outputParameters != NULL) {
  956. free(streamObject->outputParameters);
  957. streamObject->outputParameters = NULL;
  958. }
  959.  
  960. if (streamObject->callbackContext != NULL) {
  961. Py_XDECREF(streamObject->callbackContext->callback);
  962. free(streamObject->callbackContext);
  963. streamObject->callbackContext = NULL;
  964. }
  965.  
  966. /* designate the stream as closed */
  967. streamObject->is_open = 0;
  968. }
  969.  
  970. static void
  971. _pyAudio_Stream_dealloc(_pyAudio_Stream* self)
  972. {
  973. /* deallocate memory if necessary */
  974. _cleanup_Stream_object(self);
  975.  
  976. /* free the object */
  977. Py_TYPE(self)->tp_free((PyObject*) self);
  978. }
  979.  
  980.  
  981. static PyObject *
  982. _pyAudio_Stream_get_structVersion(_pyAudio_Stream *self,
  983. void *closure)
  984. {
  985. /* sanity check */
  986. if (!_is_open(self)) {
  987. PyErr_SetObject(PyExc_IOError,
  988. Py_BuildValue("(s,i)",
  989. "Stream closed",
  990. paBadStreamPtr));
  991. return NULL;
  992. }
  993.  
  994. if ((!self->streamInfo)) {
  995. PyErr_SetObject(PyExc_IOError,
  996. Py_BuildValue("(s,i)",
  997. "No StreamInfo available",
  998. paBadStreamPtr));
  999. return NULL;
  1000. }
  1001.  
  1002. return PyLong_FromLong(self->streamInfo->structVersion);
  1003. }
  1004.  
  1005. static PyObject *
  1006. _pyAudio_Stream_get_inputLatency(_pyAudio_Stream *self,
  1007. void *closure)
  1008. {
  1009. /* sanity check */
  1010. if (!_is_open(self)) {
  1011. PyErr_SetObject(PyExc_IOError,
  1012. Py_BuildValue("(s,i)",
  1013. "Stream closed",
  1014. paBadStreamPtr));
  1015. return NULL;
  1016. }
  1017.  
  1018. /* sanity check */
  1019. if ((!self->streamInfo)) {
  1020. PyErr_SetObject(PyExc_IOError,
  1021. Py_BuildValue("(s,i)",
  1022. "No StreamInfo available",
  1023. paBadStreamPtr));
  1024. return NULL;
  1025. }
  1026.  
  1027. return PyFloat_FromDouble(self->streamInfo->inputLatency);
  1028. }
  1029.  
  1030. static PyObject *
  1031. _pyAudio_Stream_get_outputLatency(_pyAudio_Stream *self,
  1032. void *closure)
  1033. {
  1034. /* sanity check */
  1035. if (!_is_open(self)) {
  1036. PyErr_SetObject(PyExc_IOError,
  1037. Py_BuildValue("(s,i)",
  1038. "Stream closed",
  1039. paBadStreamPtr));
  1040. return NULL;
  1041. }
  1042.  
  1043. /* sanity check */
  1044. if ((!self->streamInfo)) {
  1045. PyErr_SetObject(PyExc_IOError,
  1046. Py_BuildValue("(s,i)",
  1047. "No StreamInfo available",
  1048. paBadStreamPtr));
  1049. return NULL;
  1050. }
  1051.  
  1052. return PyFloat_FromDouble(self->streamInfo->outputLatency);
  1053. }
  1054.  
  1055. static PyObject *
  1056. _pyAudio_Stream_get_sampleRate(_pyAudio_Stream *self,
  1057. void *closure)
  1058. {
  1059. /* sanity check */
  1060. if (!_is_open(self)) {
  1061. PyErr_SetObject(PyExc_IOError,
  1062. Py_BuildValue("(s,i)",
  1063. "Stream closed",
  1064. paBadStreamPtr));
  1065. return NULL;
  1066. }
  1067.  
  1068. /* sanity check */
  1069. if ((!self->streamInfo)) {
  1070. PyErr_SetObject(PyExc_IOError,
  1071. Py_BuildValue("(s,i)",
  1072. "No StreamInfo available",
  1073. paBadStreamPtr));
  1074. return NULL;
  1075. }
  1076.  
  1077. return PyFloat_FromDouble(self->streamInfo->sampleRate);
  1078. }
  1079.  
  1080. static int
  1081. _pyAudio_Stream_antiset(_pyAudio_Stream *self,
  1082. PyObject *value,
  1083. void *closure)
  1084. {
  1085. /* read-only: do not allow users to change values */
  1086. PyErr_SetString(PyExc_AttributeError,
  1087. "Fields read-only: cannot modify values");
  1088. return -1;
  1089. }
  1090.  
  1091. static PyGetSetDef _pyAudio_Stream_getseters[] = {
  1092. {"structVersion",
  1093. (getter) _pyAudio_Stream_get_structVersion,
  1094. (setter) _pyAudio_Stream_antiset,
  1095. "struct version",
  1096. NULL},
  1097.  
  1098. {"inputLatency",
  1099. (getter) _pyAudio_Stream_get_inputLatency,
  1100. (setter) _pyAudio_Stream_antiset,
  1101. "input latency",
  1102. NULL},
  1103.  
  1104. {"outputLatency",
  1105. (getter) _pyAudio_Stream_get_outputLatency,
  1106. (setter) _pyAudio_Stream_antiset,
  1107. "output latency",
  1108. NULL},
  1109.  
  1110. {"sampleRate",
  1111. (getter) _pyAudio_Stream_get_sampleRate,
  1112. (setter) _pyAudio_Stream_antiset,
  1113. "sample rate",
  1114. NULL},
  1115.  
  1116. {NULL}
  1117. };
  1118.  
  1119. static PyTypeObject _pyAudio_StreamType = {
  1120. PyVarObject_HEAD_INIT(NULL, 0)
  1121. "_portaudio.Stream", /*tp_name*/
  1122. sizeof(_pyAudio_Stream), /*tp_basicsize*/
  1123. 0, /*tp_itemsize*/
  1124. (destructor) _pyAudio_Stream_dealloc, /*tp_dealloc*/
  1125. 0, /*tp_print*/
  1126. 0, /*tp_getattr*/
  1127. 0, /*tp_setattr*/
  1128. 0, /*tp_compare*/
  1129. 0, /*tp_repr*/
  1130. 0, /*tp_as_number*/
  1131. 0, /*tp_as_sequence*/
  1132. 0, /*tp_as_mapping*/
  1133. 0, /*tp_hash */
  1134. 0, /*tp_call*/
  1135. 0, /*tp_str*/
  1136. 0, /*tp_getattro*/
  1137. 0, /*tp_setattro*/
  1138. 0, /*tp_as_buffer*/
  1139. Py_TPFLAGS_DEFAULT, /*tp_flags*/
  1140. "Port Audio Stream", /* tp_doc */
  1141. 0, /* tp_traverse */
  1142. 0, /* tp_clear */
  1143. 0, /* tp_richcompare */
  1144. 0, /* tp_weaklistoffset */
  1145. 0, /* tp_iter */
  1146. 0, /* tp_iternext */
  1147. 0, /* tp_methods */
  1148. 0, /* tp_members */
  1149. _pyAudio_Stream_getseters, /* tp_getset */
  1150. 0, /* tp_base */
  1151. 0, /* tp_dict */
  1152. 0, /* tp_descr_get */
  1153. 0, /* tp_descr_set */
  1154. 0, /* tp_dictoffset */
  1155. 0, /* tp_init */
  1156. 0, /* tp_alloc */
  1157. 0, /* tp_new */
  1158. };
  1159.  
  1160. static _pyAudio_Stream *
  1161. _create_Stream_object(void)
  1162. {
  1163. _pyAudio_Stream *obj;
  1164.  
  1165. /* don't allow subclassing? */
  1166. obj = (_pyAudio_Stream *) PyObject_New(_pyAudio_Stream,
  1167. &_pyAudio_StreamType);
  1168. return obj;
  1169. }
  1170.  
  1171.  
  1172. /************************************************************
  1173.  *
  1174.  * III. PortAudio Method Implementations
  1175.  *
  1176.  ************************************************************/
  1177.  
  1178. /*************************************************************
  1179.  * Version Info
  1180.  *************************************************************/
  1181.  
  1182. static PyObject *
  1183. pa_get_version(PyObject *self, PyObject *args)
  1184. {
  1185. if (!PyArg_ParseTuple(args, ""))
  1186. return NULL;
  1187.  
  1188. return PyLong_FromLong(Pa_GetVersion());
  1189. }
  1190.  
  1191. static PyObject *
  1192. pa_get_version_text(PyObject *self, PyObject *args)
  1193. {
  1194. if (!PyArg_ParseTuple(args, ""))
  1195. return NULL;
  1196.  
  1197. return PyUnicode_FromString(Pa_GetVersionText());
  1198. }
  1199.  
  1200. /*************************************************************
  1201.  * Initialization/Termination
  1202.  *************************************************************/
  1203.  
  1204. static PyObject *
  1205. pa_initialize(PyObject *self, PyObject *args)
  1206. {
  1207. int err;
  1208. err = Pa_Initialize();
  1209. if (err != paNoError) {
  1210. Pa_Terminate();
  1211. #ifdef VERBOSE
  1212. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1213. fprintf(stderr, "Error number: %d\n", err);
  1214. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  1215. #endif
  1216. PyErr_SetObject(PyExc_IOError,
  1217. Py_BuildValue("(s,i)",
  1218. Pa_GetErrorText(err), err));
  1219. return NULL;
  1220. }
  1221.  
  1222. Py_INCREF(Py_None);
  1223. return Py_None;
  1224. }
  1225.  
  1226. static PyObject *
  1227. pa_terminate(PyObject *self, PyObject *args)
  1228. {
  1229. Pa_Terminate();
  1230. Py_INCREF(Py_None);
  1231. return Py_None;
  1232. }
  1233.  
  1234. /*************************************************************
  1235.  * HostAPI
  1236.  *************************************************************/
  1237.  
  1238. static PyObject *
  1239. pa_get_host_api_count(PyObject *self, PyObject *args)
  1240. {
  1241. PaHostApiIndex count;
  1242.  
  1243. if (!PyArg_ParseTuple(args, ""))
  1244. return NULL;
  1245.  
  1246. count = Pa_GetHostApiCount();
  1247.  
  1248. if (count < 0) {
  1249.  
  1250. #ifdef VERBOSE
  1251. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1252. fprintf(stderr, "Error number: %d\n", count);
  1253. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(count));
  1254. #endif
  1255.  
  1256. PyErr_SetObject(PyExc_IOError,
  1257. Py_BuildValue("(s,i)",
  1258. Pa_GetErrorText(count), count));
  1259. return NULL;
  1260. }
  1261.  
  1262. return PyLong_FromLong(count);
  1263. }
  1264.  
  1265. static PyObject *
  1266. pa_get_default_host_api(PyObject *self, PyObject *args)
  1267. {
  1268. PaHostApiIndex index;
  1269.  
  1270. if (!PyArg_ParseTuple(args, ""))
  1271. return NULL;
  1272.  
  1273. index = Pa_GetDefaultHostApi();
  1274.  
  1275. if (index < 0) {
  1276.  
  1277. #ifdef VERBOSE
  1278. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1279. fprintf(stderr, "Error number: %d\n", index);
  1280. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(index));
  1281. #endif
  1282.  
  1283. PyErr_SetObject(PyExc_IOError,
  1284. Py_BuildValue("(s,i)",
  1285. Pa_GetErrorText(index), index));
  1286. return NULL;
  1287. }
  1288.  
  1289. return PyLong_FromLong(index);
  1290. }
  1291.  
  1292. static PyObject *
  1293. pa_host_api_type_id_to_host_api_index(PyObject *self, PyObject *args)
  1294. {
  1295. PaHostApiTypeId typeid;
  1296. PaHostApiIndex index;
  1297.  
  1298. if (!PyArg_ParseTuple(args, "i", &typeid))
  1299. return NULL;
  1300.  
  1301. index = Pa_HostApiTypeIdToHostApiIndex(typeid);
  1302.  
  1303. if (index < 0) {
  1304.  
  1305. #ifdef VERBOSE
  1306. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1307. fprintf(stderr, "Error number: %d\n", index);
  1308. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(index));
  1309. #endif
  1310.  
  1311. PyErr_SetObject(PyExc_IOError,
  1312. Py_BuildValue("(s,i)",
  1313. Pa_GetErrorText(index), index));
  1314. return NULL;
  1315. }
  1316.  
  1317. return PyLong_FromLong(index);
  1318. }
  1319.  
  1320. static PyObject *
  1321. pa_host_api_device_index_to_device_index(PyObject *self, PyObject *args)
  1322. {
  1323. PaHostApiIndex apiIndex;
  1324. int hostApiDeviceindex;
  1325. PaDeviceIndex devIndex;
  1326.  
  1327.  
  1328. if (!PyArg_ParseTuple(args, "ii", &apiIndex, &hostApiDeviceindex))
  1329. return NULL;
  1330.  
  1331. devIndex = Pa_HostApiDeviceIndexToDeviceIndex(apiIndex, hostApiDeviceindex);
  1332. if (devIndex < 0) {
  1333.  
  1334. #ifdef VERBOSE
  1335. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1336. fprintf(stderr, "Error number: %d\n", devIndex);
  1337. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(devIndex));
  1338. #endif
  1339.  
  1340. PyErr_SetObject(PyExc_IOError,
  1341. Py_BuildValue("(s,i)",
  1342. Pa_GetErrorText(devIndex), devIndex));
  1343. return NULL;
  1344. }
  1345.  
  1346. return PyLong_FromLong(devIndex);
  1347. }
  1348.  
  1349. static PyObject *
  1350. pa_get_host_api_info(PyObject *self, PyObject *args)
  1351. {
  1352. PaHostApiIndex index;
  1353. PaHostApiInfo* _info;
  1354. _pyAudio_paHostApiInfo* py_info;
  1355.  
  1356. if (!PyArg_ParseTuple(args, "i", &index))
  1357. return NULL;
  1358.  
  1359. _info = (PaHostApiInfo *) Pa_GetHostApiInfo(index);
  1360.  
  1361. if (!_info) {
  1362. PyErr_SetObject(PyExc_IOError,
  1363. Py_BuildValue("(s,i)",
  1364. "Invalid host api info",
  1365. paInvalidHostApi));
  1366. return NULL;
  1367. }
  1368.  
  1369. py_info = _create_paHostApiInfo_object();
  1370. py_info->apiInfo = _info;
  1371.  
  1372. return (PyObject *) py_info;
  1373. }
  1374.  
  1375. /*************************************************************
  1376.  * Device API
  1377.  *************************************************************/
  1378.  
  1379. static PyObject *
  1380. pa_get_device_count(PyObject *self, PyObject *args)
  1381. {
  1382. PaDeviceIndex count;
  1383.  
  1384. if (!PyArg_ParseTuple(args, ""))
  1385. return NULL;
  1386.  
  1387. count = Pa_GetDeviceCount();
  1388. if (count < 0) {
  1389.  
  1390. #ifdef VERBOSE
  1391. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1392. fprintf(stderr, "Error number: %d\n", count);
  1393. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(count));
  1394. #endif
  1395.  
  1396. PyErr_SetObject(PyExc_IOError,
  1397. Py_BuildValue("(s,i)",
  1398. Pa_GetErrorText(count), count));
  1399. return NULL;
  1400. }
  1401.  
  1402. return PyLong_FromLong(count);
  1403. }
  1404.  
  1405. static PyObject *
  1406. pa_get_default_input_device(PyObject *self, PyObject *args)
  1407. {
  1408. PaDeviceIndex index;
  1409.  
  1410. if (!PyArg_ParseTuple(args, ""))
  1411. return NULL;
  1412.  
  1413. index = Pa_GetDefaultInputDevice();
  1414. if (index == paNoDevice) {
  1415. PyErr_SetString(PyExc_IOError, "No Default Input Device Available");
  1416. return NULL;
  1417. } else if (index < 0) {
  1418.  
  1419. #ifdef VERBOSE
  1420. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1421. fprintf(stderr, "Error number: %d\n", index);
  1422. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(index));
  1423. #endif
  1424.  
  1425. PyErr_SetObject(PyExc_IOError,
  1426. Py_BuildValue("(s,i)",
  1427. Pa_GetErrorText(index), index));
  1428. return NULL;
  1429. }
  1430.  
  1431. return PyLong_FromLong(index);
  1432. }
  1433.  
  1434. static PyObject *
  1435. pa_get_default_output_device(PyObject *self, PyObject *args)
  1436. {
  1437. PaDeviceIndex index;
  1438.  
  1439. if (!PyArg_ParseTuple(args, ""))
  1440. return NULL;
  1441.  
  1442. index = Pa_GetDefaultOutputDevice();
  1443. if (index == paNoDevice) {
  1444. PyErr_SetString(PyExc_IOError, "No Default Output Device Available");
  1445. return NULL;
  1446. } else if (index < 0) {
  1447.  
  1448. #ifdef VERBOSE
  1449. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1450. fprintf(stderr, "Error number: %d\n", index);
  1451. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(index));
  1452. #endif
  1453.  
  1454. PyErr_SetObject(PyExc_IOError,
  1455. Py_BuildValue("(s,i)",
  1456. Pa_GetErrorText(index), index));
  1457. return NULL;
  1458. }
  1459.  
  1460. return PyLong_FromLong(index);
  1461. }
  1462.  
  1463. static PyObject *
  1464. pa_get_device_info(PyObject *self, PyObject *args)
  1465. {
  1466. PaDeviceIndex index;
  1467. PaDeviceInfo* _info;
  1468. _pyAudio_paDeviceInfo* py_info;
  1469.  
  1470. if (!PyArg_ParseTuple(args, "i", &index))
  1471. return NULL;
  1472.  
  1473. _info = (PaDeviceInfo *) Pa_GetDeviceInfo(index);
  1474.  
  1475. if (!_info) {
  1476. PyErr_SetObject(PyExc_IOError,
  1477. Py_BuildValue("(s,i)",
  1478. "Invalid device info", paInvalidDevice));
  1479. return NULL;
  1480. }
  1481.  
  1482. py_info = _create_paDeviceInfo_object();
  1483. py_info->devInfo = _info;
  1484. return (PyObject *) py_info;
  1485. }
  1486.  
  1487. /*************************************************************
  1488.  * Stream Open / Close / Supported
  1489.  *************************************************************/
  1490.  
  1491. int
  1492. _stream_callback_cfunction(const void *input,
  1493. void *output,
  1494. unsigned long frameCount,
  1495. const PaStreamCallbackTimeInfo *timeInfo,
  1496. PaStreamCallbackFlags statusFlags,
  1497. void *userData)
  1498. {
  1499. int return_val = paAbort;
  1500. PyGILState_STATE _state = PyGILState_Ensure();
  1501.  
  1502. #ifdef VERBOSE
  1503. if (statusFlags != 0) {
  1504. printf("Status flag set: ");
  1505. if (statusFlags & paInputUnderflow) {
  1506. printf("input underflow!\n");
  1507. }
  1508. if (statusFlags & paInputOverflow) {
  1509. printf("input overflow!\n");
  1510. }
  1511. if (statusFlags & paOutputUnderflow) {
  1512. printf("output underflow!\n");
  1513. }
  1514. if (statusFlags & paOutputUnderflow) {
  1515. printf("output overflow!\n");
  1516. }
  1517. if (statusFlags & paPrimingOutput) {
  1518. printf("priming output!\n");
  1519. }
  1520. }
  1521. #endif
  1522.  
  1523. PyAudioCallbackContext *context = (PyAudioCallbackContext *)userData;
  1524. PyObject *py_callback = context->callback;
  1525. unsigned int bytes_per_frame = context->frame_size;
  1526. long main_thread_id = context->main_thread_id;
  1527.  
  1528. PyObject *py_frame_count = PyLong_FromUnsignedLong(frameCount);
  1529. PyObject *py_time_info = Py_BuildValue("{s:d,s:d,s:d}",
  1530. "input_buffer_adc_time",
  1531. timeInfo->inputBufferAdcTime,
  1532. "current_time",
  1533. timeInfo->currentTime,
  1534. "output_buffer_dac_time",
  1535. timeInfo->outputBufferDacTime);
  1536. PyObject *py_status_flags = PyLong_FromUnsignedLong(statusFlags);
  1537. PyObject *py_input_data = Py_None;
  1538. const char *pData;
  1539. int output_len;
  1540. PyObject *py_result;
  1541.  
  1542. if (input) {
  1543. py_input_data = PyBytes_FromStringAndSize(input,
  1544. bytes_per_frame * frameCount);
  1545. }
  1546.  
  1547. py_result = PyObject_CallFunctionObjArgs(py_callback,
  1548. py_input_data,
  1549. py_frame_count,
  1550. py_time_info,
  1551. py_status_flags,
  1552. NULL);
  1553.  
  1554. if (py_result == NULL) {
  1555. #ifdef VERBOSE
  1556. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1557. fprintf(stderr, "Error message: Could not call callback function\n");
  1558. #endif
  1559. PyObject *err = PyErr_Occurred();
  1560.  
  1561. if (err) {
  1562. PyThreadState_SetAsyncExc(main_thread_id, err);
  1563.  
  1564. // Print out a stack trace to help debugging.
  1565. // TODO: make VERBOSE a runtime flag so users can control
  1566. // the amount of logging.
  1567. PyErr_Print();
  1568. }
  1569.  
  1570. goto end;
  1571. }
  1572.  
  1573.  
  1574. if (!PyArg_ParseTuple(py_result,
  1575. "z#i",
  1576. &pData,
  1577. &output_len,
  1578. &return_val)) {
  1579. #ifdef VERBOSE
  1580. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1581. fprintf(stderr, "Error message: Could not parse callback return value\n");
  1582. #endif
  1583.  
  1584. PyObject *err = PyErr_Occurred();
  1585.  
  1586. if (err) {
  1587. PyThreadState_SetAsyncExc(main_thread_id, err);
  1588.  
  1589. // Print out a stack trace to help debugging.
  1590. // TODO: make VERBOSE a runtime flag so users can control
  1591. // the amount of logging.
  1592. PyErr_Print();
  1593. }
  1594.  
  1595. Py_XDECREF(py_result);
  1596. return_val = paAbort;
  1597. goto end;
  1598. }
  1599.  
  1600. Py_DECREF(py_result);
  1601.  
  1602. if ((return_val != paComplete) &&
  1603. (return_val != paAbort) &&
  1604. (return_val != paContinue)) {
  1605. PyErr_SetString(PyExc_ValueError,
  1606. "Invalid PaStreamCallbackResult from callback");
  1607. PyThreadState_SetAsyncExc(main_thread_id, PyErr_Occurred());
  1608. PyErr_Print();
  1609.  
  1610. // Quit the callback loop
  1611. return_val = paAbort;
  1612.  
  1613. goto end;
  1614. }
  1615.  
  1616. // Copy bytes for playback only if this is an output stream:
  1617.  
  1618. if (output) {
  1619. char *output_data = (char*)output;
  1620. memcpy(output_data, pData, min(output_len, bytes_per_frame * frameCount));
  1621.  
  1622. // Pad out the rest of the buffer with 0s if callback returned
  1623. // too few frames (and assume paComplete).
  1624. if (output_len < (frameCount * bytes_per_frame)) {
  1625. memset(output_data + output_len,
  1626. 0,
  1627. (frameCount * bytes_per_frame) - output_len);
  1628. return_val = paComplete;
  1629. }
  1630. }
  1631.  
  1632. end:
  1633.  
  1634. if (input) {
  1635. // Decrement this at the end, after memcpy, in case the user
  1636. // returns py_input_data back for playback.
  1637. Py_DECREF(py_input_data);
  1638. }
  1639.  
  1640. Py_XDECREF(py_frame_count);
  1641. Py_XDECREF(py_time_info);
  1642. Py_XDECREF(py_status_flags);
  1643.  
  1644. PyGILState_Release(_state);
  1645. return return_val;
  1646. }
  1647.  
  1648. static PyObject *
  1649. pa_open(PyObject *self, PyObject *args, PyObject *kwargs)
  1650. {
  1651. int rate, channels;
  1652. int input, output, frames_per_buffer;
  1653. int input_device_index = -1;
  1654. int output_device_index = -1;
  1655. PyObject *input_device_index_arg = NULL;
  1656. PyObject *output_device_index_arg = NULL;
  1657. PyObject *stream_callback = NULL;
  1658. PaSampleFormat format;
  1659. PaError err;
  1660. PyObject *input_device_index_long;
  1661. PyObject *output_device_index_long;
  1662. PaStreamParameters *outputParameters = NULL;
  1663. PaStreamParameters *inputParameters = NULL;
  1664. PaStream *stream = NULL;
  1665. PaStreamInfo *streamInfo = NULL;
  1666. PyAudioCallbackContext *context = NULL;
  1667. _pyAudio_Stream *streamObject;
  1668.  
  1669. /* pass in rate, channel, width */
  1670. static char *kwlist[] = {"rate",
  1671. "channels",
  1672. "format",
  1673. "input",
  1674. "output",
  1675. "input_device_index",
  1676. "output_device_index",
  1677. "frames_per_buffer",
  1678. "input_host_api_specific_stream_info",
  1679. "output_host_api_specific_stream_info",
  1680. "stream_callback",
  1681. NULL};
  1682.  
  1683. #ifdef MACOSX
  1684. _pyAudio_MacOSX_hostApiSpecificStreamInfo *inputHostSpecificStreamInfo =
  1685. NULL;
  1686. _pyAudio_MacOSX_hostApiSpecificStreamInfo *outputHostSpecificStreamInfo =
  1687. NULL;
  1688. #else
  1689. /* mostly ignored...*/
  1690. PyObject *inputHostSpecificStreamInfo = NULL;
  1691. PyObject *outputHostSpecificStreamInfo = NULL;
  1692. #endif
  1693.  
  1694. /* default to neither output nor input */
  1695. input = 0;
  1696. output = 0;
  1697. frames_per_buffer = DEFAULT_FRAMES_PER_BUFFER;
  1698.  
  1699. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  1700. #ifdef MACOSX
  1701. "iik|iiOOiO!O!O",
  1702. #else
  1703. "iik|iiOOiOOO",
  1704. #endif
  1705. kwlist,
  1706. &rate, &channels, &format,
  1707. &input, &output,
  1708. &input_device_index_arg,
  1709. &output_device_index_arg,
  1710. &frames_per_buffer,
  1711. #ifdef MACOSX
  1712. &_pyAudio_MacOSX_hostApiSpecificStreamInfoType,
  1713. #endif
  1714. &inputHostSpecificStreamInfo,
  1715. #ifdef MACOSX
  1716. &_pyAudio_MacOSX_hostApiSpecificStreamInfoType,
  1717. #endif
  1718. &outputHostSpecificStreamInfo,
  1719. &stream_callback))
  1720.  
  1721. return NULL;
  1722.  
  1723. if (stream_callback && (PyCallable_Check(stream_callback) == 0)) {
  1724. PyErr_SetString(PyExc_TypeError, "stream_callback must be callable");
  1725. return NULL;
  1726. }
  1727.  
  1728. /* check to see if device indices were specified */
  1729. if ((input_device_index_arg == NULL) ||
  1730. (input_device_index_arg == Py_None)) {
  1731.  
  1732. #ifdef VERBOSE
  1733. printf("Using default input device\n");
  1734. #endif
  1735.  
  1736. input_device_index = -1;
  1737.  
  1738. } else {
  1739. // Support both Python 2 and Python 3 by using PyNumber_Check
  1740. if (!PyNumber_Check(input_device_index_arg)) {
  1741. PyErr_SetString(PyExc_ValueError,
  1742. "input_device_index must be integer (or None)");
  1743. return NULL;
  1744. }
  1745.  
  1746. input_device_index_long =
  1747. PyNumber_Long(input_device_index_arg);
  1748.  
  1749. input_device_index = (int) PyLong_AsLong(input_device_index_long);
  1750. Py_DECREF(input_device_index_long);
  1751.  
  1752. #ifdef VERBOSE
  1753. printf("Using input device index number: %d\n", input_device_index);
  1754. #endif
  1755. }
  1756.  
  1757. if ((output_device_index_arg == NULL) ||
  1758. (output_device_index_arg == Py_None)) {
  1759.  
  1760. #ifdef VERBOSE
  1761. printf("Using default output device\n");
  1762. #endif
  1763.  
  1764. output_device_index = -1;
  1765.  
  1766. } else {
  1767. // Support both Python 2 and Python 3 by using PyNumber_Check
  1768. if (!PyNumber_Check(output_device_index_arg)) {
  1769. PyErr_SetString(PyExc_ValueError,
  1770. "output_device_index must be integer (or None)");
  1771. return NULL;
  1772. }
  1773.  
  1774. output_device_index_long =
  1775. PyNumber_Long(output_device_index_arg);
  1776. output_device_index = (int) PyLong_AsLong(output_device_index_long);
  1777. Py_DECREF(output_device_index_long);
  1778.  
  1779. #ifdef VERBOSE
  1780. printf("Using output device index number: %d\n", output_device_index);
  1781. #endif
  1782. }
  1783.  
  1784. /* sanity checks */
  1785. if (input == 0 && output == 0) {
  1786. PyErr_SetString(PyExc_ValueError, "Must specify either input or output");
  1787. return NULL;
  1788. }
  1789.  
  1790. if (channels < 1) {
  1791. PyErr_SetString(PyExc_ValueError, "Invalid audio channels");
  1792. return NULL;
  1793. }
  1794.  
  1795. if (output) {
  1796. outputParameters =
  1797. (PaStreamParameters *) malloc(sizeof(PaStreamParameters));
  1798.  
  1799.  
  1800. if (output_device_index < 0)
  1801. /* default output device */
  1802. outputParameters->device = Pa_GetDefaultOutputDevice();
  1803. else
  1804. outputParameters->device = output_device_index;
  1805.  
  1806. /* final check -- ensure that there is a default device */
  1807. if (outputParameters->device < 0 ||
  1808. outputParameters->device >= Pa_GetDeviceCount()) {
  1809. free(outputParameters);
  1810. PyErr_SetObject(PyExc_IOError,
  1811. Py_BuildValue("(s,i)",
  1812. "Invalid output device "
  1813. "(no default output device)",
  1814. paInvalidDevice));
  1815. return NULL;
  1816. }
  1817.  
  1818. outputParameters->channelCount = channels;
  1819. outputParameters->sampleFormat = format;
  1820. outputParameters->suggestedLatency =
  1821. Pa_GetDeviceInfo(outputParameters->device)->defaultLowOutputLatency;
  1822. outputParameters->hostApiSpecificStreamInfo = NULL;
  1823.  
  1824. #ifdef MACOSX
  1825. if (outputHostSpecificStreamInfo) {
  1826. outputParameters->hostApiSpecificStreamInfo =
  1827. outputHostSpecificStreamInfo->paMacCoreStreamInfo;
  1828. }
  1829. #endif
  1830.  
  1831. }
  1832.  
  1833. if (input) {
  1834. inputParameters =
  1835. (PaStreamParameters *) malloc(sizeof(PaStreamParameters));
  1836.  
  1837. if (input_device_index < 0) {
  1838. /* default output device */
  1839. inputParameters->device = Pa_GetDefaultInputDevice();
  1840. } else {
  1841. inputParameters->device = input_device_index;
  1842. }
  1843.  
  1844. /* final check -- ensure that there is a default device */
  1845. if (inputParameters->device < 0) {
  1846. free(inputParameters);
  1847. PyErr_SetObject(PyExc_IOError,
  1848. Py_BuildValue("(s,i)",
  1849. "Invalid input device "
  1850. "(no default output device)",
  1851. paInvalidDevice));
  1852. return NULL;
  1853. }
  1854.  
  1855. inputParameters->channelCount = channels;
  1856. inputParameters->sampleFormat = format;
  1857. inputParameters->suggestedLatency =
  1858. Pa_GetDeviceInfo(inputParameters->device)->defaultLowInputLatency;
  1859. inputParameters->hostApiSpecificStreamInfo = NULL;
  1860.  
  1861. #ifdef MACOSX
  1862. if (inputHostSpecificStreamInfo) {
  1863. inputParameters->hostApiSpecificStreamInfo =
  1864. inputHostSpecificStreamInfo->paMacCoreStreamInfo;
  1865. }
  1866. #endif
  1867.  
  1868. }
  1869.  
  1870. // Handle callback mode:
  1871. if (stream_callback) {
  1872. Py_INCREF(stream_callback);
  1873. context = (PyAudioCallbackContext *) malloc(sizeof(PyAudioCallbackContext));
  1874. context->callback = (PyObject *) stream_callback;
  1875. context->main_thread_id = PyThreadState_Get()->thread_id;
  1876. context->frame_size = Pa_GetSampleSize(format) * channels;
  1877. }
  1878.  
  1879. err = Pa_OpenStream(&stream,
  1880. /* input/output parameters */
  1881. /* NULL values are ignored */
  1882. inputParameters,
  1883. outputParameters,
  1884. /* Samples Per Second */
  1885. rate,
  1886. /* allocate frames in the buffer */
  1887. frames_per_buffer,
  1888. /* we won't output out of range samples
  1889. so don't bother clipping them */
  1890. paClipOff,
  1891. /* callback, if specified */
  1892. (stream_callback)?(_stream_callback_cfunction):(NULL),
  1893. /* callback userData, if applicable */
  1894. context);
  1895.  
  1896. if (err != paNoError) {
  1897.  
  1898. #ifdef VERBOSE
  1899. fprintf(stderr, "An error occured while using the portaudio stream\n");
  1900. fprintf(stderr, "Error number: %d\n", err);
  1901. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  1902. #endif
  1903.  
  1904. PyErr_SetObject(PyExc_IOError,
  1905. Py_BuildValue("(s,i)",
  1906. Pa_GetErrorText(err), err));
  1907. return NULL;
  1908. }
  1909.  
  1910. streamInfo = (PaStreamInfo *) Pa_GetStreamInfo(stream);
  1911. if (!streamInfo) {
  1912. /* Pa_Terminate(); */
  1913. PyErr_SetObject(PyExc_IOError,
  1914. Py_BuildValue("(s,i)",
  1915. "Could not get stream information",
  1916. paInternalError));
  1917. return NULL;
  1918. }
  1919.  
  1920. streamObject = _create_Stream_object();
  1921. streamObject->stream = stream;
  1922. streamObject->inputParameters = inputParameters;
  1923. streamObject->outputParameters = outputParameters;
  1924. streamObject->is_open = 1;
  1925. streamObject->streamInfo = streamInfo;
  1926. streamObject->callbackContext = context;
  1927.  
  1928. return (PyObject *) streamObject;
  1929. }
  1930.  
  1931. static PyObject *
  1932. pa_close(PyObject *self, PyObject *args)
  1933. {
  1934. PyObject *stream_arg;
  1935. _pyAudio_Stream *streamObject;
  1936.  
  1937. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  1938. return NULL;
  1939.  
  1940. streamObject = (_pyAudio_Stream *) stream_arg;
  1941.  
  1942. _cleanup_Stream_object(streamObject);
  1943.  
  1944. Py_INCREF(Py_None);
  1945. return Py_None;
  1946. }
  1947.  
  1948. static PyObject *
  1949. pa_get_sample_size(PyObject *self, PyObject *args)
  1950. {
  1951. PaSampleFormat format;
  1952. int size_in_bytes;
  1953.  
  1954. if (!PyArg_ParseTuple(args, "k", &format))
  1955. return NULL;
  1956.  
  1957. size_in_bytes = Pa_GetSampleSize(format);
  1958.  
  1959. if (size_in_bytes < 0) {
  1960. PyErr_SetObject(PyExc_ValueError,
  1961. Py_BuildValue("(s,i)",
  1962. Pa_GetErrorText(size_in_bytes),
  1963. size_in_bytes));
  1964. return NULL;
  1965. }
  1966.  
  1967. return PyLong_FromLong(size_in_bytes);
  1968. }
  1969.  
  1970.  
  1971. static PyObject *
  1972. pa_is_format_supported(PyObject *self, PyObject *args,
  1973. PyObject *kwargs)
  1974. {
  1975. /* pass in rate, channel, width */
  1976. static char *kwlist[] = {
  1977. "sample_rate",
  1978. "input_device",
  1979. "input_channels",
  1980. "input_format",
  1981. "output_device",
  1982. "output_channels",
  1983. "output_format",
  1984. NULL
  1985. };
  1986.  
  1987. int input_device, input_channels;
  1988. int output_device, output_channels;
  1989. float sample_rate;
  1990. PaStreamParameters inputParams;
  1991. PaStreamParameters outputParams;
  1992. PaSampleFormat input_format, output_format;
  1993. PaError error;
  1994.  
  1995. input_device = input_channels =
  1996. output_device = output_channels = -1;
  1997.  
  1998. input_format = output_format = -1;
  1999.  
  2000. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "f|iikiik", kwlist,
  2001. &sample_rate,
  2002. &input_device,
  2003. &input_channels,
  2004. &input_format,
  2005. &output_device,
  2006. &output_channels,
  2007. &output_format))
  2008. return NULL;
  2009.  
  2010. if (!(input_device < 0)) {
  2011. inputParams.device = input_device;
  2012. inputParams.channelCount = input_channels;
  2013. inputParams.sampleFormat = input_format;
  2014. inputParams.suggestedLatency = 0;
  2015. inputParams.hostApiSpecificStreamInfo = NULL;
  2016. }
  2017.  
  2018. if (!(output_device < 0)) {
  2019. outputParams.device = output_device;
  2020. outputParams.channelCount = output_channels;
  2021. outputParams.sampleFormat = output_format;
  2022. outputParams.suggestedLatency = 0;
  2023. outputParams.hostApiSpecificStreamInfo = NULL;
  2024. }
  2025.  
  2026. error = Pa_IsFormatSupported((input_device < 0) ? NULL : &inputParams,
  2027. (output_device < 0) ? NULL : &outputParams,
  2028. sample_rate);
  2029.  
  2030. if (error == paFormatIsSupported) {
  2031. Py_INCREF(Py_True);
  2032. return Py_True;
  2033. } else {
  2034. PyErr_SetObject(PyExc_ValueError,
  2035. Py_BuildValue("(s,i)",
  2036. Pa_GetErrorText(error),
  2037. error));
  2038. return NULL;
  2039. }
  2040. }
  2041.  
  2042. /*************************************************************
  2043.  * Stream Start / Stop / Info
  2044.  *************************************************************/
  2045.  
  2046. static PyObject *
  2047. pa_start_stream(PyObject *self, PyObject *args)
  2048. {
  2049. int err;
  2050. PyObject *stream_arg;
  2051. _pyAudio_Stream *streamObject;
  2052. PaStream *stream;
  2053.  
  2054. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2055. return NULL;
  2056.  
  2057. streamObject = (_pyAudio_Stream *) stream_arg;
  2058.  
  2059. if (!_is_open(streamObject)) {
  2060. PyErr_SetObject(PyExc_IOError,
  2061. Py_BuildValue("(s,i)",
  2062. "Stream closed",
  2063. paBadStreamPtr));
  2064. return NULL;
  2065. }
  2066.  
  2067. stream = streamObject->stream;
  2068.  
  2069. if ( ((err = Pa_StartStream(stream)) != paNoError) &&
  2070. (err != paStreamIsNotStopped)) {
  2071. _cleanup_Stream_object(streamObject);
  2072.  
  2073. #ifdef VERBOSE
  2074. fprintf(stderr, "An error occured while using the portaudio stream\n");
  2075. fprintf(stderr, "Error number: %d\n", err);
  2076. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  2077. #endif
  2078.  
  2079. PyErr_SetObject(PyExc_IOError,
  2080. Py_BuildValue("(s,i)",
  2081. Pa_GetErrorText(err),
  2082. err));
  2083. return NULL;
  2084. }
  2085.  
  2086. Py_INCREF(Py_None);
  2087. return Py_None;
  2088. }
  2089.  
  2090. static PyObject *
  2091. pa_stop_stream(PyObject *self, PyObject *args)
  2092. {
  2093.  
  2094. int err;
  2095. PyObject *stream_arg;
  2096. _pyAudio_Stream *streamObject;
  2097. PaStream *stream;
  2098.  
  2099. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2100. return NULL;
  2101.  
  2102. streamObject = (_pyAudio_Stream *) stream_arg;
  2103.  
  2104. if (!_is_open(streamObject)) {
  2105. PyErr_SetString(PyExc_IOError, "Stream not open");
  2106. return NULL;
  2107. }
  2108.  
  2109. stream = streamObject->stream;
  2110.  
  2111. Py_BEGIN_ALLOW_THREADS
  2112. err = Pa_StopStream(stream);
  2113. Py_END_ALLOW_THREADS
  2114.  
  2115. if ((err != paNoError) && (err != paStreamIsStopped)) {
  2116. _cleanup_Stream_object(streamObject);
  2117.  
  2118. #ifdef VERBOSE
  2119. fprintf(stderr, "An error occured while using the portaudio stream\n");
  2120. fprintf(stderr, "Error number: %d\n", err);
  2121. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  2122. #endif
  2123.  
  2124. PyErr_SetObject(PyExc_IOError,
  2125. Py_BuildValue("(s,i)",
  2126. Pa_GetErrorText(err),
  2127. err));
  2128. return NULL;
  2129. }
  2130.  
  2131. Py_INCREF(Py_None);
  2132. return Py_None;
  2133. }
  2134.  
  2135. static PyObject *
  2136. pa_abort_stream(PyObject *self, PyObject *args)
  2137. {
  2138. int err;
  2139. PyObject *stream_arg;
  2140. _pyAudio_Stream *streamObject;
  2141. PaStream *stream;
  2142.  
  2143. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2144. return NULL;
  2145.  
  2146. streamObject = (_pyAudio_Stream *) stream_arg;
  2147.  
  2148. if (!_is_open(streamObject)) {
  2149. PyErr_SetString(PyExc_IOError, "Stream not open");
  2150. return NULL;
  2151. }
  2152.  
  2153. stream = streamObject->stream;
  2154.  
  2155. Py_BEGIN_ALLOW_THREADS
  2156. err = Pa_AbortStream(stream);
  2157. Py_END_ALLOW_THREADS
  2158.  
  2159. if ((err != paNoError) && (err != paStreamIsStopped)) {
  2160. _cleanup_Stream_object(streamObject);
  2161.  
  2162. #ifdef VERBOSE
  2163. fprintf(stderr, "An error occured while using the portaudio stream\n");
  2164. fprintf(stderr, "Error number: %d\n", err);
  2165. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  2166. #endif
  2167.  
  2168. PyErr_SetObject(PyExc_IOError,
  2169. Py_BuildValue("(s,i)",
  2170. Pa_GetErrorText(err),
  2171. err));
  2172. return NULL;
  2173. }
  2174.  
  2175. Py_INCREF(Py_None);
  2176. return Py_None;
  2177. }
  2178.  
  2179. static PyObject *
  2180. pa_is_stream_stopped(PyObject *self, PyObject *args)
  2181. {
  2182. int err;
  2183. PyObject *stream_arg;
  2184. _pyAudio_Stream *streamObject;
  2185. PaStream *stream;
  2186.  
  2187. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2188. return NULL;
  2189.  
  2190. streamObject = (_pyAudio_Stream *) stream_arg;
  2191.  
  2192. if (!_is_open(streamObject)) {
  2193. PyErr_SetObject(PyExc_IOError,
  2194. Py_BuildValue("(s,i)",
  2195. "Stream closed",
  2196. paBadStreamPtr));
  2197. return NULL;
  2198. }
  2199.  
  2200. stream = streamObject->stream;
  2201.  
  2202. if ((err = Pa_IsStreamStopped(stream)) < 0) {
  2203. _cleanup_Stream_object(streamObject);
  2204.  
  2205. #ifdef VERBOSE
  2206. fprintf(stderr, "An error occured while using the portaudio stream\n");
  2207. fprintf(stderr, "Error number: %d\n", err);
  2208. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  2209. #endif
  2210.  
  2211. PyErr_SetObject(PyExc_IOError,
  2212. Py_BuildValue("(s,i)",
  2213. Pa_GetErrorText(err),
  2214. err));
  2215. return NULL;
  2216. }
  2217.  
  2218. if (err) {
  2219. Py_INCREF(Py_True);
  2220. return Py_True;
  2221. }
  2222.  
  2223. Py_INCREF(Py_False);
  2224. return Py_False;
  2225. }
  2226.  
  2227. static PyObject *
  2228. pa_is_stream_active(PyObject *self, PyObject *args)
  2229. {
  2230.  
  2231. int err;
  2232. PyObject *stream_arg;
  2233. _pyAudio_Stream *streamObject;
  2234. PaStream *stream;
  2235.  
  2236. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2237. return NULL;
  2238.  
  2239. streamObject = (_pyAudio_Stream *) stream_arg;
  2240.  
  2241. if (!_is_open(streamObject)) {
  2242. PyErr_SetString(PyExc_IOError, "Stream not open");
  2243. return NULL;
  2244. }
  2245.  
  2246. stream = streamObject->stream;
  2247.  
  2248. if ((err = Pa_IsStreamActive(stream)) < 0) {
  2249. _cleanup_Stream_object(streamObject);
  2250.  
  2251. #ifdef VERBOSE
  2252. fprintf(stderr, "An error occured while using the portaudio stream\n");
  2253. fprintf(stderr, "Error number: %d\n", err);
  2254. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  2255. #endif
  2256.  
  2257. PyErr_SetObject(PyExc_IOError,
  2258. Py_BuildValue("(s,i)",
  2259. Pa_GetErrorText(err),
  2260. err));
  2261. return NULL;
  2262. }
  2263.  
  2264. if (err) {
  2265. Py_INCREF(Py_True);
  2266. return Py_True;
  2267. }
  2268.  
  2269. Py_INCREF(Py_False);
  2270. return Py_False;
  2271. }
  2272.  
  2273. static PyObject *
  2274. pa_get_stream_time(PyObject *self, PyObject *args)
  2275. {
  2276. double time;
  2277. PyObject *stream_arg;
  2278. _pyAudio_Stream *streamObject;
  2279. PaStream *stream;
  2280.  
  2281. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2282. return NULL;
  2283.  
  2284. streamObject = (_pyAudio_Stream *) stream_arg;
  2285.  
  2286. if (!_is_open(streamObject)) {
  2287. PyErr_SetObject(PyExc_IOError,
  2288. Py_BuildValue("(s,i)",
  2289. "Stream closed",
  2290. paBadStreamPtr));
  2291. return NULL;
  2292. }
  2293.  
  2294. stream = streamObject->stream;
  2295.  
  2296. if ((time = Pa_GetStreamTime(stream)) == 0) {
  2297. _cleanup_Stream_object(streamObject);
  2298. PyErr_SetObject(PyExc_IOError,
  2299. Py_BuildValue("(s,i)",
  2300. "Internal Error",
  2301. paInternalError));
  2302. return NULL;
  2303. }
  2304.  
  2305. return PyFloat_FromDouble(time);
  2306. }
  2307.  
  2308. static PyObject *
  2309. pa_get_stream_cpu_load(PyObject *self, PyObject *args)
  2310. {
  2311. PyObject *stream_arg;
  2312. _pyAudio_Stream *streamObject;
  2313. PaStream *stream;
  2314.  
  2315. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2316. return NULL;
  2317.  
  2318. streamObject = (_pyAudio_Stream *) stream_arg;
  2319.  
  2320. if (!_is_open(streamObject)) {
  2321. PyErr_SetObject(PyExc_IOError,
  2322. Py_BuildValue("(s,i)",
  2323. "Stream closed",
  2324. paBadStreamPtr));
  2325. return NULL;
  2326. }
  2327.  
  2328. stream = streamObject->stream;
  2329. return PyFloat_FromDouble(Pa_GetStreamCpuLoad(stream));
  2330. }
  2331.  
  2332.  
  2333. /*************************************************************
  2334.  * Stream Read/Write
  2335.  *************************************************************/
  2336.  
  2337. static PyObject *
  2338. pa_write_stream(PyObject *self, PyObject *args)
  2339. {
  2340. const char *data;
  2341. int total_size;
  2342. int total_frames;
  2343. int err;
  2344. int should_throw_exception = 0;
  2345.  
  2346. PyObject *stream_arg;
  2347. _pyAudio_Stream *streamObject;
  2348. PaStream *stream;
  2349.  
  2350. if (!PyArg_ParseTuple(args, "O!s#i|i",
  2351. &_pyAudio_StreamType,
  2352. &stream_arg,
  2353. &data,
  2354. &total_size,
  2355. &total_frames,
  2356. &should_throw_exception))
  2357. return NULL;
  2358.  
  2359. /* make sure total frames is larger than 0 */
  2360. if (total_frames < 0) {
  2361. PyErr_SetString(PyExc_ValueError,
  2362. "Invalid number of frames");
  2363. return NULL;
  2364. }
  2365.  
  2366. streamObject = (_pyAudio_Stream *) stream_arg;
  2367.  
  2368. if (!_is_open(streamObject)) {
  2369. PyErr_SetObject(PyExc_IOError,
  2370. Py_BuildValue("(s,i)",
  2371. "Stream closed",
  2372. paBadStreamPtr));
  2373. return NULL;
  2374. }
  2375.  
  2376. stream = streamObject->stream;
  2377.  
  2378. Py_BEGIN_ALLOW_THREADS
  2379. err = Pa_WriteStream(stream, data, total_frames);
  2380. Py_END_ALLOW_THREADS
  2381.  
  2382. if (err != paNoError) {
  2383. if (err == paOutputUnderflowed) {
  2384. if (should_throw_exception)
  2385. goto error;
  2386. } else
  2387. goto error;
  2388. }
  2389.  
  2390. Py_INCREF(Py_None);
  2391. return Py_None;
  2392.  
  2393. error:
  2394. /* cleanup */
  2395. _cleanup_Stream_object(streamObject);
  2396.  
  2397. #ifdef VERBOSE
  2398. fprintf(stderr, "An error occured while using the portaudio stream\n");
  2399. fprintf(stderr, "Error number: %d\n", err);
  2400. fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
  2401. #endif
  2402.  
  2403. PyErr_SetObject(PyExc_IOError,
  2404. Py_BuildValue("(s,i)",
  2405. Pa_GetErrorText(err),
  2406. err));
  2407. return NULL;
  2408. }
  2409.  
  2410. static PyObject *
  2411. pa_read_stream(PyObject *self, PyObject *args)
  2412. {
  2413. int err;
  2414. int total_frames;
  2415. short *sampleBlock;
  2416. int num_bytes;
  2417. PyObject *rv;
  2418.  
  2419. PyObject *stream_arg;
  2420. _pyAudio_Stream *streamObject;
  2421. PaStream *stream;
  2422. PaStreamParameters *inputParameters;
  2423.  
  2424. if (!PyArg_ParseTuple(args, "O!i",
  2425. &_pyAudio_StreamType,
  2426. &stream_arg,
  2427. &total_frames))
  2428. return NULL;
  2429.  
  2430. /* make sure value is positive! */
  2431. if (total_frames < 0) {
  2432. PyErr_SetString(PyExc_ValueError, "Invalid number of frames");
  2433. return NULL;
  2434. }
  2435.  
  2436. streamObject = (_pyAudio_Stream *) stream_arg;
  2437.  
  2438. if (!_is_open(streamObject)) {
  2439. PyErr_SetObject(PyExc_IOError,
  2440. Py_BuildValue("(s,i)",
  2441. "Stream closed",
  2442. paBadStreamPtr));
  2443. return NULL;
  2444. }
  2445.  
  2446. stream = streamObject->stream;
  2447. inputParameters = streamObject->inputParameters;
  2448. num_bytes = (total_frames) * (inputParameters->channelCount) *
  2449. (Pa_GetSampleSize(inputParameters->sampleFormat));
  2450.  
  2451. #ifdef VERBOSE
  2452. fprintf(stderr, "Allocating %d bytes\n", num_bytes);
  2453. #endif
  2454.  
  2455. rv = PyBytes_FromStringAndSize(NULL, num_bytes);
  2456. sampleBlock = (short *) PyBytes_AsString(rv);
  2457.  
  2458. if (sampleBlock == NULL) {
  2459. PyErr_SetObject(PyExc_IOError,
  2460. Py_BuildValue("(s,i)",
  2461. "Out of memory",
  2462. paInsufficientMemory));
  2463. return NULL;
  2464. }
  2465.  
  2466. Py_BEGIN_ALLOW_THREADS
  2467. err = Pa_ReadStream(stream, sampleBlock, total_frames);
  2468. Py_END_ALLOW_THREADS
  2469.  
  2470. if (err != paNoError) {
  2471.  
  2472. /* ignore input overflow and output underflow */
  2473. if (err & paInputOverflowed) {
  2474.  
  2475. #ifdef VERBOSE
  2476. fprintf(stderr, "Input Overflow.\n");
  2477. #endif
  2478.  
  2479. } else if (err & paOutputUnderflowed) {
  2480.  
  2481. #ifdef VERBOSE
  2482. fprintf(stderr, "Output Underflow.\n");
  2483. #endif
  2484.  
  2485. } else {
  2486. /* clean up */
  2487. _cleanup_Stream_object(streamObject);
  2488. }
  2489.  
  2490. /* free the string buffer */
  2491. Py_XDECREF(rv);
  2492.  
  2493. PyErr_SetObject(PyExc_IOError,
  2494. Py_BuildValue("(s,i)",
  2495. Pa_GetErrorText(err), err));
  2496. return NULL;
  2497. }
  2498.  
  2499. return rv;
  2500. }
  2501.  
  2502. static PyObject *
  2503. pa_get_stream_write_available(PyObject *self, PyObject *args)
  2504. {
  2505. signed long frames;
  2506. PyObject *stream_arg;
  2507. _pyAudio_Stream *streamObject;
  2508. PaStream *stream;
  2509.  
  2510. if (!PyArg_ParseTuple(args, "O!", &_pyAudio_StreamType, &stream_arg))
  2511. return NULL;
  2512.  
  2513. streamObject = (_pyAudio_Stream *) stream_arg;
  2514.  
  2515. if (!_is_open(streamObject)) {
  2516. PyErr_SetObject(PyExc_IOError,
  2517. Py_BuildValue("(s,i)",
  2518. "Stream closed",
  2519. paBadStreamPtr));
  2520. return NULL;
  2521. }
  2522.  
  2523. stream = streamObject->stream;
  2524. frames = Pa_GetStreamWriteAvailable(stream);
  2525. return PyLong_FromLong(frames);
  2526. }
  2527.  
  2528. static PyObject *
  2529. pa_get_stream_read_available(PyObject *self, PyObject *args)
  2530. {
  2531. signed long frames;
  2532.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:28:20: fatal error: Python.h: No such file or directory
 #include "Python.h"
                    ^
compilation terminated.
stdout
Standard output is empty