wavemap 2.0.0__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wavemap-2.1.0/PKG-INFO +378 -0
- wavemap-2.1.0/pyproject.toml +47 -0
- wavemap-2.1.0/wavemap/.DS_Store +0 -0
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/__init__.py +30 -27
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/convert.py +14 -8
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/docs.py +11 -11
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/memmap.py +18 -20
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/raw.py +27 -24
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/read.py +58 -38
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/structure/structure.py +14 -15
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/structure/wave.py +5 -5
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/write.py +28 -26
- wavemap-2.0.0/PKG-INFO +0 -380
- wavemap-2.0.0/pyproject.toml +0 -8
- wavemap-2.0.0/setup.cfg +0 -7
- wavemap-2.0.0/setup.py +0 -40
- wavemap-2.0.0/test/test_convert.py +0 -37
- wavemap-2.0.0/test/test_docs.py +0 -68
- wavemap-2.0.0/test/test_expected.py +0 -21
- wavemap-2.0.0/test/test_read.py +0 -89
- wavemap-2.0.0/test/test_vs_ffmpeg.py +0 -77
- wavemap-2.0.0/test/test_write.py +0 -106
- wavemap-2.0.0/wavemap.egg-info/PKG-INFO +0 -380
- wavemap-2.0.0/wavemap.egg-info/SOURCES.txt +0 -25
- wavemap-2.0.0/wavemap.egg-info/dependency_links.txt +0 -1
- wavemap-2.0.0/wavemap.egg-info/requires.txt +0 -2
- wavemap-2.0.0/wavemap.egg-info/top_level.txt +0 -1
- {wavemap-2.0.0 → wavemap-2.1.0}/README.rst +0 -0
- {wavemap-2.0.0 → wavemap-2.1.0}/wavemap/structure/__init__.py +0 -0
wavemap-2.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wavemap
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: 🌊 Memory map WAVE or raw audio files 🌊
|
|
5
|
+
Author: Tom Ritchford
|
|
6
|
+
Author-email: Tom Ritchford <tom@swirly.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Dist: numpy>=1.24.1,<2
|
|
15
|
+
Requires-Dist: xmod>=1.3.2,<2
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/x-rst
|
|
18
|
+
|
|
19
|
+
🌊 Memory map WAVE files into numpy arrays 🌊
|
|
20
|
+
----------------------------------------------
|
|
21
|
+
|
|
22
|
+
.. image:: https://raw.githubusercontent.com/rec/wavemap/master/wavemap.png
|
|
23
|
+
:alt: WaveMap logo
|
|
24
|
+
|
|
25
|
+
Manipulate huge WAVE or RAW files as numpy matrices - even if they are too
|
|
26
|
+
large to fit into memory.
|
|
27
|
+
|
|
28
|
+
Memory mapping is a technique where files on disk are directly mapped to
|
|
29
|
+
locations in memory and use the same logic as swap space does.
|
|
30
|
+
|
|
31
|
+
Samples from a WAVE or RAW audio file are directly memory mapped to entries in
|
|
32
|
+
a ``numpy`` array, letting you manipulate very large audio files as if they
|
|
33
|
+
all fit into memory at one time, and even directly change samples on disk.
|
|
34
|
+
|
|
35
|
+
Typical usage:
|
|
36
|
+
|
|
37
|
+
.. code-block:: python
|
|
38
|
+
|
|
39
|
+
import wavemap
|
|
40
|
+
|
|
41
|
+
wm = wavemap('test.wav', 'r+') # r+ means read/write
|
|
42
|
+
# Now you have a numpy matrix that you can use like any other
|
|
43
|
+
|
|
44
|
+
wm /= 2
|
|
45
|
+
# Each sample in the file is scaled by half.
|
|
46
|
+
|
|
47
|
+
API
|
|
48
|
+
===
|
|
49
|
+
|
|
50
|
+
``wavemap()``
|
|
51
|
+
~~~~~~~~~~~~~~~~~~~~~~
|
|
52
|
+
|
|
53
|
+
.. code-block:: python
|
|
54
|
+
|
|
55
|
+
wavemap(
|
|
56
|
+
filename: str,
|
|
57
|
+
mode: str='r',
|
|
58
|
+
order: Union[str, NoneType]=None,
|
|
59
|
+
always_2d: bool=False,
|
|
60
|
+
dtype: Union[numpy.dtype, NoneType]=None,
|
|
61
|
+
shape: Union[NoneType, int, tuple]=None,
|
|
62
|
+
sample_rate: int=0,
|
|
63
|
+
roffset: int=0,
|
|
64
|
+
warn: Union[Callable, NoneType]='<function warn: print to stderr>',
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
(`wavemap/__init__.py, 56-121 <https://github.com/rec/wavemap/blob/master/wavemap/__init__.py#L56-L121>`_)
|
|
68
|
+
|
|
69
|
+
Memory map a WAVE file to a ``numpy`` array
|
|
70
|
+
|
|
71
|
+
Return an instance of ``ReadMap`` or ``WriteMap``, depending on
|
|
72
|
+
``mode``.
|
|
73
|
+
|
|
74
|
+
ARGUMENTS
|
|
75
|
+
filename
|
|
76
|
+
The name of the file being mapped
|
|
77
|
+
|
|
78
|
+
mode
|
|
79
|
+
The file is opened in this mode.
|
|
80
|
+
Must be one of ``'r'``, ``'r+'``, ``'c'``, ``'w+'``
|
|
81
|
+
|
|
82
|
+
In mode ``'r'``, the default, the file is opened read-only and
|
|
83
|
+
the ``numpy.darray`` is immutable.
|
|
84
|
+
|
|
85
|
+
In mode ``'r+'``, the file is opened read-write and changes to the
|
|
86
|
+
``numpy.darray`` are automatically applied to the file.
|
|
87
|
+
|
|
88
|
+
In mode ``'c'``, "copy-on-write", the file is opened read-only, but
|
|
89
|
+
the ``numpy.darray`` is *not* immutable: changes to the array are
|
|
90
|
+
instead stored in memory.
|
|
91
|
+
|
|
92
|
+
In mode ``'w+'``, "write", the file is opened for write, and overwrites
|
|
93
|
+
whatever else is there.
|
|
94
|
+
|
|
95
|
+
order
|
|
96
|
+
Samples usually get laid out in into a ``numpy.darray`` with``
|
|
97
|
+
shape=(N, C)`` where ``N`` is the number of audio frames, and ``C`` is
|
|
98
|
+
the number of channels.
|
|
99
|
+
|
|
100
|
+
This is called column major order, but this can be toggled by
|
|
101
|
+
setting the ``order`` parameter to ``F`` for Fortan or row-major row.
|
|
102
|
+
|
|
103
|
+
See https://stackoverflow.com/questions/27266338/
|
|
104
|
+
|
|
105
|
+
always_2d
|
|
106
|
+
If ``False``, the default, mono WAVE files with only one channel
|
|
107
|
+
get special treatment and are mapped to a one-dimensional vector
|
|
108
|
+
with ``size=(N,)``.
|
|
109
|
+
|
|
110
|
+
If ``True``, mono WAVE files are treated the same as any other file
|
|
111
|
+
and are mapped to a two-dimensional matrix with ``size=(N, 1)``.
|
|
112
|
+
|
|
113
|
+
dtype
|
|
114
|
+
The numpy datatype of the samples in the file.
|
|
115
|
+
|
|
116
|
+
shape
|
|
117
|
+
The shape of the resulting numpy.darray. Can be a tuple, or a positive
|
|
118
|
+
integer, or ``None``.
|
|
119
|
+
|
|
120
|
+
sample_rate
|
|
121
|
+
The sample rate in Hz (cycles per second)
|
|
122
|
+
|
|
123
|
+
roffset
|
|
124
|
+
How many bytes in the file after the WAV data
|
|
125
|
+
|
|
126
|
+
warn
|
|
127
|
+
Programmers are sloppy so quite a lot of real-world WAVE files have
|
|
128
|
+
recoverable errors in their format. ``warn`` is the function used to
|
|
129
|
+
report those recoverable errors. By default, it's set to print to
|
|
130
|
+
``sys.stderr`` but setting it to ``None`` disables errors entirely, or
|
|
131
|
+
you can pass your own callback in
|
|
132
|
+
|
|
133
|
+
Class ``wavemap.RawMap``
|
|
134
|
+
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
135
|
+
|
|
136
|
+
(`wavemap/raw.py, 14-67 <https://github.com/rec/wavemap/blob/master/wavemap/raw.py#L14-L67>`_)
|
|
137
|
+
|
|
138
|
+
"Memory map raw audio data from a disk file into a numpy matrix
|
|
139
|
+
|
|
140
|
+
``wavemap.RawMap.__new__()``
|
|
141
|
+
____________________________
|
|
142
|
+
|
|
143
|
+
.. code-block:: python
|
|
144
|
+
|
|
145
|
+
wavemap.RawMap.__new__(
|
|
146
|
+
cls,
|
|
147
|
+
filename: str,
|
|
148
|
+
dtype: numpy.dtype,
|
|
149
|
+
shape: Union[tuple, int, NoneType]=None,
|
|
150
|
+
mode: str='r',
|
|
151
|
+
offset: int=0,
|
|
152
|
+
roffset: int=0,
|
|
153
|
+
order: Union[str, NoneType]=None,
|
|
154
|
+
always_2d: bool=False,
|
|
155
|
+
warn: Union[Callable, NoneType]='<function warn: print to stderr>',
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
(`wavemap/raw.py, 17-67 <https://github.com/rec/wavemap/blob/master/wavemap/raw.py#L17-L67>`_)
|
|
159
|
+
|
|
160
|
+
Memory map raw audio data from a disk file into a numpy matrix
|
|
161
|
+
|
|
162
|
+
ARGUMENTS
|
|
163
|
+
cls
|
|
164
|
+
Think of this as ``self``. (This is because you need to implement ``__new__``
|
|
165
|
+
and not ``__init__`` when deriving from ``np.darray``.)
|
|
166
|
+
|
|
167
|
+
filename
|
|
168
|
+
The name of the file being mapped
|
|
169
|
+
|
|
170
|
+
dtype
|
|
171
|
+
The numpy datatype of the samples in the file.
|
|
172
|
+
|
|
173
|
+
shape
|
|
174
|
+
The shape of the resulting numpy.darray. Can be a tuple, or a positive
|
|
175
|
+
integer, or ``None``.
|
|
176
|
+
|
|
177
|
+
mode
|
|
178
|
+
The file is opened in this mode.
|
|
179
|
+
Must be one of ``'r'``, ``'r+'``, ``'c'``, ``'w+'``
|
|
180
|
+
|
|
181
|
+
In mode ``'r'``, the default, the file is opened read-only and
|
|
182
|
+
the ``numpy.darray`` is immutable.
|
|
183
|
+
|
|
184
|
+
In mode ``'r+'``, the file is opened read-write and changes to the
|
|
185
|
+
``numpy.darray`` are automatically applied to the file.
|
|
186
|
+
|
|
187
|
+
In mode ``'c'``, "copy-on-write", the file is opened read-only, but
|
|
188
|
+
the ``numpy.darray`` is *not* immutable: changes to the array are
|
|
189
|
+
instead stored in memory.
|
|
190
|
+
|
|
191
|
+
In mode ``'w+'``, "write", the file is opened for write, and overwrites
|
|
192
|
+
whatever else is there.
|
|
193
|
+
|
|
194
|
+
offset
|
|
195
|
+
How many bytes in the file before the WAV data
|
|
196
|
+
|
|
197
|
+
roffset
|
|
198
|
+
How many bytes in the file after the WAV data
|
|
199
|
+
|
|
200
|
+
order
|
|
201
|
+
Samples usually get laid out in into a ``numpy.darray`` with``
|
|
202
|
+
shape=(N, C)`` where ``N`` is the number of audio frames, and ``C`` is
|
|
203
|
+
the number of channels.
|
|
204
|
+
|
|
205
|
+
This is called column major order, but this can be toggled by
|
|
206
|
+
setting the ``order`` parameter to ``F`` for Fortan or row-major row.
|
|
207
|
+
|
|
208
|
+
See https://stackoverflow.com/questions/27266338/
|
|
209
|
+
|
|
210
|
+
always_2d
|
|
211
|
+
If ``False``, the default, mono WAVE files with only one channel
|
|
212
|
+
get special treatment and are mapped to a one-dimensional vector
|
|
213
|
+
with ``size=(N,)``.
|
|
214
|
+
|
|
215
|
+
If ``True``, mono WAVE files are treated the same as any other file
|
|
216
|
+
and are mapped to a two-dimensional matrix with ``size=(N, 1)``.
|
|
217
|
+
|
|
218
|
+
warn
|
|
219
|
+
Programmers are sloppy so quite a lot of real-world WAVE files have
|
|
220
|
+
recoverable errors in their format. ``warn`` is the function used to
|
|
221
|
+
report those recoverable errors. By default, it's set to print to
|
|
222
|
+
``sys.stderr`` but setting it to ``None`` disables errors entirely, or
|
|
223
|
+
you can pass your own callback in
|
|
224
|
+
|
|
225
|
+
Class ``wavemap.ReadMap``
|
|
226
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
227
|
+
|
|
228
|
+
(`wavemap/read.py, 18-84 <https://github.com/rec/wavemap/blob/master/wavemap/read.py#L18-L84>`_)
|
|
229
|
+
|
|
230
|
+
Memory-map an existing WAVE file into a numpy vector or matrix
|
|
231
|
+
|
|
232
|
+
``wavemap.ReadMap.__new__()``
|
|
233
|
+
_____________________________
|
|
234
|
+
|
|
235
|
+
.. code-block:: python
|
|
236
|
+
|
|
237
|
+
wavemap.ReadMap.__new__(
|
|
238
|
+
cls: Type,
|
|
239
|
+
filename: str,
|
|
240
|
+
mode: str='r',
|
|
241
|
+
order: Union[str, NoneType]=None,
|
|
242
|
+
always_2d: bool=False,
|
|
243
|
+
warn: Union[Callable, NoneType]='<function warn: print to stderr>',
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
(`wavemap/read.py, 21-84 <https://github.com/rec/wavemap/blob/master/wavemap/read.py#L21-L84>`_)
|
|
247
|
+
|
|
248
|
+
Memory-map an existing WAVE file into a numpy matrix.
|
|
249
|
+
|
|
250
|
+
ARGUMENTS
|
|
251
|
+
cls
|
|
252
|
+
Think of this as ``self``. (This is because you need to implement ``__new__``
|
|
253
|
+
and not ``__init__`` when deriving from ``np.darray``.)
|
|
254
|
+
|
|
255
|
+
filename
|
|
256
|
+
The name of the file being mapped
|
|
257
|
+
|
|
258
|
+
mode
|
|
259
|
+
The file is opened in this mode.
|
|
260
|
+
Must be one of ``'r'``, ``'r+'`` and ``'c'``.
|
|
261
|
+
|
|
262
|
+
In mode ``'r'``, the default, the file is opened read-only and
|
|
263
|
+
the ``numpy.darray`` is immutable.
|
|
264
|
+
|
|
265
|
+
In mode ``'r+'``, the file is opened read-write and changes to the
|
|
266
|
+
``numpy.darray`` are automatically applied to the file.
|
|
267
|
+
|
|
268
|
+
In mode ``'c'``, "copy-on-write", the file is opened read-only, but
|
|
269
|
+
the ``numpy.darray`` is *not* immutable: changes to the array are
|
|
270
|
+
instead stored in memory.
|
|
271
|
+
|
|
272
|
+
order
|
|
273
|
+
Samples usually get laid out in into a ``numpy.darray`` with``
|
|
274
|
+
shape=(N, C)`` where ``N`` is the number of audio frames, and ``C`` is
|
|
275
|
+
the number of channels.
|
|
276
|
+
|
|
277
|
+
This is called column major order, but this can be toggled by
|
|
278
|
+
setting the ``order`` parameter to ``F`` for Fortan or row-major row.
|
|
279
|
+
|
|
280
|
+
See https://stackoverflow.com/questions/27266338/
|
|
281
|
+
|
|
282
|
+
always_2d
|
|
283
|
+
If ``False``, the default, mono WAVE files with only one channel
|
|
284
|
+
get special treatment and are mapped to a one-dimensional vector
|
|
285
|
+
with ``size=(N,)``.
|
|
286
|
+
|
|
287
|
+
If ``True``, mono WAVE files are treated the same as any other file
|
|
288
|
+
and are mapped to a two-dimensional matrix with ``size=(N, 1)``.
|
|
289
|
+
|
|
290
|
+
warn
|
|
291
|
+
Programmers are sloppy so quite a lot of real-world WAVE files have
|
|
292
|
+
recoverable errors in their format. ``warn`` is the function used to
|
|
293
|
+
report those recoverable errors. By default, it's set to print to
|
|
294
|
+
``sys.stderr`` but setting it to ``None`` disables errors entirely, or
|
|
295
|
+
you can pass your own callback in
|
|
296
|
+
|
|
297
|
+
Class ``wavemap.WriteMap``
|
|
298
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
299
|
+
|
|
300
|
+
(`wavemap/write.py, 12-115 <https://github.com/rec/wavemap/blob/master/wavemap/write.py#L12-L115>`_)
|
|
301
|
+
|
|
302
|
+
"Memory-map a new wave file into a new numpy vector or matrix
|
|
303
|
+
|
|
304
|
+
``wavemap.WriteMap.__new__()``
|
|
305
|
+
______________________________
|
|
306
|
+
|
|
307
|
+
.. code-block:: python
|
|
308
|
+
|
|
309
|
+
wavemap.WriteMap.__new__(
|
|
310
|
+
cls: Type,
|
|
311
|
+
filename: str,
|
|
312
|
+
dtype: numpy.dtype,
|
|
313
|
+
shape: Union[NoneType, int, tuple],
|
|
314
|
+
sample_rate: int,
|
|
315
|
+
roffset: int=0,
|
|
316
|
+
warn: Union[Callable, NoneType]='<function warn: print to stderr>',
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
(`wavemap/write.py, 15-85 <https://github.com/rec/wavemap/blob/master/wavemap/write.py#L15-L85>`_)
|
|
320
|
+
|
|
321
|
+
Open a memory-mapped WAVE file in write mode and overwrite any existing
|
|
322
|
+
file.
|
|
323
|
+
|
|
324
|
+
ARGUMENTS
|
|
325
|
+
cls
|
|
326
|
+
Think of this as ``self``. (This is because you need to implement ``__new__``
|
|
327
|
+
and not ``__init__`` when deriving from ``np.darray``.)
|
|
328
|
+
|
|
329
|
+
filename
|
|
330
|
+
The name of the file being mapped
|
|
331
|
+
|
|
332
|
+
dtype
|
|
333
|
+
The numpy datatype of the samples in the file.
|
|
334
|
+
|
|
335
|
+
shape
|
|
336
|
+
The shape of the resulting numpy.darray. Can be a tuple, or a positive
|
|
337
|
+
integer, or ``None``.
|
|
338
|
+
|
|
339
|
+
sample_rate
|
|
340
|
+
The sample rate in Hz (cycles per second)
|
|
341
|
+
|
|
342
|
+
roffset
|
|
343
|
+
How many bytes in the file after the WAV data
|
|
344
|
+
|
|
345
|
+
warn
|
|
346
|
+
Programmers are sloppy so quite a lot of real-world WAVE files have
|
|
347
|
+
recoverable errors in their format. ``warn`` is the function used to
|
|
348
|
+
report those recoverable errors. By default, it's set to print to
|
|
349
|
+
``sys.stderr`` but setting it to ``None`` disables errors entirely, or
|
|
350
|
+
you can pass your own callback in
|
|
351
|
+
|
|
352
|
+
``wavemap.convert()``
|
|
353
|
+
~~~~~~~~~~~~~~~~~~~~~
|
|
354
|
+
|
|
355
|
+
.. code-block:: python
|
|
356
|
+
|
|
357
|
+
wavemap.convert(
|
|
358
|
+
arr: numpy.ndarray,
|
|
359
|
+
dtype: Union[numpy.dtype, NoneType],
|
|
360
|
+
must_copy: bool=False,
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
(`wavemap/convert.py, 6-77 <https://github.com/rec/wavemap/blob/master/wavemap/convert.py#L6-L77>`_)
|
|
364
|
+
|
|
365
|
+
Returns a copy of a numpy array or matrix that represents audio data in
|
|
366
|
+
another type, scaling and shifting as necessary.
|
|
367
|
+
|
|
368
|
+
ARGUMENTS
|
|
369
|
+
arr
|
|
370
|
+
A numpy darray representing an audio signal
|
|
371
|
+
|
|
372
|
+
dtype
|
|
373
|
+
The numpy dtype to convert to - none means "no conversion"
|
|
374
|
+
|
|
375
|
+
must_copy
|
|
376
|
+
If true, ``arr`` is copied even if it is already the requested type
|
|
377
|
+
|
|
378
|
+
(automatically generated by `doks <https://github.com/rec/doks/>`_ on 2021-02-23T14:37:02.652534)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "wavemap"
|
|
3
|
+
version = "2.1.0"
|
|
4
|
+
description = "🌊 Memory map WAVE or raw audio files 🌊"
|
|
5
|
+
authors = [{ name = "Tom Ritchford", email = "tom@swirly.com" }]
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
readme = "README.rst"
|
|
8
|
+
license = "MIT"
|
|
9
|
+
classifiers = ["Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14"]
|
|
10
|
+
dependencies = [
|
|
11
|
+
"numpy>=1.24.1,<2",
|
|
12
|
+
"xmod>=1.3.2,<2",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.doks]
|
|
16
|
+
auto = true
|
|
17
|
+
source = 'wavemap/__init__.py'
|
|
18
|
+
|
|
19
|
+
[tool.ruff]
|
|
20
|
+
[dependency-groups]
|
|
21
|
+
dev = [
|
|
22
|
+
"coverage>=7.1.0,<8",
|
|
23
|
+
"pytest>=7.2.1,<8",
|
|
24
|
+
"pyupgrade>=3.21.2",
|
|
25
|
+
"ruff>=0.14.14",
|
|
26
|
+
"stroll>=1.1.0,<2",
|
|
27
|
+
"tdir>=1.4.1,<2",
|
|
28
|
+
"ty>=0.0.14",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[tool.uv]
|
|
32
|
+
|
|
33
|
+
[tool.uv.build-backend]
|
|
34
|
+
module-root = ""
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["uv_build>=0.9.0,<0.10.0"]
|
|
38
|
+
build-backend = "uv_build"
|
|
39
|
+
[tool.coverage.run]
|
|
40
|
+
branch = true
|
|
41
|
+
source = "wavemap"
|
|
42
|
+
|
|
43
|
+
[tool.coverage.report]
|
|
44
|
+
fail_under = "68"
|
|
45
|
+
skip_covered = true
|
|
46
|
+
exclude_lines = ["pragma: no cover", "if False:", "if __name__ == .__main__.:", "raise NotImplementedError"]
|
|
47
|
+
|
|
Binary file
|
|
@@ -26,31 +26,34 @@ Typical usage:
|
|
|
26
26
|
wm /= 2
|
|
27
27
|
# Each sample in the file is scaled by half.
|
|
28
28
|
"""
|
|
29
|
+
|
|
30
|
+
from typing import Optional, Union
|
|
31
|
+
from collections.abc import Callable
|
|
32
|
+
|
|
33
|
+
import numpy as np
|
|
34
|
+
import xmod
|
|
35
|
+
|
|
29
36
|
from . import docs
|
|
30
37
|
from .convert import convert
|
|
31
38
|
from .raw import RawMap, warn
|
|
32
39
|
from .read import ReadMap as ReadMap
|
|
33
40
|
from .write import WriteMap as WriteMap
|
|
34
|
-
from typing import Callable, Optional, Union
|
|
35
|
-
import numpy as np
|
|
36
|
-
import xmod
|
|
37
41
|
|
|
38
42
|
__all__ = (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
"wavemap",
|
|
44
|
+
"RawMap",
|
|
45
|
+
"ReadMap",
|
|
46
|
+
"WriteMap",
|
|
47
|
+
"copy_to",
|
|
48
|
+
"new_like",
|
|
49
|
+
"convert",
|
|
46
50
|
)
|
|
47
|
-
__version__ = '2.0.0'
|
|
48
51
|
|
|
49
52
|
copy_to = WriteMap.copy_to
|
|
50
53
|
new_like = WriteMap.new_like
|
|
51
|
-
_DOKS = {warn:
|
|
52
|
-
_WRITE_PARAMETERS =
|
|
53
|
-
_READ_PARAMETERS =
|
|
54
|
+
_DOKS = {warn: "<function warn: print to stderr>"}
|
|
55
|
+
_WRITE_PARAMETERS = "dtype", "shape", "sample_rate"
|
|
56
|
+
_READ_PARAMETERS = "order", "always_2d"
|
|
54
57
|
|
|
55
58
|
|
|
56
59
|
@xmod(mutable=True)
|
|
@@ -60,20 +63,20 @@ def wavemap(
|
|
|
60
63
|
#
|
|
61
64
|
# Read parameters
|
|
62
65
|
#
|
|
63
|
-
mode: str =
|
|
64
|
-
order:
|
|
66
|
+
mode: str = "r",
|
|
67
|
+
order: str | None = None,
|
|
65
68
|
always_2d: bool = False,
|
|
66
69
|
#
|
|
67
70
|
# Write parameters
|
|
68
71
|
#
|
|
69
|
-
dtype:
|
|
70
|
-
shape:
|
|
72
|
+
dtype: np.dtype | None = None,
|
|
73
|
+
shape: None | int | tuple = None,
|
|
71
74
|
sample_rate: int = 0,
|
|
72
75
|
roffset: int = 0,
|
|
73
76
|
#
|
|
74
77
|
# Read and write parameters
|
|
75
78
|
#
|
|
76
|
-
warn:
|
|
79
|
+
warn: Callable | None = warn,
|
|
77
80
|
):
|
|
78
81
|
"""
|
|
79
82
|
Memory map a WAVE file to a `numpy` array
|
|
@@ -81,18 +84,18 @@ def wavemap(
|
|
|
81
84
|
Return an instance of `ReadMap` or `WriteMap`, depending on
|
|
82
85
|
`mode`.
|
|
83
86
|
"""
|
|
84
|
-
if mode.startswith(
|
|
87
|
+
if mode.startswith("w"):
|
|
85
88
|
if not dtype:
|
|
86
|
-
raise ValueError(
|
|
89
|
+
raise ValueError("dtype must be set for write")
|
|
87
90
|
if not shape:
|
|
88
|
-
raise ValueError(
|
|
91
|
+
raise ValueError("shape must be set for write")
|
|
89
92
|
if not sample_rate:
|
|
90
|
-
raise ValueError(
|
|
93
|
+
raise ValueError("sample_rate must be set for write")
|
|
91
94
|
|
|
92
95
|
if order:
|
|
93
|
-
raise ValueError(
|
|
96
|
+
raise ValueError("order cannot be set for write")
|
|
94
97
|
if always_2d:
|
|
95
|
-
raise ValueError(
|
|
98
|
+
raise ValueError("always_2d cannot be set for write")
|
|
96
99
|
|
|
97
100
|
return WriteMap(
|
|
98
101
|
filename=filename,
|
|
@@ -104,9 +107,9 @@ def wavemap(
|
|
|
104
107
|
)
|
|
105
108
|
else:
|
|
106
109
|
if shape:
|
|
107
|
-
raise ValueError(
|
|
110
|
+
raise ValueError("shape cannot be set for write")
|
|
108
111
|
if sample_rate:
|
|
109
|
-
raise ValueError(
|
|
112
|
+
raise ValueError("sample_rate cannot be set for write")
|
|
110
113
|
|
|
111
114
|
result = ReadMap(
|
|
112
115
|
filename=filename,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
from numpy.lib.stride_tricks import as_strided
|
|
2
1
|
from typing import Optional
|
|
2
|
+
|
|
3
3
|
import numpy as np
|
|
4
|
+
from numpy.lib.stride_tricks import as_strided
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def convert(
|
|
7
|
-
arr: np.ndarray, dtype: Optional[np.dtype], must_copy: bool = False
|
|
8
|
-
):
|
|
7
|
+
def convert(arr: np.ndarray, dtype: np.dtype | None, must_copy: bool = False):
|
|
9
8
|
"""
|
|
10
9
|
Returns a copy of a numpy array or matrix that represents audio data in
|
|
11
10
|
another type, scaling and shifting as necessary.
|
|
@@ -27,8 +26,8 @@ def convert(
|
|
|
27
26
|
arr = np.copy(arr)
|
|
28
27
|
return arr
|
|
29
28
|
|
|
30
|
-
old_int =
|
|
31
|
-
new_int =
|
|
29
|
+
old_int = "int" in str(old_t)
|
|
30
|
+
new_int = "int" in str(new_t)
|
|
32
31
|
|
|
33
32
|
if not (new_int or old_int):
|
|
34
33
|
# Convert between floats
|
|
@@ -96,8 +95,15 @@ def _twenty_four_bit(shape, new, raw, itemsize):
|
|
|
96
95
|
assert not (frames % 4)
|
|
97
96
|
|
|
98
97
|
# https://stackoverflow.com/a/34128171/4383
|
|
99
|
-
raw = new(shape=(itemsize * frames // 4,), dtype=
|
|
100
|
-
strided = as_strided(
|
|
98
|
+
raw = new(shape=(itemsize * frames // 4,), dtype="int32")
|
|
99
|
+
strided = as_strided(
|
|
100
|
+
raw,
|
|
101
|
+
strides=(
|
|
102
|
+
12,
|
|
103
|
+
3,
|
|
104
|
+
),
|
|
105
|
+
shape=(frames, 4),
|
|
106
|
+
)
|
|
101
107
|
reshaped = np.reshape(strided, shape=shape)
|
|
102
108
|
|
|
103
109
|
result = reshaped & 0x00FFFFFF
|
|
@@ -15,9 +15,9 @@ Think of this as `self`. (This is because you need to implement `__new__`
|
|
|
15
15
|
and not `__init__` when deriving from `np.darray`.)
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
DTYPE =
|
|
18
|
+
DTYPE = "The numpy datatype of the samples in the file."
|
|
19
19
|
|
|
20
|
-
FILENAME =
|
|
20
|
+
FILENAME = "The name of the file being mapped"
|
|
21
21
|
|
|
22
22
|
ORDER = """
|
|
23
23
|
Samples usually get laid out in into a `numpy.darray` with`
|
|
@@ -63,9 +63,9 @@ In mode `'w+'`, "write", the file is opened for write, and overwrites
|
|
|
63
63
|
whatever else is there.
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
|
-
OFFSET =
|
|
67
|
-
ROFFSET =
|
|
68
|
-
SAMPLE_RATE =
|
|
66
|
+
OFFSET = "How many bytes in the file before the WAV data"
|
|
67
|
+
ROFFSET = "How many bytes in the file after the WAV data"
|
|
68
|
+
SAMPLE_RATE = "The sample rate in Hz (cycles per second)"
|
|
69
69
|
|
|
70
70
|
SHAPE = """
|
|
71
71
|
The shape of the resulting numpy.darray. Can be a tuple, or a positive
|
|
@@ -87,19 +87,19 @@ def arguments(*names, subs=None):
|
|
|
87
87
|
names = [(i, subs.get(i, i).upper()) for i in names]
|
|
88
88
|
missing = [n for (n, a) in names if a not in globals()]
|
|
89
89
|
if missing:
|
|
90
|
-
raise ValueError(f
|
|
90
|
+
raise ValueError(f"Cannot document arguments {missing}")
|
|
91
91
|
|
|
92
|
-
yield
|
|
92
|
+
yield "ARGUMENTS"
|
|
93
93
|
for name, attr in names:
|
|
94
|
-
yield f
|
|
94
|
+
yield f" {name}"
|
|
95
95
|
for line in globals()[attr].strip().splitlines():
|
|
96
|
-
yield line and f
|
|
97
|
-
yield
|
|
96
|
+
yield line and f" {line}"
|
|
97
|
+
yield ""
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
def add_arguments(func, names, subs=None):
|
|
101
101
|
params = arguments(*names, subs=subs)
|
|
102
|
-
func.__doc__ = func.__doc__.rstrip() +
|
|
102
|
+
func.__doc__ = func.__doc__.rstrip() + "\n\n" + "\n".join(params)
|
|
103
103
|
return func
|
|
104
104
|
|
|
105
105
|
|