home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / bin / asoundconf < prev    next >
Encoding:
Text File  |  2007-02-18  |  12.7 KB  |  459 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. asoundconf set-pulseaudio
  42. asoundconf unset-pulseaudio
  43. '''
  44.  
  45.  
  46. def help(): 
  47.         print usage
  48.  
  49.  
  50. def ensure_our_conf_exists():
  51.     '''If it does not exist then generate a default configuration
  52.     file with no settings.
  53.  
  54.     Return: True on success, False if the file could not be created.
  55.     '''
  56.  
  57.     if os.path.exists(our_conf_file):
  58.         return True
  59.  
  60.     try:
  61.         open(our_conf_file, 'w').write(our_conf_header)
  62.         return True
  63.     except IOError:
  64.         print >> sys.stderr, 'Error: could not create', our_conf_file
  65.         return False
  66.  
  67.  
  68. def ensure_asound_rc_exists():
  69.     '''Generate a default user configuration file with only the
  70.     inclusion line.
  71.  
  72.     Return: True on success, False if the file could not be created.
  73.     '''
  74.  
  75.     if os.path.exists(asoundrc_file):
  76.         return True
  77.  
  78.     try:
  79.         open(asoundrc_file, 'w').write('%s\n%s\n<%s>\n\n' % (asoundrc_header, inclusion_comment, our_conf_file))
  80.         return True
  81.     except IOError:
  82.         print >> sys.stderr, 'Error: could not create', asoundrc_file
  83.         return False
  84.  
  85.  
  86. def sds_transition():
  87.     '''Replace the magic comments added to the user configuration file
  88.     by the obsolete set-default-soundcard program with the standard
  89.     inclusion statement for our configuration file.
  90.     '''
  91.  
  92.     if not os.path.exists(asoundrc_file):
  93.         return
  94.  
  95.     lines = open(asoundrc_file).readlines()
  96.  
  97.     start_marker_re = re.compile('### BEGIN set-default-soundcard')
  98.     end_marker_re = re.compile('### END set-default-soundcard')
  99.  
  100.     userconf_lines = []
  101.     our_conf_lines = []
  102.  
  103.     # read up to start comment
  104.     lineno = 0
  105.     found = 0
  106.     for l in lines:
  107.         lineno = lineno+1
  108.         if start_marker_re.match(l):
  109.             found = 1
  110.             break
  111.         userconf_lines.append(l)
  112.  
  113.     if found:
  114.         # replace magic comment section with include
  115.         userconf_lines.append('%s\n<%s>\n\n' % (inclusion_comment, our_conf_file))
  116.     else:
  117.         # no magic comment
  118.         return
  119.  
  120.     # read magic comment section until end marker and add it to asoundconf
  121.     found = 0
  122.     for l in lines[lineno:]:
  123.         lineno = lineno+1
  124.         if end_marker_re.match(l):
  125.             found = 1
  126.             break
  127.         if not l.startswith('#'):
  128.             our_conf_lines.append(l)
  129.  
  130.     if not found:
  131.         # no complete magic comment
  132.         return
  133.  
  134.     # add the rest to user conf
  135.     userconf_lines = userconf_lines + lines[lineno:]
  136.  
  137.     # write our configuration file
  138.     if not ensure_our_conf_exists():
  139.         return
  140.     try:
  141.         open(our_conf_file, 'a').writelines(our_conf_lines)
  142.     except IOError:
  143.         return # panic out
  144.  
  145.     # write user configuration file
  146.     try:
  147.         open(asoundrc_file, 'w').writelines(userconf_lines)
  148.     except IOError:
  149.         pass
  150.  
  151.  
  152. def is_active():
  153.     '''Check that the user configuration file is either absent, or,
  154.     if present, that it includifies the asoundconf configuration file;
  155.     in those cases asoundconf can be used to change the user's ALSA
  156.     library configuration.
  157.  
  158.     Also transition from the legacy set-default-soundcard program.
  159.  
  160.     Return True if the above condition is met, False if not.
  161.     '''
  162.  
  163.     if not os.path.exists(asoundrc_file):
  164.         return True
  165.  
  166.     sds_transition()
  167.  
  168.     # check whether or not the file has the inclusion line
  169.     include_re = re.compile('\s*<\s*%s\s*>' % our_conf_file)
  170.     for l in open(asoundrc_file):
  171.         if include_re.match(l):
  172.             return True
  173.  
  174.     return False
  175.  
  176. def get(prmtr):
  177.     '''Print the value of the given parameter on stdout
  178.  
  179.     Also transition from the legacy set-default-soundcard program.
  180.  
  181.     Return True on success, and False if the value is not set.
  182.     '''
  183.  
  184.     sds_transition()
  185.  
  186.     if not os.path.exists(our_conf_file):
  187.         return False
  188.  
  189.     setting_re = re.compile(setting_re_template % prmtr)
  190.  
  191.     try:
  192.         for line in open(our_conf_file):
  193.             m = setting_re.match(line)
  194.             if m:
  195.                 print m.group(1).strip()
  196.                 return True
  197.         return False
  198.     except IOError:
  199.         return False
  200.  
  201. def list():
  202.     '''Get card names from /proc/asound/cards'''
  203.  
  204.     cardspath = '/proc/asound/cards'
  205.     if not os.path.exists(cardspath):
  206.         return False
  207.     procfile = open(cardspath, 'rb')
  208.     cardline = re.compile('^\s*\d+\s*\[')
  209.     card_lines = []
  210.     lines = procfile.readlines()
  211.     for l in lines:
  212.         if cardline.match(l):
  213.             card_lines.append(re.sub(r'^\s*\d+\s*\[(\w+)\s*\].+','\\1',l))
  214.     print "Names of available sound cards:"
  215.     for cardname in card_lines:
  216.         print cardname.strip()
  217.     return True
  218.  
  219. def delete(prmtr):
  220.     '''Delete the given parameter.
  221.  
  222.     Also transition from the legacy set-default-soundcard program.
  223.  
  224.     Return True on success, and False on an error.
  225.     '''
  226.  
  227.     sds_transition()
  228.  
  229.     if not os.path.exists(our_conf_file):
  230.         return False
  231.  
  232.     setting_re = re.compile(setting_re_template % prmtr)
  233.     lines = []
  234.     try:
  235.         lines = open(our_conf_file).readlines()
  236.     except IOError:
  237.         return False
  238.  
  239.     found = 0
  240.     for i in xrange(len(lines)):
  241.         if setting_re.match(lines[i]):
  242.             del lines[i]
  243.             found = 1
  244.             break
  245.  
  246.     if found:
  247.         # write back file
  248.         try:
  249.             f = open(our_conf_file, 'w')
  250.         except IOError:
  251.             return False
  252.         f.writelines(lines)
  253.  
  254.     return True
  255.  
  256.  
  257. def set(prmtr, value):
  258.     '''Set the given parameter to the given value
  259.  
  260.     Also transition from the legacy set-default-soundcard program.
  261.  
  262.     Return True on success, and False on an error.
  263.     '''
  264.  
  265.     sds_transition()
  266.  
  267.     setting_re = re.compile(setting_re_template % prmtr)
  268.     lines = []
  269.  
  270.     ensure_asound_rc_exists()
  271.     # N.B. We continue even if asoundrc could not be created
  272.     # and we do NOT ensure that our configuration is "active"
  273.  
  274.     if not ensure_our_conf_exists():
  275.         return False
  276.  
  277.     try:
  278.         lines = open(our_conf_file).readlines()
  279.     except IOError:
  280.         return False
  281.  
  282.     newsetting = '%s %s\n' % (prmtr, value)
  283.  
  284.     # if setting is already present, change it
  285.     found = 0
  286.     for i in xrange(len(lines)):
  287.         if setting_re.match(lines[i]):
  288.             lines[i] = newsetting
  289.             found = 1
  290.             break
  291.  
  292.     if not found:
  293.         lines.append(newsetting)
  294.  
  295.     # write back file
  296.     try:
  297.         f = open(our_conf_file, 'w')
  298.     except IOError:
  299.         return False
  300.     f.writelines(lines)
  301.     return True
  302.  
  303. def set_default_card(card):
  304.     return set('!defaults.pcm.card', card) and \
  305.     set('defaults.ctl.card', card) and \
  306.     set('defaults.pcm.device', '0') and \
  307.     set('defaults.pcm.subdevice', '-1') and \
  308.     set('defaults.pcm.nonblock', '1') and \
  309.     set('defaults.pcm.ipc_key', '5678293') and \
  310.     set('defaults.pcm.ipc_gid', 'audio') and \
  311.     set('defaults.pcm.ipc_perm', '0660') and \
  312.     set('defaults.pcm.dmix_max_periods', '0') and \
  313.     set('defaults.pcm.dmix_rate', '48000') and \
  314.     set('defaults.pcm.dmix_format', 'S16') and \
  315.     set('defaults.pcm.front.card', 'defaults.pcm.card') and \
  316.     set('defaults.pcm.front.device', 'defaults.pcm.device') and \
  317.     set('defaults.pcm.rear.card', 'defaults.pcm.card') and \
  318.     set('defaults.pcm.rear.device', 'defaults.pcm.device') and \
  319.     set('defaults.pcm.center_lfe.card', 'defaults.pcm.card') and \
  320.     set('defaults.pcm.center_lfe.device', 'defaults.pcm.device') and \
  321.     set('defaults.pcm.side.card', 'defaults.pcm.card') and \
  322.     set('defaults.pcm.side.device', 'defaults.pcm.device') and \
  323.     set('defaults.pcm.surround40.card', 'defaults.pcm.card') and \
  324.     set('defaults.pcm.surround40.device', 'defaults.pcm.device') and \
  325.     set('defaults.pcm.surround41.card', 'defaults.pcm.card') and \
  326.     set('defaults.pcm.surround41.device', 'defaults.pcm.device') and \
  327.     set('defaults.pcm.surround50.card', 'defaults.pcm.card') and \
  328.     set('defaults.pcm.surround50.device', 'defaults.pcm.device') and \
  329.     set('defaults.pcm.surround51.card', 'defaults.pcm.card') and \
  330.     set('defaults.pcm.surround51.device', 'defaults.pcm.device') and \
  331.     set('defaults.pcm.surround71.card', 'defaults.pcm.card') and \
  332.     set('defaults.pcm.surround71.device', 'defaults.pcm.device') and \
  333.     set('defaults.pcm.iec958.card', 'defaults.pcm.card') and \
  334.     set('defaults.pcm.iec958.device', 'defaults.pcm.device') and \
  335.     set('defaults.pcm.modem.card', 'defaults.pcm.card') and \
  336.     set('defaults.pcm.modem.device', 'defaults.pcm.device') and \
  337.     set('defaults.rawmidi.card', '0') and \
  338.     set('defaults.rawmidi.device', '0') and \
  339.     set('defaults.rawmidi.subdevice', '-1') and \
  340.     set('defaults.hwdep.card', '0') and \
  341.     set('defaults.hwdep.device', '0') and \
  342.     set('defaults.timer.class', '2') and \
  343.     set('defaults.timer.sclass', '0') and \
  344.     set('defaults.timer.card', '0') and \
  345.     set('defaults.timer.device', '0') and \
  346.     set('defaults.timer.subdevice', '0')
  347.  
  348. def reset_default_card():
  349.     return delete('defaults.pcm.card') and \
  350.     delete('defaults.ctl.card') and \
  351.     delete('defaults.pcm.device') and \
  352.     delete('defaults.pcm.subdevice') and \
  353.     delete('defaults.pcm.nonblock') and \
  354.     delete('defaults.pcm.ipc_key') and \
  355.     delete('defaults.pcm.ipc_gid') and \
  356.     delete('defaults.pcm.ipc_perm') and \
  357.     delete('defaults.pcm.dmix_max_periods') and \
  358.     delete('defaults.pcm.dmix_rate') and \
  359.     delete('defaults.pcm.dmix_format') and \
  360.     delete('defaults.pcm.front.card') and \
  361.     delete('defaults.pcm.front.device') and \
  362.     delete('defaults.pcm.rear.card') and \
  363.     delete('defaults.pcm.rear.device') and \
  364.     delete('defaults.pcm.center_lfe.card') and \
  365.     delete('defaults.pcm.center_lfe.device') and \
  366.     delete('defaults.pcm.side.card') and \
  367.     delete('defaults.pcm.side.device') and \
  368.     delete('defaults.pcm.surround40.card') and \
  369.     delete('defaults.pcm.surround40.device') and \
  370.     delete('defaults.pcm.surround41.card') and \
  371.     delete('defaults.pcm.surround41.device') and \
  372.     delete('defaults.pcm.surround50.card') and \
  373.     delete('defaults.pcm.surround50.device') and \
  374.     delete('defaults.pcm.surround51.card') and \
  375.     delete('defaults.pcm.surround51.device') and \
  376.     delete('defaults.pcm.surround71.card') and \
  377.     delete('defaults.pcm.surround71.device') and \
  378.     delete('defaults.pcm.iec958.card') and \
  379.     delete('defaults.pcm.iec958.device') and \
  380.     delete('defaults.pcm.modem.card') and \
  381.     delete('defaults.pcm.modem.device') and \
  382.     delete('defaults.rawmidi.card') and \
  383.     delete('defaults.rawmidi.device') and \
  384.     delete('defaults.rawmidi.subdevice') and \
  385.     delete('defaults.hwdep.card') and \
  386.     delete('defaults.hwdep.device') and \
  387.     delete('defaults.timer.class') and \
  388.     delete('defaults.timer.sclass') and \
  389.     delete('defaults.timer.card') and \
  390.     delete('defaults.timer.device') and \
  391.     delete('defaults.timer.subdevice')
  392.  
  393. def set_pulseaudio():
  394.     return set('pcm.!default', '{ type pulse }') and \
  395.     set('ctl.!default', '{ type pulse }')
  396.  
  397. def unset_pulseaudio():
  398.     return delete('pcm.!default') and \
  399.     delete('ctl.!default')
  400.  
  401. def exit_code(result):
  402.     '''Exit program with code 0 if result is True, otherwise exit with code
  403.     1.
  404.     '''
  405.  
  406.     if result:
  407.         sys.exit(0)
  408.     else:
  409.         sys.exit(1)
  410.  
  411.  
  412. ##
  413. ## main
  414. ##
  415.  
  416. if len(sys.argv) < 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
  417.         help()
  418.         sys.exit(0)
  419.  
  420. if sys.argv[1] == 'is-active':
  421.     exit_code(is_active())
  422.  
  423. if sys.argv[1] == 'get':
  424.     if len(sys.argv) != 3:
  425.         help()
  426.         sys.exit(1)
  427.     exit_code(get(sys.argv[2]))
  428.  
  429. if sys.argv[1] == 'delete':
  430.     if len(sys.argv) != 3:
  431.         help()
  432.         sys.exit(1)
  433.     exit_code(delete(sys.argv[2]))
  434.  
  435. if sys.argv[1] == 'set':
  436.     if len(sys.argv) != 4:
  437.         help()
  438.         sys.exit(1)
  439.     exit_code(set(sys.argv[2], sys.argv[3]))
  440.  
  441. if sys.argv[1] == 'list':
  442.     exit_code(list())
  443.  
  444. if sys.argv[1] == 'set-default-card':
  445.     exit_code(set_default_card(sys.argv[2]))
  446.  
  447. if sys.argv[1] == 'reset-default-card':
  448.     exit_code(reset_default_card())
  449.  
  450. if sys.argv[1] == 'set-pulseaudio':
  451.     exit_code(set_pulseaudio())
  452.  
  453. if sys.argv[1] == 'unset-pulseaudio':
  454.     exit_code(unset_pulseaudio())
  455.  
  456. help()
  457. sys.exit(1)
  458.  
  459.