https://github.com/spatialaudio/python-pa-ringbuffer
:snake: Python wrapper for PortAudio's ring buffer :ring:
https://github.com/spatialaudio/python-pa-ringbuffer
Last synced: 9 months ago
JSON representation
:snake: Python wrapper for PortAudio's ring buffer :ring:
- Host: GitHub
- URL: https://github.com/spatialaudio/python-pa-ringbuffer
- Owner: spatialaudio
- License: mit
- Created: 2017-02-25T08:49:20.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2021-05-27T16:32:07.000Z (over 4 years ago)
- Last Synced: 2024-08-09T10:02:56.565Z (over 1 year ago)
- Language: Python
- Homepage:
- Size: 23.4 KB
- Stars: 7
- Watchers: 9
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
- Contributing: CONTRIBUTING.rst
- License: LICENSE
Awesome Lists containing this project
README
Python wrapper for PortAudio's ring buffer
==========================================
The `ring buffer functionality`_ is typically not included in binary
distributions of PortAudio_, therefore most Python wrappers don't include it,
either.
The ``pa_ringbuffer`` module provides only a Python wrapper, the actual
PortAudio ring buffer code has to be compiled separately, see Usage_.
It can be used on any Python version where CFFI_ is available.
This module is designed to be used together with the sounddevice_ module (it
might work with other modules, too) for non-blocking transfer of data between
the main Python program and an audio callback function which is implemented in C
or some other compiled language.
.. _PortAudio: http://portaudio.com/
.. _ring buffer functionality: http://portaudio.com/docs/v19-doxydocs-dev/
pa__ringbuffer_8h.html
.. _sounddevice: http://python-sounddevice.readthedocs.io/
.. _CFFI: http://cffi.readthedocs.io/
Usage
-----
This module is not meant to be used on its own, it is only useful in cooperation
with another Python module using CFFI.
For an example, have a look at https://github.com/spatialaudio/python-rtmixer.
You can get the Python code from PyPI_, for example in your ``setup.py`` file
(in the following example, your module would be called ``mycffimodule``):
.. code:: python
from setuptools import setup
setup(
name=...,
version=...,
author=...,
...,
cffi_modules=['mycffimodule_build.py:ffibuilder'],
setup_requires=['CFFI', 'pa_ringbuffer'],
install_requires=['pa_ringbuffer'],
...,
)
.. _PyPI: https://pypi.python.org/pypi/pa-ringbuffer
Alternatively, you can just copy the file ``src/pa_ringbuffer.py`` to your own
source directory and import it from there.
You can build your own CFFI module like described in
http://cffi.readthedocs.io/en/latest/cdef.html, just adding a few more bits to
your ``mycffimodule_build.py``:
.. code:: python
from cffi import FFI
import pa_ringbuffer
ffibuilder = FFI()
ffibuilder.cdef(pa_ringbuffer.cdef())
ffibuilder.cdef("""
/* my own declarations */
""")
ffibuilder.set_source(
'_mycffimodule',
'/* my implementation */',
sources=['portaudio/src/common/pa_ringbuffer.c'],
)
if __name__ == '__main__':
ffibuilder.compile(verbose=True)
Note that the following files must be available to the compiler:
* https://github.com/PortAudio/portaudio/blob/master/src/common/pa_ringbuffer.c
* https://github.com/PortAudio/portaudio/blob/master/src/common/pa_ringbuffer.h
* https://github.com/PortAudio/portaudio/blob/master/src/common/pa_memorybarrier.h
For your own C code, you might need some definitions from the main PortAudio
header:
* https://github.com/PortAudio/portaudio/blob/master/include/portaudio.h
Once you have compiled your extension module (with the help of CFFI), you can
use something like this in your own module to get access to the ``RingBuffer``
class:
.. code:: python
import pa_ringbuffer
from _mycffimodule import ffi, lib
RingBuffer = pa_ringbuffer.init(ffi, lib)
API Reference
-------------
There are only two functions:
``pa_ringbuffer.cdef()``
^^^^^^^^^^^^^^^^^^^^^^^^
This function returns a string containing C declarations from the file
``pa_ringbuffer.h``, which can be used as argument to CFFI's `cdef()`_ function
(see Usage_ above). Note that the returned declarations are slightly different
when called on a macOS/Darwin system.
.. _cdef(): http://cffi.readthedocs.io/en/latest/
cdef.html#ffi-ffibuilder-cdef-declaring-types-and-functions
``pa_ringbuffer.init(ffi, lib)``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This function returns the ``RingBuffer`` class which is associated with the CFFI
instance given by ``ffi`` and ``lib``.
Creating the Documentation
--------------------------
The documentation of the ``RingBuffer`` class is not available separately.
If you are using Sphinx_, you can seamlessly include the documentation of the
``RingBuffer`` class with your own documentation.
An example for this can be found at
https://github.com/spatialaudio/python-rtmixer, the generated documentation is
available at https://python-rtmixer.readthedocs.io/api.html#rtmixer.RingBuffer.
You'll need to have the autodoc_ extension activated in your ``conf.py``:
.. code:: python
extensions = [
...,
'sphinx.ext.autodoc',
...,
]
And somewhere within your module documentation, you should add this:
.. code:: rst
.. autoclass:: RingBuffer
:inherited-members:
Before that, you might have to use the currentmodule_ directive to select your
own module. Using automodule_ should also do.
If you want to use Sphinx's nitpicky_ setting,
you'll have to add a few things to ``nitpick_ignore``:
.. code:: python
nitpicky = True
nitpick_ignore = [
('py:class', 'optional'),
('py:class', 'buffer'),
('py:class', 'CData pointer'),
]
.. _Sphinx: http://www.sphinx-doc.org/
.. _autodoc: http://www.sphinx-doc.org/ext/autodoc.html
.. _currentmodule: http://www.sphinx-doc.org/domains.html
#directive-py:currentmodule
.. _automodule: http://www.sphinx-doc.org/ext/autodoc.html#directive-automodule
.. _nitpicky: https://www.sphinx-doc.org/en/master/
usage/configuration.html#confval-nitpicky