[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