blob: 3a2b80cbe383be8075f1b2198e9a1c1c330067b5 [file] [log] [blame]
Andrew Hsiehffab9582013-06-18 12:29:14 -07001"""Convert "arbitrary" sound files to AIFF (Apple and SGI's audio format).
2
3Input may be compressed.
4Uncompressed file type may be AIFF, WAV, VOC, 8SVX, NeXT/Sun, and others.
5An exception is raised if the file is not of a recognized type.
6Returned filename is either the input filename or a temporary filename;
7in the latter case the caller must ensure that it is removed.
8Other temporary files used are removed by the function.
9"""
10from warnings import warnpy3k
11warnpy3k("the toaiff module has been removed in Python 3.0", stacklevel=2)
12del warnpy3k
13
14import os
15import tempfile
16import pipes
17import sndhdr
18
19__all__ = ["error", "toaiff"]
20
21table = {}
22
23t = pipes.Template()
24t.append('sox -t au - -t aiff -r 8000 -', '--')
25table['au'] = t
26
27# XXX The following is actually sub-optimal.
28# XXX The HCOM sampling rate can be 22k, 22k/2, 22k/3 or 22k/4.
29# XXX We must force the output sampling rate else the SGI won't play
30# XXX files sampled at 5.5k or 7.333k; however this means that files
31# XXX sampled at 11k are unnecessarily expanded.
32# XXX Similar comments apply to some other file types.
33t = pipes.Template()
34t.append('sox -t hcom - -t aiff -r 22050 -', '--')
35table['hcom'] = t
36
37t = pipes.Template()
38t.append('sox -t voc - -t aiff -r 11025 -', '--')
39table['voc'] = t
40
41t = pipes.Template()
42t.append('sox -t wav - -t aiff -', '--')
43table['wav'] = t
44
45t = pipes.Template()
46t.append('sox -t 8svx - -t aiff -r 16000 -', '--')
47table['8svx'] = t
48
49t = pipes.Template()
50t.append('sox -t sndt - -t aiff -r 16000 -', '--')
51table['sndt'] = t
52
53t = pipes.Template()
54t.append('sox -t sndr - -t aiff -r 16000 -', '--')
55table['sndr'] = t
56
57uncompress = pipes.Template()
58uncompress.append('uncompress', '--')
59
60
61class error(Exception):
62 pass
63
64def toaiff(filename):
65 temps = []
66 ret = None
67 try:
68 ret = _toaiff(filename, temps)
69 finally:
70 for temp in temps[:]:
71 if temp != ret:
72 try:
73 os.unlink(temp)
74 except os.error:
75 pass
76 temps.remove(temp)
77 return ret
78
79def _toaiff(filename, temps):
80 if filename[-2:] == '.Z':
81 (fd, fname) = tempfile.mkstemp()
82 os.close(fd)
83 temps.append(fname)
84 sts = uncompress.copy(filename, fname)
85 if sts:
86 raise error, filename + ': uncompress failed'
87 else:
88 fname = filename
89 try:
90 ftype = sndhdr.whathdr(fname)
91 if ftype:
92 ftype = ftype[0] # All we're interested in
93 except IOError, msg:
94 if type(msg) == type(()) and len(msg) == 2 and \
95 type(msg[0]) == type(0) and type(msg[1]) == type(''):
96 msg = msg[1]
97 if type(msg) != type(''):
98 msg = repr(msg)
99 raise error, filename + ': ' + msg
100 if ftype == 'aiff':
101 return fname
102 if ftype is None or not ftype in table:
103 raise error, '%s: unsupported audio file type %r' % (filename, ftype)
104 (fd, temp) = tempfile.mkstemp()
105 os.close(fd)
106 temps.append(temp)
107 sts = table[ftype].copy(fname, temp)
108 if sts:
109 raise error, filename + ': conversion to aiff failed'
110 return temp