home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_262 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  22.3 KB  |  900 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import struct
  5. import __builtin__
  6. __all__ = [
  7.     'Error',
  8.     'open',
  9.     'openfp']
  10.  
  11. class Error(Exception):
  12.     pass
  13.  
  14. _AIFC_version = 0xA2805140L
  15.  
  16. def _read_long(file):
  17.     
  18.     try:
  19.         return struct.unpack('>l', file.read(4))[0]
  20.     except struct.error:
  21.         raise EOFError
  22.  
  23.  
  24.  
  25. def _read_ulong(file):
  26.     
  27.     try:
  28.         return struct.unpack('>L', file.read(4))[0]
  29.     except struct.error:
  30.         raise EOFError
  31.  
  32.  
  33.  
  34. def _read_short(file):
  35.     
  36.     try:
  37.         return struct.unpack('>h', file.read(2))[0]
  38.     except struct.error:
  39.         raise EOFError
  40.  
  41.  
  42.  
  43. def _read_string(file):
  44.     length = ord(file.read(1))
  45.     if length == 0:
  46.         data = ''
  47.     else:
  48.         data = file.read(length)
  49.     if length & 1 == 0:
  50.         dummy = file.read(1)
  51.     
  52.     return data
  53.  
  54. _HUGE_VAL = 1.79769e+308
  55.  
  56. def _read_float(f):
  57.     expon = _read_short(f)
  58.     sign = 1
  59.     if expon < 0:
  60.         sign = -1
  61.         expon = expon + 32768
  62.     
  63.     himant = _read_ulong(f)
  64.     lomant = _read_ulong(f)
  65.     if himant == himant and lomant == lomant:
  66.         pass
  67.     elif lomant == 0:
  68.         f = 0
  69.     elif expon == 32767:
  70.         f = _HUGE_VAL
  71.     else:
  72.         expon = expon - 16383
  73.         f = (himant * 0x100000000L + lomant) * pow(2, expon - 63)
  74.     return sign * f
  75.  
  76.  
  77. def _write_short(f, x):
  78.     f.write(struct.pack('>h', x))
  79.  
  80.  
  81. def _write_long(f, x):
  82.     f.write(struct.pack('>L', x))
  83.  
  84.  
  85. def _write_string(f, s):
  86.     if len(s) > 255:
  87.         raise ValueError('string exceeds maximum pstring length')
  88.     len(s) > 255
  89.     f.write(chr(len(s)))
  90.     f.write(s)
  91.     if len(s) & 1 == 0:
  92.         f.write(chr(0))
  93.     
  94.  
  95.  
  96. def _write_float(f, x):
  97.     import math
  98.     if x < 0:
  99.         sign = 32768
  100.         x = x * -1
  101.     else:
  102.         sign = 0
  103.     if x == 0:
  104.         expon = 0
  105.         himant = 0
  106.         lomant = 0
  107.     else:
  108.         (fmant, expon) = math.frexp(x)
  109.         if expon > 16384 or fmant >= 1:
  110.             expon = sign | 32767
  111.             himant = 0
  112.             lomant = 0
  113.         else:
  114.             expon = expon + 16382
  115.             if expon < 0:
  116.                 fmant = math.ldexp(fmant, expon)
  117.                 expon = 0
  118.             
  119.             expon = expon | sign
  120.             fmant = math.ldexp(fmant, 32)
  121.             fsmant = math.floor(fmant)
  122.             himant = long(fsmant)
  123.             fmant = math.ldexp(fmant - fsmant, 32)
  124.             fsmant = math.floor(fmant)
  125.             lomant = long(fsmant)
  126.     _write_short(f, expon)
  127.     _write_long(f, himant)
  128.     _write_long(f, lomant)
  129.  
  130. from chunk import Chunk
  131.  
  132. class Aifc_read:
  133.     
  134.     def initfp(self, file):
  135.         self._version = 0
  136.         self._decomp = None
  137.         self._convert = None
  138.         self._markers = []
  139.         self._soundpos = 0
  140.         self._file = file
  141.         chunk = Chunk(file)
  142.         if chunk.getname() != 'FORM':
  143.             raise Error, 'file does not start with FORM id'
  144.         chunk.getname() != 'FORM'
  145.         formdata = chunk.read(4)
  146.         if formdata == 'AIFF':
  147.             self._aifc = 0
  148.         elif formdata == 'AIFC':
  149.             self._aifc = 1
  150.         else:
  151.             raise Error, 'not an AIFF or AIFF-C file'
  152.         self._comm_chunk_read = formdata == 'AIFF'
  153.         while None:
  154.             self._ssnd_seek_needed = 1
  155.             
  156.             try:
  157.                 chunk = Chunk(self._file)
  158.             except EOFError:
  159.                 break
  160.  
  161.             chunkname = chunk.getname()
  162.             if chunkname == 'COMM':
  163.                 self._read_comm_chunk(chunk)
  164.                 self._comm_chunk_read = 1
  165.             elif chunkname == 'SSND':
  166.                 self._ssnd_chunk = chunk
  167.                 dummy = chunk.read(8)
  168.                 self._ssnd_seek_needed = 0
  169.             elif chunkname == 'FVER':
  170.                 self._version = _read_ulong(chunk)
  171.             elif chunkname == 'MARK':
  172.                 self._readmark(chunk)
  173.             
  174.             continue
  175.             if not (self._comm_chunk_read) or not (self._ssnd_chunk):
  176.                 raise Error, 'COMM chunk and/or SSND chunk missing'
  177.             not (self._ssnd_chunk)
  178.             if self._aifc and self._decomp:
  179.                 import cl
  180.                 params = [
  181.                     cl.ORIGINAL_FORMAT,
  182.                     0,
  183.                     cl.BITS_PER_COMPONENT,
  184.                     self._sampwidth * 8,
  185.                     cl.FRAME_RATE,
  186.                     self._framerate]
  187.                 if self._nchannels == 1:
  188.                     params[1] = cl.MONO
  189.                 elif self._nchannels == 2:
  190.                     params[1] = cl.STEREO_INTERLEAVED
  191.                 else:
  192.                     raise Error, 'cannot compress more than 2 channels'
  193.                 (self._nchannels == 1)._decomp.SetParams(params)
  194.             
  195.  
  196.     
  197.     def __init__(self, f):
  198.         if type(f) == type(''):
  199.             f = __builtin__.open(f, 'rb')
  200.         
  201.         self.initfp(f)
  202.  
  203.     
  204.     def getfp(self):
  205.         return self._file
  206.  
  207.     
  208.     def rewind(self):
  209.         self._ssnd_seek_needed = 1
  210.         self._soundpos = 0
  211.  
  212.     
  213.     def close(self):
  214.         if self._decomp:
  215.             self._decomp.CloseDecompressor()
  216.             self._decomp = None
  217.         
  218.         self._file.close()
  219.  
  220.     
  221.     def tell(self):
  222.         return self._soundpos
  223.  
  224.     
  225.     def getnchannels(self):
  226.         return self._nchannels
  227.  
  228.     
  229.     def getnframes(self):
  230.         return self._nframes
  231.  
  232.     
  233.     def getsampwidth(self):
  234.         return self._sampwidth
  235.  
  236.     
  237.     def getframerate(self):
  238.         return self._framerate
  239.  
  240.     
  241.     def getcomptype(self):
  242.         return self._comptype
  243.  
  244.     
  245.     def getcompname(self):
  246.         return self._compname
  247.  
  248.     
  249.     def getparams(self):
  250.         return (self.getnchannels(), self.getsampwidth(), self.getframerate(), self.getnframes(), self.getcomptype(), self.getcompname())
  251.  
  252.     
  253.     def getmarkers(self):
  254.         if len(self._markers) == 0:
  255.             return None
  256.         return self._markers
  257.  
  258.     
  259.     def getmark(self, id):
  260.         for marker in self._markers:
  261.             if id == marker[0]:
  262.                 return marker
  263.         
  264.         raise Error, 'marker %r does not exist' % (id,)
  265.  
  266.     
  267.     def setpos(self, pos):
  268.         if pos < 0 or pos > self._nframes:
  269.             raise Error, 'position not in range'
  270.         pos > self._nframes
  271.         self._soundpos = pos
  272.         self._ssnd_seek_needed = 1
  273.  
  274.     
  275.     def readframes(self, nframes):
  276.         if self._ssnd_seek_needed:
  277.             self._ssnd_chunk.seek(0)
  278.             dummy = self._ssnd_chunk.read(8)
  279.             pos = self._soundpos * self._framesize
  280.             if pos:
  281.                 self._ssnd_chunk.seek(pos + 8)
  282.             
  283.             self._ssnd_seek_needed = 0
  284.         
  285.         if nframes == 0:
  286.             return ''
  287.         data = self._ssnd_chunk.read(nframes * self._framesize)
  288.         if self._convert and data:
  289.             data = self._convert(data)
  290.         
  291.         self._soundpos = self._soundpos + len(data) / (self._nchannels * self._sampwidth)
  292.         return data
  293.  
  294.     
  295.     def _decomp_data(self, data):
  296.         import cl
  297.         dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE, len(data) * 2)
  298.         return self._decomp.Decompress(len(data) / self._nchannels, data)
  299.  
  300.     
  301.     def _ulaw2lin(self, data):
  302.         import audioop
  303.         return audioop.ulaw2lin(data, 2)
  304.  
  305.     
  306.     def _adpcm2lin(self, data):
  307.         import audioop
  308.         if not hasattr(self, '_adpcmstate'):
  309.             self._adpcmstate = None
  310.         
  311.         (data, self._adpcmstate) = audioop.adpcm2lin(data, 2, self._adpcmstate)
  312.         return data
  313.  
  314.     
  315.     def _read_comm_chunk(self, chunk):
  316.         self._nchannels = _read_short(chunk)
  317.         self._nframes = _read_long(chunk)
  318.         self._sampwidth = (_read_short(chunk) + 7) / 8
  319.         self._framerate = int(_read_float(chunk))
  320.         self._framesize = self._nchannels * self._sampwidth
  321.         if self._aifc:
  322.             kludge = 0
  323.             if chunk.chunksize == 18:
  324.                 kludge = 1
  325.                 print 'Warning: bad COMM chunk size'
  326.                 chunk.chunksize = 23
  327.             
  328.             self._comptype = chunk.read(4)
  329.             if kludge:
  330.                 length = ord(chunk.file.read(1))
  331.                 if length & 1 == 0:
  332.                     length = length + 1
  333.                 
  334.                 chunk.chunksize = chunk.chunksize + length
  335.                 chunk.file.seek(-1, 1)
  336.             
  337.             self._compname = _read_string(chunk)
  338.             if self._comptype != 'NONE':
  339.                 if self._comptype == 'G722':
  340.                     
  341.                     try:
  342.                         import audioop
  343.                     except ImportError:
  344.                         pass
  345.  
  346.                     self._convert = self._adpcm2lin
  347.                     self._framesize = self._framesize / 4
  348.                     return None
  349.                 self._comptype == 'G722'
  350.                 
  351.                 try:
  352.                     import cl
  353.                 except ImportError:
  354.                     if self._comptype == 'ULAW':
  355.                         
  356.                         try:
  357.                             import audioop
  358.                             self._convert = self._ulaw2lin
  359.                             self._framesize = self._framesize / 2
  360.                             return None
  361.                         except ImportError:
  362.                             pass
  363.                         except:
  364.                             None<EXCEPTION MATCH>ImportError
  365.                         
  366.  
  367.                     None<EXCEPTION MATCH>ImportError
  368.                     raise Error, 'cannot read compressed AIFF-C files'
  369.  
  370.                 if self._comptype == 'ULAW':
  371.                     scheme = cl.G711_ULAW
  372.                     self._framesize = self._framesize / 2
  373.                 elif self._comptype == 'ALAW':
  374.                     scheme = cl.G711_ALAW
  375.                     self._framesize = self._framesize / 2
  376.                 else:
  377.                     raise Error, 'unsupported compression type'
  378.                 self._decomp = (self._comptype == 'ULAW').OpenDecompressor(scheme)
  379.                 self._convert = self._decomp_data
  380.             
  381.         else:
  382.             self._comptype = 'NONE'
  383.             self._compname = 'not compressed'
  384.  
  385.     
  386.     def _readmark(self, chunk):
  387.         nmarkers = _read_short(chunk)
  388.         
  389.         try:
  390.             for i in range(nmarkers):
  391.                 id = _read_short(chunk)
  392.                 pos = _read_long(chunk)
  393.                 name = _read_string(chunk)
  394.                 if pos or name:
  395.                     self._markers.append((id, pos, name))
  396.                     continue
  397.         except EOFError:
  398.             print 'Warning: MARK chunk contains only', len(self._markers),
  399.             if len(self._markers) == 1:
  400.                 print 'marker',
  401.             else:
  402.                 print 'markers',
  403.             print 'instead of', nmarkers
  404.  
  405.  
  406.  
  407.  
  408. class Aifc_write:
  409.     
  410.     def __init__(self, f):
  411.         if type(f) == type(''):
  412.             filename = f
  413.             f = __builtin__.open(f, 'wb')
  414.         else:
  415.             filename = '???'
  416.         self.initfp(f)
  417.         if filename[-5:] == '.aiff':
  418.             self._aifc = 0
  419.         else:
  420.             self._aifc = 1
  421.  
  422.     
  423.     def initfp(self, file):
  424.         self._file = file
  425.         self._version = _AIFC_version
  426.         self._comptype = 'NONE'
  427.         self._compname = 'not compressed'
  428.         self._comp = None
  429.         self._convert = None
  430.         self._nchannels = 0
  431.         self._sampwidth = 0
  432.         self._framerate = 0
  433.         self._nframes = 0
  434.         self._nframeswritten = 0
  435.         self._datawritten = 0
  436.         self._datalength = 0
  437.         self._markers = []
  438.         self._marklength = 0
  439.         self._aifc = 1
  440.  
  441.     
  442.     def __del__(self):
  443.         if self._file:
  444.             self.close()
  445.         
  446.  
  447.     
  448.     def aiff(self):
  449.         if self._nframeswritten:
  450.             raise Error, 'cannot change parameters after starting to write'
  451.         self._nframeswritten
  452.         self._aifc = 0
  453.  
  454.     
  455.     def aifc(self):
  456.         if self._nframeswritten:
  457.             raise Error, 'cannot change parameters after starting to write'
  458.         self._nframeswritten
  459.         self._aifc = 1
  460.  
  461.     
  462.     def setnchannels(self, nchannels):
  463.         if self._nframeswritten:
  464.             raise Error, 'cannot change parameters after starting to write'
  465.         self._nframeswritten
  466.         if nchannels < 1:
  467.             raise Error, 'bad # of channels'
  468.         nchannels < 1
  469.         self._nchannels = nchannels
  470.  
  471.     
  472.     def getnchannels(self):
  473.         if not self._nchannels:
  474.             raise Error, 'number of channels not set'
  475.         self._nchannels
  476.         return self._nchannels
  477.  
  478.     
  479.     def setsampwidth(self, sampwidth):
  480.         if self._nframeswritten:
  481.             raise Error, 'cannot change parameters after starting to write'
  482.         self._nframeswritten
  483.         if sampwidth < 1 or sampwidth > 4:
  484.             raise Error, 'bad sample width'
  485.         sampwidth > 4
  486.         self._sampwidth = sampwidth
  487.  
  488.     
  489.     def getsampwidth(self):
  490.         if not self._sampwidth:
  491.             raise Error, 'sample width not set'
  492.         self._sampwidth
  493.         return self._sampwidth
  494.  
  495.     
  496.     def setframerate(self, framerate):
  497.         if self._nframeswritten:
  498.             raise Error, 'cannot change parameters after starting to write'
  499.         self._nframeswritten
  500.         if framerate <= 0:
  501.             raise Error, 'bad frame rate'
  502.         framerate <= 0
  503.         self._framerate = framerate
  504.  
  505.     
  506.     def getframerate(self):
  507.         if not self._framerate:
  508.             raise Error, 'frame rate not set'
  509.         self._framerate
  510.         return self._framerate
  511.  
  512.     
  513.     def setnframes(self, nframes):
  514.         if self._nframeswritten:
  515.             raise Error, 'cannot change parameters after starting to write'
  516.         self._nframeswritten
  517.         self._nframes = nframes
  518.  
  519.     
  520.     def getnframes(self):
  521.         return self._nframeswritten
  522.  
  523.     
  524.     def setcomptype(self, comptype, compname):
  525.         if self._nframeswritten:
  526.             raise Error, 'cannot change parameters after starting to write'
  527.         self._nframeswritten
  528.         if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
  529.             raise Error, 'unsupported compression type'
  530.         comptype not in ('NONE', 'ULAW', 'ALAW', 'G722')
  531.         self._comptype = comptype
  532.         self._compname = compname
  533.  
  534.     
  535.     def getcomptype(self):
  536.         return self._comptype
  537.  
  538.     
  539.     def getcompname(self):
  540.         return self._compname
  541.  
  542.     
  543.     def setparams(self, info):
  544.         (nchannels, sampwidth, framerate, nframes, comptype, compname) = info
  545.         if self._nframeswritten:
  546.             raise Error, 'cannot change parameters after starting to write'
  547.         self._nframeswritten
  548.         if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
  549.             raise Error, 'unsupported compression type'
  550.         comptype not in ('NONE', 'ULAW', 'ALAW', 'G722')
  551.         self.setnchannels(nchannels)
  552.         self.setsampwidth(sampwidth)
  553.         self.setframerate(framerate)
  554.         self.setnframes(nframes)
  555.         self.setcomptype(comptype, compname)
  556.  
  557.     
  558.     def getparams(self):
  559.         if not (self._nchannels) and not (self._sampwidth) or not (self._framerate):
  560.             raise Error, 'not all parameters set'
  561.         not (self._framerate)
  562.         return (self._nchannels, self._sampwidth, self._framerate, self._nframes, self._comptype, self._compname)
  563.  
  564.     
  565.     def setmark(self, id, pos, name):
  566.         if id <= 0:
  567.             raise Error, 'marker ID must be > 0'
  568.         id <= 0
  569.         if pos < 0:
  570.             raise Error, 'marker position must be >= 0'
  571.         pos < 0
  572.         if type(name) != type(''):
  573.             raise Error, 'marker name must be a string'
  574.         type(name) != type('')
  575.         for i in range(len(self._markers)):
  576.             if id == self._markers[i][0]:
  577.                 self._markers[i] = (id, pos, name)
  578.                 return None
  579.         
  580.         self._markers.append((id, pos, name))
  581.  
  582.     
  583.     def getmark(self, id):
  584.         for marker in self._markers:
  585.             if id == marker[0]:
  586.                 return marker
  587.         
  588.         raise Error, 'marker %r does not exist' % (id,)
  589.  
  590.     
  591.     def getmarkers(self):
  592.         if len(self._markers) == 0:
  593.             return None
  594.         return self._markers
  595.  
  596.     
  597.     def tell(self):
  598.         return self._nframeswritten
  599.  
  600.     
  601.     def writeframesraw(self, data):
  602.         self._ensure_header_written(len(data))
  603.         nframes = len(data) / (self._sampwidth * self._nchannels)
  604.         if self._convert:
  605.             data = self._convert(data)
  606.         
  607.         self._file.write(data)
  608.         self._nframeswritten = self._nframeswritten + nframes
  609.         self._datawritten = self._datawritten + len(data)
  610.  
  611.     
  612.     def writeframes(self, data):
  613.         self.writeframesraw(data)
  614.         if self._nframeswritten != self._nframes or self._datalength != self._datawritten:
  615.             self._patchheader()
  616.         
  617.  
  618.     
  619.     def close(self):
  620.         self._ensure_header_written(0)
  621.         if self._datawritten & 1:
  622.             self._file.write(chr(0))
  623.             self._datawritten = self._datawritten + 1
  624.         
  625.         self._writemarkers()
  626.         if self._nframeswritten != self._nframes and self._datalength != self._datawritten or self._marklength:
  627.             self._patchheader()
  628.         
  629.         if self._comp:
  630.             self._comp.CloseCompressor()
  631.             self._comp = None
  632.         
  633.         self._file.close()
  634.  
  635.     
  636.     def _comp_data(self, data):
  637.         import cl
  638.         dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data))
  639.         dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data))
  640.         return self._comp.Compress(self._nframes, data)
  641.  
  642.     
  643.     def _lin2ulaw(self, data):
  644.         import audioop
  645.         return audioop.lin2ulaw(data, 2)
  646.  
  647.     
  648.     def _lin2adpcm(self, data):
  649.         import audioop
  650.         if not hasattr(self, '_adpcmstate'):
  651.             self._adpcmstate = None
  652.         
  653.         (data, self._adpcmstate) = audioop.lin2adpcm(data, 2, self._adpcmstate)
  654.         return data
  655.  
  656.     
  657.     def _ensure_header_written(self, datasize):
  658.         if not self._nframeswritten:
  659.             if self._comptype in ('ULAW', 'ALAW'):
  660.                 if not self._sampwidth:
  661.                     self._sampwidth = 2
  662.                 
  663.                 if self._sampwidth != 2:
  664.                     raise Error, 'sample width must be 2 when compressing with ULAW or ALAW'
  665.                 self._sampwidth != 2
  666.             
  667.             if self._comptype == 'G722':
  668.                 if not self._sampwidth:
  669.                     self._sampwidth = 2
  670.                 
  671.                 if self._sampwidth != 2:
  672.                     raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)'
  673.                 self._sampwidth != 2
  674.             
  675.             if not self._nchannels:
  676.                 raise Error, '# channels not specified'
  677.             self._nchannels
  678.             if not self._sampwidth:
  679.                 raise Error, 'sample width not specified'
  680.             self._sampwidth
  681.             if not self._framerate:
  682.                 raise Error, 'sampling rate not specified'
  683.             self._framerate
  684.             self._write_header(datasize)
  685.         
  686.  
  687.     
  688.     def _init_compression(self):
  689.         if self._comptype == 'G722':
  690.             self._convert = self._lin2adpcm
  691.             return None
  692.         
  693.         try:
  694.             import cl
  695.         except ImportError:
  696.             self._comptype == 'G722'
  697.             self._comptype == 'G722'
  698.             if self._comptype == 'ULAW':
  699.                 
  700.                 try:
  701.                     import audioop
  702.                     self._convert = self._lin2ulaw
  703.                     return None
  704.                 except ImportError:
  705.                     pass
  706.                 except:
  707.                     None<EXCEPTION MATCH>ImportError
  708.                 
  709.  
  710.             None<EXCEPTION MATCH>ImportError
  711.             raise Error, 'cannot write compressed AIFF-C files'
  712.         except:
  713.             self._comptype == 'G722'
  714.  
  715.         if self._comptype == 'ULAW':
  716.             scheme = cl.G711_ULAW
  717.         elif self._comptype == 'ALAW':
  718.             scheme = cl.G711_ALAW
  719.         else:
  720.             raise Error, 'unsupported compression type'
  721.         self._comp = (self._comptype == 'G722').OpenCompressor(scheme)
  722.         params = [
  723.             cl.ORIGINAL_FORMAT,
  724.             0,
  725.             cl.BITS_PER_COMPONENT,
  726.             self._sampwidth * 8,
  727.             cl.FRAME_RATE,
  728.             self._framerate,
  729.             cl.FRAME_BUFFER_SIZE,
  730.             100,
  731.             cl.COMPRESSED_BUFFER_SIZE,
  732.             100]
  733.         if self._nchannels == 1:
  734.             params[1] = cl.MONO
  735.         elif self._nchannels == 2:
  736.             params[1] = cl.STEREO_INTERLEAVED
  737.         else:
  738.             raise Error, 'cannot compress more than 2 channels'
  739.         (self._nchannels == 1)._comp.SetParams(params)
  740.         dummy = self._comp.Compress(0, '')
  741.         self._convert = self._comp_data
  742.  
  743.     
  744.     def _write_header(self, initlength):
  745.         if self._aifc and self._comptype != 'NONE':
  746.             self._init_compression()
  747.         
  748.         self._file.write('FORM')
  749.         if not self._nframes:
  750.             self._nframes = initlength / (self._nchannels * self._sampwidth)
  751.         
  752.         self._datalength = self._nframes * self._nchannels * self._sampwidth
  753.         if self._datalength & 1:
  754.             self._datalength = self._datalength + 1
  755.         
  756.         if self._aifc:
  757.             if self._comptype in ('ULAW', 'ALAW'):
  758.                 self._datalength = self._datalength / 2
  759.                 if self._datalength & 1:
  760.                     self._datalength = self._datalength + 1
  761.                 
  762.             elif self._comptype == 'G722':
  763.                 self._datalength = (self._datalength + 3) / 4
  764.                 if self._datalength & 1:
  765.                     self._datalength = self._datalength + 1
  766.                 
  767.             
  768.         
  769.         self._form_length_pos = self._file.tell()
  770.         commlength = self._write_form_length(self._datalength)
  771.         if self._aifc:
  772.             self._file.write('AIFC')
  773.             self._file.write('FVER')
  774.             _write_long(self._file, 4)
  775.             _write_long(self._file, self._version)
  776.         else:
  777.             self._file.write('AIFF')
  778.         self._file.write('COMM')
  779.         _write_long(self._file, commlength)
  780.         _write_short(self._file, self._nchannels)
  781.         self._nframes_pos = self._file.tell()
  782.         _write_long(self._file, self._nframes)
  783.         _write_short(self._file, self._sampwidth * 8)
  784.         _write_float(self._file, self._framerate)
  785.         if self._aifc:
  786.             self._file.write(self._comptype)
  787.             _write_string(self._file, self._compname)
  788.         
  789.         self._file.write('SSND')
  790.         self._ssnd_length_pos = self._file.tell()
  791.         _write_long(self._file, self._datalength + 8)
  792.         _write_long(self._file, 0)
  793.         _write_long(self._file, 0)
  794.  
  795.     
  796.     def _write_form_length(self, datalength):
  797.         if self._aifc:
  798.             commlength = 23 + len(self._compname)
  799.             if commlength & 1:
  800.                 commlength = commlength + 1
  801.             
  802.             verslength = 12
  803.         else:
  804.             commlength = 18
  805.             verslength = 0
  806.         _write_long(self._file, 4 + verslength + self._marklength + 8 + commlength + 16 + datalength)
  807.         return commlength
  808.  
  809.     
  810.     def _patchheader(self):
  811.         curpos = self._file.tell()
  812.         if self._datawritten & 1:
  813.             datalength = self._datawritten + 1
  814.             self._file.write(chr(0))
  815.         else:
  816.             datalength = self._datawritten
  817.         if datalength == self._datalength and self._nframes == self._nframeswritten and self._marklength == 0:
  818.             self._file.seek(curpos, 0)
  819.             return None
  820.         self._file.seek(self._form_length_pos, 0)
  821.         dummy = self._write_form_length(datalength)
  822.         self._file.seek(self._nframes_pos, 0)
  823.         _write_long(self._file, self._nframeswritten)
  824.         self._file.seek(self._ssnd_length_pos, 0)
  825.         _write_long(self._file, datalength + 8)
  826.         self._file.seek(curpos, 0)
  827.         self._nframes = self._nframeswritten
  828.         self._datalength = datalength
  829.  
  830.     
  831.     def _writemarkers(self):
  832.         if len(self._markers) == 0:
  833.             return None
  834.         self._file.write('MARK')
  835.         length = 2
  836.         for marker in self._markers:
  837.             (id, pos, name) = marker
  838.             length = length + len(name) + 1 + 6
  839.             if len(name) & 1 == 0:
  840.                 length = length + 1
  841.                 continue
  842.             len(self._markers) == 0
  843.         
  844.         _write_long(self._file, length)
  845.         self._marklength = length + 8
  846.         _write_short(self._file, len(self._markers))
  847.         for marker in self._markers:
  848.             (id, pos, name) = marker
  849.             _write_short(self._file, id)
  850.             _write_long(self._file, pos)
  851.             _write_string(self._file, name)
  852.         
  853.  
  854.  
  855.  
  856. def open(f, mode = None):
  857.     if mode is None:
  858.         if hasattr(f, 'mode'):
  859.             mode = f.mode
  860.         else:
  861.             mode = 'rb'
  862.     
  863.     if mode in ('r', 'rb'):
  864.         return Aifc_read(f)
  865.     if mode in ('w', 'wb'):
  866.         return Aifc_write(f)
  867.     raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
  868.  
  869. openfp = open
  870. if __name__ == '__main__':
  871.     import sys
  872.     if not sys.argv[1:]:
  873.         sys.argv.append('/usr/demos/data/audio/bach.aiff')
  874.     
  875.     fn = sys.argv[1]
  876.     f = open(fn, 'r')
  877.     print 'Reading', fn
  878.     print 'nchannels =', f.getnchannels()
  879.     print 'nframes   =', f.getnframes()
  880.     print 'sampwidth =', f.getsampwidth()
  881.     print 'framerate =', f.getframerate()
  882.     print 'comptype  =', f.getcomptype()
  883.     print 'compname  =', f.getcompname()
  884.     if sys.argv[2:]:
  885.         gn = sys.argv[2]
  886.         print 'Writing', gn
  887.         g = open(gn, 'w')
  888.         g.setparams(f.getparams())
  889.         while None:
  890.             data = f.readframes(1024)
  891.             if not data:
  892.                 break
  893.             
  894.             continue
  895.             g.close()
  896.             f.close()
  897.             print 'Done.'
  898.     sys.argv[2:]
  899.  
  900.