/src/pyaudio.py

https://github.com/bastibe/PyAudio · Python · 1103 lines · 588 code · 67 blank · 448 comment · 40 complexity · b17a052a21d8db2397a84ec9162c9040 MD5 · raw file

  1. # PyAudio : Python Bindings for PortAudio.
  2. # Copyright (c) 2006-2012 Hubert Pham
  3. # Permission is hereby granted, free of charge, to any person obtaining
  4. # a copy of this software and associated documentation files (the
  5. # "Software"), to deal in the Software without restriction, including
  6. # without limitation the rights to use, copy, modify, merge, publish,
  7. # distribute, sublicense, and/or sell copies of the Software, and to
  8. # permit persons to whom the Software is furnished to do so, subject to
  9. # the following conditions:
  10. # The above copyright notice and this permission notice shall be
  11. # included in all copies or substantial portions of the Software.
  12. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. """
  20. PyAudio provides Python bindings for PortAudio, the cross-platform
  21. audio I/O library. With PyAudio, you can easily use Python to play and
  22. record audio on a variety of platforms. PyAudio is inspired by:
  23. * pyPortAudio/fastaudio: Python bindings for PortAudio v18 API.
  24. * tkSnack: cross-platform sound toolkit for Tcl/Tk and Python.
  25. .. include:: ../sphinx/examples.rst
  26. Overview
  27. --------
  28. **Classes**
  29. :py:class:`PyAudio`, :py:class:`Stream`
  30. .. only:: pamac
  31. **Host Specific Classes**
  32. :py:class:`PaMacCoreStreamInfo`
  33. **Stream Conversion Convenience Functions**
  34. :py:func:`get_sample_size`, :py:func:`get_format_from_width`
  35. **PortAudio version**
  36. :py:func:`get_portaudio_version`, :py:func:`get_portaudio_version_text`
  37. .. |PaSampleFormat| replace:: :ref:`PortAudio Sample Format <PaSampleFormat>`
  38. .. _PaSampleFormat:
  39. **Portaudio Sample Formats**
  40. :py:data:`paFloat32`, :py:data:`paInt32`, :py:data:`paInt24`,
  41. :py:data:`paInt16`, :py:data:`paInt8`, :py:data:`paUInt8`,
  42. :py:data:`paCustomFormat`
  43. .. |PaHostAPI| replace:: :ref:`PortAudio Host API <PaHostAPI>`
  44. .. _PaHostAPI:
  45. **PortAudio Host APIs**
  46. :py:data:`paInDevelopment`, :py:data:`paDirectSound`, :py:data:`paMME`,
  47. :py:data:`paASIO`, :py:data:`paSoundManager`, :py:data:`paCoreAudio`,
  48. :py:data:`paOSS`, :py:data:`paALSA`, :py:data:`paAL`, :py:data:`paBeOS`,
  49. :py:data:`paWDMKS`, :py:data:`paJACK`, :py:data:`paWASAPI`,
  50. :py:data:`paNoDevice`
  51. .. |PaErrorCode| replace:: :ref:`PortAudio Error Code <PaErrorCode>`
  52. .. _PaErrorCode:
  53. **PortAudio Error Codes**
  54. :py:data:`paNoError`, :py:data:`paNotInitialized`,
  55. :py:data:`paUnanticipatedHostError`, :py:data:`paInvalidChannelCount`,
  56. :py:data:`paInvalidSampleRate`, :py:data:`paInvalidDevice`,
  57. :py:data:`paInvalidFlag`, :py:data:`paSampleFormatNotSupported`,
  58. :py:data:`paBadIODeviceCombination`, :py:data:`paInsufficientMemory`,
  59. :py:data:`paBufferTooBig`, :py:data:`paBufferTooSmall`,
  60. :py:data:`paNullCallback`, :py:data:`paBadStreamPtr`,
  61. :py:data:`paTimedOut`, :py:data:`paInternalError`,
  62. :py:data:`paDeviceUnavailable`,
  63. :py:data:`paIncompatibleHostApiSpecificStreamInfo`,
  64. :py:data:`paStreamIsStopped`, :py:data:`paStreamIsNotStopped`,
  65. :py:data:`paInputOverflowed`, :py:data:`paOutputUnderflowed`,
  66. :py:data:`paHostApiNotFound`, :py:data:`paInvalidHostApi`,
  67. :py:data:`paCanNotReadFromACallbackStream`,
  68. :py:data:`paCanNotWriteToACallbackStream`,
  69. :py:data:`paCanNotReadFromAnOutputOnlyStream`,
  70. :py:data:`paCanNotWriteToAnInputOnlyStream`,
  71. :py:data:`paIncompatibleStreamHostApi`
  72. .. |PaCallbackReturnCodes| replace:: :ref:`PortAudio Callback Return Code <PaCallbackReturnCodes>`
  73. .. _PaCallbackReturnCodes:
  74. **PortAudio Callback Return Codes**
  75. :py:data:`paContinue`, :py:data:`paComplete`, :py:data:`paAbort`
  76. .. |PaCallbackFlags| replace:: :ref:`PortAutio Callback Flag <PaCallbackFlags>`
  77. .. _PaCallbackFlags:
  78. **PortAudio Callback Flags**
  79. :py:data:`paInputUnderflow`, :py:data:`paInputOverflow`,
  80. :py:data:`paOutputUnderflow`, :py:data:`paOutputOverflow`,
  81. :py:data:`paPrimingOutput`
  82. """
  83. __author__ = "Hubert Pham"
  84. __version__ = "0.2.7"
  85. __docformat__ = "restructuredtext en"
  86. import sys
  87. # attempt to import PortAudio
  88. try:
  89. import _portaudio as pa
  90. except ImportError:
  91. print("Please build and install the PortAudio Python " +
  92. "bindings first.")
  93. sys.exit(-1)
  94. ############################################################
  95. # GLOBALS
  96. ############################################################
  97. ##### PaSampleFormat Sample Formats #####
  98. paFloat32 = pa.paFloat32 #: 32 bit float
  99. paInt32 = pa.paInt32 #: 32 bit int
  100. paInt24 = pa.paInt24 #: 24 bit int
  101. paInt16 = pa.paInt16 #: 16 bit int
  102. paInt8 = pa.paInt8 #: 8 bit int
  103. paUInt8 = pa.paUInt8 #: 8 bit unsigned int
  104. paCustomFormat = pa.paCustomFormat #: a custom data format
  105. ###### HostAPI TypeId #####
  106. paInDevelopment = pa.paInDevelopment #: Still in development
  107. paDirectSound = pa.paDirectSound #: DirectSound (Windows only)
  108. paMME = pa.paMME #: Multimedia Extension (Windows only)
  109. paASIO = pa.paASIO #: Steinberg Audio Stream Input/Output
  110. paSoundManager = pa.paSoundManager #: SoundManager (OSX only)
  111. paCoreAudio = pa.paCoreAudio #: CoreAudio (OSX only)
  112. paOSS = pa.paOSS #: Open Sound System (Linux only)
  113. paALSA = pa.paALSA #: Advanced Linux Sound Architecture (Linux only)
  114. paAL = pa.paAL #: Open Audio Library
  115. paBeOS = pa.paBeOS #: BeOS Sound System
  116. paWDMKS = pa.paWDMKS #: Windows Driver Model (Windows only)
  117. paJACK = pa.paJACK #: JACK Audio Connection Kit
  118. paWASAPI = pa.paWASAPI #: Windows Vista Audio stack architecture
  119. paNoDevice = pa.paNoDevice #: Not actually an audio device
  120. ###### portaudio error codes #####
  121. paNoError = pa.paNoError
  122. paNotInitialized = pa.paNotInitialized
  123. paUnanticipatedHostError = pa.paUnanticipatedHostError
  124. paInvalidChannelCount = pa.paInvalidChannelCount
  125. paInvalidSampleRate = pa.paInvalidSampleRate
  126. paInvalidDevice = pa.paInvalidDevice
  127. paInvalidFlag = pa.paInvalidFlag
  128. paSampleFormatNotSupported = pa.paSampleFormatNotSupported
  129. paBadIODeviceCombination = pa.paBadIODeviceCombination
  130. paInsufficientMemory = pa.paInsufficientMemory
  131. paBufferTooBig = pa.paBufferTooBig
  132. paBufferTooSmall = pa.paBufferTooSmall
  133. paNullCallback = pa.paNullCallback
  134. paBadStreamPtr = pa.paBadStreamPtr
  135. paTimedOut = pa.paTimedOut
  136. paInternalError = pa.paInternalError
  137. paDeviceUnavailable = pa.paDeviceUnavailable
  138. paIncompatibleHostApiSpecificStreamInfo = pa.paIncompatibleHostApiSpecificStreamInfo
  139. paStreamIsStopped = pa.paStreamIsStopped
  140. paStreamIsNotStopped = pa.paStreamIsNotStopped
  141. paInputOverflowed = pa.paInputOverflowed
  142. paOutputUnderflowed = pa.paOutputUnderflowed
  143. paHostApiNotFound = pa.paHostApiNotFound
  144. paInvalidHostApi = pa.paInvalidHostApi
  145. paCanNotReadFromACallbackStream = pa.paCanNotReadFromACallbackStream
  146. paCanNotWriteToACallbackStream = pa.paCanNotWriteToACallbackStream
  147. paCanNotReadFromAnOutputOnlyStream = pa.paCanNotReadFromAnOutputOnlyStream
  148. paCanNotWriteToAnInputOnlyStream = pa.paCanNotWriteToAnInputOnlyStream
  149. paIncompatibleStreamHostApi = pa.paIncompatibleStreamHostApi
  150. ###### portaudio callback return codes ######
  151. paContinue = pa.paContinue #: There is more audio data to come
  152. paComplete = pa.paComplete #: This was the last block of audio data
  153. paAbort = pa.paAbort #: An error ocurred, stop playback/recording
  154. ###### portaudio callback flags ######
  155. paInputUnderflow = pa.paInputUnderflow #: Buffer underflow in input
  156. paInputOverflow = pa.paInputOverflow #: Buffer overflow in input
  157. paOutputUnderflow = pa.paOutputUnderflow #: Buffer underflow in output
  158. paOutputOverflow = pa.paOutputOverflow #: Buffer overflow in output
  159. paPrimingOutput = pa.paPrimingOutput #: Just priming, not playing yet
  160. ############################################################
  161. # Convenience Functions
  162. ############################################################
  163. def get_sample_size(format):
  164. """
  165. Returns the size (in bytes) for the specified
  166. sample *format*.
  167. :param format: A |PaSampleFormat| constant.
  168. :raises ValueError: on invalid specified `format`.
  169. :rtype: integer
  170. """
  171. return pa.get_sample_size(format)
  172. def get_format_from_width(width, unsigned=True):
  173. """
  174. Returns a PortAudio format constant for the specified *width*.
  175. :param width: The desired sample width in bytes (1, 2, 3, or 4)
  176. :param unsigned: For 1 byte width, specifies signed or unsigned format.
  177. :raises ValueError: when invalid *width*
  178. :rtype: A |PaSampleFormat| constant
  179. """
  180. if width == 1:
  181. if unsigned:
  182. return paUInt8
  183. else:
  184. return paInt8
  185. elif width == 2:
  186. return paInt16
  187. elif width == 3:
  188. return paInt24
  189. elif width == 4:
  190. return paFloat32
  191. else:
  192. raise ValueError("Invalid width: %d" % width)
  193. ############################################################
  194. # Versioning
  195. ############################################################
  196. def get_portaudio_version():
  197. """
  198. Returns portaudio version.
  199. :rtype: string
  200. """
  201. return pa.get_version()
  202. def get_portaudio_version_text():
  203. """
  204. Returns PortAudio version as a text string.
  205. :rtype: string
  206. """
  207. return pa.get_version_text()
  208. ############################################################
  209. # Wrapper around _portaudio Stream (Internal)
  210. ############################################################
  211. # Note: See PyAudio class below for main export.
  212. class Stream:
  213. """
  214. PortAudio Stream Wrapper. Use :py:func:`PyAudio.open` to make a new
  215. :py:class:`Stream`.
  216. **Opening and Closing**
  217. :py:func:`__init__`, :py:func:`close`
  218. **Stream Info**
  219. :py:func:`get_input_latency`, :py:func:`get_output_latency`,
  220. :py:func:`get_time`, :py:func:`get_cpu_load`
  221. **Stream Management**
  222. :py:func:`start_stream`, :py:func:`stop_stream`, :py:func:`is_active`,
  223. :py:func:`is_stopped`
  224. **Input Output**
  225. :py:func:`write`, :py:func:`read`, :py:func:`get_read_available`,
  226. :py:func:`get_write_available`
  227. """
  228. def __init__(self,
  229. PA_manager,
  230. rate,
  231. channels,
  232. format,
  233. input=False,
  234. output=False,
  235. input_device_index=None,
  236. output_device_index=None,
  237. frames_per_buffer=1024,
  238. start=True,
  239. input_host_api_specific_stream_info=None,
  240. output_host_api_specific_stream_info=None,
  241. stream_callback=None):
  242. """
  243. Initialize a stream; this should be called by
  244. :py:func:`PyAudio.open`. A stream can either be input, output,
  245. or both.
  246. :param PA_manager: A reference to the managing :py:class:`PyAudio`
  247. instance
  248. :param rate: Sampling rate
  249. :param channels: Number of channels
  250. :param format: Sampling size and format. See |PaSampleFormat|.
  251. :param input: Specifies whether this is an input stream.
  252. Defaults to ``False``.
  253. :param output: Specifies whether this is an output stream.
  254. Defaults to ``False``.
  255. :param input_device_index: Index of Input Device to use.
  256. Unspecified (or ``None``) uses default device.
  257. Ignored if `input` is ``False``.
  258. :param output_device_index:
  259. Index of Output Device to use.
  260. Unspecified (or ``None``) uses the default device.
  261. Ignored if `output` is ``False``.
  262. :param frames_per_buffer: Specifies the number of frames per buffer.
  263. :param start: Start the stream running immediately.
  264. Defaults to ``True``. In general, there is no reason to set
  265. this to ``False``.
  266. :param input_host_api_specific_stream_info: Specifies a host API
  267. specific stream information data structure for input.
  268. .. only:: pamac
  269. See :py:class:`PaMacCoreStreamInfo`.
  270. :param output_host_api_specific_stream_info: Specifies a host API
  271. specific stream information data structure for output.
  272. .. only:: pamac
  273. See :py:class:`PaMacCoreStreamInfo`.
  274. :param stream_callback: Specifies a callback function for
  275. *non-blocking* (callback) operation. Default is
  276. ``None``, which indicates *blocking* operation (i.e.,
  277. :py:func:`Stream.read` and :py:func:`Stream.write`). To use
  278. non-blocking operation, specify a callback that conforms
  279. to the following signature:
  280. .. code-block:: python
  281. callback(in_data, # recorded data if input=True; else None
  282. frame_count, # number of frames
  283. time_info, # dictionary
  284. status_flags) # PaCallbackFlags
  285. ``time_info`` is a dictionary with the following keys:
  286. ``input_buffer_adc_time``, ``current_time``, and
  287. ``output_buffer_dac_time``; see the PortAudio
  288. documentation for their meanings. ``status_flags`` is one
  289. of |PaCallbackFlags|.
  290. The callback must return a tuple:
  291. .. code-block:: python
  292. (out_data, flag)
  293. ``out_data`` is a byte array whose length should be the
  294. (``frame_count * channels * bytes-per-channel``) if
  295. ``output=True`` or ``None`` if ``output=False``. ``flag``
  296. must be either :py:data:`paContinue`, :py:data:`paComplete` or
  297. :py:data:`paAbort` (one of |PaCallbackReturnCodes|).
  298. When ``output=True`` and ``out_data`` does not contain at
  299. least ``frame_count`` frames, :py:data:`paComplete` is
  300. assumed for ``flag``.
  301. **Note:** ``stream_callback`` is called in a separate
  302. thread (from the main thread). Exceptions that occur in
  303. the ``stream_callback`` will:
  304. 1. print a traceback on standard error to aid debugging,
  305. 2. queue the exception to be thrown (at some point) in
  306. the main thread, and
  307. 3. return `paAbort` to PortAudio to stop the stream.
  308. **Note:** Do not call :py:func:`Stream.read` or
  309. :py:func:`Stream.write` if using non-blocking operation.
  310. **See:** PortAudio's callback signature for additional
  311. details: http://portaudio.com/docs/v19-doxydocs/portaudio_8h.html#a8a60fb2a5ec9cbade3f54a9c978e2710
  312. :raise ValueError: Neither input nor output are set True.
  313. """
  314. # no stupidity allowed
  315. if not (input or output):
  316. raise ValueError("Must specify an input or output " + "stream.")
  317. # remember parent
  318. self._parent = PA_manager
  319. # remember if we are an: input, output (or both)
  320. self._is_input = input
  321. self._is_output = output
  322. # are we running?
  323. self._is_running = start
  324. # remember some parameters
  325. self._rate = rate
  326. self._channels = channels
  327. self._format = format
  328. self._frames_per_buffer = frames_per_buffer
  329. arguments = {
  330. 'rate' : rate,
  331. 'channels' : channels,
  332. 'format' : format,
  333. 'input' : input,
  334. 'output' : output,
  335. 'input_device_index' : input_device_index,
  336. 'output_device_index' : output_device_index,
  337. 'frames_per_buffer' : frames_per_buffer}
  338. if input_host_api_specific_stream_info:
  339. _l = input_host_api_specific_stream_info
  340. arguments[
  341. 'input_host_api_specific_stream_info'
  342. ] = _l._get_host_api_stream_object()
  343. if output_host_api_specific_stream_info:
  344. _l = output_host_api_specific_stream_info
  345. arguments[
  346. 'output_host_api_specific_stream_info'
  347. ] = _l._get_host_api_stream_object()
  348. if stream_callback:
  349. arguments['stream_callback'] = stream_callback
  350. # calling pa.open returns a stream object
  351. self._stream = pa.open(**arguments)
  352. self._input_latency = self._stream.inputLatency
  353. self._output_latency = self._stream.outputLatency
  354. if self._is_running:
  355. pa.start_stream(self._stream)
  356. def close(self):
  357. """ Close the stream """
  358. pa.close(self._stream)
  359. self._is_running = False
  360. self._parent._remove_stream(self)
  361. ############################################################
  362. # Stream Info
  363. ############################################################
  364. def get_input_latency(self):
  365. """
  366. Return the input latency.
  367. :rtype: float
  368. """
  369. return self._stream.inputLatency
  370. def get_output_latency(self):
  371. """
  372. Return the input latency.
  373. :rtype: float
  374. """
  375. return self._stream.outputLatency
  376. def get_time(self):
  377. """
  378. Return stream time.
  379. :rtype: float
  380. """
  381. return pa.get_stream_time(self._stream)
  382. def get_cpu_load(self):
  383. """
  384. Return the CPU load. This is always 0.0 for the
  385. blocking API.
  386. :rtype: float
  387. """
  388. return pa.get_stream_cpu_load(self._stream)
  389. ############################################################
  390. # Stream Management
  391. ############################################################
  392. def start_stream(self):
  393. """ Start the stream. """
  394. if self._is_running:
  395. return
  396. pa.start_stream(self._stream)
  397. self._is_running = True
  398. def stop_stream(self):
  399. """
  400. Stop the stream. Once the stream is stopped, one may not call
  401. write or read. Call :py:func:`start_stream` to resume the
  402. stream.
  403. """
  404. if not self._is_running:
  405. return
  406. pa.stop_stream(self._stream)
  407. self._is_running = False
  408. def is_active(self):
  409. """
  410. Returns whether the stream is active.
  411. :rtype: bool
  412. """
  413. return pa.is_stream_active(self._stream)
  414. def is_stopped(self):
  415. """
  416. Returns whether the stream is stopped.
  417. :rtype: bool
  418. """
  419. return pa.is_stream_stopped(self._stream)
  420. ############################################################
  421. # Reading/Writing
  422. ############################################################
  423. def write(self, frames, num_frames=None,
  424. exception_on_underflow=False):
  425. """
  426. Write samples to the stream. Do not call when using
  427. *non-blocking* mode.
  428. :param frames:
  429. The frames of data.
  430. :param num_frames:
  431. The number of frames to write.
  432. Defaults to None, in which this value will be
  433. automatically computed.
  434. :param exception_on_underflow:
  435. Specifies whether an exception should be thrown
  436. (or silently ignored) on buffer underflow. Defaults
  437. to False for improved performance, especially on
  438. slower platforms.
  439. :raises IOError: if the stream is not an output stream
  440. or if the write operation was unsuccessful.
  441. :rtype: `None`
  442. """
  443. if not self._is_output:
  444. raise IOError("Not output stream",
  445. paCanNotWriteToAnInputOnlyStream)
  446. if num_frames == None:
  447. # determine how many frames to read
  448. width = get_sample_size(self._format)
  449. num_frames = int(len(frames) / (self._channels * width))
  450. #print len(frames), self._channels, self._width, num_frames
  451. pa.write_stream(self._stream, frames, num_frames,
  452. exception_on_underflow)
  453. def read(self, num_frames):
  454. """
  455. Read samples from the stream. Do not call when using
  456. *non-blocking* mode.
  457. :param num_frames: The number of frames to read.
  458. :raises IOError: if stream is not an input stream
  459. or if the read operation was unsuccessful.
  460. :rtype: string
  461. """
  462. if not self._is_input:
  463. raise IOError("Not input stream",
  464. paCanNotReadFromAnOutputOnlyStream)
  465. return pa.read_stream(self._stream, num_frames)
  466. def get_read_available(self):
  467. """
  468. Return the number of frames that can be read without waiting.
  469. :rtype: integer
  470. """
  471. return pa.get_stream_read_available(self._stream)
  472. def get_write_available(self):
  473. """
  474. Return the number of frames that can be written without
  475. waiting.
  476. :rtype: integer
  477. """
  478. return pa.get_stream_write_available(self._stream)
  479. ############################################################
  480. # Main Export
  481. ############################################################
  482. class PyAudio:
  483. """
  484. Python interface to PortAudio. Provides methods to:
  485. - initialize and terminate PortAudio
  486. - open and close streams
  487. - query and inspect the available PortAudio Host APIs
  488. - query and inspect the available PortAudio audio
  489. devices
  490. Use this class to open and close streams.
  491. **Stream Management**
  492. :py:func:`open`, :py:func:`close`
  493. **Host API**
  494. :py:func:`get_host_api_count`, :py:func:`get_default_host_api_info`,
  495. :py:func:`get_host_api_info_by_type`,
  496. :py:func:`get_host_api_info_by_index`,
  497. :py:func:`get_device_info_by_host_api_device_index`
  498. **Device API**
  499. :py:func:`get_device_count`, :py:func:`is_format_supported`,
  500. :py:func:`get_default_input_device_info`,
  501. :py:func:`get_default_output_device_info`,
  502. :py:func:`get_device_info_by_index`
  503. **Stream Format Conversion**
  504. :py:func:`get_sample_size`, :py:func:`get_format_from_width`
  505. **Details**
  506. """
  507. ############################################################
  508. # Initialization and Termination
  509. ############################################################
  510. def __init__(self):
  511. """Initialize PortAudio."""
  512. pa.initialize()
  513. self._streams = set()
  514. def terminate(self):
  515. """
  516. Terminate PortAudio.
  517. :attention: Be sure to call this method for every instance of
  518. this object to release PortAudio resources.
  519. """
  520. for stream in self._streams.copy():
  521. stream.close()
  522. self._streams = set()
  523. pa.terminate()
  524. ############################################################
  525. # Stream Format
  526. ############################################################
  527. def get_sample_size(self, format):
  528. """
  529. Returns the size (in bytes) for the specified
  530. sample `format` (a |PaSampleFormat| constant).
  531. :param format: A |PaSampleFormat| constant.
  532. :raises ValueError: Invalid specified `format`.
  533. :rtype: integer
  534. """
  535. return pa.get_sample_size(format)
  536. def get_format_from_width(self, width, unsigned=True):
  537. """
  538. Returns a PortAudio format constant for the specified `width`.
  539. :param width: The desired sample width in bytes (1, 2, 3, or 4)
  540. :param unsigned: For 1 byte width, specifies signed or unsigned format.
  541. :raises ValueError: for invalid `width`
  542. :rtype: A |PaSampleFormat| constant.
  543. """
  544. if width == 1:
  545. if unsigned:
  546. return paUInt8
  547. else:
  548. return paInt8
  549. elif width == 2:
  550. return paInt16
  551. elif width == 3:
  552. return paInt24
  553. elif width == 4:
  554. return paFloat32
  555. else:
  556. raise ValueError("Invalid width: %d" % width)
  557. ############################################################
  558. # Stream Factory
  559. ############################################################
  560. def open(self, *args, **kwargs):
  561. """
  562. Open a new stream. See constructor for
  563. :py:func:`Stream.__init__` for parameter details.
  564. :returns: A new :py:class:`Stream`
  565. """
  566. stream = Stream(self, *args, **kwargs)
  567. self._streams.add(stream)
  568. return stream
  569. def close(self, stream):
  570. """
  571. Close a stream. Typically use :py:func:`Stream.close` instead.
  572. :param stream: An instance of the :py:class:`Stream` object.
  573. :raises ValueError: if stream does not exist.
  574. """
  575. if stream not in self._streams:
  576. raise ValueError("Stream `%s' not found" % str(stream))
  577. stream.close()
  578. def _remove_stream(self, stream):
  579. """
  580. Internal method. Removes a stream.
  581. :param stream: An instance of the :py:class:`Stream` object.
  582. """
  583. if stream in self._streams:
  584. self._streams.remove(stream)
  585. ############################################################
  586. # Host API Inspection
  587. ############################################################
  588. def get_host_api_count(self):
  589. """
  590. Return the number of available PortAudio Host APIs.
  591. :rtype: integer
  592. """
  593. return pa.get_host_api_count()
  594. def get_default_host_api_info(self):
  595. """
  596. Return a dictionary containing the default Host API
  597. parameters. The keys of the dictionary mirror the data fields
  598. of PortAudio's ``PaHostApiInfo`` structure.
  599. :raises IOError: if no default input device is available
  600. :rtype: dict
  601. """
  602. defaultHostApiIndex = pa.get_default_host_api()
  603. return self.get_host_api_info_by_index(defaultHostApiIndex)
  604. def get_host_api_info_by_type(self, host_api_type):
  605. """
  606. Return a dictionary containing the Host API parameters for the
  607. host API specified by the `host_api_type`. The keys of the
  608. dictionary mirror the data fields of PortAudio's ``PaHostApiInfo``
  609. structure.
  610. :param host_api_type: The desired |PaHostAPI|
  611. :raises IOError: for invalid `host_api_type`
  612. :rtype: dict
  613. """
  614. index = pa.host_api_type_id_to_host_api_index(host_api_type)
  615. return self.get_host_api_info_by_index(index)
  616. def get_host_api_info_by_index(self, host_api_index):
  617. """
  618. Return a dictionary containing the Host API parameters for the
  619. host API specified by the `host_api_index`. The keys of the
  620. dictionary mirror the data fields of PortAudio's ``PaHostApiInfo``
  621. structure.
  622. :param host_api_index: The host api index
  623. :raises IOError: for invalid `host_api_index`
  624. :rtype: dict
  625. """
  626. return self._make_host_api_dictionary(
  627. host_api_index,
  628. pa.get_host_api_info(host_api_index)
  629. )
  630. def get_device_info_by_host_api_device_index(self,
  631. host_api_index,
  632. host_api_device_index):
  633. """
  634. Return a dictionary containing the Device parameters for a
  635. given Host API's n'th device. The keys of the dictionary
  636. mirror the data fields of PortAudio's ``PaDeviceInfo`` structure.
  637. :param host_api_index: The Host API index number
  638. :param host_api_device_index: The n'th device of the host API
  639. :raises IOError: for invalid indices
  640. :rtype: dict
  641. """
  642. long_method_name = pa.host_api_device_index_to_device_index
  643. device_index = long_method_name(host_api_index,
  644. host_api_device_index)
  645. return self.get_device_info_by_index(device_index)
  646. def _make_host_api_dictionary(self, index, host_api_struct):
  647. """
  648. Internal method to create Host API dictionary that mirrors
  649. PortAudio's ``PaHostApiInfo`` structure.
  650. :rtype: dict
  651. """
  652. return {'index' : index,
  653. 'structVersion' : host_api_struct.structVersion,
  654. 'type' : host_api_struct.type,
  655. 'name' : host_api_struct.name,
  656. 'deviceCount' : host_api_struct.deviceCount,
  657. 'defaultInputDevice' : host_api_struct.defaultInputDevice,
  658. 'defaultOutputDevice' : host_api_struct.defaultOutputDevice}
  659. ############################################################
  660. # Device Inspection
  661. ############################################################
  662. def get_device_count(self):
  663. """
  664. Return the number of PortAudio Host APIs.
  665. :rtype: integer
  666. """
  667. return pa.get_device_count()
  668. def is_format_supported(self, rate,
  669. input_device=None,
  670. input_channels=None,
  671. input_format=None,
  672. output_device=None,
  673. output_channels=None,
  674. output_format=None):
  675. """
  676. Check to see if specified device configuration
  677. is supported. Returns True if the configuration
  678. is supported; throws a ValueError exception otherwise.
  679. :param rate:
  680. Specifies the desired rate (in Hz)
  681. :param input_device:
  682. The input device index. Specify ``None`` (default) for
  683. half-duplex output-only streams.
  684. :param input_channels:
  685. The desired number of input channels. Ignored if
  686. `input_device` is not specified (or ``None``).
  687. :param input_format:
  688. PortAudio sample format constant defined
  689. in this module
  690. :param output_device:
  691. The output device index. Specify ``None`` (default) for
  692. half-duplex input-only streams.
  693. :param output_channels:
  694. The desired number of output channels. Ignored if
  695. `input_device` is not specified (or ``None``).
  696. :param output_format:
  697. |PaSampleFormat| constant.
  698. :rtype: bool
  699. :raises ValueError: tuple containing (error string, |PaErrorCode|).
  700. """
  701. if input_device == None and output_device == None:
  702. raise ValueError("must specify stream format for input, " +\
  703. "output, or both", paInvalidDevice);
  704. kwargs = {}
  705. if input_device != None:
  706. kwargs['input_device'] = input_device
  707. kwargs['input_channels'] = input_channels
  708. kwargs['input_format'] = input_format
  709. if output_device != None:
  710. kwargs['output_device'] = output_device
  711. kwargs['output_channels'] = output_channels
  712. kwargs['output_format'] = output_format
  713. return pa.is_format_supported(rate, **kwargs)
  714. def get_default_input_device_info(self):
  715. """
  716. Return the default input Device parameters as a
  717. dictionary. The keys of the dictionary mirror the data fields
  718. of PortAudio's ``PaDeviceInfo`` structure.
  719. :raises IOError: No default input device available.
  720. :rtype: dict
  721. """
  722. device_index = pa.get_default_input_device()
  723. return self.get_device_info_by_index(device_index)
  724. def get_default_output_device_info(self):
  725. """
  726. Return the default output Device parameters as a
  727. dictionary. The keys of the dictionary mirror the data fields
  728. of PortAudio's ``PaDeviceInfo`` structure.
  729. :raises IOError: No default output device available.
  730. :rtype: dict
  731. """
  732. device_index = pa.get_default_output_device()
  733. return self.get_device_info_by_index(device_index)
  734. def get_device_info_by_index(self, device_index):
  735. """
  736. Return the Device parameters for device specified in
  737. `device_index` as a dictionary. The keys of the dictionary
  738. mirror the data fields of PortAudio's ``PaDeviceInfo``
  739. structure.
  740. :param device_index: The device index
  741. :raises IOError: Invalid `device_index`.
  742. :rtype: dict
  743. """
  744. return self._make_device_info_dictionary(
  745. device_index,
  746. pa.get_device_info(device_index)
  747. )
  748. def _make_device_info_dictionary(self, index, device_info):
  749. """
  750. Internal method to create Device Info dictionary that mirrors
  751. PortAudio's ``PaDeviceInfo`` structure.
  752. :rtype: dict
  753. """
  754. return {'index' : index,
  755. 'structVersion' : device_info.structVersion,
  756. 'name' : device_info.name,
  757. 'hostApi' : device_info.hostApi,
  758. 'maxInputChannels' : device_info.maxInputChannels,
  759. 'maxOutputChannels' : device_info.maxOutputChannels,
  760. 'defaultLowInputLatency' :
  761. device_info.defaultLowInputLatency,
  762. 'defaultLowOutputLatency' :
  763. device_info.defaultLowOutputLatency,
  764. 'defaultHighInputLatency' :
  765. device_info.defaultHighInputLatency,
  766. 'defaultHighOutputLatency' :
  767. device_info.defaultHighOutputLatency,
  768. 'defaultSampleRate' :
  769. device_info.defaultSampleRate
  770. }
  771. ######################################################################
  772. # Host Specific Stream Info
  773. ######################################################################
  774. try:
  775. paMacCoreStreamInfo = pa.paMacCoreStreamInfo
  776. except AttributeError:
  777. pass
  778. else:
  779. class PaMacCoreStreamInfo:
  780. """
  781. Mac OS X-only: PaMacCoreStreamInfo is a PortAudio Host API
  782. Specific Stream Info data structure for specifying Mac OS
  783. X-only settings. Instantiate this class (if desired) and pass
  784. the instance as the argument in :py:func:`PyAudio.open` to parameters
  785. ``input_host_api_specific_stream_info`` or
  786. ``output_host_api_specific_stream_info``.
  787. (See :py:func:`Stream.__init__`.)
  788. :note: Mac OS X only.
  789. .. |PaMacCoreFlags| replace:: :ref:`PortAudio Mac Core Flags <PaMacCoreFlags>`
  790. .. _PaMacCoreFlags:
  791. **PortAudio Mac Core Flags**
  792. :py:data:`paMacCoreChangeDeviceParameters`,
  793. :py:data:`paMacCoreFailIfConversionRequired`,
  794. :py:data:`paMacCoreConversionQualityMin`,
  795. :py:data:`paMacCoreConversionQualityMedium`,
  796. :py:data:`paMacCoreConversionQualityLow`,
  797. :py:data:`paMacCoreConversionQualityHigh`,
  798. :py:data:`paMacCoreConversionQualityMax`,
  799. :py:data:`paMacCorePlayNice`,
  800. :py:data:`paMacCorePro`,
  801. :py:data:`paMacCoreMinimizeCPUButPlayNice`,
  802. :py:data:`paMacCoreMinimizeCPU`
  803. **Settings**
  804. :py:func:`get_flags`, :py:func:`get_channel_map`
  805. """
  806. paMacCoreChangeDeviceParameters = pa.paMacCoreChangeDeviceParameters
  807. paMacCoreFailIfConversionRequired = pa.paMacCoreFailIfConversionRequired
  808. paMacCoreConversionQualityMin = pa.paMacCoreConversionQualityMin
  809. paMacCoreConversionQualityMedium = pa.paMacCoreConversionQualityMedium
  810. paMacCoreConversionQualityLow = pa.paMacCoreConversionQualityLow
  811. paMacCoreConversionQualityHigh = pa.paMacCoreConversionQualityHigh
  812. paMacCoreConversionQualityMax = pa.paMacCoreConversionQualityMax
  813. paMacCorePlayNice = pa.paMacCorePlayNice
  814. paMacCorePro = pa.paMacCorePro
  815. paMacCoreMinimizeCPUButPlayNice = pa.paMacCoreMinimizeCPUButPlayNice
  816. paMacCoreMinimizeCPU = pa.paMacCoreMinimizeCPU
  817. def __init__(self, flags=None, channel_map=None):
  818. """
  819. Initialize with flags and channel_map. See PortAudio
  820. documentation for more details on these parameters; they are
  821. passed almost verbatim to the PortAudio library.
  822. :param flags: |PaMacCoreFlags| OR'ed together.
  823. See :py:class:`PaMacCoreStreamInfo`.
  824. :param channel_map: An array describing the channel mapping.
  825. See PortAudio documentation for usage.
  826. """
  827. kwargs = {"flags" : flags,
  828. "channel_map" : channel_map}
  829. if flags == None:
  830. del kwargs["flags"]
  831. if channel_map == None:
  832. del kwargs["channel_map"]
  833. self._paMacCoreStreamInfo = paMacCoreStreamInfo(**kwargs)
  834. def get_flags(self):
  835. """
  836. Return the flags set at instantiation.
  837. :rtype: integer
  838. """
  839. return self._paMacCoreStreamInfo.flags
  840. def get_channel_map(self):
  841. """
  842. Return the channel map set at instantiation.
  843. :rtype: tuple or None
  844. """
  845. return self._paMacCoreStreamInfo.channel_map
  846. def _get_host_api_stream_object(self):
  847. """Private method."""
  848. return self._paMacCoreStreamInfo