Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-85525: Indicate supported sound header formats #21575

Merged
merged 4 commits into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions Doc/library/sndhdr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,52 @@ be the sample size in bits or ``'A'`` for A-LAW or ``'U'`` for u-LAW.
.. versionchanged:: 3.5
Result changed from a tuple to a namedtuple.

The following sound header types are recognized, as listed below with the return value
from :func:`whathdr`: and :func:`what`:

+------------+------------------------------------+
| Value | Sound header format |
+============+====================================+
| ``'aifc'`` | Compressed Audio Interchange Files |
+------------+------------------------------------+
| ``'aiff'`` | Audio Interchange Files |
nanjekyejoannah marked this conversation as resolved.
Show resolved Hide resolved
+------------+------------------------------------+
| ``'au'`` | Au Files |
+------------+------------------------------------+
| ``'hcom'`` | HCOM Files |
+------------+------------------------------------+
+------------+------------------------------------+
nanjekyejoannah marked this conversation as resolved.
Show resolved Hide resolved
| ``'sndt'`` | Sndtool Sound Files |
+------------+------------------------------------+
| ``'voc'`` | Creative Labs Audio Files |
+------------+------------------------------------+
| ``'wav'`` | Waveform Audio File Format Files |
+------------+------------------------------------+
| ``'8svx'`` | 8-Bit Sampled Voice Files |
+------------+------------------------------------+
| ``'sb'`` | Signed Byte Audio Data Files |
+------------+------------------------------------+
| ``'ub'`` | UB Files |
+------------+------------------------------------+
| ``'ul'`` | uLAW Audio Files |
+------------+------------------------------------+

.. data:: tests
nanjekyejoannah marked this conversation as resolved.
Show resolved Hide resolved

A list of functions performing the individual tests. Each function takes two
arguments: the byte-stream and an open file-like object. When :func:`what` is
called with a byte-stream, the file-like object will be ``None``.

The test function should return a string describing the image type if the test
succeeded, or ``None`` if it failed.

Example:

.. code-block:: pycon

>>> import sndhdr
>>> imghdr.what('bass.wav')
'wav'
>>> imghdr.whathdr('bass.wav')
'wav'

8 changes: 8 additions & 0 deletions Lib/sndhdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def whathdr(filename):
tests = []

def test_aifc(h, f):
"""AIFC and AIFF files"""
with warnings.catch_warnings():
warnings.simplefilter('ignore', category=DeprecationWarning)
import aifc
Expand All @@ -100,6 +101,7 @@ def test_aifc(h, f):


def test_au(h, f):
"""AU and SND files"""
if h.startswith(b'.snd'):
func = get_long_be
elif h[:4] in (b'\0ds.', b'dns.'):
Expand Down Expand Up @@ -133,6 +135,7 @@ def test_au(h, f):


def test_hcom(h, f):
"""HCOM file"""
if h[65:69] != b'FSSD' or h[128:132] != b'HCOM':
return None
divisor = get_long_be(h[144:148])
Expand All @@ -146,6 +149,7 @@ def test_hcom(h, f):


def test_voc(h, f):
"""VOC file"""
if not h.startswith(b'Creative Voice File\032'):
return None
sbseek = get_short_le(h[20:22])
Expand All @@ -160,6 +164,7 @@ def test_voc(h, f):


def test_wav(h, f):
"""WAV file"""
import wave
# 'RIFF' <len> 'WAVE' 'fmt ' <len>
if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ':
Expand All @@ -176,6 +181,7 @@ def test_wav(h, f):


def test_8svx(h, f):
"""8SVX file"""
if not h.startswith(b'FORM') or h[8:12] != b'8SVX':
return None
# Should decode it to get #channels -- assume always 1
Expand All @@ -185,6 +191,7 @@ def test_8svx(h, f):


def test_sndt(h, f):
"""SNDT file"""
if h.startswith(b'SOUND'):
nsamples = get_long_le(h[8:12])
rate = get_short_le(h[20:22])
Expand All @@ -194,6 +201,7 @@ def test_sndt(h, f):


def test_sndr(h, f):
"""SNDR file"""
if h.startswith(b'\0\0'):
rate = get_short_le(h[2:4])
if 4000 <= rate <= 25000:
Expand Down