[Python-modules-commits] [audioread] 01/04: Import audioread_2.1.5.orig.tar.gz
Tristan Seligmann
mithrandi at moszumanska.debian.org
Fri Jun 30 00:47:40 UTC 2017
This is an automated email from the git hooks/post-receive script.
mithrandi pushed a commit to branch master
in repository audioread.
commit e1846d0d4ea4850d388bb8219e20e3e0632dbb54
Author: Tristan Seligmann <mithrandi at debian.org>
Date: Fri Jun 30 02:43:33 2017 +0200
Import audioread_2.1.5.orig.tar.gz
---
PKG-INFO | 18 +++++++++++++-----
README.rst | 15 +++++++++++----
audioread/__init__.py | 2 ++
audioread/ffdec.py | 6 +++---
audioread/macca.py | 26 ++++++++++++++++++--------
audioread/maddec.py | 10 +++++++---
audioread/rawread.py | 35 +++++++++++++++++++++++++++++------
audioread/version.py | 18 ++++++++++++++++++
setup.py | 6 +++++-
9 files changed, 106 insertions(+), 30 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index 396a5b2..587f759 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: audioread
-Version: 2.1.4
+Version: 2.1.5
Summary: multi-library, cross-platform audio decoding
Home-page: https://github.com/sampsyo/audioread
Author: Adrian Sampson
@@ -43,10 +43,10 @@ Description: audioread
do_something(buf)
Buffers in the file can be accessed by iterating over the object returned from
- ``audio_open``. Each buffer is a ``buffer`` or ``str`` object containing raw
- **16-bit little-endian signed integer PCM data**. (Currently, these PCM format
- parameters are not configurable, but this could be added to most of the
- backends.)
+ ``audio_open``. Each buffer is a bytes-like object (``buffer``, ``bytes``, or
+ ``bytearray``) containing raw **16-bit little-endian signed integer PCM
+ data**. (Currently, these PCM format parameters are not configurable, but this
+ could be added to most of the backends.)
Additional values are available as fields on the audio file object:
@@ -73,6 +73,13 @@ Description: audioread
Version History
---------------
+ 2.1.5
+ Properly clean up the file handle when a backend fails to decode a file.
+ Fix parsing of "N.M" channel counts in the FFmpeg backend (thanks to @piem).
+ Avoid a crash in the raw backend when a file uses an unsupported number of
+ bits per sample (namely, 24-bit samples in Python < 3.4).
+ Add a ``__version__`` value to the package.
+
2.1.4
Fix a bug in the FFmpeg backend where, after closing a file, the program's
standard input stream would be "broken" and wouldn't receive any input.
@@ -187,3 +194,4 @@ Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
diff --git a/README.rst b/README.rst
index 0c968d7..1cbe833 100644
--- a/README.rst
+++ b/README.rst
@@ -35,10 +35,10 @@ Use the library like so::
do_something(buf)
Buffers in the file can be accessed by iterating over the object returned from
-``audio_open``. Each buffer is a ``buffer`` or ``str`` object containing raw
-**16-bit little-endian signed integer PCM data**. (Currently, these PCM format
-parameters are not configurable, but this could be added to most of the
-backends.)
+``audio_open``. Each buffer is a bytes-like object (``buffer``, ``bytes``, or
+``bytearray``) containing raw **16-bit little-endian signed integer PCM
+data**. (Currently, these PCM format parameters are not configurable, but this
+could be added to most of the backends.)
Additional values are available as fields on the audio file object:
@@ -65,6 +65,13 @@ convert compressed audio files to WAV files.
Version History
---------------
+2.1.5
+ Properly clean up the file handle when a backend fails to decode a file.
+ Fix parsing of "N.M" channel counts in the FFmpeg backend (thanks to @piem).
+ Avoid a crash in the raw backend when a file uses an unsupported number of
+ bits per sample (namely, 24-bit samples in Python < 3.4).
+ Add a ``__version__`` value to the package.
+
2.1.4
Fix a bug in the FFmpeg backend where, after closing a file, the program's
standard input stream would be "broken" and wouldn't receive any input.
diff --git a/audioread/__init__.py b/audioread/__init__.py
index eecce32..740bc55 100644
--- a/audioread/__init__.py
+++ b/audioread/__init__.py
@@ -14,6 +14,8 @@
"""Decode audio files."""
+from .version import version as __version__ # noqa
+
class DecodeError(Exception):
"""The base exception class for all decoding errors raised by this
diff --git a/audioread/ffdec.py b/audioread/ffdec.py
index 622f31d..ce02df8 100644
--- a/audioread/ffdec.py
+++ b/audioread/ffdec.py
@@ -231,9 +231,9 @@ class FFmpegAudioFile(object):
if mode == 'stereo':
self.channels = 2
else:
- match = re.match(r'(\d+) ', mode)
- if match:
- self.channels = int(match.group(1))
+ cmatch = re.match(r'(\d+)\.?(\d)?', mode)
+ if cmatch:
+ self.channels = sum(map(int, cmatch.group().split('.')))
else:
self.channels = 1
else:
diff --git a/audioread/macca.py b/audioread/macca.py
index 0ad2002..e1903c0 100644
--- a/audioread/macca.py
+++ b/audioread/macca.py
@@ -8,7 +8,7 @@
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
-#
+#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
@@ -26,12 +26,15 @@ from . import DecodeError
def _load_framework(name):
return ctypes.cdll.LoadLibrary(ctypes.util.find_library(name))
+
+
_coreaudio = _load_framework('AudioToolbox')
_corefoundation = _load_framework('CoreFoundation')
-# Convert CFStrings to C strings.
+# Convert CFStrings to C strings.
_corefoundation.CFStringGetCStringPtr.restype = ctypes.c_char_p
-_corefoundation.CFStringGetCStringPtr.argtypes = [ctypes.c_void_p, ctypes.c_int]
+_corefoundation.CFStringGetCStringPtr.argtypes = [ctypes.c_void_p,
+ ctypes.c_int]
# Free memory.
_corefoundation.CFRelease.argtypes = [ctypes.c_void_p]
@@ -82,6 +85,7 @@ def multi_char_literal(chars):
num |= ord(char) << shift
return num
+
PROP_FILE_DATA_FORMAT = multi_char_literal('ffmt')
PROP_CLIENT_DATA_FORMAT = multi_char_literal('cfmt')
PROP_LENGTH = multi_char_literal('#frm')
@@ -107,6 +111,7 @@ class MacError(DecodeError):
msg = 'error %i' % code
super(MacError, self).__init__(msg)
+
def check(err):
"""If err is nonzero, raise a MacError exception."""
if err == ERROR_NOT_FOUND:
@@ -127,6 +132,7 @@ class CFObject(object):
if _corefoundation:
_corefoundation.CFRelease(self._obj)
+
class CFURL(CFObject):
def __init__(self, filename):
if not isinstance(filename, bytes):
@@ -136,7 +142,7 @@ class CFURL(CFObject):
0, filename, len(filename), False
)
super(CFURL, self).__init__(url)
-
+
def __str__(self):
cfstr = _corefoundation.CFURLGetString(self._obj)
out = _corefoundation.CFStringGetCStringPtr(cfstr, 0)
@@ -159,6 +165,7 @@ class AudioStreamBasicDescription(ctypes.Structure):
("mReserved", ctypes.c_uint),
]
+
class AudioBuffer(ctypes.Structure):
_fields_ = [
("mNumberChannels", ctypes.c_uint),
@@ -166,6 +173,7 @@ class AudioBuffer(ctypes.Structure):
("mData", ctypes.c_void_p),
]
+
class AudioBufferList(ctypes.Structure):
_fields_ = [
("mNumberBuffers", ctypes.c_uint),
@@ -295,7 +303,8 @@ class ExtAudioFile(object):
buflist = AudioBufferList()
buflist.mNumberBuffers = 1
- buflist.mBuffers[0].mNumberChannels = self._client_fmt.mChannelsPerFrame
+ buflist.mBuffers[0].mNumberChannels = \
+ self._client_fmt.mChannelsPerFrame
buflist.mBuffers[0].mDataByteSize = blocksize
buflist.mBuffers[0].mData = ctypes.cast(buf, ctypes.c_void_p)
@@ -303,14 +312,14 @@ class ExtAudioFile(object):
check(_coreaudio.ExtAudioFileRead(
self._obj, ctypes.byref(frames), ctypes.byref(buflist)
))
-
+
assert buflist.mNumberBuffers == 1
size = buflist.mBuffers[0].mDataByteSize
if not size:
break
data = ctypes.cast(buflist.mBuffers[0].mData,
- ctypes.POINTER(ctypes.c_char))
+ ctypes.POINTER(ctypes.c_char))
blob = data[:size]
yield blob
@@ -324,9 +333,10 @@ class ExtAudioFile(object):
if _coreaudio:
self.close()
- # Context manager.
+ # Context manager methods.
def __enter__(self):
return self
+
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
return False
diff --git a/audioread/maddec.py b/audioread/maddec.py
index a2e129a..8dd7aaa 100644
--- a/audioread/maddec.py
+++ b/audioread/maddec.py
@@ -8,7 +8,7 @@
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
-#
+#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
@@ -16,15 +16,18 @@
import mad
from . import DecodeError
+
class UnsupportedError(DecodeError):
"""The file is not readable by MAD."""
+
class MadAudioFile(object):
"""MPEG audio file decoder using the MAD library."""
def __init__(self, filename):
self.fp = open(filename, 'rb')
self.mf = mad.MadFile(self.fp)
- if not self.mf.total_time(): # Indicates a failed open.
+ if not self.mf.total_time(): # Indicates a failed open.
+ self.fp.close()
raise UnsupportedError()
def close(self):
@@ -46,7 +49,7 @@ class MadAudioFile(object):
def samplerate(self):
"""Sample rate in Hz."""
return self.mf.samplerate()
-
+
@property
def duration(self):
"""Length of the audio in seconds (a float)."""
@@ -75,6 +78,7 @@ class MadAudioFile(object):
# Context manager.
def __enter__(self):
return self
+
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
return False
diff --git a/audioread/rawread.py b/audioread/rawread.py
index 7ce2579..2ff476a 100644
--- a/audioread/rawread.py
+++ b/audioread/rawread.py
@@ -18,13 +18,25 @@ import aifc
import sunau
import audioop
import struct
+import sys
from . import DecodeError
+# Produce two-byte (16-bit) output samples.
TARGET_WIDTH = 2
+# Python 3.4 added support for 24-bit (3-byte) samples.
+if sys.version_info > (3, 4, 0):
+ SUPPORTED_WIDTHS = (1, 2, 3, 4)
+else:
+ SUPPORTED_WIDTHS = (1, 2, 4)
+
class UnsupportedError(DecodeError):
- """File is neither an AIFF nor a WAV file."""
+ """File is not an AIFF, WAV, or Au file."""
+
+
+class BitWidthError(DecodeError):
+ """The file uses an unsupported bit width."""
def byteswap(s):
@@ -42,8 +54,8 @@ def byteswap(s):
class RawAudioFile(object):
- """An AIFF or WAV file that can be read by the Python standard
- library modules ``wave`` and ``aifc``.
+ """An AIFF, WAV, or Au file that can be read by the Python standard
+ library modules ``wave``, ``aifc``, and ``sunau``.
"""
def __init__(self, filename):
self._fh = open(filename, 'rb')
@@ -51,34 +63,45 @@ class RawAudioFile(object):
try:
self._file = aifc.open(self._fh)
except aifc.Error:
- # Return to the beginning of the file to try the WAV reader.
+ # Return to the beginning of the file to try the next reader.
self._fh.seek(0)
else:
self._needs_byteswap = True
+ self._check()
return
try:
self._file = wave.open(self._fh)
except wave.Error:
- # Return to the beginning of the file to try the next reader
self._fh.seek(0)
pass
else:
self._needs_byteswap = False
+ self._check()
return
try:
self._file = sunau.open(self._fh)
except sunau.Error:
- # Return to the beginning of the file to try the next reader
self._fh.seek(0)
pass
else:
self._needs_byteswap = True
+ self._check()
return
+ # None of the three libraries could open the file.
+ self._fh.close()
raise UnsupportedError()
+ def _check(self):
+ """Check that the files' parameters allow us to decode it and
+ raise an error otherwise.
+ """
+ if self._file.getsampwidth() not in SUPPORTED_WIDTHS:
+ self.close()
+ raise BitWidthError()
+
def close(self):
"""Close the underlying file."""
self._file.close()
diff --git a/audioread/version.py b/audioread/version.py
new file mode 100644
index 0000000..d3e3fee
--- /dev/null
+++ b/audioread/version.py
@@ -0,0 +1,18 @@
+# This file is part of audioread.
+# Copyright 2017, Adrian Sampson.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+
+"""Version data for the audioread package."""
+
+version = '2.1.5'
+short_version = '2.1'
diff --git a/setup.py b/setup.py
index 1d3aa58..58845cb 100644
--- a/setup.py
+++ b/setup.py
@@ -14,6 +14,9 @@
import os
from distutils.core import setup
+import imp
+
+version = imp.load_source('audioread.version', 'audioread/version.py')
def _read(fn):
@@ -22,7 +25,7 @@ def _read(fn):
setup(name='audioread',
- version='2.1.4',
+ version=version.version,
description='multi-library, cross-platform audio decoding',
author='Adrian Sampson',
author_email='adrian at radbox.org',
@@ -44,5 +47,6 @@ setup(name='audioread',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
],
)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/audioread.git
More information about the Python-modules-commits
mailing list