Audio/AudioControl: Commit loads of long uncommited changes
[audiocontrol.git] / Mixer.py
1 import Actions, OSC, Events, Views, curses
2
3 class Mixer(Views.View):
4
5     def __init__(self, context, label, x, y, dx, dy, channels, oscserver, remote):
6         Views.View.__init__(self, context, label, x, y, dx, dy)
7         self._context = context
8         self._server = oscserver
9         self._remote = remote
10         self._server.registerHandler(self._remote, self._oscEvent)
11         self._server.command(self._remote,'/mixer/get_channel_count')
12         self._channelNames = channels
13         self._channels = None
14         self._volume = None
15         self._muteState = None
16
17     def updateView(self, bindings):
18         pass
19
20     def init(self):
21         Views.View.init(self)
22
23     def _redraw(self):
24         if not self._channels : return
25         for i in range(self._channels):
26             self.win().addstr(i+1,2,self._channelNames[i][:8])
27             self._redrawValue(i+1)
28         self.win().refresh()
29
30     def _redrawValue(self, channel):
31         if self._muteState[channel-1] == self.MUTED:
32             self.win().addstr(channel,11,'Muted',curses.A_BOLD)
33         elif self._volume[channel-1] is not None:
34             self.win().addstr(channel,11, '%5.1f dB' % self._volume[channel-1])
35         self.win().refresh()
36
37     ACTIVE = 0
38     PENDING = 1
39     MUTED = 2
40
41     def _oscEvent(self, path, data):
42         if path == '/mixer/channel/gain':
43             # channel, gain
44             if self._muteState[data[0]-1] != self.MUTED:
45                 self._volume[data[0]-1] = data[1]
46             if self._muteState[data[0]-1] == self.PENDING:
47                 self._muteState[data[0]-1] = self.MUTED
48                 self._set(data[0],-90.0)
49             self._redrawValue(data[0])
50             return [ Events.ControlEvent(self._context, data[0], data[1]) ]
51         elif path == '/mixer/channel_count':
52             # channel_count
53             self._channels = int(data[0])
54             self._volume = [ None ] * self._channels
55             self._muteState = [ self.ACTIVE ] * self._channels
56             while  len(self._channelNames) < self._channels:
57                 self._channelNames.append("Channel %d" % (len(self._channelNames)+1))
58             self._redraw()
59             for i in range(self._channels):
60                 self._get(i+1)
61                 
62         return []
63
64     def mute(self, channel):
65         if self._muteState[channel-1] == self.ACTIVE:
66             self._muteState[channel-1] = self.PENDING
67             self._get(channel)
68
69     def unmute(self, channel):
70         if self._muteState[channel-1] != self.ACTIVE:
71             if self._muteState[channel-1] == self.MUTED:
72                 self._set(channel, self._volume[channel-1])
73             self._muteState[channel-1] = self.ACTIVE
74
75     def muteToggle(self, channel):
76         if self._muteState[channel-1] == self.ACTIVE:
77             self.mute(channel)
78         else:
79             self.unmute(channel)
80
81     def muteToggleAll(self):
82         if [ x for x in self._muteState if x is not self.MUTED ]:
83             for i in range(self._channels):
84                 self.mute(i+1)
85         else:
86             for i in range(self._channels):
87                 self.unmute(i+1)
88
89     def get(self, channel):
90         if self._muteState is None or self._muteState[channel-1] == self.ACTIVE:
91             self._get(channel)
92
93     def _get(self, channel):
94         self._server.command(self._remote,'/mixer/channel/get_gain', channel)
95
96     def set(self, channel, value):
97         if self._muteState is None or self._muteState[channel-1] == self.ACTIVE:
98             self._set(channel, value)
99
100     def _set(self, channel, value):
101         self._server.command(self._remote,'/mixer/channel/set_gain', channel, value)
102
103     def cycleVolume(self, channel, volumes):
104         if self._muteState is None or self._muteState[channel-1] != self.ACTIVE:
105             return
106         elif self._volume[channel-1] is not None:
107             for i in range(len(volumes)):
108                 if not volumes[i]-0.01 < self._volume[channel-1]:
109                     self._set(channel,volumes[i])
110                     return
111             self._set(channel, volumes[0])
112
113     class ParamGetter(object):
114
115         def __init__(self, mixer, channel):
116             self._mixer = mixer
117             self._channel = channel
118
119         def __call__(self):
120             self._mixer.get(self._channel)
121
122     class ParamSetter(object):
123
124         def __init__(self, mixer, channel):
125             self._mixer = mixer
126             self._channel = channel
127
128         def __call__(self, value):
129             self._mixer.set(self._channel, value)
130
131     def assignController(self, controller, title, channel, min=-12.0, max=6.0):
132         controller.assign(title,
133                           self.ParamSetter(self, channel),
134                           self.ParamGetter(self, channel),
135                           Events.Event(self._context, channel),
136                           min, max, [ 0.0 ])
137
138
139
140 class AssignController(Actions.Action):
141
142     def __init__(self, name, mixer, controller, title, channel, min=-12.0, max=6.0):
143         Actions.Action.__init__(self, name)
144         self._mixer = mixer
145         self._controller = controller
146         self._title = title
147         self._channel = channel
148         self._min = min
149         self._max = max
150
151     def __call__(self, binding):
152         self._mixer.assignController(self._controller,
153                                      self._title,
154                                      self._channel,
155                                      self._min,
156                                      self._max)
157
158
159 class MuteChannel(Actions.Action):
160
161     def __init__(self, name, mixer, channel):
162         Actions.Action.__init__(self, name)
163         self._mixer = mixer
164         self._channel = channel
165
166     def __call__(self, binding):
167         self._mixer.mute(self._channel)
168
169
170 class UnmuteChannel(Actions.Action):
171
172     def __init__(self, name, mixer, channel):
173         Actions.Action.__init__(self, name, mixer, channel)
174         Actions.Action.__init__(self, name)
175         self._mixer = mixer
176         self._channel = channel
177         
178     def __call__(self, binding):
179         self._mixer.unmute(self._channel)
180         
181
182 class ToggleMuteChannel(Actions.Action):
183
184     def __init__(self, name, mixer, channel):
185         Actions.Action.__init__(self, name)
186         self._mixer = mixer
187         self._channel = channel
188
189     def __call__(self, binding):
190         self._mixer.muteToggle(self._channel)
191
192 class ToggleMuteAll(Actions.Action):
193
194     def __init__(self, name, mixer):
195         Actions.Action.__init__(self, name)
196         self._mixer = mixer
197
198     def __call__(self, binding):
199         self._mixer.muteToggleAll()
200
201 class CycleVolume(Actions.Action):
202
203     def __init__(self, name, mixer, channel, volumes):
204         Actions.Action.__init__(self, name)
205         self._mixer = mixer
206         self._channel = channel
207         self._volumes = volumes
208
209     def __call__(self, binding):
210         self._mixer.cycleVolume(self._channel, self._volumes)
211
212 def register( viewmanager,
213               oscserver,
214               context,
215               label,
216               x, y, dx, dy,
217               channels, 
218               remote ):
219     mixer = Mixer(context, label, x, y, dx, dy, channels, oscserver, remote)
220     viewmanager.registerView( mixer )
221     return mixer