home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / audiodev.py < prev    next >
Text File  |  2003-12-30  |  7KB  |  258 lines

  1. """Classes for manipulating audio devices (currently only for Sun and SGI)"""
  2.  
  3. __all__ = ["error","AudioDev"]
  4.  
  5. class error(Exception):
  6.     pass
  7.  
  8. class Play_Audio_sgi:
  9.     # Private instance variables
  10. ##      if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \
  11. ##                params, config, inited_outrate, inited_width, \
  12. ##                inited_nchannels, port, converter, classinited: private
  13.  
  14.     classinited = 0
  15.     frameratelist = nchannelslist = sampwidthlist = None
  16.  
  17.     def initclass(self):
  18.         import AL
  19.         self.frameratelist = [
  20.                   (48000, AL.RATE_48000),
  21.                   (44100, AL.RATE_44100),
  22.                   (32000, AL.RATE_32000),
  23.                   (22050, AL.RATE_22050),
  24.                   (16000, AL.RATE_16000),
  25.                   (11025, AL.RATE_11025),
  26.                   ( 8000,  AL.RATE_8000),
  27.                   ]
  28.         self.nchannelslist = [
  29.                   (1, AL.MONO),
  30.                   (2, AL.STEREO),
  31.                   (4, AL.QUADRO),
  32.                   ]
  33.         self.sampwidthlist = [
  34.                   (1, AL.SAMPLE_8),
  35.                   (2, AL.SAMPLE_16),
  36.                   (3, AL.SAMPLE_24),
  37.                   ]
  38.         self.classinited = 1
  39.  
  40.     def __init__(self):
  41.         import al, AL
  42.         if not self.classinited:
  43.             self.initclass()
  44.         self.oldparams = []
  45.         self.params = [AL.OUTPUT_RATE, 0]
  46.         self.config = al.newconfig()
  47.         self.inited_outrate = 0
  48.         self.inited_width = 0
  49.         self.inited_nchannels = 0
  50.         self.converter = None
  51.         self.port = None
  52.         return
  53.  
  54.     def __del__(self):
  55.         if self.port:
  56.             self.stop()
  57.         if self.oldparams:
  58.             import al, AL
  59.             al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
  60.             self.oldparams = []
  61.  
  62.     def wait(self):
  63.         if not self.port:
  64.             return
  65.         import time
  66.         while self.port.getfilled() > 0:
  67.             time.sleep(0.1)
  68.         self.stop()
  69.  
  70.     def stop(self):
  71.         if self.port:
  72.             self.port.closeport()
  73.             self.port = None
  74.         if self.oldparams:
  75.             import al, AL
  76.             al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
  77.             self.oldparams = []
  78.  
  79.     def setoutrate(self, rate):
  80.         for (raw, cooked) in self.frameratelist:
  81.             if rate == raw:
  82.                 self.params[1] = cooked
  83.                 self.inited_outrate = 1
  84.                 break
  85.         else:
  86.             raise error, 'bad output rate'
  87.  
  88.     def setsampwidth(self, width):
  89.         for (raw, cooked) in self.sampwidthlist:
  90.             if width == raw:
  91.                 self.config.setwidth(cooked)
  92.                 self.inited_width = 1
  93.                 break
  94.         else:
  95.             if width == 0:
  96.                 import AL
  97.                 self.inited_width = 0
  98.                 self.config.setwidth(AL.SAMPLE_16)
  99.                 self.converter = self.ulaw2lin
  100.             else:
  101.                 raise error, 'bad sample width'
  102.  
  103.     def setnchannels(self, nchannels):
  104.         for (raw, cooked) in self.nchannelslist:
  105.             if nchannels == raw:
  106.                 self.config.setchannels(cooked)
  107.                 self.inited_nchannels = 1
  108.                 break
  109.         else:
  110.             raise error, 'bad # of channels'
  111.  
  112.     def writeframes(self, data):
  113.         if not (self.inited_outrate and self.inited_nchannels):
  114.             raise error, 'params not specified'
  115.         if not self.port:
  116.             import al, AL
  117.             self.port = al.openport('Python', 'w', self.config)
  118.             self.oldparams = self.params[:]
  119.             al.getparams(AL.DEFAULT_DEVICE, self.oldparams)
  120.             al.setparams(AL.DEFAULT_DEVICE, self.params)
  121.         if self.converter:
  122.             data = self.converter(data)
  123.         self.port.writesamps(data)
  124.  
  125.     def getfilled(self):
  126.         if self.port:
  127.             return self.port.getfilled()
  128.         else:
  129.             return 0
  130.  
  131.     def getfillable(self):
  132.         if self.port:
  133.             return self.port.getfillable()
  134.         else:
  135.             return self.config.getqueuesize()
  136.  
  137.     # private methods
  138. ##      if 0: access *: private
  139.  
  140.     def ulaw2lin(self, data):
  141.         import audioop
  142.         return audioop.ulaw2lin(data, 2)
  143.  
  144. class Play_Audio_sun:
  145. ##      if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
  146. ##                inited_nchannels, converter: private
  147.  
  148.     def __init__(self):
  149.         self.outrate = 0
  150.         self.sampwidth = 0
  151.         self.nchannels = 0
  152.         self.inited_outrate = 0
  153.         self.inited_width = 0
  154.         self.inited_nchannels = 0
  155.         self.converter = None
  156.         self.port = None
  157.         return
  158.  
  159.     def __del__(self):
  160.         self.stop()
  161.  
  162.     def setoutrate(self, rate):
  163.         self.outrate = rate
  164.         self.inited_outrate = 1
  165.  
  166.     def setsampwidth(self, width):
  167.         self.sampwidth = width
  168.         self.inited_width = 1
  169.  
  170.     def setnchannels(self, nchannels):
  171.         self.nchannels = nchannels
  172.         self.inited_nchannels = 1
  173.  
  174.     def writeframes(self, data):
  175.         if not (self.inited_outrate and self.inited_width and self.inited_nchannels):
  176.             raise error, 'params not specified'
  177.         if not self.port:
  178.             import sunaudiodev, SUNAUDIODEV
  179.             self.port = sunaudiodev.open('w')
  180.             info = self.port.getinfo()
  181.             info.o_sample_rate = self.outrate
  182.             info.o_channels = self.nchannels
  183.             if self.sampwidth == 0:
  184.                 info.o_precision = 8
  185.                 self.o_encoding = SUNAUDIODEV.ENCODING_ULAW
  186.                 # XXX Hack, hack -- leave defaults
  187.             else:
  188.                 info.o_precision = 8 * self.sampwidth
  189.                 info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR
  190.                 self.port.setinfo(info)
  191.         if self.converter:
  192.             data = self.converter(data)
  193.         self.port.write(data)
  194.  
  195.     def wait(self):
  196.         if not self.port:
  197.             return
  198.         self.port.drain()
  199.         self.stop()
  200.  
  201.     def stop(self):
  202.         if self.port:
  203.             self.port.flush()
  204.             self.port.close()
  205.             self.port = None
  206.  
  207.     def getfilled(self):
  208.         if self.port:
  209.             return self.port.obufcount()
  210.         else:
  211.             return 0
  212.  
  213. ##    # Nobody remembers what this method does, and it's broken. :-(
  214. ##    def getfillable(self):
  215. ##        return BUFFERSIZE - self.getfilled()
  216.  
  217. def AudioDev():
  218.     # Dynamically try to import and use a platform specific module.
  219.     try:
  220.         import al
  221.     except ImportError:
  222.         try:
  223.             import sunaudiodev
  224.             return Play_Audio_sun()
  225.         except ImportError:
  226.             try:
  227.                 import Audio_mac
  228.             except ImportError:
  229.                 raise error, 'no audio device'
  230.             else:
  231.                 return Audio_mac.Play_Audio_mac()
  232.     else:
  233.         return Play_Audio_sgi()
  234.  
  235. def test(fn = None):
  236.     import sys
  237.     if sys.argv[1:]:
  238.         fn = sys.argv[1]
  239.     else:
  240.         fn = 'f:just samples:just.aif'
  241.     import aifc
  242.     af = aifc.open(fn, 'r')
  243.     print fn, af.getparams()
  244.     p = AudioDev()
  245.     p.setoutrate(af.getframerate())
  246.     p.setsampwidth(af.getsampwidth())
  247.     p.setnchannels(af.getnchannels())
  248.     BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels()
  249.     while 1:
  250.         data = af.readframes(BUFSIZ)
  251.         if not data: break
  252.         print len(data)
  253.         p.writeframes(data)
  254.     p.wait()
  255.  
  256. if __name__ == '__main__':
  257.     test()
  258.