Import upstream version 2.1.8, md5 f8a67aac7eb5a0bb263851fc4ddbb527
Debian Janitor
4 years ago
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 |
0 | 0 | Metadata-Version: 1.1 |
1 | 1 | Name: audioread |
2 | Version: 2.1.5 | |
2 | Version: 2.1.8 | |
3 | 3 | Summary: multi-library, cross-platform audio decoding |
4 | 4 | Home-page: https://github.com/sampsyo/audioread |
5 | 5 | Author: Adrian Sampson |
32 | 32 | .. _wave: http://docs.python.org/library/wave.html |
33 | 33 | .. _aifc: http://docs.python.org/library/aifc.html |
34 | 34 | .. _sunau: http://docs.python.org/library/sunau.html |
35 | .. _PyGObject: https://wiki.gnome.org/Projects/PyGObject | |
35 | .. _PyGObject: https://pygobject.readthedocs.io/ | |
36 | 36 | |
37 | 37 | Use the library like so:: |
38 | 38 | |
60 | 60 | unsupported by the backends; if the file doesn't exist, a standard ``IOError`` |
61 | 61 | will be raised. |
62 | 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 | ||
63 | 68 | Audioread is "universal" and supports both Python 2 (2.6+) and Python 3 |
64 | 69 | (3.2+). |
65 | 70 | |
71 | 76 | |
72 | 77 | Version History |
73 | 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). | |
74 | 99 | |
75 | 100 | 2.1.5 |
76 | 101 | Properly clean up the file handle when a backend fails to decode a file. |
24 | 24 | .. _wave: http://docs.python.org/library/wave.html |
25 | 25 | .. _aifc: http://docs.python.org/library/aifc.html |
26 | 26 | .. _sunau: http://docs.python.org/library/sunau.html |
27 | .. _PyGObject: https://wiki.gnome.org/Projects/PyGObject | |
27 | .. _PyGObject: https://pygobject.readthedocs.io/ | |
28 | 28 | |
29 | 29 | Use the library like so:: |
30 | 30 | |
52 | 52 | unsupported by the backends; if the file doesn't exist, a standard ``IOError`` |
53 | 53 | will be raised. |
54 | 54 | |
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 | ||
55 | 60 | Audioread is "universal" and supports both Python 2 (2.6+) and Python 3 |
56 | 61 | (3.2+). |
57 | 62 | |
63 | 68 | |
64 | 69 | Version History |
65 | 70 | --------------- |
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). | |
66 | 91 | |
67 | 92 | 2.1.5 |
68 | 93 | Properly clean up the file handle when a backend fails to decode a file. |
13 | 13 | |
14 | 14 | """Decode audio files.""" |
15 | 15 | |
16 | from . import ffdec | |
17 | from .exceptions import DecodeError, NoBackendError | |
16 | 18 | 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 | """ | |
29 | 19 | |
30 | 20 | |
31 | 21 | def _gst_available(): |
69 | 59 | return True |
70 | 60 | |
71 | 61 | |
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 | ||
76 | 65 | # Standard-library WAV and AIFF readers. |
77 | 66 | from . import rawread |
78 | try: | |
79 | return rawread.RawAudioFile(path) | |
80 | except DecodeError: | |
81 | pass | |
67 | result = [rawread.RawAudioFile] | |
82 | 68 | |
83 | 69 | # Core Audio. |
84 | 70 | if _ca_available(): |
85 | 71 | from . import macca |
86 | try: | |
87 | return macca.ExtAudioFile(path) | |
88 | except DecodeError: | |
89 | pass | |
72 | result.append(macca.ExtAudioFile) | |
90 | 73 | |
91 | 74 | # GStreamer. |
92 | 75 | if _gst_available(): |
93 | 76 | from . import gstdec |
94 | try: | |
95 | return gstdec.GstAudioFile(path) | |
96 | except DecodeError: | |
97 | pass | |
77 | result.append(gstdec.GstAudioFile) | |
98 | 78 | |
99 | 79 | # MAD. |
100 | 80 | if _mad_available(): |
101 | 81 | 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: | |
102 | 109 | try: |
103 | return maddec.MadAudioFile(path) | |
110 | return BackendClass(path) | |
104 | 111 | except DecodeError: |
105 | 112 | pass |
106 | 113 | |
107 | # FFmpeg. | |
108 | from . import ffdec | |
109 | try: | |
110 | return ffdec.FFmpegAudioFile(path) | |
111 | except DecodeError: | |
112 | pass | |
113 | ||
114 | 114 | # All backends failed! |
115 | 115 | 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 | """ |
26 | 26 | except ImportError: |
27 | 27 | import Queue as queue |
28 | 28 | |
29 | from . import DecodeError | |
29 | from .exceptions import DecodeError | |
30 | 30 | |
31 | 31 | COMMANDS = ('ffmpeg', 'avconv') |
32 | ||
33 | if sys.platform == "win32": | |
34 | PROC_FLAGS = 0x08000000 | |
35 | else: | |
36 | PROC_FLAGS = 0 | |
32 | 37 | |
33 | 38 | |
34 | 39 | class FFmpegError(DecodeError): |
90 | 95 | if i == len(commands) - 1: |
91 | 96 | # No more commands to try. |
92 | 97 | 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 | |
93 | 116 | |
94 | 117 | |
95 | 118 | # For Windows error switch management, we need a lock to keep the mode |
124 | 147 | stdout=subprocess.PIPE, |
125 | 148 | stderr=subprocess.PIPE, |
126 | 149 | stdin=self.devnull, |
150 | creationflags=PROC_FLAGS, | |
127 | 151 | ) |
128 | 152 | |
129 | 153 | except OSError: |
257 | 281 | |
258 | 282 | def close(self): |
259 | 283 | """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() | |
265 | 312 | |
266 | 313 | def __del__(self): |
267 | 314 | self.close() |
54 | 54 | import sys |
55 | 55 | import threading |
56 | 56 | import os |
57 | from . import DecodeError | |
57 | ||
58 | from .exceptions import DecodeError | |
58 | 59 | |
59 | 60 | try: |
60 | 61 | import queue |
141 | 142 | """ |
142 | 143 | def __init__(self): |
143 | 144 | super(MainLoopThread, self).__init__() |
144 | self.loop = GLib.MainLoop() | |
145 | self.loop = GLib.MainLoop.new(None, False) | |
145 | 146 | self.daemon = True |
146 | 147 | |
147 | 148 | def run(self): |
310 | 311 | # New data is available from the pipeline! Dump it into our |
311 | 312 | # queue (or possibly block if we're full). |
312 | 313 | 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.") | |
314 | 328 | return Gst.FlowReturn.OK |
315 | 329 | |
316 | 330 | def _unkown_type(self, uridecodebin, decodebin, caps): |
17 | 17 | import ctypes |
18 | 18 | import ctypes.util |
19 | 19 | import copy |
20 | from . import DecodeError | |
20 | ||
21 | from .exceptions import DecodeError | |
21 | 22 | |
22 | 23 | |
23 | 24 | # CoreFoundation and CoreAudio libraries along with their function |
42 | 42 | out = self.mf.read(block_size) |
43 | 43 | if not out: |
44 | 44 | break |
45 | yield out | |
45 | yield bytes(out) | |
46 | 46 | |
47 | 47 | @property |
48 | 48 | def samplerate(self): |
18 | 18 | import audioop |
19 | 19 | import struct |
20 | 20 | import sys |
21 | from . import DecodeError | |
21 | ||
22 | from .exceptions import DecodeError | |
22 | 23 | |
23 | 24 | # Produce two-byte (16-bit) output samples. |
24 | 25 | TARGET_WIDTH = 2 |
13 | 13 | |
14 | 14 | """Version data for the audioread package.""" |
15 | 15 | |
16 | version = '2.1.5' | |
16 | version = '2.1.8' | |
17 | 17 | short_version = '2.1' |
Binary diff not shown
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 | audioread |
12 | 12 | # included in all copies or substantial portions of the Software. |
13 | 13 | |
14 | 14 | import os |
15 | from distutils.core import setup | |
15 | from setuptools import setup | |
16 | 16 | import imp |
17 | 17 | |
18 | 18 | version = imp.load_source('audioread.version', 'audioread/version.py') |
35 | 35 | |
36 | 36 | packages=['audioread'], |
37 | 37 | |
38 | setup_requires=[ | |
39 | 'pytest-runner' | |
40 | ], | |
41 | ||
42 | tests_require=[ | |
43 | 'pytest' | |
44 | ], | |
45 | ||
38 | 46 | classifiers=[ |
39 | 47 | 'Topic :: Multimedia :: Sound/Audio :: Conversion', |
40 | 48 | '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 |