Codebase list audioread / aff95c5
Import upstream version 2.1.8, md5 f8a67aac7eb5a0bb263851fc4ddbb527 Debian Janitor 4 years ago
20 changed file(s) with 526 addition(s) and 53 deletion(s). Raw diff Collapse all Expand all
0 Copyright (c) 2011-2018 Adrian Sampson
1
2 Permission is hereby granted, free of charge, to any person obtaining a copy
3 of this software and associated documentation files (the "Software"), to deal
4 in the Software without restriction, including without limitation the rights
5 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6 copies of the Software, and to permit persons to whom the Software is
7 furnished to do so, subject to the following conditions:
8
9 The above copyright notice and this permission notice shall be included in all
10 copies or substantial portions of the Software.
11
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 NONINFRINGEMENT.
15 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
18 OR OTHER DEALINGS IN THE SOFTWARE.
0 # Documentation.
1 include README.rst
2 # Example script.
3 include decode.py
4 # License
5 include LICENSE
00 Metadata-Version: 1.1
11 Name: audioread
2 Version: 2.1.5
2 Version: 2.1.8
33 Summary: multi-library, cross-platform audio decoding
44 Home-page: https://github.com/sampsyo/audioread
55 Author: Adrian Sampson
3232 .. _wave: http://docs.python.org/library/wave.html
3333 .. _aifc: http://docs.python.org/library/aifc.html
3434 .. _sunau: http://docs.python.org/library/sunau.html
35 .. _PyGObject: https://wiki.gnome.org/Projects/PyGObject
35 .. _PyGObject: https://pygobject.readthedocs.io/
3636
3737 Use the library like so::
3838
6060 unsupported by the backends; if the file doesn't exist, a standard ``IOError``
6161 will be raised.
6262
63 A second optional parameter to ``audio_open`` specifies which backends to try
64 (instead of trying them all, which is the default). You can use the
65 ``available_backends`` function to get a list backends that are usable on the
66 current system.
67
6368 Audioread is "universal" and supports both Python 2 (2.6+) and Python 3
6469 (3.2+).
6570
7176
7277 Version History
7378 ---------------
79
80 2.1.8
81 Fix an unhandled ``OSError`` when FFmpeg is not installed.
82
83 2.1.7
84 Properly close some filehandles in the FFmpeg backend (thanks to
85 @RyanMarcus and @ssssam).
86 The maddec backend now always produces bytes objects, like the other
87 backends (thanks to @ssssam).
88 Resolve an audio data memory leak in the GStreamer backend (thanks again to
89 @ssssam).
90 You can now optionally specify which specific backends ``audio_open`` should
91 try (thanks once again to @ssssam).
92 On Windows, avoid opening a console window to run FFmpeg (thanks to @flokX).
93
94 2.1.6
95 Fix a "no such process" crash in the FFmpeg backend on Windows Subsystem for
96 Linux (thanks to @llamasoft).
97 Avoid suppressing SIGINT in the GStreamer backend on older versions of
98 PyGObject (thanks to @lazka).
7499
75100 2.1.5
76101 Properly clean up the file handle when a backend fails to decode a file.
2424 .. _wave: http://docs.python.org/library/wave.html
2525 .. _aifc: http://docs.python.org/library/aifc.html
2626 .. _sunau: http://docs.python.org/library/sunau.html
27 .. _PyGObject: https://wiki.gnome.org/Projects/PyGObject
27 .. _PyGObject: https://pygobject.readthedocs.io/
2828
2929 Use the library like so::
3030
5252 unsupported by the backends; if the file doesn't exist, a standard ``IOError``
5353 will be raised.
5454
55 A second optional parameter to ``audio_open`` specifies which backends to try
56 (instead of trying them all, which is the default). You can use the
57 ``available_backends`` function to get a list backends that are usable on the
58 current system.
59
5560 Audioread is "universal" and supports both Python 2 (2.6+) and Python 3
5661 (3.2+).
5762
6368
6469 Version History
6570 ---------------
71
72 2.1.8
73 Fix an unhandled ``OSError`` when FFmpeg is not installed.
74
75 2.1.7
76 Properly close some filehandles in the FFmpeg backend (thanks to
77 @RyanMarcus and @ssssam).
78 The maddec backend now always produces bytes objects, like the other
79 backends (thanks to @ssssam).
80 Resolve an audio data memory leak in the GStreamer backend (thanks again to
81 @ssssam).
82 You can now optionally specify which specific backends ``audio_open`` should
83 try (thanks once again to @ssssam).
84 On Windows, avoid opening a console window to run FFmpeg (thanks to @flokX).
85
86 2.1.6
87 Fix a "no such process" crash in the FFmpeg backend on Windows Subsystem for
88 Linux (thanks to @llamasoft).
89 Avoid suppressing SIGINT in the GStreamer backend on older versions of
90 PyGObject (thanks to @lazka).
6691
6792 2.1.5
6893 Properly clean up the file handle when a backend fails to decode a file.
1313
1414 """Decode audio files."""
1515
16 from . import ffdec
17 from .exceptions import DecodeError, NoBackendError
1618 from .version import version as __version__ # noqa
17
18
19 class DecodeError(Exception):
20 """The base exception class for all decoding errors raised by this
21 package.
22 """
23
24
25 class NoBackendError(DecodeError):
26 """The file could not be decoded by any backend. Either no backends
27 are available or each available backend failed to decode the file.
28 """
2919
3020
3121 def _gst_available():
6959 return True
7060
7161
72 def audio_open(path):
73 """Open an audio file using a library that is available on this
74 system.
75 """
62 def available_backends():
63 """Returns a list of backends that are available on this system."""
64
7665 # Standard-library WAV and AIFF readers.
7766 from . import rawread
78 try:
79 return rawread.RawAudioFile(path)
80 except DecodeError:
81 pass
67 result = [rawread.RawAudioFile]
8268
8369 # Core Audio.
8470 if _ca_available():
8571 from . import macca
86 try:
87 return macca.ExtAudioFile(path)
88 except DecodeError:
89 pass
72 result.append(macca.ExtAudioFile)
9073
9174 # GStreamer.
9275 if _gst_available():
9376 from . import gstdec
94 try:
95 return gstdec.GstAudioFile(path)
96 except DecodeError:
97 pass
77 result.append(gstdec.GstAudioFile)
9878
9979 # MAD.
10080 if _mad_available():
10181 from . import maddec
82 result.append(maddec.MadAudioFile)
83
84 # FFmpeg.
85 if ffdec.available():
86 result.append(ffdec.FFmpegAudioFile)
87
88 return result
89
90
91 def audio_open(path, backends=None):
92 """Open an audio file using a library that is available on this
93 system.
94
95 The optional `backends` parameter can be a list of audio file
96 classes to try opening the file with. If it is not provided,
97 `audio_open` tries all available backends. If you call this function
98 many times, you can avoid the cost of checking for available
99 backends every time by calling `available_backends` once and passing
100 the result to each `audio_open` call.
101
102 If all backends fail to read the file, a NoBackendError exception is
103 raised.
104 """
105 if backends is None:
106 backends = available_backends()
107
108 for BackendClass in backends:
102109 try:
103 return maddec.MadAudioFile(path)
110 return BackendClass(path)
104111 except DecodeError:
105112 pass
106113
107 # FFmpeg.
108 from . import ffdec
109 try:
110 return ffdec.FFmpegAudioFile(path)
111 except DecodeError:
112 pass
113
114114 # All backends failed!
115115 raise NoBackendError()
0 # This file is part of audioread.
1 # Copyright 2013, Adrian Sampson.
2 #
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 #
11 # The above copyright notice and this permission notice shall be
12 # included in all copies or substantial portions of the Software.
13
14
15 class DecodeError(Exception):
16 """The base exception class for all decoding errors raised by this
17 package.
18 """
19
20
21 class NoBackendError(DecodeError):
22 """The file could not be decoded by any backend. Either no backends
23 are available or each available backend failed to decode the file.
24 """
2626 except ImportError:
2727 import Queue as queue
2828
29 from . import DecodeError
29 from .exceptions import DecodeError
3030
3131 COMMANDS = ('ffmpeg', 'avconv')
32
33 if sys.platform == "win32":
34 PROC_FLAGS = 0x08000000
35 else:
36 PROC_FLAGS = 0
3237
3338
3439 class FFmpegError(DecodeError):
9095 if i == len(commands) - 1:
9196 # No more commands to try.
9297 raise
98
99
100 def available():
101 """Detect whether the FFmpeg backend can be used on this system.
102 """
103 try:
104 proc = popen_multiple(
105 COMMANDS,
106 ['-version'],
107 stdout=subprocess.PIPE,
108 stderr=subprocess.PIPE,
109 creationflags=PROC_FLAGS,
110 )
111 except OSError:
112 return False
113 else:
114 proc.wait()
115 return proc.returncode == 0
93116
94117
95118 # For Windows error switch management, we need a lock to keep the mode
124147 stdout=subprocess.PIPE,
125148 stderr=subprocess.PIPE,
126149 stdin=self.devnull,
150 creationflags=PROC_FLAGS,
127151 )
128152
129153 except OSError:
257281
258282 def close(self):
259283 """Close the ffmpeg process used to perform the decoding."""
260 # Kill the process if it is still running.
261 if hasattr(self, 'proc') and self.proc.returncode is None:
262 self.proc.kill()
263 self.proc.wait()
264 self.devnull.close()
284 if hasattr(self, 'proc'):
285 # First check the process's execution status before attempting to
286 # kill it. This fixes an issue on Windows Subsystem for Linux where
287 # ffmpeg closes normally on its own, but never updates
288 # `returncode`.
289 self.proc.poll()
290
291 # Kill the process if it is still running.
292 if self.proc.returncode is None:
293 self.proc.kill()
294 self.proc.wait()
295
296 # Wait for the stream-reading threads to exit. (They need to
297 # stop reading before we can close the streams.)
298 if hasattr(self, 'stderr_reader'):
299 self.stderr_reader.join()
300 if hasattr(self, 'stdout_reader'):
301 self.stdout_reader.join()
302
303 # Close the stdout and stderr streams that were opened by Popen,
304 # which should occur regardless of if the process terminated
305 # cleanly.
306 self.proc.stdout.close()
307 self.proc.stderr.close()
308
309 # Close the handle to os.devnull, which is opened regardless of if
310 # a subprocess is successfully created.
311 self.devnull.close()
265312
266313 def __del__(self):
267314 self.close()
5454 import sys
5555 import threading
5656 import os
57 from . import DecodeError
57
58 from .exceptions import DecodeError
5859
5960 try:
6061 import queue
141142 """
142143 def __init__(self):
143144 super(MainLoopThread, self).__init__()
144 self.loop = GLib.MainLoop()
145 self.loop = GLib.MainLoop.new(None, False)
145146 self.daemon = True
146147
147148 def run(self):
310311 # New data is available from the pipeline! Dump it into our
311312 # queue (or possibly block if we're full).
312313 buf = sink.emit('pull-sample').get_buffer()
313 self.queue.put(buf.extract_dup(0, buf.get_size()))
314
315 # We can't use Gst.Buffer.extract() to read the data as it crashes
316 # when called through PyGObject. We also can't use
317 # Gst.Buffer.extract_dup() because we have no way in Python to free
318 # the memory that it returns. Instead we get access to the actual
319 # data via Gst.Memory.map().
320 mem = buf.get_all_memory()
321 success, info = mem.map(Gst.MapFlags.READ)
322 if success:
323 data = info.data
324 mem.unmap(info)
325 self.queue.put(data)
326 else:
327 raise GStreamerError("Unable to map buffer memory while reading the file.")
314328 return Gst.FlowReturn.OK
315329
316330 def _unkown_type(self, uridecodebin, decodebin, caps):
1717 import ctypes
1818 import ctypes.util
1919 import copy
20 from . import DecodeError
20
21 from .exceptions import DecodeError
2122
2223
2324 # CoreFoundation and CoreAudio libraries along with their function
4242 out = self.mf.read(block_size)
4343 if not out:
4444 break
45 yield out
45 yield bytes(out)
4646
4747 @property
4848 def samplerate(self):
1818 import audioop
1919 import struct
2020 import sys
21 from . import DecodeError
21
22 from .exceptions import DecodeError
2223
2324 # Produce two-byte (16-bit) output samples.
2425 TARGET_WIDTH = 2
1313
1414 """Version data for the audioread package."""
1515
16 version = '2.1.5'
16 version = '2.1.8'
1717 short_version = '2.1'
0 Metadata-Version: 1.1
1 Name: audioread
2 Version: 2.1.8
3 Summary: multi-library, cross-platform audio decoding
4 Home-page: https://github.com/sampsyo/audioread
5 Author: Adrian Sampson
6 Author-email: adrian@radbox.org
7 License: MIT
8 Description: audioread
9 =========
10
11 .. image:: https://secure.travis-ci.org/beetbox/audioread.png
12 :target: https://travis-ci.org/beetbox/audioread/
13
14 Decode audio files using whichever backend is available. The library
15 currently supports:
16
17 - `Gstreamer`_ via `PyGObject`_.
18 - `Core Audio`_ on Mac OS X via `ctypes`_. (PyObjC not required.)
19 - `MAD`_ via the `pymad`_ bindings.
20 - `FFmpeg`_ or `Libav`_ via its command-line interface.
21 - The standard library `wave`_, `aifc`_, and `sunau`_ modules (for
22 uncompressed audio formats).
23
24 .. _Gstreamer: http://gstreamer.freedesktop.org/
25 .. _gst-python: http://gstreamer.freedesktop.org/modules/gst-python.html
26 .. _Core Audio: http://developer.apple.com/technologies/mac/audio-and-video.html
27 .. _ctypes: http://docs.python.org/library/ctypes.html
28 .. _MAD: http://www.underbit.com/products/mad/
29 .. _pymad: http://spacepants.org/src/pymad/
30 .. _FFmpeg: http://ffmpeg.org/
31 .. _Libav: https://www.libav.org/
32 .. _wave: http://docs.python.org/library/wave.html
33 .. _aifc: http://docs.python.org/library/aifc.html
34 .. _sunau: http://docs.python.org/library/sunau.html
35 .. _PyGObject: https://pygobject.readthedocs.io/
36
37 Use the library like so::
38
39 with audioread.audio_open(filename) as f:
40 print(f.channels, f.samplerate, f.duration)
41 for buf in f:
42 do_something(buf)
43
44 Buffers in the file can be accessed by iterating over the object returned from
45 ``audio_open``. Each buffer is a bytes-like object (``buffer``, ``bytes``, or
46 ``bytearray``) containing raw **16-bit little-endian signed integer PCM
47 data**. (Currently, these PCM format parameters are not configurable, but this
48 could be added to most of the backends.)
49
50 Additional values are available as fields on the audio file object:
51
52 - ``channels`` is the number of audio channels (an integer).
53 - ``samplerate`` is given in Hz (an integer).
54 - ``duration`` is the length of the audio in seconds (a float).
55
56 The ``audio_open`` function transparently selects a backend that can read the
57 file. (Each backend is implemented in a module inside the ``audioread``
58 package.) If no backends succeed in opening the file, a ``DecodeError``
59 exception is raised. This exception is only used when the file type is
60 unsupported by the backends; if the file doesn't exist, a standard ``IOError``
61 will be raised.
62
63 A second optional parameter to ``audio_open`` specifies which backends to try
64 (instead of trying them all, which is the default). You can use the
65 ``available_backends`` function to get a list backends that are usable on the
66 current system.
67
68 Audioread is "universal" and supports both Python 2 (2.6+) and Python 3
69 (3.2+).
70
71 Example
72 -------
73
74 The included ``decode.py`` script demonstrates using this package to
75 convert compressed audio files to WAV files.
76
77 Version History
78 ---------------
79
80 2.1.8
81 Fix an unhandled ``OSError`` when FFmpeg is not installed.
82
83 2.1.7
84 Properly close some filehandles in the FFmpeg backend (thanks to
85 @RyanMarcus and @ssssam).
86 The maddec backend now always produces bytes objects, like the other
87 backends (thanks to @ssssam).
88 Resolve an audio data memory leak in the GStreamer backend (thanks again to
89 @ssssam).
90 You can now optionally specify which specific backends ``audio_open`` should
91 try (thanks once again to @ssssam).
92 On Windows, avoid opening a console window to run FFmpeg (thanks to @flokX).
93
94 2.1.6
95 Fix a "no such process" crash in the FFmpeg backend on Windows Subsystem for
96 Linux (thanks to @llamasoft).
97 Avoid suppressing SIGINT in the GStreamer backend on older versions of
98 PyGObject (thanks to @lazka).
99
100 2.1.5
101 Properly clean up the file handle when a backend fails to decode a file.
102 Fix parsing of "N.M" channel counts in the FFmpeg backend (thanks to @piem).
103 Avoid a crash in the raw backend when a file uses an unsupported number of
104 bits per sample (namely, 24-bit samples in Python < 3.4).
105 Add a ``__version__`` value to the package.
106
107 2.1.4
108 Fix a bug in the FFmpeg backend where, after closing a file, the program's
109 standard input stream would be "broken" and wouldn't receive any input.
110
111 2.1.3
112 Avoid some warnings in the GStreamer backend when using modern versions of
113 GLib. We now require at least GLib 2.32.
114
115 2.1.2
116 Fix a file descriptor leak when opening and closing many files using
117 GStreamer.
118
119 2.1.1
120 Just fix ReST formatting in the README.
121
122 2.1.0
123 The FFmpeg backend can now also use Libav's ``avconv`` command.
124 Fix a warning by requiring GStreamer >= 1.0.
125 Fix some Python 3 crashes with the new GStreamer backend (thanks to
126 @xix-xeaon).
127
128 2.0.0
129 The GStreamer backend now uses GStreamer 1.x via the new
130 gobject-introspection API (and is compatible with Python 3).
131
132 1.2.2
133 When running FFmpeg on Windows, disable its crash dialog. Thanks to
134 jcsaaddupuy.
135
136 1.2.1
137 Fix an unhandled exception when opening non-raw audio files (thanks to
138 aostanin).
139 Fix Python 3 compatibility for the raw-file backend.
140
141 1.2.0
142 Add support for FFmpeg on Windows (thanks to Jean-Christophe Saad-Dupuy).
143
144 1.1.0
145 Add support for Sun/NeXT `Au files`_ via the standard-library ``sunau``
146 module (thanks to Dan Ellis).
147
148 1.0.3
149 Use the rawread (standard-library) backend for .wav files.
150
151 1.0.2
152 Send SIGKILL, not SIGTERM, to ffmpeg processes to avoid occasional hangs.
153
154 1.0.1
155 When GStreamer fails to report a duration, raise an exception instead of
156 silently setting the duration field to None.
157
158 1.0.0
159 Catch GStreamer's exception when necessary components, such as
160 ``uridecodebin``, are missing.
161 The GStreamer backend now accepts relative paths.
162 Fix a hang in GStreamer when the stream finishes before it begins (when
163 reading broken files).
164 Initial support for Python 3.
165
166 0.8
167 All decoding errors are now subclasses of ``DecodeError``.
168
169 0.7
170 Fix opening WAV and AIFF files via Unicode filenames.
171
172 0.6
173 Make FFmpeg timeout more robust.
174 Dump FFmpeg output on timeout.
175 Fix a nondeterministic hang in the Gstreamer backend.
176 Fix a file descriptor leak in the MAD backend.
177
178 0.5
179 Fix crash when FFmpeg fails to report a duration.
180 Fix a hang when FFmpeg fills up its stderr output buffer.
181 Add a timeout to ``ffmpeg`` tool execution (currently 10 seconds for each
182 4096-byte read); a ``ReadTimeoutError`` exception is raised if the tool times
183 out.
184
185 0.4
186 Fix channel count detection for FFmpeg backend.
187
188 0.3
189 Fix a problem with the Gstreamer backend where audio files could be left open
190 even after the ``GstAudioFile`` was "closed".
191
192 0.2
193 Fix a hang in the GStreamer backend that occurs occasionally on some
194 platforms.
195
196 0.1
197 Initial release.
198
199 .. _Au files: http://en.wikipedia.org/wiki/Au_file_format
200
201 Et Cetera
202 ---------
203
204 ``audioread`` is by Adrian Sampson. It is made available under `the MIT
205 license`_. An alternative to this module is `decoder.py`_.
206
207 .. _the MIT license: http://www.opensource.org/licenses/mit-license.php
208 .. _decoder.py: http://www.brailleweb.com/cgi-bin/python.py
209
210 Platform: ALL
211 Classifier: Topic :: Multimedia :: Sound/Audio :: Conversion
212 Classifier: Intended Audience :: Developers
213 Classifier: Programming Language :: Python :: 2
214 Classifier: Programming Language :: Python :: 2.6
215 Classifier: Programming Language :: Python :: 2.7
216 Classifier: Programming Language :: Python :: 3
217 Classifier: Programming Language :: Python :: 3.2
218 Classifier: Programming Language :: Python :: 3.3
219 Classifier: Programming Language :: Python :: 3.4
220 Classifier: Programming Language :: Python :: 3.5
221 Classifier: Programming Language :: Python :: 3.6
0 LICENSE
1 MANIFEST.in
2 README.rst
3 decode.py
4 setup.cfg
5 setup.py
6 audioread/__init__.py
7 audioread/exceptions.py
8 audioread/ffdec.py
9 audioread/gstdec.py
10 audioread/macca.py
11 audioread/maddec.py
12 audioread/rawread.py
13 audioread/version.py
14 audioread.egg-info/.pbr.json.icloud
15 audioread.egg-info/PKG-INFO
16 audioread.egg-info/SOURCES.txt
17 audioread.egg-info/dependency_links.txt
18 audioread.egg-info/top_level.txt
19 test/test_audioread.py
0 [aliases]
1 test = pytest
2
3 [egg_info]
4 tag_build =
5 tag_date = 0
6
1212 # included in all copies or substantial portions of the Software.
1313
1414 import os
15 from distutils.core import setup
15 from setuptools import setup
1616 import imp
1717
1818 version = imp.load_source('audioread.version', 'audioread/version.py')
3535
3636 packages=['audioread'],
3737
38 setup_requires=[
39 'pytest-runner'
40 ],
41
42 tests_require=[
43 'pytest'
44 ],
45
3846 classifiers=[
3947 'Topic :: Multimedia :: Sound/Audio :: Conversion',
4048 'Intended Audience :: Developers',
0 # This file is part of audioread.
1 # Copyright 2018, Sam Thursfield
2 #
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 #
11 # The above copyright notice and this permission notice shall be
12 # included in all copies or substantial portions of the Software.
13
14
15 import json
16 import os
17 import sys
18
19 import pytest
20
21 import audioread
22
23
24 # The 'audiofile' fixture is defined in conftest.py.
25
26
27 def test_audioread_early_exit(audiofile):
28 """Abort the read before it is completed.
29
30 This test guards against regressions such as
31 https://github.com/beetbox/audioread/pull/78
32
33 """
34 with audioread.audio_open(audiofile.path) as a:
35 assert int(a.duration) == int(audiofile.duration)
36 assert a.channels == audiofile.channels
37 assert a.samplerate == audiofile.samplerate
38 # Now we exit the context manager without reading any data.
39
40
41 def test_audioread_full(audiofile):
42 """Read the audio data from the file."""
43 with audioread.audio_open(audiofile.path) as a:
44 assert int(a.duration) == int(audiofile.duration)
45 assert a.channels == audiofile.channels
46 assert a.samplerate == audiofile.samplerate
47
48 # Now read all the data and assert that it's the correct type.
49 for block in a:
50 assert type(block) == bytes