Skip to content

Commit 7a56e8a

Browse files
committed
DOC: Major documentation update
1 parent d0e1b2e commit 7a56e8a

5 files changed

Lines changed: 70 additions & 55 deletions

File tree

README.rst

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,29 @@ Features:
1717

1818
* playback of multiple signals at the same time (that's why it's called "mixer")
1919

20-
* non-blocking callback function, using PortAudio ringbuffers
21-
2220
* play from buffer, play from ringbuffer
2321

2422
* record into buffer, record into ringbuffer
2523

2624
* multichannel support
2725

28-
* all memory allocations/deallocations happen outside of the audio callback
29-
30-
* NumPy arrays with data type 'float32' can be easily used (via the buffer
26+
* NumPy arrays with data type ``'float32'`` can be easily used (via the buffer
3127
protocol) as long as they are C-contiguous
3228

33-
Planned features:
29+
* fixed latency playback, (close to) no jitter (optional)
3430

35-
* fixed latency playback, no jitter (optional)
31+
* to be verified ...
3632

3733
* sample-accurate playback/recording (with known offset)
3834

35+
* to be verified ...
36+
37+
* non-blocking callback function, using PortAudio ringbuffers
38+
39+
* all memory allocations/deallocations happen outside the audio callback
40+
41+
Planned features:
42+
3943
* meticulous reporting of overruns/underruns
4044

4145
* loopback tests to verify correct operation and accurate latency values

doc/conf.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,18 @@
11
from subprocess import check_output
22

3-
needs_sphinx = '1.3' # for sphinx.ext.napoleon
4-
53
extensions = [
64
'sphinx.ext.autodoc',
75
'sphinx.ext.intersphinx',
86
'sphinx.ext.viewcode',
9-
'sphinx.ext.napoleon', # support for NumPy-style docstrings
107
]
118

12-
autoclass_content = 'init'
13-
autodoc_member_order = 'bysource'
14-
15-
napoleon_google_docstring = False
16-
napoleon_numpy_docstring = True
17-
napoleon_include_private_with_doc = False
18-
napoleon_include_special_with_doc = False
19-
napoleon_use_admonition_for_examples = False
20-
napoleon_use_admonition_for_notes = False
21-
napoleon_use_admonition_for_references = False
22-
napoleon_use_ivar = False
23-
napoleon_use_param = False
24-
napoleon_use_rtype = False
25-
269
intersphinx_mapping = {
2710
'python': ('https://docs.python.org/3/', None),
2811
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
29-
'sounddevice': ('http://python-sounddevice.readthedocs.io/en/latest/',
30-
None),
12+
'sounddevice':
13+
('http://python-sounddevice.readthedocs.io/en/latest/', None),
3114
}
3215

33-
source_suffix = '.rst'
3416
master_doc = 'index'
3517

3618
authors = 'Matthias Geier'

doc/index.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,22 @@ API Documentation
88
-----------------
99

1010
.. automodule:: rtmixer
11+
12+
.. autoclass:: Mixer
13+
:members: play_buffer, play_ringbuffer, actions, cancel, wait
14+
:undoc-members:
15+
16+
.. autoclass:: Recorder
1117
:members:
1218
:undoc-members:
1319

20+
.. autoclass:: MixerAndRecorder
21+
:members:
22+
:undoc-members:
23+
24+
.. autoclass:: RingBuffer
25+
:inherited-members:
26+
1427
.. only:: html
1528

1629
Index

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
long_description=open('README.rst').read(),
3030
license='MIT',
3131
keywords='sound audio PortAudio realtime low-latency'.split(),
32-
#url='http://python-rtmixer.readthedocs.io/',
32+
url='http://python-rtmixer.readthedocs.io/',
3333
platforms='any',
3434
classifiers=[
3535
'License :: OSI Approved :: MIT License',

src/rtmixer.py

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
"""Reliable low-latency audio playback and recording."""
1+
"""Reliable low-latency audio playback and recording.
22
3+
http://python-rtmixer.readthedocs.io/
4+
5+
"""
36
__version__ = '0.0.0'
47

58
import sounddevice as _sd
@@ -45,7 +48,8 @@ def cancel(self, action, time=0, allow_belated=True):
4548
order to stop the given *action*.
4649
4750
This function typically returns before the *action* is actually
48-
stopped. Use `wait()` to wait until it's done.
51+
stopped. Use `wait()` (on either one of the two actions) to
52+
wait until it's done.
4953
5054
"""
5155
cancel_action = _ffi.new('struct action*', dict(
@@ -99,17 +103,22 @@ def _drain_result_q(self):
99103

100104

101105
class Mixer(_Base):
102-
"""PortAudio output stream for realtime mixing."""
106+
"""PortAudio output stream for realtime mixing.
103107
104-
def __init__(self, **kwargs):
105-
"""Create a realtime mixer object.
108+
Takes the same keyword arguments as `sounddevice.OutputStream`,
109+
except *callback* (a callback function implemented in C is used
110+
internally) and *dtype* (which is always ``'float32'``).
106111
107-
Takes the same keyword arguments as `sounddevice.OutputStream`,
108-
except *callback* and *dtype*.
112+
Uses default values from `sounddevice.default` (except *dtype*,
113+
which is always ``'float32'``).
109114
110-
Uses default values from `sounddevice.default`.
115+
Has the same methods and attributes as `sounddevice.OutputStream`
116+
(except :meth:`~sounddevice.Stream.write` and
117+
:attr:`~sounddevice.Stream.write_available`), plus the following:
111118
112-
"""
119+
"""
120+
121+
def __init__(self, **kwargs):
113122
_Base.__init__(self, kind='output', **kwargs)
114123
self._state.output_channels = self.channels
115124

@@ -136,10 +145,10 @@ def play_buffer(self, buffer, channels, start=0, allow_belated=True):
136145

137146
def play_ringbuffer(self, ringbuffer, channels=None, start=0,
138147
allow_belated=True):
139-
"""Send a ring buffer to the callback to be played back.
148+
"""Send a `RingBuffer` to the callback to be played back.
140149
141150
By default, the number of channels is obtained from the ring
142-
buffer's *elementsize*.
151+
buffer's :attr:`~RingBuffer.elementsize`.
143152
144153
"""
145154
_, samplesize = _sd._split(self.samplesize)
@@ -162,17 +171,21 @@ def play_ringbuffer(self, ringbuffer, channels=None, start=0,
162171

163172

164173
class Recorder(_Base):
165-
"""PortAudio input stream for realtime recording."""
174+
"""PortAudio input stream for realtime recording.
166175
167-
def __init__(self, **kwargs):
168-
"""Create a realtime recording object.
176+
Takes the same keyword arguments as `sounddevice.InputStream`,
177+
except *callback* (a callback function implemented in C is used
178+
internally) and *dtype* (which is always ``'float32'``).
169179
170-
Takes the same keyword arguments as `sounddevice.InputStream`,
171-
except *callback* and *dtype*.
180+
Uses default values from `sounddevice.default` (except *dtype*,
181+
which is always ``'float32'``).
172182
173-
Uses default values from `sounddevice.default`.
183+
Has the same methods and attributes as `Mixer`, except that
184+
`play_buffer()` and `play_ringbuffer()` are replaced by:
174185
175-
"""
186+
"""
187+
188+
def __init__(self, **kwargs):
176189
_Base.__init__(self, kind='input', **kwargs)
177190
self._state.input_channels = self.channels
178191

@@ -197,10 +210,10 @@ def record_buffer(self, buffer, channels, start=0, allow_belated=True):
197210

198211
def record_ringbuffer(self, ringbuffer, channels=None, start=0,
199212
allow_belated=True):
200-
"""Send a ring buffer to the callback to be recorded into.
213+
"""Send a `RingBuffer` to the callback to be recorded into.
201214
202215
By default, the number of channels is obtained from the ring
203-
buffer's *elementsize*.
216+
buffer's :attr:`~RingBuffer.elementsize`.
204217
205218
"""
206219
samplesize, _ = _sd._split(self.samplesize)
@@ -223,17 +236,20 @@ def record_ringbuffer(self, ringbuffer, channels=None, start=0,
223236

224237

225238
class MixerAndRecorder(Mixer, Recorder):
226-
"""PortAudio stream for realtime mixing and recording."""
239+
"""PortAudio stream for realtime mixing and recording.
227240
228-
def __init__(self, **kwargs):
229-
"""Create a realtime mixer object with recording capabilities.
241+
Takes the same keyword arguments as `sounddevice.Stream`, except
242+
*callback* (a callback function implemented in C is used internally)
243+
and *dtype* (which is always ``'float32'``).
230244
231-
Takes the same keyword arguments as `sounddevice.Stream`,
232-
except *callback* and *dtype*.
245+
Uses default values from `sounddevice.default` (except *dtype*,
246+
which is always ``'float32'``).
233247
234-
Uses default values from `sounddevice.default`.
248+
Inherits all methods and attributes from `Mixer` and `Recorder`.
235249
236-
"""
250+
"""
251+
252+
def __init__(self, **kwargs):
237253
_Base.__init__(self, kind='duplex', **kwargs)
238254
self._state.input_channels = self.channels[0]
239255
self._state.output_channels = self.channels[1]

0 commit comments

Comments
 (0)