home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / bin / asoundconf < prev    next >
Encoding:
Text File  |  2006-07-30  |  9.9 KB  |  395 lines

  1. #!/usr/bin/python
  2.  
  3. # (C) 2005 Canonical Ltd.
  4. # Author: Martin Pitt <martin.pitt@ubuntu.com>
  5. # License: GNU General Public License, version 2 or any later version
  6. #
  7. # Modified by: Thomas Hood, Daniel T Chen
  8. #
  9. # Get and set configuration parameters in ~/.asoundrc.asoundconf.
  10.  
  11. import sys, re, os.path
  12.  
  13. our_conf_file = os.path.expanduser('~/.asoundrc.asoundconf')
  14. asoundrc_file = os.path.expanduser('~/.asoundrc')
  15.  
  16. setting_re_template = '!?\s*%s\s*(?:=|\s)\s*([^;,]+)[;,]?$'
  17.  
  18. our_conf_header = '''# ALSA library configuration file managed by asoundconf(1).
  19. #
  20. # MANUAL CHANGES TO THIS FILE WILL BE OVERWRITTEN!
  21. #
  22. # Manual changes to the ALSA library configuration should be implemented
  23. # by editing the ~/.asoundrc file, not by editing this file.
  24. '''
  25.  
  26. asoundrc_header = '''# ALSA library configuration file
  27. '''
  28.  
  29. inclusion_comment = '''# Include settings that are under the control of asoundconf(1).
  30. # (To disable these settings, comment out this line.)'''
  31.  
  32. usage = '''Usage:
  33. asoundconf is-active
  34. asoundconf get|delete PARAMETER
  35. asoundconf set PARAMETER VALUE
  36. asoundconf list
  37.  
  38. Convenience macro functions:
  39. asoundconf set-default-card CARD
  40. asoundconf reset-default-card
  41. '''
  42.  
  43.  
  44. def help(): 
  45.         print usage
  46.  
  47.  
  48. def ensure_our_conf_exists():
  49.     '''If it does not exist then generate a default configuration
  50.     file with no settings.
  51.  
  52.     Return: True on success, False if the file could not be created.
  53.     '''
  54.  
  55.     if os.path.exists(our_conf_file):
  56.         return True
  57.  
  58.     try:
  59.         open(our_conf_file, 'w').write(our_conf_header)
  60.         return True
  61.     except IOError:
  62.         print >> sys.stderr, 'Error: could not create', our_conf_file
  63.         return False
  64.  
  65.  
  66. def ensure_asound_rc_exists():
  67.     '''Generate a default user configuration file with only the
  68.     inclusion line.
  69.  
  70.     Return: True on success, False if the file could not be created.
  71.     '''
  72.  
  73.     if os.path.exists(asoundrc_file):
  74.         return True
  75.  
  76.     try:
  77.         open(asoundrc_file, 'w').write('%s\n%s\n<%s>\n\n' % (asoundrc_header, inclusion_comment, our_conf_file))
  78.         return True
  79.     except IOError:
  80.         print >> sys.stderr, 'Error: could not create', asoundrc_file
  81.         return False
  82.  
  83.  
  84. def sds_transition():
  85.     '''Replace the magic comments added to the user configuration file
  86.     by the obsolete set-default-soundcard program with the standard
  87.     inclusion statement for our configuration file.
  88.     '''
  89.  
  90.     if not os.path.exists(asoundrc_file):
  91.         return
  92.  
  93.     lines = open(asoundrc_file).readlines()
  94.  
  95.     start_marker_re = re.compile('### BEGIN set-default-soundcard')
  96.     end_marker_re = re.compile('### END set-default-soundcard')
  97.  
  98.     userconf_lines = []
  99.     our_conf_lines = []
  100.  
  101.     # read up to start comment
  102.     lineno = 0
  103.     found = 0
  104.     for l in lines:
  105.         lineno = lineno+1
  106.         if start_marker_re.match(l):
  107.             found = 1
  108.             break
  109.         userconf_lines.append(l)
  110.  
  111.     if found:
  112.         # replace magic comment section with include
  113.         userconf_lines.append('%s\n<%s>\n\n' % (inclusion_comment, our_conf_file))
  114.     else:
  115.         # no magic comment
  116.         return
  117.  
  118.     # read magic comment section until end marker and add it to asoundconf
  119.     found = 0
  120.     for l in lines[lineno:]:
  121.         lineno = lineno+1
  122.         if end_marker_re.match(l):
  123.             found = 1
  124.             break
  125.         if not l.startswith('#'):
  126.             our_conf_lines.append(l)
  127.  
  128.     if not found:
  129.         # no complete magic comment
  130.         return
  131.  
  132.     # add the rest to user conf
  133.     userconf_lines = userconf_lines + lines[lineno:]
  134.  
  135.     # write our configuration file
  136.     if not ensure_our_conf_exists():
  137.         return
  138.     try:
  139.         open(our_conf_file, 'a').writelines(our_conf_lines)
  140.     except IOError:
  141.         return # panic out
  142.  
  143.     # write user configuration file
  144.     try:
  145.         open(asoundrc_file, 'w').writelines(userconf_lines)
  146.     except IOError:
  147.         pass
  148.  
  149.  
  150. def is_active():
  151.     '''Check that the user configuration file is either absent, or,
  152.     if present, that it includifies the asoundconf configuration file;
  153.     in those cases asoundconf can be used to change the user's ALSA
  154.     library configuration.
  155.  
  156.     Also transition from the legacy set-default-soundcard program.
  157.  
  158.     Return True if the above condition is met, False if not.
  159.     '''
  160.  
  161.     if not os.path.exists(asoundrc_file):
  162.         return True
  163.  
  164.     sds_transition()
  165.  
  166.     # check whether or not the file has the inclusion line
  167.     include_re = re.compile('\s*<\s*%s\s*>' % our_conf_file)
  168.     for l in open(asoundrc_file):
  169.         if include_re.match(l):
  170.             return True
  171.  
  172.     return False
  173.  
  174. def get(prmtr):
  175.     '''Print the value of the given parameter on stdout
  176.  
  177.     Also transition from the legacy set-default-soundcard program.
  178.  
  179.     Return True on success, and False if the value is not set.
  180.     '''
  181.  
  182.     sds_transition()
  183.  
  184.     if not os.path.exists(our_conf_file):
  185.         return False
  186.  
  187.     setting_re = re.compile(setting_re_template % prmtr)
  188.  
  189.     try:
  190.         for line in open(our_conf_file):
  191.             m = setting_re.match(line)
  192.             if m:
  193.                 print m.group(1).strip()
  194.                 return True
  195.         return False
  196.     except IOError:
  197.         return False
  198.  
  199. def list():
  200.     '''Get card names from /proc/asound/cards'''
  201.  
  202.     cardspath = '/proc/asound/cards'
  203.     if not os.path.exists(cardspath):
  204.         return False
  205.     procfile = open(cardspath, 'rb')
  206.     cardline = re.compile('^\s*\d+\s*\[')
  207.     card_lines = []
  208.     lines = procfile.readlines()
  209.     for l in lines:
  210.         if cardline.match(l):
  211.             card_lines.append(re.sub(r'^\s*\d+\s*\[(\w+)\s*\].+','\\1',l))
  212.     print "Names of available sound cards:"
  213.     for cardname in card_lines:
  214.         print cardname.strip()
  215.     return True
  216.  
  217. def delete(prmtr):
  218.     '''Delete the given parameter.
  219.  
  220.     Also transition from the legacy set-default-soundcard program.
  221.  
  222.     Return True on success, and False on an error.
  223.     '''
  224.  
  225.     sds_transition()
  226.  
  227.     if not os.path.exists(our_conf_file):
  228.         return False
  229.  
  230.     setting_re = re.compile(setting_re_template % prmtr)
  231.     lines = []
  232.     try:
  233.         lines = open(our_conf_file).readlines()
  234.     except IOError:
  235.         return False
  236.  
  237.     found = 0
  238.     for i in xrange(len(lines)):
  239.         if setting_re.match(lines[i]):
  240.             del lines[i]
  241.             found = 1
  242.             break
  243.  
  244.     if found:
  245.         # write back file
  246.         try:
  247.             f = open(our_conf_file, 'w')
  248.         except IOError:
  249.             return False
  250.         f.writelines(lines)
  251.  
  252.     return True
  253.  
  254.  
  255. def set(prmtr, value):
  256.     '''Set the given parameter to the given value
  257.  
  258.     Also transition from the legacy set-default-soundcard program.
  259.  
  260.     Return True on success, and False on an error.
  261.     '''
  262.  
  263.     sds_transition()
  264.  
  265.     setting_re = re.compile(setting_re_template % prmtr)
  266.     lines = []
  267.  
  268.     ensure_asound_rc_exists()
  269.     # N.B. We continue even if asoundrc could not be created
  270.     # and we do NOT ensure that our configuration is "active"
  271.  
  272.     if not ensure_our_conf_exists():
  273.         return False
  274.  
  275.     try:
  276.         lines = open(our_conf_file).readlines()
  277.     except IOError:
  278.         return False
  279.  
  280.     newsetting = '%s %s\n' % (prmtr, value)
  281.  
  282.     # if setting is already present, change it
  283.     found = 0
  284.     for i in xrange(len(lines)):
  285.         if setting_re.match(lines[i]):
  286.             lines[i] = newsetting
  287.             found = 1
  288.             break
  289.  
  290.     if not found:
  291.         lines.append(newsetting)
  292.  
  293.     # write back file
  294.     try:
  295.         f = open(our_conf_file, 'w')
  296.     except IOError:
  297.         return False
  298.     f.writelines(lines)
  299.     return True
  300.  
  301. def set_default_card(card):
  302.     return set ('!defaults.pcm.card', card) and \
  303.     set ('defaults.ctl.card', card) and \
  304.     set ('defaults.pcm.device', '0') and \
  305.     set ('defaults.pcm.subdevice', '-1') and \
  306.     set('defaults.pcm.nonblock', '1') and \
  307.     set('defaults.pcm.ipc_key', '5678293') and \
  308.     set('defaults.pcm.ipc_gid', 'audio') and \
  309.     set('defaults.pcm.ipc_perm', '0660') and \
  310.     set('defaults.pcm.dmix_max_periods', '0') and \
  311.     set('defaults.rawmidi.card', '0') and \
  312.     set('defaults.rawmidi.device', '0') and \
  313.     set('defaults.rawmidi.subdevice', '-1') and \
  314.     set('defaults.hwdep.card', '0') and \
  315.     set('defaults.hwdep.device', '0') and \
  316.     set('defaults.timer.class', '2') and \
  317.     set('defaults.timer.sclass', '0') and \
  318.     set('defaults.timer.card', '0') and \
  319.     set('defaults.timer.device', '0') and \
  320.     set('defaults.timer.subdevice', '0')
  321.  
  322. def reset_default_card():
  323.     return delete('defaults.pcm.card') and \
  324.     delete('defaults.ctl.card') and \
  325.     delete('defaults.pcm.device') and \
  326.     delete('defaults.pcm.subdevice') and \
  327.     delete('defaults.pcm.nonblock') and \
  328.     delete('defaults.pcm.ipc_key') and \
  329.     delete('defaults.pcm.ipc_gid') and \
  330.     delete('defaults.pcm.ipc_perm') and \
  331.     delete('defaults.pcm.dmix_max_periods') and \
  332.     delete('defaults.rawmidi.card') and \
  333.     delete('defaults.rawmidi.device') and \
  334.     delete('defaults.rawmidi.subdevice') and \
  335.     delete('defaults.hwdep.card') and \
  336.     delete('defaults.hwdep.device') and \
  337.     delete('defaults.timer.class') and \
  338.     delete('defaults.timer.sclass') and \
  339.     delete('defaults.timer.card') and \
  340.     delete('defaults.timer.device') and \
  341.     delete('defaults.timer.subdevice')
  342.  
  343. def exit_code(result):
  344.     '''Exit program with code 0 if result is True, otherwise exit with code
  345.     1.
  346.     '''
  347.  
  348.     if result:
  349.         sys.exit(0)
  350.     else:
  351.         sys.exit(1)
  352.  
  353.  
  354. ##
  355. ## main
  356. ##
  357.  
  358. if len(sys.argv) < 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
  359.         help()
  360.         sys.exit(0)
  361.  
  362. if sys.argv[1] == 'is-active':
  363.     exit_code(is_active())
  364.  
  365. if sys.argv[1] == 'get':
  366.     if len(sys.argv) != 3:
  367.         help()
  368.         sys.exit(1)
  369.     exit_code(get(sys.argv[2]))
  370.  
  371. if sys.argv[1] == 'delete':
  372.     if len(sys.argv) != 3:
  373.         help()
  374.         sys.exit(1)
  375.     exit_code(delete(sys.argv[2]))
  376.  
  377. if sys.argv[1] == 'set':
  378.     if len(sys.argv) != 4:
  379.         help()
  380.         sys.exit(1)
  381.     exit_code(set(sys.argv[2], sys.argv[3]))
  382.  
  383. if sys.argv[1] == 'list':
  384.     exit_code(list())
  385.  
  386. if sys.argv[1] == 'set-default-card':
  387.     exit_code(set_default_card(sys.argv[2]))
  388.  
  389. if sys.argv[1] == 'reset-default-card':
  390.     exit_code(reset_default_card())
  391.  
  392. help()
  393. sys.exit(1)
  394.  
  395.