1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3# -*- Python -*- 4 5from pyalsa.alsahcontrol import HControl, Element as HElement, \ 6 Info as HInfo, Value as HValue, InterfaceId, \ 7 EventMask, EventMaskRemove 8 9MIXER = InterfaceId['Mixer'] 10MIXERS = str(MIXER) 11 12class BaseElement(InternalMElement): 13 14 def __init__(self, mixer, name, index, weight): 15 InternalMElement.__init__(self, mixer, name, index, weight) 16 self.channels = 0 17 self.min = [0, 0] 18 self.max = [0, 0] 19 20 def opsIsChannel(self, dir, chn): 21 return chn >= 0 and chn < self.channels 22 23 def opsGetRange(self, dir): 24 return (0, self.min[dir], self.max[dir]) 25 26 def opsSetRange(self, dir, min, max): 27 self.min[dir] = min 28 self.max[dir] = max 29 30 def volumeToUser(self, info, dir, value): 31 min = info.min 32 max = info.max 33 if min == max: 34 return self.min[dir] 35 n = (value - min) * (self.max[dir] - self.min[dir]) 36 return self.min[dir] + (n + (max - min) / 2) / (max - min) 37 38 def volumeFromUser(self, info, dir, value): 39 min = info.min 40 max = info.max 41 if self.max[dir] == self.min[dir]: 42 return min 43 n = (value - self.min[dir]) * (max - min) 44 return min + (n + (self.max[dir] - self.min[dir]) / 2) / (self.max[dir] - self.min[dir]) 45 46class StandardElement(BaseElement): 47 48 def __init__(self, mixer, name, index, weight): 49 BaseElement.__init__(self, mixer, name, index, weight) 50 self.channels = 1 51 self.volume = [None, None] 52 self.volumeinfo = [None, None] 53 self.volumearray = [None, None] 54 self.switch = [None, None] 55 self.switchinfo = [None, None] 56 self.switcharray = [None, None] 57 58 def decideChannels(self): 59 max = 0 60 for i in [0, 1]: 61 if self.volume[i]: 62 count = self.volumeinfo[i].count 63 if count > max: 64 max = count 65 if self.switch[i]: 66 count = self.switchinfo[i].count 67 if count > max: 68 max = count 69 self.channels = max 70 71 def attachVolume(self, helem, dir): 72 self.volume[dir] = helem 73 self.volumeinfo[dir] = HInfo(helem) 74 self.min[dir] = self.volumeinfo[dir].min 75 self.max[dir] = self.volumeinfo[dir].max 76 self.volumearray[dir] = HValue(helem).getArray(self.volumeinfo[dir].type, self.volumeinfo[dir].count) 77 78 def attachSwitch(self, helem, dir): 79 self.switch[dir] = helem 80 self.switchinfo[dir] = HInfo(helem) 81 self.switcharray[dir] = HValue(helem).getArray(self.switchinfo[dir].type, self.switchinfo[dir].count) 82 83 def attach(self, helem): 84 BaseElement.attach(self, helem) 85 if helem.name.endswith('Playback Volume'): 86 self.attachVolume(helem, 0) 87 self.caps |= self.CAP_PVOLUME 88 elif helem.name.endswith('Capture Volume'): 89 self.attachVolume(helem, 1) 90 self.caps |= self.CAP_CVOLUME 91 elif helem.name.endswith('Playback Switch'): 92 self.attachSwitch(helem, 0) 93 self.caps |= self.CAP_PSWITCH 94 elif helem.name.endswith('Capture Switch'): 95 self.attachSwitch(helem, 1) 96 self.caps |= self.CAP_CSWITCH 97 self.decideChannels() 98 self.eventInfo() 99 100 def opsGetVolume(self, dir, chn): 101 return (0, self.volumeToUser(self.volumeinfo[dir], dir, self.volumearray[dir][chn])) 102 103 def opsSetVolume(self, dir, chn, value): 104 val = self.volumeFromUser(self.volumeinfo[dir], dir, value) 105 if self.volumearray[dir][chn] == val: 106 return 107 self.volumearray[dir][chn] = val 108 hv = HValue(self.volume[dir]) 109 hv.setArray(self.volumeinfo[dir].type, self.volumearray[dir]) 110 hv.write() 111 112 def opsGetSwitch(self, dir, chn): 113 return (0, self.switcharray[dir][chn]) 114 115 def opsSetSwitch(self, dir, chn, value): 116 if self.switcharray[dir][chn] and value: 117 return 118 if not self.switcharray[dir][chn] and not value: 119 return 120 self.switcharray[dir] = int(value) 121 hv = HValue(self.switch[dir]) 122 hv.setArray(self.switchinfo[dir].type, self.switcharray[dir]) 123 hv.write() 124 125 def update(self, helem): 126 for i in [0, 1]: 127 if helem == self.volume[i]: 128 self.volumearray[i] = HValue(helem).getArray(self.volumeinfo[i].type, self.volumeinfo[i].count) 129 elif helem == self.switch[i]: 130 self.switcharray[i] = HValue(helem).getArray(self.switchinfo[i].type, self.switchinfo[i].count) 131 self.eventValue() 132 133class EnumElement(BaseElement): 134 135 def __init__(self, mixer, name, index, weight): 136 BaseElement.__init__(self, mixer, name, index, weight) 137 self.mycaps = 0 138 139 def attach(self, helem): 140 BaseElement.attach(self, helem) 141 self.enum = helem 142 self.enuminfo = HInfo(helem) 143 self.enumarray = HValue(helem).getArray(self.enuminfo.type, self.enuminfo.count) 144 self.channels = self.enuminfo.count 145 self.texts = self.enuminfo.itemNames 146 self.caps |= self.mycaps 147 148 def opsIsEnumerated(self, dir=-1): 149 if dir < 0: 150 return 1 151 if dir == 0 and self.mycaps & self.CAP_PENUM: 152 return 1 153 if dir == 1 and self.mycaps & self.CAP_CENUM: 154 return 1 155 156 def opsIsEnumCnt(self, dir): 157 return self.enuminfo.items 158 159 def opsGetEnumItemName(self, item): 160 return (0, self.texts[item]) 161 162 def opsGetEnumItem(self, chn): 163 if chn >= self.channels: 164 return -1 165 return (0, self.enumarray[chn]) 166 167 def opsSetEnumItem(self, chn, value): 168 if chn >= self.channels: 169 return -1 170 if self.enumarray[chn] == value: 171 return 172 self.enumarray[chn] = int(value) 173 hv = HValue(self.enum) 174 hv.setArray(self.enuminfo.type, self.enumarray) 175 hv.write() 176 177 def update(self, helem): 178 self.enumarray = HValue(helem).getArray(self.enuminfo.type, self.enuminfo.count) 179 self.eventValue() 180 181class EnumElementPlayback(EnumElement): 182 183 def __init__(self, mixer, name, index, weight): 184 EnumElement.__init__(self, mixer, name, index, weight) 185 self.mycaps = self.CAP_PENUM 186 187class EnumElementCapture(EnumElement): 188 189 def __init__(self, mixer, name, index, weight): 190 EnumElement.__init__(self, mixer, name, index, weight) 191 self.mycaps = self.CAP_CENUM 192 193ELEMS = [] 194 195def element_add(helem): 196 key = helem.name+'//'+str(helem.index)+'//'+str(helem.interface) 197 if not CONTROLS.has_key(key): 198 return 199 val = CONTROLS[key] 200 felem = None 201 for elem in ELEMS: 202 if elem.name == val[0] and elem.index == val[1]: 203 felem = elem 204 break 205 if not felem: 206 felem = mixer.newMElement(val[3], val[0], val[1], val[2]) 207 mixer.addMElement(felem) 208 ELEMS.append(felem) 209 felem.attach(helem) 210 211def eventHandler(evmask, helem, melem): 212 if evmask == EventMaskRemove: 213 return 214 if evmask & EventMask['Add']: 215 element_add(helem) 216 if evmask & EventMask['Value']: 217 melem.update(helem) 218 219def init(): 220 hctl = HControl(device, load=False) 221 mixer.attachHCtl(hctl) 222 mixer.register() 223