home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/python
-
- # (C) 2005 Canonical Ltd.
- # Author: Martin Pitt <martin.pitt@ubuntu.com>
- # License: GNU General Public License, version 2 or any later version
- #
- # Modified by: Thomas Hood, Daniel T Chen
- #
- # Get and set configuration parameters in ~/.asoundrc.asoundconf.
-
- import sys, re, os.path
-
- our_conf_file = os.path.expanduser('~/.asoundrc.asoundconf')
- asoundrc_file = os.path.expanduser('~/.asoundrc')
-
- setting_re_template = '!?\s*%s\s*(?:=|\s)\s*([^;,]+)[;,]?$'
-
- our_conf_header = '''# ALSA library configuration file managed by asoundconf(1).
- #
- # MANUAL CHANGES TO THIS FILE WILL BE OVERWRITTEN!
- #
- # Manual changes to the ALSA library configuration should be implemented
- # by editing the ~/.asoundrc file, not by editing this file.
- '''
-
- asoundrc_header = '''# ALSA library configuration file
- '''
-
- inclusion_comment = '''# Include settings that are under the control of asoundconf(1).
- # (To disable these settings, comment out this line.)'''
-
- usage = '''Usage:
- asoundconf is-active
- asoundconf get|delete PARAMETER
- asoundconf set PARAMETER VALUE
- asoundconf list
-
- Convenience macro functions:
- asoundconf set-default-card CARD
- asoundconf reset-default-card
- asoundconf set-pulseaudio
- asoundconf unset-pulseaudio
- '''
-
-
- def help():
- print usage
-
-
- def ensure_our_conf_exists():
- '''If it does not exist then generate a default configuration
- file with no settings.
-
- Return: True on success, False if the file could not be created.
- '''
-
- if os.path.exists(our_conf_file):
- return True
-
- try:
- open(our_conf_file, 'w').write(our_conf_header)
- return True
- except IOError:
- print >> sys.stderr, 'Error: could not create', our_conf_file
- return False
-
-
- def ensure_asound_rc_exists():
- '''Generate a default user configuration file with only the
- inclusion line.
-
- Return: True on success, False if the file could not be created.
- '''
-
- if os.path.exists(asoundrc_file):
- return True
-
- try:
- open(asoundrc_file, 'w').write('%s\n%s\n<%s>\n\n' % (asoundrc_header, inclusion_comment, our_conf_file))
- return True
- except IOError:
- print >> sys.stderr, 'Error: could not create', asoundrc_file
- return False
-
-
- def sds_transition():
- '''Replace the magic comments added to the user configuration file
- by the obsolete set-default-soundcard program with the standard
- inclusion statement for our configuration file.
- '''
-
- if not os.path.exists(asoundrc_file):
- return
-
- lines = open(asoundrc_file).readlines()
-
- start_marker_re = re.compile('### BEGIN set-default-soundcard')
- end_marker_re = re.compile('### END set-default-soundcard')
-
- userconf_lines = []
- our_conf_lines = []
-
- # read up to start comment
- lineno = 0
- found = 0
- for l in lines:
- lineno = lineno+1
- if start_marker_re.match(l):
- found = 1
- break
- userconf_lines.append(l)
-
- if found:
- # replace magic comment section with include
- userconf_lines.append('%s\n<%s>\n\n' % (inclusion_comment, our_conf_file))
- else:
- # no magic comment
- return
-
- # read magic comment section until end marker and add it to asoundconf
- found = 0
- for l in lines[lineno:]:
- lineno = lineno+1
- if end_marker_re.match(l):
- found = 1
- break
- if not l.startswith('#'):
- our_conf_lines.append(l)
-
- if not found:
- # no complete magic comment
- return
-
- # add the rest to user conf
- userconf_lines = userconf_lines + lines[lineno:]
-
- # write our configuration file
- if not ensure_our_conf_exists():
- return
- try:
- open(our_conf_file, 'a').writelines(our_conf_lines)
- except IOError:
- return # panic out
-
- # write user configuration file
- try:
- open(asoundrc_file, 'w').writelines(userconf_lines)
- except IOError:
- pass
-
-
- def is_active():
- '''Check that the user configuration file is either absent, or,
- if present, that it includifies the asoundconf configuration file;
- in those cases asoundconf can be used to change the user's ALSA
- library configuration.
-
- Also transition from the legacy set-default-soundcard program.
-
- Return True if the above condition is met, False if not.
- '''
-
- if not os.path.exists(asoundrc_file):
- return True
-
- sds_transition()
-
- # check whether or not the file has the inclusion line
- include_re = re.compile('\s*<\s*%s\s*>' % our_conf_file)
- for l in open(asoundrc_file):
- if include_re.match(l):
- return True
-
- return False
-
- def get(prmtr):
- '''Print the value of the given parameter on stdout
-
- Also transition from the legacy set-default-soundcard program.
-
- Return True on success, and False if the value is not set.
- '''
-
- sds_transition()
-
- if not os.path.exists(our_conf_file):
- return False
-
- setting_re = re.compile(setting_re_template % prmtr)
-
- try:
- for line in open(our_conf_file):
- m = setting_re.match(line)
- if m:
- print m.group(1).strip()
- return True
- return False
- except IOError:
- return False
-
- def list():
- '''Get card names from /proc/asound/cards'''
-
- cardspath = '/proc/asound/cards'
- if not os.path.exists(cardspath):
- return False
- procfile = open(cardspath, 'rb')
- cardline = re.compile('^\s*\d+\s*\[')
- card_lines = []
- lines = procfile.readlines()
- for l in lines:
- if cardline.match(l):
- card_lines.append(re.sub(r'^\s*\d+\s*\[(\w+)\s*\].+','\\1',l))
- print "Names of available sound cards:"
- for cardname in card_lines:
- print cardname.strip()
- return True
-
- def delete(prmtr):
- '''Delete the given parameter.
-
- Also transition from the legacy set-default-soundcard program.
-
- Return True on success, and False on an error.
- '''
-
- sds_transition()
-
- if not os.path.exists(our_conf_file):
- return False
-
- setting_re = re.compile(setting_re_template % prmtr)
- lines = []
- try:
- lines = open(our_conf_file).readlines()
- except IOError:
- return False
-
- found = 0
- for i in xrange(len(lines)):
- if setting_re.match(lines[i]):
- del lines[i]
- found = 1
- break
-
- if found:
- # write back file
- try:
- f = open(our_conf_file, 'w')
- except IOError:
- return False
- f.writelines(lines)
-
- return True
-
-
- def set(prmtr, value):
- '''Set the given parameter to the given value
-
- Also transition from the legacy set-default-soundcard program.
-
- Return True on success, and False on an error.
- '''
-
- sds_transition()
-
- setting_re = re.compile(setting_re_template % prmtr)
- lines = []
-
- ensure_asound_rc_exists()
- # N.B. We continue even if asoundrc could not be created
- # and we do NOT ensure that our configuration is "active"
-
- if not ensure_our_conf_exists():
- return False
-
- try:
- lines = open(our_conf_file).readlines()
- except IOError:
- return False
-
- newsetting = '%s %s\n' % (prmtr, value)
-
- # if setting is already present, change it
- found = 0
- for i in xrange(len(lines)):
- if setting_re.match(lines[i]):
- lines[i] = newsetting
- found = 1
- break
-
- if not found:
- lines.append(newsetting)
-
- # write back file
- try:
- f = open(our_conf_file, 'w')
- except IOError:
- return False
- f.writelines(lines)
- return True
-
- def set_default_card(card):
- return set('!defaults.pcm.card', card) and \
- set('defaults.ctl.card', card) and \
- set('defaults.pcm.device', '0') and \
- set('defaults.pcm.subdevice', '-1') and \
- set('defaults.pcm.nonblock', '1') and \
- set('defaults.pcm.ipc_key', '5678293') and \
- set('defaults.pcm.ipc_gid', 'audio') and \
- set('defaults.pcm.ipc_perm', '0660') and \
- set('defaults.pcm.dmix_max_periods', '0') and \
- set('defaults.pcm.dmix_rate', '48000') and \
- set('defaults.pcm.dmix_format', 'S16') and \
- set('defaults.pcm.front.card', 'defaults.pcm.card') and \
- set('defaults.pcm.front.device', 'defaults.pcm.device') and \
- set('defaults.pcm.rear.card', 'defaults.pcm.card') and \
- set('defaults.pcm.rear.device', 'defaults.pcm.device') and \
- set('defaults.pcm.center_lfe.card', 'defaults.pcm.card') and \
- set('defaults.pcm.center_lfe.device', 'defaults.pcm.device') and \
- set('defaults.pcm.side.card', 'defaults.pcm.card') and \
- set('defaults.pcm.side.device', 'defaults.pcm.device') and \
- set('defaults.pcm.surround40.card', 'defaults.pcm.card') and \
- set('defaults.pcm.surround40.device', 'defaults.pcm.device') and \
- set('defaults.pcm.surround41.card', 'defaults.pcm.card') and \
- set('defaults.pcm.surround41.device', 'defaults.pcm.device') and \
- set('defaults.pcm.surround50.card', 'defaults.pcm.card') and \
- set('defaults.pcm.surround50.device', 'defaults.pcm.device') and \
- set('defaults.pcm.surround51.card', 'defaults.pcm.card') and \
- set('defaults.pcm.surround51.device', 'defaults.pcm.device') and \
- set('defaults.pcm.surround71.card', 'defaults.pcm.card') and \
- set('defaults.pcm.surround71.device', 'defaults.pcm.device') and \
- set('defaults.pcm.iec958.card', 'defaults.pcm.card') and \
- set('defaults.pcm.iec958.device', 'defaults.pcm.device') and \
- set('defaults.pcm.modem.card', 'defaults.pcm.card') and \
- set('defaults.pcm.modem.device', 'defaults.pcm.device') and \
- set('defaults.rawmidi.card', '0') and \
- set('defaults.rawmidi.device', '0') and \
- set('defaults.rawmidi.subdevice', '-1') and \
- set('defaults.hwdep.card', '0') and \
- set('defaults.hwdep.device', '0') and \
- set('defaults.timer.class', '2') and \
- set('defaults.timer.sclass', '0') and \
- set('defaults.timer.card', '0') and \
- set('defaults.timer.device', '0') and \
- set('defaults.timer.subdevice', '0')
-
- def reset_default_card():
- return delete('defaults.pcm.card') and \
- delete('defaults.ctl.card') and \
- delete('defaults.pcm.device') and \
- delete('defaults.pcm.subdevice') and \
- delete('defaults.pcm.nonblock') and \
- delete('defaults.pcm.ipc_key') and \
- delete('defaults.pcm.ipc_gid') and \
- delete('defaults.pcm.ipc_perm') and \
- delete('defaults.pcm.dmix_max_periods') and \
- delete('defaults.pcm.dmix_rate') and \
- delete('defaults.pcm.dmix_format') and \
- delete('defaults.pcm.front.card') and \
- delete('defaults.pcm.front.device') and \
- delete('defaults.pcm.rear.card') and \
- delete('defaults.pcm.rear.device') and \
- delete('defaults.pcm.center_lfe.card') and \
- delete('defaults.pcm.center_lfe.device') and \
- delete('defaults.pcm.side.card') and \
- delete('defaults.pcm.side.device') and \
- delete('defaults.pcm.surround40.card') and \
- delete('defaults.pcm.surround40.device') and \
- delete('defaults.pcm.surround41.card') and \
- delete('defaults.pcm.surround41.device') and \
- delete('defaults.pcm.surround50.card') and \
- delete('defaults.pcm.surround50.device') and \
- delete('defaults.pcm.surround51.card') and \
- delete('defaults.pcm.surround51.device') and \
- delete('defaults.pcm.surround71.card') and \
- delete('defaults.pcm.surround71.device') and \
- delete('defaults.pcm.iec958.card') and \
- delete('defaults.pcm.iec958.device') and \
- delete('defaults.pcm.modem.card') and \
- delete('defaults.pcm.modem.device') and \
- delete('defaults.rawmidi.card') and \
- delete('defaults.rawmidi.device') and \
- delete('defaults.rawmidi.subdevice') and \
- delete('defaults.hwdep.card') and \
- delete('defaults.hwdep.device') and \
- delete('defaults.timer.class') and \
- delete('defaults.timer.sclass') and \
- delete('defaults.timer.card') and \
- delete('defaults.timer.device') and \
- delete('defaults.timer.subdevice')
-
- def set_pulseaudio():
- return set('pcm.!default', '{ type pulse }') and \
- set('ctl.!default', '{ type pulse }')
-
- def unset_pulseaudio():
- return delete('pcm.!default') and \
- delete('ctl.!default')
-
- def exit_code(result):
- '''Exit program with code 0 if result is True, otherwise exit with code
- 1.
- '''
-
- if result:
- sys.exit(0)
- else:
- sys.exit(1)
-
-
- ##
- ## main
- ##
-
- if len(sys.argv) < 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
- help()
- sys.exit(0)
-
- if sys.argv[1] == 'is-active':
- exit_code(is_active())
-
- if sys.argv[1] == 'get':
- if len(sys.argv) != 3:
- help()
- sys.exit(1)
- exit_code(get(sys.argv[2]))
-
- if sys.argv[1] == 'delete':
- if len(sys.argv) != 3:
- help()
- sys.exit(1)
- exit_code(delete(sys.argv[2]))
-
- if sys.argv[1] == 'set':
- if len(sys.argv) != 4:
- help()
- sys.exit(1)
- exit_code(set(sys.argv[2], sys.argv[3]))
-
- if sys.argv[1] == 'list':
- exit_code(list())
-
- if sys.argv[1] == 'set-default-card':
- exit_code(set_default_card(sys.argv[2]))
-
- if sys.argv[1] == 'reset-default-card':
- exit_code(reset_default_card())
-
- if sys.argv[1] == 'set-pulseaudio':
- exit_code(set_pulseaudio())
-
- if sys.argv[1] == 'unset-pulseaudio':
- exit_code(unset_pulseaudio())
-
- help()
- sys.exit(1)
-
-