Viewing file: soundcardBackend.py (20.17 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
## soundcardBackend.py - Contains the backend code needed for system-config-soundcard ## Copyright (C) 2002, 2003 Red Hat, Inc. ## Copyright (C) 2002, 2003 Brent Fox <bfox@redhat.com> ## Copyright (C) 2004, 2005 Bastien Nocera <hadess@hadess.net>
## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version.
## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
## TODO ## - surround test (alsa-speaker test) ## - clean-up objects interfaces ## - remove all 2.4 stuff
import string import kudzu import os import getopt import sys import commands import signal import timeit import gtk
import soundcardBackendSoundCard import soundcardBackendKudzu import soundcardBackendProc import soundcardBackendHal
## ## I18N ## from rhpl.translate import _, N_ import rhpl.translate as translate translate.textdomain ("system-config-soundcard")
DETECTION_KUDZU = "kudzu" DETECTION_PROC = "proc" DETECTION_HAL = "hal"
## ## Error message ## def errorDialog(text): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, text)
dlg.set_title(_("Error")) dlg.set_default_size(100, 100) dlg.set_position (gtk.WIN_POS_CENTER_ON_PARENT) dlg.set_border_width(2) dlg.set_modal(True) rc = dlg.run() dlg.destroy() return
## ## Get position ## def position(list, name): for line in list: if line[1] == name: return line[0] #errorDialog(_("Unable to find module %s in %s!") % (name, "/proc/asound/modules")) print _("Unable to find module %s in %s!") % (name, "/proc/asound/modules") return 0
## ## Usage ## def usage(): print \ _("""Usage: system-config-soundcard [OPTIONS] Options: -h, --help display this help and exit -k, --kernel= which kernel version to assume: 2.4 (modules.conf) 2.6 (modprobe.conf, default) """)
## ## Options ##
global kernel_type kver = os.uname()[2] kernel_type = string.join(kver.split('.')[0:2], '.')
def options(): try: (opts, rest_args) = getopt.getopt(sys.argv[1:], "hk:", ["driver=", "help", "kernel="]) except (getopt.GetoptError), e: print e print usage() sys.exit(1) for (opt, value) in opts: if opt == "-h" or opt == "--help": usage() sys.exit(0) if opt == "-k" or opt == "--kernel": kernel_type = value if kernel_type != '2.4' and kernel_type != '2.6': print "ERROR: Invalid kernel version:", kernel_type usage() sys.exit(0)
## ## Sort for cards devices ## def soundCardDevice_sort(device1, device2): return cmp(device1[0], device2[0])
class soundConfiguration: def __init__(self): self.doDebug = False # coundcard configuration self.default_card = 0 self.default_device = 0 self.hardware_device = 0 self.card_max_index = 7 self.card_min_index = 0 self.card_index_changed = False self.card_default_changed = False
self.readAlsaConfig()
def dump(self): print " ----------- soundConfiguration -----------" print "default_card %d" % self.default_card print "hardware_device %d" % self.hardware_device print "card_max_index %d" % self.card_max_index print "card_min_index %d" % self.card_min_index print "\n" return
def readAlsaConfig(self): # Check alsa configuration try: fd = open('/etc/asound.conf', 'r') line = fd.readline() line = fd.readline() self.hardware_device = (cmp(line[:7],'#HWCONF') != 1)
line = fd.readline() if not cmp(line[:4],'#DEV'): self.default_device = int(line[4:]) fd.close() except: self.hardware_device = 0 self.default_device = 0
try: self.default_card = int(commands.getoutput('/bin/alsacard')) except: self.default_card = 0 if self.doDebug: print "Read config:\ncard %d\ndevice %d\nHW %d" % (self.default_card, self.default_device, self.hardware_device)
def writeAlsaConfig(self, cardArray):
# Writing to asound.conf index = self.default_card device = cardArray[index].default_device if kernel_type == '2.6': lines = []
lines.append("#Generated by system-config-soundcard, do not edit by hand\n") if self.hardware_device: lines.append("#HWCONF\n") lines.append("#DEV %d\n" % device) lines.append("pcm.!default { type hw card %d device %d } \n" % (index, device)) lines.append("ctl.!default { type hw card %d }\n" % index) else: lines.append("#SWCONF\n") lines.append("#DEV %d\n" % device) lines.append("defaults.pcm.card %d \n" % index) lines.append("defaults.pcm.device %d \n" % device) lines.append("defaults.ctl.card %d \n" % index)
fd = open('/etc/asound.conf', 'w') for line in lines: fd.write(line) fd.close()
return True
def cardIndexChanged(self): self.card_index_changed = True self.card_default_changed = True def cardDefaultChanged(self): self.card_default_changed = True # ------------------------------------------------------------------------ # Configuring routines - modprobe.conf # ------------------------------------------------------------------------ def getCardLast(self, cardArray): num = 0 for card in cardArray: if card.active: num = card.index return num def rewriteModprobe(self, cardArray): try: fd = open('/etc/modprobe.conf', 'r') list = fd.readlines() fd.close() except: return False
sound_lines = [] modprobe = [] position = -1 for whole_line in list: position = position + 1 line = string.strip(whole_line) if line == []: modprobe.append(whole_line) continue; tmp = line.split() if tmp == [] or tmp[0] == [] or tmp[1] == [] or\ tmp[2] == [] or tmp[0][0] == '#': modprobe.append(whole_line) continue if tmp[0] != "alias" and tmp[1][:3] != "snd" and\ tmp[2][:9] != "snd-card-": modprobe.append(whole_line) continue if tmp[0] != "options" and tmp[1][:3] != "snd" and\ tmp[2][:5] != "index" and tmp[2][:11] != "cards_limit": modprobe.append(whole_line) continue sound_lines.append([position] + tmp)
modprobe.append("options snd cards_limit=" + `len(cardArray)` + "\n") for card in cardArray: if card.active: modprobe.append("alias snd-card-%d %s\n" % (card.index, card.driver)) modprobe.append("options %s index=%d\n" % (card.driver, card.index))
try: os.rename('/etc/modprobe.conf', '/etc/modprobe.conf.scs') fd = open('/etc/modprobe.conf', 'w') fd.writelines(modprobe) fd.close() except: return False
return True
# ------------------------------------------------------------------------ # Configuring routines - sound modules reloading # ------------------------------------------------------------------------
def searchList(self, module_name, module_list): for module in module_list: if module_name == module[0]: return module[1] return []
def composeList(self, module_name, module_list): module_childs = self.searchList(module_name, module_list) result = [] for module in module_childs: result = result + self.composeList(module, module_list) result.append(module_name) return result
def unloadModule(self, module_name, module_list): path = "/sbin/modprobe" args = ["/sbin/modprobe", "-r"] + self.composeList(module_name, module_list) print args return os.spawnv(os.P_WAIT, path, args)
def unloadModules(self): try: pipe = os.popen("/sbin/lsmod", 'r', 10000) lines = pipe.readlines() pipe.close() except: return "" module_list = [] for line in lines: tmp = line.split() res = [] res.append(tmp[0]) if len(tmp) == 4: res.append(tmp[3].split(',')) else: res.append([]) module_list.append(res) if self.unloadModule("snd", module_list): errorDialog(_("Unable to remove kernel modules. You need to reboot your box for the changes to take effect.")) def loadModules(self, cardArray): for card in cardArray: if card.active: print card.driver ret = os.spawnv(os.P_WAIT, "/sbin/modprobe", ["/sbin/modprobe", card.driver]) if ret: errorDialog(_("Unable to load kernel module %s. You need to reboot your box for the changes to take effect.") % card.driver)
def reloadModules(self, cardArray): self.unloadModules() self.loadModules(cardArray) self.card_index_changed = False
def writeConfig(self, cardArray): ret_alsa = ret_mod = True if self.card_index_changed: ret_mod = self.rewriteModprobe(cardArray) if not ret_mod: errorDialog(_("Unable to write %s!") % ("/etc/modprobe.conf")) elif ret_mod: self.unloadModules() self.loadModules(cardArray) self.card_index_changed = False
if self.card_default_changed: ret_alsa = self.writeAlsaConfig(cardArray) if ret_alsa: self.card_default_changed = False else: errorDialog(_("Unable to write ALSA configuration files!"))
return ret_mod and ret_alsa
class soundcardBackend: def __init__(self): self.doDebug = True self.soundcardBackendKudzu = soundcardBackendKudzu.soundcardBackendKudzu() self.soundcardBackendProc = soundcardBackendProc.soundcardBackendProc() self.soundcardBackendHal = soundcardBackendHal.soundcardBackendHal() # Load general configuration self.soundConfig = soundConfiguration() # Detect cards self.detectCards()
def destroy(self, args): return
def mergeCards(self, original_array, new_array): for card in range(self.soundConfig.card_max_index + 1): if not original_array[card].active and new_array[card].active: original_array[card] = new_array[card] return original_array
def detectCards(self): # List of all cards in system self.cardArray = self.mergeCards(self.probeCards(DETECTION_HAL),\ self.probeCards(DETECTION_KUDZU)) self.cardArray = self.mergeCards(self.cardArray,\ self.probeCards(DETECTION_PROC)) self.card_index_changed = True return
# ------------------------------------------------------------------------ # Probe routines # ------------------------------------------------------------------------ def createCardArray(self): list = [] for card in range(self.soundConfig.card_max_index + 1): list.append(soundcardBackendSoundCard.soundCard(card)) return list def probeCards(self, method): default_card = self.getDefaultCard() default_device = self.soundConfig.default_device card_list = self.createCardArray() card_max = self.soundConfig.card_max_index + 1 if method == DETECTION_KUDZU: return self.soundcardBackendKudzu.probeCards(default_card,\ default_device, card_list, card_max) elif method == DETECTION_PROC: return self.soundcardBackendProc.probeCards(default_card,\ default_device, card_list, card_max) elif method == DETECTION_HAL: return self.soundcardBackendHal.probeCards(default_card,\ default_device, card_list, card_max) # ------------------------------------------------------------------------ # Test sound routines # ------------------------------------------------------------------------
def checkTestSound(self, card_index): return self.cardArray[card_index].checkTestSound() def playTestSound(self, card_index): return self.cardArray[card_index].playTestSound()
def stopTestSound(self, card_index): return self.cardArray[card_index].stopTestSound()
def checkTestSound(self, card_index): return self.cardArray[card_index].checkTestSound()
# ------------------------------------------------------------------------ # Interface routines # ------------------------------------------------------------------------
def getCard(self, card_index): return self.cardArray[card_index]
def setCard(self, card): self.cardArray[card.index] = card def getCardArray(self): return self.cardArray
def getCardNum(self): num = 0 for card in self.cardArray: if card.active: num += 1 return num def getCardLast(self): num = 0 for card in self.cardArray: if card.active: num = card.index return num def isCardIndexValid(self, index): return index >= self.soundConfig.card_min_index and index <= self.soundConfig.card_max_index def setCardIndexAndReOrder(self, index, direction): new_index = index + direction # No active card if not self.cardArray[index].active or \ not self.isCardIndexValid(index) or \ not self.isCardIndexValid(new_index): return
if not self.cardArray[new_index].active: # No conflict self.cardArray[new_index] = self.cardArray[index] self.cardArray[new_index].index = new_index self.cardArray[index] = soundcardBackendSoundCard.soundCard(index) else: # Conflict - switch cards tmp = self.cardArray[new_index] self.cardArray[new_index] = self.cardArray[index] self.cardArray[index] = tmp self.cardArray[new_index].index = new_index self.cardArray[index].index = index
self.defaultDeviceCorrection(index, direction)
return def defaultDeviceCorrection(self, index, direction): new_index = index + direction if index == self.soundConfig.default_card: self.soundConfig.default_card = new_index elif new_index == self.soundConfig.default_card: self.soundConfig.default_card = index self.soundConfig.cardDefaultChanged() return # -------------- # Device Interface # -------------- def getCardDevices(self, card_index): return self.cardArray[card_index].device_list
def setCardTestDevice(self, card_index, device_index): self.cardArray[card_index].test_sound_device = device_index def getCardTestDevice(self, card_index): return self.cardArray[card_index].test_sound_device
def setCardDefaultDevice(self, card_index, device_index): self.cardArray[card_index].default_device = device_index def getCardDefaultDevice(self, card_index): return self.cardArray[card_index].default_device
# -------------- # Card Volume # -------------- def getVolume(self, card_index): return self.cardArray[card_index].getVolume() def setVolume(self, card_index, volume): self.cardArray[card_index].setVolume(volume) # -------------- # Other conrols # -------------- def setDefaultCard(self, index): self.soundConfig.default_card = index self.soundConfig.cardDefaultChanged() def getDefaultCard(self): return self.soundConfig.default_card def getDefaultCardCard(self): return self.cardArray[self.soundConfig.default_card]
def setHardwareDevice(self, state): self.soundConfig.hardware_device = state; self.soundConfig.cardDefaultChanged()
def getHardwareDevice(self): return self.soundConfig.hardware_device
def cardIndexChanged(self): self.soundConfig.cardIndexChanged() def writeConfig(self): self.soundConfig.writeConfig(self.cardArray) def reloadModules(self, *args): self.soundConfig.reloadModules(self.cardArray) # ------------------------------------------------------------------------ # Info routines # ------------------------------------------------------------------------ def writeLog(self, second = None): os.system("/usr/share/system-config-soundcard/system-config-soundcard.logger")
def getDriverVersion(self): try: fd = open('/proc/asound/version', 'r') line = fd.readline() fd.close() pos = string.find(line,"Version") if pos == -1: return line list = string.split(line[pos:]) return line[:pos] + list[0] + " " + list[1] except: return "" def getLibVersion(self): try: pipe = os.popen("rpm -q alsa-lib", 'r', 1000) line = pipe.readline() pipe.close() return string.replace(line,'\n',' ') except: return "" def getUtilsVersion(self): try: pipe = os.popen("rpm -q alsa-utils", 'r', 1000) line = pipe.readline() pipe.close() return string.replace(line,'\n',' ') except: return ""
def dumpCards(self, active_only = 0): for card in self.cardArray: print "--------- Card %d --------" % card.index if active_only and not card.active: print "Not Active" continue else: print "Active %d" % card.active print "Vendor: %s" % card.maker print "Model: %s" % card.model print "Driver: %s\n" % card.driver print "Volume: %d" % card.volume print "Devices:" print card.device_list
print "Test device %d" % card.test_sound_device
|