1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# -*- python -*-
'''
xpybar – xmobar replacement written in python
Copyright © 2014, 2015, 2016, 2017 Mattias Andrée (maandree@member.fsf.org)
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 3 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, see <http://www.gnu.org/licenses/>.
'''
import alsaaudio
class ALSA:
'''
ALSA volume controller
@variable cardindex:int The index of the audio card
@variable cardname:str The name of the audio card, will be
'default' if the default audio card is selected
using it's logical name or logical index
@variable mixername:str The name of the mixer
@variable mixer:alsaaudio.Mixer The mixer object used internally by this class
'''
ALL_CHANNELS = -1
'''
:int Channel index that selects all available channels
'''
DEFAULT_CARD = -1
'''
:int Logical index of the default audio card
'''
def __init__(self, card = -1, mixername = 'Master', *, cardindex = None):
'''
Constructor
@param card:int|str The index or name of the audio card,
`ALSA.DEFAULT_CARD` (-1) or 'default' for the default card
@param mixername:str The name of the mixer
'''
if card == -1 and cardindex is not None: # For backwards compatibility
card = cardindex
if isinstance(card, str):
if card == 'default':
card = -1
else:
card = alsaaudio.cards().index(card)
self.cardindex = card
self.mixername = mixername
self.mixer = alsaaudio.Mixer(self.mixername, 0, self.cardindex)
self.cardname = self.mixer.cardname
def get_volume(self):
'''
Get the volume for each channel on the mixer
@return :list<int?> The [0, 100] volume for each channel, `None` on a channel indicate that it is muted
'''
self.mixer = alsaaudio.Mixer(self.mixername, 0, self.cardindex)
vs = self.mixer.getvolume()
try:
ms = self.mixer.getmute()
except:
ms = [0] * len(vs)
return [v if m == 0 else None for (v, m) in zip(vs, ms)]
def set_volume(self, volume, channel = -1):
'''
Set the volume for a channel on the mixer
@param volume:int? The [0, 100] volume for the channel, `None` to mute the channel
@param channel:int The index of the channel, `ALSA.ALL_CHANNELS` (-1) for all channels
'''
if volume is None:
self.mixer.setmute(1, channel)
else:
self.mixer.setvolume(volume, channel)
try:
self.mixer.setmute(0, channel)
except:
pass # some mixers do not have mute switch
def get_mute(self):
'''
Get the mute status for each channel on the mixer
@return :list<bool> Whether mixer is muted for each channel
'''
self.mixer = alsaaudio.Mixer(self.mixername, 0, self.cardindex)
try:
return [m == 1 for m in self.mixer.getmute()]
except:
return [False] * len(self.mixer.getvolume())
def set_mute(self, mute, channel = -1):
'''
Set the mute status on the mixer
@param mute:bool Whether the mixer should be muted on the channel
@param channel:int The index of the channel, `ALSA.ALL_CHANNELS` (-1) for all channels
'''
self.mixer.setmute(mute, channel)
@staticmethod
def get_cards():
'''
Get the names of all available audio cards
@return :list<str> The names of all available audio cards
'''
return alsaaudio.cards()
@staticmethod
def get_mixers(card = -1, *, cardindex = None):
'''
Get the names of all available mixers for an audio card
@param card:int|str The index or name of the audio card,
`ALSA.DEFAULT_CARD` (-1) or 'default' for the default card
@return :list<str> The names of all available mixers for an audio card
'''
if card == -1 and cardindex is not None: # For backwards compatibility
card = cardindex
if isinstance(card, str):
if card == 'default':
card = -1
else:
card = alsaaudio.cards().index(card)
return alsaaudio.mixers(cardindex)
|