diff -r 7b165c7ab7ef Doc/library/sndhdr.rst --- a/Doc/library/sndhdr.rst Thu Aug 01 15:32:49 2013 +0200 +++ b/Doc/library/sndhdr.rst Thu Aug 01 18:08:36 2013 +0300 @@ -16,7 +16,7 @@ The :mod:`sndhdr` provides utility functions which attempt to determine the type of sound data which is in a file. When these functions are able to determine -what type of sound data is stored in a file, they return a tuple ``(type, +what type of sound data is stored in a file, they return a namedtuple ``(type, sampling_rate, channels, frames, bits_per_sample)``. The value for *type* indicates the data type and will be one of the strings ``'aifc'``, ``'aiff'``, ``'au'``, ``'hcom'``, ``'sndr'``, ``'sndt'``, ``'voc'``, ``'wav'``, ``'8svx'``, @@ -31,13 +31,13 @@ .. function:: what(filename) Determines the type of sound data stored in the file *filename* using - :func:`whathdr`. If it succeeds, returns a tuple as described above, otherwise + :func:`whathdr`. If it succeeds, returns a namedtuple as described above, otherwise ``None`` is returned. .. function:: whathdr(filename) Determines the type of sound data stored in a file based on the file header. - The name of the file is given by *filename*. This function returns a tuple as + The name of the file is given by *filename*. This function returns a namedtuple as described above on success, or ``None``. diff -r 7b165c7ab7ef Lib/sndhdr.py --- a/Lib/sndhdr.py Thu Aug 01 15:32:49 2013 +0200 +++ b/Lib/sndhdr.py Thu Aug 01 18:08:36 2013 +0300 @@ -32,6 +32,11 @@ __all__ = ['what', 'whathdr'] +from collections import namedtuple + +_SndHeaders = namedtuple('_SndHeaders', + 'filetype framerate nchannels nframes sampwidth') + def what(filename): """Guess the type of a sound file.""" res = whathdr(filename) @@ -70,7 +75,7 @@ a = aifc.open(f, 'r') except (EOFError, aifc.Error): return None - return (fmt, a.getframerate(), a.getnchannels(), + return _SndHeaders(fmt, a.getframerate(), a.getnchannels(), a.getnframes(), 8 * a.getsampwidth()) tests.append(test_aifc) @@ -104,7 +109,7 @@ nframe = data_size / frame_size else: nframe = -1 - return filetype, rate, nchannels, nframe, sample_bits + return _SndHeaders(filetype, rate, nchannels, nframe, sample_bits) tests.append(test_au) @@ -117,7 +122,7 @@ rate = 22050 / divisor else: rate = 0 - return 'hcom', rate, 1, -1, 8 + return _SndHeaders('hcom', rate, 1, -1, 8) tests.append(test_hcom) @@ -131,7 +136,7 @@ ratecode = 256 - h[sbseek+4] if ratecode: rate = int(1000000.0 / ratecode) - return 'voc', rate, 1, -1, 8 + return _SndHeaders('voc', rate, 1, -1, 8) tests.append(test_voc) @@ -146,7 +151,7 @@ w = wave.openfp(f, 'r') except (EOFError, wave.Error): return None - return ('wav', w.getframerate(), w.getnchannels(), + return _SndHeaders('wav', w.getframerate(), w.getnchannels(), w.getnframes(), 8*w.getsampwidth()) tests.append(test_wav) @@ -156,7 +161,7 @@ if not h.startswith(b'FORM') or h[8:12] != b'8SVX': return None # Should decode it to get #channels -- assume always 1 - return '8svx', 0, 1, 0, 8 + return _SndHeaders('8svx', 0, 1, 0, 8) tests.append(test_8svx) @@ -165,7 +170,7 @@ if h.startswith(b'SOUND'): nsamples = get_long_le(h[8:12]) rate = get_short_le(h[20:22]) - return 'sndt', rate, 1, nsamples, 8 + return _SndHeaders('sndt', rate, 1, nsamples, 8) tests.append(test_sndt) @@ -174,7 +179,7 @@ if h.startswith(b'\0\0'): rate = get_short_le(h[2:4]) if 4000 <= rate <= 25000: - return 'sndr', rate, 1, -1, 8 + return _SndHeaders('sndr', rate, 1, -1, 8) tests.append(test_sndr) diff -r 7b165c7ab7ef Lib/test/test_sndhdr.py --- a/Lib/test/test_sndhdr.py Thu Aug 01 15:32:49 2013 +0200 +++ b/Lib/test/test_sndhdr.py Thu Aug 01 18:08:36 2013 +0300 @@ -1,4 +1,5 @@ import sndhdr +import pickle import unittest from test.support import findfile @@ -18,6 +19,18 @@ what = sndhdr.what(filename) self.assertNotEqual(what, None, filename) self.assertSequenceEqual(what, expected) + self.assertEqual(what.filetype, expected[0]) + self.assertEqual(what.framerate, expected[1]) + self.assertEqual(what.nchannels, expected[2]) + self.assertEqual(what.nframes, expected[3]) + self.assertEqual(what.sampwidth, expected[4]) + + def test_pickleable(self): + filename = findfile('sndhdr.aifc', subdir="sndhdrdata") + what = sndhdr.what(filename) + dump = pickle.dumps(what) + self.assertEqual(pickle.loads(dump), what) + if __name__ == '__main__': unittest.main()