diff --git a/Lib/lib-old/whatsound.py b/Lib/lib-old/whatsound.py
index b7b349c..1b1df23 100644
--- a/Lib/lib-old/whatsound.py
+++ b/Lib/lib-old/whatsound.py
@@ -1,270 +1 @@
-# This module contains several routines that help recognizing sound
-# files.
-#
-# Function whathdr() recognizes various types of sound file headers.
-# It understands almost all headers that SOX can decode.
-#
-# The return tuple contains the following items, in this order:
-# - file type (as SOX understands it)
-# - sampling rate (0 if unknown or hard to decode)
-# - number of channels (0 if unknown or hard to decode)
-# - number of frames in the file (-1 if unknown or hard to decode)
-# - number of bits/sample, or 'U' for U-LAW, or 'A' for A-LAW
-#
-# If the file doesn't have a recognizable type, it returns None.
-# If the file can't be opened, IOError is raised.
-#
-# To compute the total time, divide the number of frames by the
-# sampling rate (a frame contains a sample for each channel).
-#
-# Function whatraw() calls the "whatsound" program and interprets its
-# output.  You'll have to guess the sampling rate by listening though!
-#
-# Function what() calls whathdr() and if it doesn't recognize the file
-# then calls whatraw().
-#
-# Finally, the function test() is a simple main program that calls
-# what() for all files mentioned on the argument list.  For directory
-# arguments it calls what() for all files in that directory.  Default
-# argument is "." (testing all files in the current directory).  The
-# option -r tells it to recurse down directories found inside
-# explicitly given directories.
-#
-# The file structure is top-down except that the test program and its
-# subroutine come last.
-
-
-#------------------------------------------------------#
-# Guess the type of any sound file, raw or with header #
-#------------------------------------------------------#
-
-def what(filename):
-	res = whathdr(filename)
-	if not res:
-		res = whatraw(filename)
-	return res
-
-
-#-----------------------------#
-# Guess the type of raw sound #
-#-----------------------------#
-
-def whatraw(filename):
-	# Assume it's always 1 channel, byte-sized samples
-	# Don't assume anything about the rate
-	import os
-	from stat import ST_SIZE
-	# XXX "whatsound" should be part of the distribution somehow...
-	cmd = 'whatsound ' + filename + ' 2>/dev/null'
-	cmd = 'PATH=$PATH:/ufs/guido/bin/sgi\n' + cmd
-	pipe = os.popen(cmd, 'r')
-	data = pipe.read()
-	sts = pipe.close()
-	if sts:
-		return None
-	if data[:13] == '-t raw -b -s ':
-		type = 'sb'
-		sample_size = 8
-	elif data[:13] == '-t raw -b -u ':
-		type = 'ub'
-		sample_size = 8
-	elif data[:13] == '-t raw -b -U ':
-		type = 'ul'
-		sample_size = 'U'
-	else:
-		return None
-	try:
-		frame_count = os.stat(filename)[ST_SIZE]
-	except IOError:
-		frame_count = -1
-	return type, 0, 1, frame_count, sample_size
-
-
-#-------------------------#
-# Recognize sound headers #
-#-------------------------#
-
-def whathdr(filename):
-	f = open(filename, 'r')
-	h = f.read(512)
-	for tf in tests:
-		res = tf(h, f)
-		if res:
-			return res
-	return None
-
-
-#-----------------------------------#
-# Subroutines per sound header type #
-#-----------------------------------#
-
-tests = []
-
-def test_aifc(h, f):
-	import aifc
-	if h[:4] <> 'FORM':
-		return None
-	if h[8:12] == 'AIFC':
-		fmt = 'aifc'
-	elif h[8:12] == 'AIFF':
-		fmt = 'aiff'
-	else:
-		return None
-	f.seek(0)
-	try:
-		a = aifc.openfp(f, 'r')
-	except (EOFError, aifc.Error):
-		return None
-	return (fmt, a.getframerate(), a.getnchannels(), \
-		a.getnframes(), 8*a.getsampwidth())
-
-tests.append(test_aifc)
-
-
-def test_au(h, f):
-	if h[:4] == '.snd':
-		f = get_long_be
-	elif h[:4] in ('\0ds.', 'dns.'):
-		f = get_long_le
-	else:
-		return None
-	type = 'au'
-	hdr_size = f(h[4:8])
-	data_size = f(h[8:12])
-	encoding = f(h[12:16])
-	rate = f(h[16:20])
-	nchannels = f(h[20:24])
-	sample_size = 1 # default
-	if encoding == 1:
-		sample_bits = 'U'
-	elif encoding == 2:
-		sample_bits = 8
-	elif encoding == 3:
-		sample_bits = 16
-		sample_size = 2
-	else:
-		sample_bits = '?'
-	frame_size = sample_size * nchannels
-	return type, rate, nchannels, data_size/frame_size, sample_bits
-
-tests.append(test_au)
-
-
-def test_hcom(h, f):
-	if h[65:69] <> 'FSSD' or h[128:132] <> 'HCOM':
-		return None
-	divisor = get_long_be(h[128+16:128+20])
-	return 'hcom', 22050/divisor, 1, -1, 8
-
-tests.append(test_hcom)
-
-
-def test_voc(h, f):
-	if h[:20] <> 'Creative Voice File\032':
-		return None
-	sbseek = get_short_le(h[20:22])
-	rate = 0
-	if 0 <= sbseek < 500 and h[sbseek] == '\1':
-		ratecode = ord(h[sbseek+4])
-		rate = int(1000000.0 / (256 - ratecode))
-	return 'voc', rate, 1, -1, 8
-
-tests.append(test_voc)
-
-
-def test_wav(h, f):
-	# 'RIFF' <len> 'WAVE' 'fmt ' <len>
-	if h[:4] <> 'RIFF' or h[8:12] <> 'WAVE' or h[12:16] <> 'fmt ':
-		return None
-	style = get_short_le(h[20:22])
-	nchannels = get_short_le(h[22:24])
-	rate = get_long_le(h[24:28])
-	sample_bits = get_short_le(h[34:36])
-	return 'wav', rate, nchannels, -1, sample_bits
-
-tests.append(test_wav)
-
-
-def test_8svx(h, f):
-	if h[:4] <> 'FORM' or h[8:12] <> '8SVX':
-		return None
-	# Should decode it to get #channels -- assume always 1
-	return '8svx', 0, 1, 0, 8
-
-tests.append(test_8svx)
-
-
-def test_sndt(h, f):
-	if h[:5] == 'SOUND':
-		nsamples = get_long_le(h[8:12])
-		rate = get_short_le(h[20:22])
-		return 'sndt', rate, 1, nsamples, 8
-
-tests.append(test_sndt)
-
-
-def test_sndr(h, f):
-	if h[:2] == '\0\0':
-		rate = get_short_le(h[2:4])
-		if 4000 <= rate <= 25000:
-			return 'sndr', rate, 1, -1, 8
-
-tests.append(test_sndr)
-
-
-#---------------------------------------------#
-# Subroutines to extract numbers from strings #
-#---------------------------------------------#
-
-def get_long_be(s):
-	return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
-
-def get_long_le(s):
-	return (ord(s[3])<<24) | (ord(s[2])<<16) | (ord(s[1])<<8) | ord(s[0])
-
-def get_short_be(s):
-	return (ord(s[0])<<8) | ord(s[1])
-
-def get_short_le(s):
-	return (ord(s[1])<<8) | ord(s[0])
-
-
-#--------------------#
-# Small test program #
-#--------------------#
-
-def test():
-	import sys
-	recursive = 0
-	if sys.argv[1:] and sys.argv[1] == '-r':
-		del sys.argv[1:2]
-		recursive = 1
-	try:
-		if sys.argv[1:]:
-			testall(sys.argv[1:], recursive, 1)
-		else:
-			testall(['.'], recursive, 1)
-	except KeyboardInterrupt:
-		sys.stderr.write('\n[Interrupted]\n')
-		sys.exit(1)
-
-def testall(list, recursive, toplevel):
-	import sys
-	import os
-	for filename in list:
-		if os.path.isdir(filename):
-			print filename + '/:',
-			if recursive or toplevel:
-				print 'recursing down:'
-				import glob
-				names = glob.glob(os.path.join(filename, '*'))
-				testall(names, recursive, 0)
-			else:
-				print '*** directory (use -r) ***'
-		else:
-			print filename + ':',
-			sys.stdout.flush()
-			try:
-				print what(filename)
-			except IOError:
-				print '*** not found ***'
+from sndhdr import *
diff --git a/Lib/whatsound.py b/Lib/whatsound.py
index b7b349c..1b1df23 100644
--- a/Lib/whatsound.py
+++ b/Lib/whatsound.py
@@ -1,270 +1 @@
-# This module contains several routines that help recognizing sound
-# files.
-#
-# Function whathdr() recognizes various types of sound file headers.
-# It understands almost all headers that SOX can decode.
-#
-# The return tuple contains the following items, in this order:
-# - file type (as SOX understands it)
-# - sampling rate (0 if unknown or hard to decode)
-# - number of channels (0 if unknown or hard to decode)
-# - number of frames in the file (-1 if unknown or hard to decode)
-# - number of bits/sample, or 'U' for U-LAW, or 'A' for A-LAW
-#
-# If the file doesn't have a recognizable type, it returns None.
-# If the file can't be opened, IOError is raised.
-#
-# To compute the total time, divide the number of frames by the
-# sampling rate (a frame contains a sample for each channel).
-#
-# Function whatraw() calls the "whatsound" program and interprets its
-# output.  You'll have to guess the sampling rate by listening though!
-#
-# Function what() calls whathdr() and if it doesn't recognize the file
-# then calls whatraw().
-#
-# Finally, the function test() is a simple main program that calls
-# what() for all files mentioned on the argument list.  For directory
-# arguments it calls what() for all files in that directory.  Default
-# argument is "." (testing all files in the current directory).  The
-# option -r tells it to recurse down directories found inside
-# explicitly given directories.
-#
-# The file structure is top-down except that the test program and its
-# subroutine come last.
-
-
-#------------------------------------------------------#
-# Guess the type of any sound file, raw or with header #
-#------------------------------------------------------#
-
-def what(filename):
-	res = whathdr(filename)
-	if not res:
-		res = whatraw(filename)
-	return res
-
-
-#-----------------------------#
-# Guess the type of raw sound #
-#-----------------------------#
-
-def whatraw(filename):
-	# Assume it's always 1 channel, byte-sized samples
-	# Don't assume anything about the rate
-	import os
-	from stat import ST_SIZE
-	# XXX "whatsound" should be part of the distribution somehow...
-	cmd = 'whatsound ' + filename + ' 2>/dev/null'
-	cmd = 'PATH=$PATH:/ufs/guido/bin/sgi\n' + cmd
-	pipe = os.popen(cmd, 'r')
-	data = pipe.read()
-	sts = pipe.close()
-	if sts:
-		return None
-	if data[:13] == '-t raw -b -s ':
-		type = 'sb'
-		sample_size = 8
-	elif data[:13] == '-t raw -b -u ':
-		type = 'ub'
-		sample_size = 8
-	elif data[:13] == '-t raw -b -U ':
-		type = 'ul'
-		sample_size = 'U'
-	else:
-		return None
-	try:
-		frame_count = os.stat(filename)[ST_SIZE]
-	except IOError:
-		frame_count = -1
-	return type, 0, 1, frame_count, sample_size
-
-
-#-------------------------#
-# Recognize sound headers #
-#-------------------------#
-
-def whathdr(filename):
-	f = open(filename, 'r')
-	h = f.read(512)
-	for tf in tests:
-		res = tf(h, f)
-		if res:
-			return res
-	return None
-
-
-#-----------------------------------#
-# Subroutines per sound header type #
-#-----------------------------------#
-
-tests = []
-
-def test_aifc(h, f):
-	import aifc
-	if h[:4] <> 'FORM':
-		return None
-	if h[8:12] == 'AIFC':
-		fmt = 'aifc'
-	elif h[8:12] == 'AIFF':
-		fmt = 'aiff'
-	else:
-		return None
-	f.seek(0)
-	try:
-		a = aifc.openfp(f, 'r')
-	except (EOFError, aifc.Error):
-		return None
-	return (fmt, a.getframerate(), a.getnchannels(), \
-		a.getnframes(), 8*a.getsampwidth())
-
-tests.append(test_aifc)
-
-
-def test_au(h, f):
-	if h[:4] == '.snd':
-		f = get_long_be
-	elif h[:4] in ('\0ds.', 'dns.'):
-		f = get_long_le
-	else:
-		return None
-	type = 'au'
-	hdr_size = f(h[4:8])
-	data_size = f(h[8:12])
-	encoding = f(h[12:16])
-	rate = f(h[16:20])
-	nchannels = f(h[20:24])
-	sample_size = 1 # default
-	if encoding == 1:
-		sample_bits = 'U'
-	elif encoding == 2:
-		sample_bits = 8
-	elif encoding == 3:
-		sample_bits = 16
-		sample_size = 2
-	else:
-		sample_bits = '?'
-	frame_size = sample_size * nchannels
-	return type, rate, nchannels, data_size/frame_size, sample_bits
-
-tests.append(test_au)
-
-
-def test_hcom(h, f):
-	if h[65:69] <> 'FSSD' or h[128:132] <> 'HCOM':
-		return None
-	divisor = get_long_be(h[128+16:128+20])
-	return 'hcom', 22050/divisor, 1, -1, 8
-
-tests.append(test_hcom)
-
-
-def test_voc(h, f):
-	if h[:20] <> 'Creative Voice File\032':
-		return None
-	sbseek = get_short_le(h[20:22])
-	rate = 0
-	if 0 <= sbseek < 500 and h[sbseek] == '\1':
-		ratecode = ord(h[sbseek+4])
-		rate = int(1000000.0 / (256 - ratecode))
-	return 'voc', rate, 1, -1, 8
-
-tests.append(test_voc)
-
-
-def test_wav(h, f):
-	# 'RIFF' <len> 'WAVE' 'fmt ' <len>
-	if h[:4] <> 'RIFF' or h[8:12] <> 'WAVE' or h[12:16] <> 'fmt ':
-		return None
-	style = get_short_le(h[20:22])
-	nchannels = get_short_le(h[22:24])
-	rate = get_long_le(h[24:28])
-	sample_bits = get_short_le(h[34:36])
-	return 'wav', rate, nchannels, -1, sample_bits
-
-tests.append(test_wav)
-
-
-def test_8svx(h, f):
-	if h[:4] <> 'FORM' or h[8:12] <> '8SVX':
-		return None
-	# Should decode it to get #channels -- assume always 1
-	return '8svx', 0, 1, 0, 8
-
-tests.append(test_8svx)
-
-
-def test_sndt(h, f):
-	if h[:5] == 'SOUND':
-		nsamples = get_long_le(h[8:12])
-		rate = get_short_le(h[20:22])
-		return 'sndt', rate, 1, nsamples, 8
-
-tests.append(test_sndt)
-
-
-def test_sndr(h, f):
-	if h[:2] == '\0\0':
-		rate = get_short_le(h[2:4])
-		if 4000 <= rate <= 25000:
-			return 'sndr', rate, 1, -1, 8
-
-tests.append(test_sndr)
-
-
-#---------------------------------------------#
-# Subroutines to extract numbers from strings #
-#---------------------------------------------#
-
-def get_long_be(s):
-	return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
-
-def get_long_le(s):
-	return (ord(s[3])<<24) | (ord(s[2])<<16) | (ord(s[1])<<8) | ord(s[0])
-
-def get_short_be(s):
-	return (ord(s[0])<<8) | ord(s[1])
-
-def get_short_le(s):
-	return (ord(s[1])<<8) | ord(s[0])
-
-
-#--------------------#
-# Small test program #
-#--------------------#
-
-def test():
-	import sys
-	recursive = 0
-	if sys.argv[1:] and sys.argv[1] == '-r':
-		del sys.argv[1:2]
-		recursive = 1
-	try:
-		if sys.argv[1:]:
-			testall(sys.argv[1:], recursive, 1)
-		else:
-			testall(['.'], recursive, 1)
-	except KeyboardInterrupt:
-		sys.stderr.write('\n[Interrupted]\n')
-		sys.exit(1)
-
-def testall(list, recursive, toplevel):
-	import sys
-	import os
-	for filename in list:
-		if os.path.isdir(filename):
-			print filename + '/:',
-			if recursive or toplevel:
-				print 'recursing down:'
-				import glob
-				names = glob.glob(os.path.join(filename, '*'))
-				testall(names, recursive, 0)
-			else:
-				print '*** directory (use -r) ***'
-		else:
-			print filename + ':',
-			sys.stdout.flush()
-			try:
-				print what(filename)
-			except IOError:
-				print '*** not found ***'
+from sndhdr import *
