home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / AUDIODEV.PY < prev    next >
Encoding:
Python Source  |  2000-09-28  |  5.9 KB  |  255 lines

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