Skip to content

Commit 4d41637

Browse files
committed
DOC: even more documentation
1 parent 6ad411b commit 4d41637

File tree

2 files changed

+114
-84
lines changed

2 files changed

+114
-84
lines changed

README.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Usage
2525

2626
This module is not meant to be used on its own, it is only useful in cooperation
2727
with another Python module using CFFI.
28+
For an example, have a look at https://github.com/spatialaudio/python-rtmixer.
2829

2930
You can get the Python code from PyPI_, for example in your ``setup.py`` file:
3031

@@ -113,3 +114,38 @@ when called on a macOS/Darwin system.
113114

114115
This function returns the ``RingBuffer`` class which is associated with the CFFI
115116
instance given by ``ffi`` and ``lib``.
117+
118+
Creating the Documentation
119+
--------------------------
120+
121+
The documentation of the ``RingBuffer`` class is not available separately.
122+
If you are using Sphinx_, you can seamlessly include the documentation of the
123+
``RingBuffer`` class with your own documentation.
124+
An example for this can be found at
125+
https://github.com/spatialaudio/python-rtmixer, the generated documentation is
126+
available at http://python-rtmixer.readthedocs.io/#rtmixer.RingBuffer.
127+
128+
You'll need to have the autodoc_ extension activated in your ``conf.py``:
129+
130+
.. code:: python
131+
132+
extensions = [
133+
...,
134+
'sphinx.ext.autodoc',
135+
...,
136+
]
137+
138+
And somewhere within your module documentation, you should add this:
139+
140+
.. code:: rst
141+
142+
.. autoclass:: RingBuffer
143+
:inherited-members:
144+
145+
Before that, you might have to use the currentmodule_ directive to select your
146+
own module.
147+
148+
.. _Sphinx: http://www.sphinx-doc.org/
149+
.. _autodoc: http://www.sphinx-doc.org/ext/autodoc.html
150+
.. _currentmodule: http://www.sphinx-doc.org/domains.html
151+
#directive-py:currentmodule

src/pa_ringbuffer.py

Lines changed: 78 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ def cdef():
1111
ring_buffer_size_t = 'int32_t'
1212
else:
1313
ring_buffer_size_t = 'long'
14-
1514
return """
1615
/* Declarations from PortAudio's pa_ringbuffer.h: */
1716
typedef %(ring_buffer_size_t)s ring_buffer_size_t;
@@ -43,32 +42,41 @@ def init(ffi, lib):
4342
"""Return RingBuffer class using the given CFFI instance."""
4443

4544
class RingBuffer(_RingBufferBase):
45+
__doc__ = _RingBufferBase.__doc__
4646
_ffi = ffi
4747
_lib = lib
4848

4949
return RingBuffer
5050

5151

5252
class _RingBufferBase(object):
53-
"""Wrapper for PortAudio's ring buffer.
53+
"""PortAudio's single-reader single-writer lock-free ring buffer.
5454
55-
See __init__().
55+
C API documentation:
56+
http://portaudio.com/docs/v19-doxydocs-dev/pa__ringbuffer_8h.html
57+
Python wrapper:
58+
https://github.com/spatialaudio/python-pa-ringbuffer
5659
57-
"""
60+
Instances of this class can be used to transport data between Python
61+
code and some compiled code running on a different thread.
5862
59-
def __init__(self, elementsize, size):
60-
"""Create an instance of PortAudio's ring buffer.
63+
This only works when there is a single reader and a single writer
64+
(i.e. one thread or callback writes to the ring buffer, another
65+
thread or callback reads from it).
6166
62-
http://portaudio.com/docs/v19-doxydocs-dev/pa__ringbuffer_8h.html
67+
This ring buffer is *not* appropriate for passing data from one
68+
Python thread to another Python thread. For this, the `queue.Queue`
69+
class from the standard library can be used.
6370
64-
Parameters
65-
----------
66-
elementsize : int
67-
The size of a single data element in bytes.
68-
size : int
69-
The number of elements in the buffer (must be a power of 2).
71+
:param elementsize: The size of a single data element in bytes.
72+
:type elementsize: int
73+
:param size: The number of elements in the buffer (must be a
74+
power of 2).
75+
:type size: int
7076
71-
"""
77+
"""
78+
79+
def __init__(self, elementsize, size):
7280
self._ptr = self._ffi.new('PaUtilRingBuffer*')
7381
self._data = self._ffi.new('unsigned char[]', size * elementsize)
7482
res = self._lib.PaUtil_InitializeRingBuffer(
@@ -80,7 +88,8 @@ def __init__(self, elementsize, size):
8088
def flush(self):
8189
"""Reset buffer to empty.
8290
83-
Should only be called when buffer is NOT being read or written.
91+
Should only be called when buffer is **not** being read or
92+
written.
8493
8594
"""
8695
self._lib.PaUtil_FlushRingBuffer(self._ptr)
@@ -98,17 +107,13 @@ def read_available(self):
98107
def write(self, data, size=-1):
99108
"""Write data to the ring buffer.
100109
101-
Parameters
102-
----------
103-
data : CData pointer or buffer or bytes
104-
Data to write to the buffer.
105-
size : int, optional
106-
The number of elements to be written.
110+
:param data: Data to write to the buffer.
111+
:type data: CData pointer or buffer or bytes
112+
:param size: The number of elements to be written.
113+
:type size: int, optional
107114
108-
Returns
109-
-------
110-
int
111-
The number of elements written.
115+
:returns: The number of elements written.
116+
:rtype: int
112117
113118
"""
114119
try:
@@ -124,17 +129,13 @@ def write(self, data, size=-1):
124129
def read(self, size=-1):
125130
"""Read data from the ring buffer into a new buffer.
126131
127-
Parameters
128-
----------
129-
size : int, optional
130-
The number of elements to be read.
132+
:param size: The number of elements to be read.
131133
If not specified, all available elements are read.
134+
:type size: int, optional
132135
133-
Returns
134-
-------
135-
buffer
136-
A new buffer containing the read data.
136+
:returns: A new buffer containing the read data.
137137
Its size may be less than the requested *size*.
138+
:rtype: buffer
138139
139140
"""
140141
if size < 0:
@@ -146,16 +147,12 @@ def read(self, size=-1):
146147
def readinto(self, data):
147148
"""Read data from the ring buffer into a user-provided buffer.
148149
149-
Parameters
150-
----------
151-
data : CData pointer or buffer
152-
The memory where the data should be stored.
150+
:param data: The memory where the data should be stored.
151+
:type data: CData pointer or buffer
153152
154-
Returns
155-
-------
156-
int
157-
The number of elements read, which may be less than the size
158-
of *data*.
153+
:returns: The number of elements read, which may be less than
154+
the size of *data*.
155+
:rtype: int
159156
160157
"""
161158
try:
@@ -170,20 +167,18 @@ def readinto(self, data):
170167
def get_write_buffers(self, size):
171168
"""Get buffer(s) to which we can write data.
172169
173-
Parameters
174-
----------
175-
size : int
176-
The number of elements desired.
177-
178-
Returns
179-
-------
180-
int
181-
The room available to be written or the given *size*,
182-
whichever is smaller.
183-
buffer
184-
The first buffer.
185-
buffer
186-
The second buffer.
170+
When done writing, use :meth:`advance_write_index` to make the
171+
written data available for reading.
172+
173+
:param size: The number of elements desired.
174+
:type size: int
175+
176+
:returns:
177+
* The room available to be written or the given *size*,
178+
whichever is smaller.
179+
* The first buffer.
180+
* The second buffer.
181+
:rtype: (int, buffer, buffer)
187182
188183
"""
189184
ptr1 = self._ffi.new('void**')
@@ -198,35 +193,34 @@ def get_write_buffers(self, size):
198193
def advance_write_index(self, size):
199194
"""Advance the write index to the next location to be written.
200195
201-
Parameters
202-
----------
203-
size : int
204-
The number of elements to advance.
196+
:param size: The number of elements to advance.
197+
:type size: int
205198
206-
Returns
207-
-------
208-
int
209-
The new position.
199+
:returns: The new position.
200+
:rtype: int
201+
202+
.. note:: This is only needed when using
203+
:meth:`get_write_buffers`, the method :meth:`write` takes
204+
care of this by itself!
210205
211206
"""
212207
return self._lib.PaUtil_AdvanceRingBufferWriteIndex(self._ptr, size)
213208

214209
def get_read_buffers(self, size):
215210
"""Get buffer(s) from which we can read data.
216211
217-
Parameters
218-
----------
219-
size : int
220-
The number of elements desired.
212+
When done reading, use :meth:`advance_read_index` to make the
213+
memory available for writing again.
214+
215+
:param size: The number of elements desired.
216+
:type size: int
221217
222-
Returns
223-
-------
224-
int
225-
The number of elements available for reading.
226-
buffer
227-
The first buffer.
228-
buffer
229-
The second buffer.
218+
:returns:
219+
* The number of elements available for reading (which might
220+
be less than the requested *size*).
221+
* The first buffer.
222+
* The second buffer.
223+
:rtype: (int, buffer, buffer)
230224
231225
"""
232226
ptr1 = self._ffi.new('void**')
@@ -241,15 +235,15 @@ def get_read_buffers(self, size):
241235
def advance_read_index(self, size):
242236
"""Advance the read index to the next location to be read.
243237
244-
Parameters
245-
----------
246-
size : int
247-
The number of elements to advance.
238+
:param size: The number of elements to advance.
239+
:type size: int
240+
241+
:returns: The new position.
242+
:rtype: int
248243
249-
Returns
250-
-------
251-
int
252-
The new position.
244+
.. note:: This is only needed when using
245+
:meth:`get_read_buffers`, the methods :meth:`read` and
246+
:meth:`readinto` take care of this by themselves!
253247
254248
"""
255249
return self._lib.PaUtil_AdvanceRingBufferReadIndex(self._ptr, size)

0 commit comments

Comments
 (0)