Audio/AudioControl: Lots of fixes
[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             premutes = None
56             if self._muteState is not None:
57                 premutes = self._muteState
58             self._muteState = [ self.ACTIVE ] * self._channels
59             if premutes:
60                 for i in range(len(self._muteState)):
61                     if i < len(premutes):
62                         self._muteState[i] = premutes[i]
63             while  len(self._channelNames) < self._channels:
64                 self._channelNames.append("Channel %d" % (len(self._channelNames)+1))
65             self._redraw()
66             for i in range(self._channels):
67                 self._set(i+1, 0.0)
68                 
69         return []
70
71     def mute(self, channel):
72         if self._channels is None:
73             if self._muteState is None:
74                 self._muteState = []
75             while(len(self._muteState) < channel) : self._muteState.append( self.ACTIVE )
76             self._muteState[channel-1] = self.PENDING
77         else:
78             if self._muteState[channel-1] == self.ACTIVE:
79                 self._muteState[channel-1] = self.PENDING
80                 self._get(channel)
81
82     def unmute(self, channel):
83         if self._muteState[channel-1] != self.ACTIVE:
84             if self._muteState[channel-1] == self.MUTED:
85                 self._set(channel, self._volume[channel-1])
86             self._muteState[channel-1] = self.ACTIVE
87
88     def muteToggle(self, channel):
89         if self._muteState[channel-1] == self.ACTIVE:
90             self.mute(channel)
91         else:
92             self.unmute(channel)
93
94     def muteToggleAll(self):
95         if [ x for x in self._muteState if x is not self.MUTED ]:
96             for i in range(self._channels):
97                 self.mute(i+1)
98         else:
99             for i in range(self._channels):
100                 self.unmute(i+1)
101
102     def get(self, channel):
103         if self._muteState is None or self._muteState[channel-1] == self.ACTIVE:
104             self._get(channel)
105
106     def _get(self, channel):
107         self._server.command(self._remote,'/mixer/channel/get_gain', channel)
108
109     def set(self, channel, value):
110         if self._muteState is None or self._muteState[channel-1] == self.ACTIVE:
111             self._set(channel, value)
112
113     def _set(self, channel, value):
114         self._server.command(self._remote,'/mixer/channel/set_gain', channel, value)
115
116     def cycleVolume(self, channel, volumes):
117         if self._muteState is None or self._muteState[channel-1] != self.ACTIVE:
118             return
119         elif self._volume[channel-1] is not None:
120             for i in range(len(volumes)):
121                 if not volumes[i]-0.01 < self._volume[channel-1]:
122                     self._set(channel,volumes[i])
123                     return
124             self._set(channel, volumes[0])
125
126     class ParamGetter(object):
127
128         def __init__(self, mixer, channel):
129             self._mixer = mixer
130             self._channel = channel
131
132         def __call__(self):
133             self._mixer.get(self._channel)
134
135     class ParamSetter(object):
136
137         def __init__(self, mixer, channel):
138             self._mixer = mixer
139             self._channel = channel
140
141         def __call__(self, value):
142             self._mixer.set(self._channel, value)
143
144     def assignController(self, controller, title, channel, min=-12.0, max=6.0, stops = [ 0.0 ]):
145         controller.assign(title,
146                           self.ParamSetter(self, channel),
147                           self.ParamGetter(self, channel),
148                           Events.Event(self._context, channel),
149                           min, max, stops)
150
151
152
153 class AssignController(Actions.Action):
154
155     def __init__(self, name, mixer, controller, title, channel, min=-12.0, max=6.0, stops = [ 0.0 ]):
156         Actions.Action.__init__(self, name)
157         self._mixer = mixer
158         self._controller = controller
159         self._title = title
160         self._channel = channel
161         self._min = min
162         self._max = max
163         self._stops = stops
164
165     def __call__(self, binding):
166         self._mixer.assignController(self._controller,
167                                      self._title,
168                                      self._channel,
169                                      self._min,
170                                      self._max,
171                                      self._stops)
172
173
174 class MuteChannel(Actions.Action):
175
176     def __init__(self, name, mixer, channel):
177         Actions.Action.__init__(self, name)
178         self._mixer = mixer
179         self._channel = channel
180
181     def __call__(self, binding):
182         self._mixer.mute(self._channel)
183
184
185 class UnmuteChannel(Actions.Action):
186
187     def __init__(self, name, mixer, channel):
188         Actions.Action.__init__(self, name, mixer, channel)
189         Actions.Action.__init__(self, name)
190         self._mixer = mixer
191         self._channel = channel
192         
193     def __call__(self, binding):
194         self._mixer.unmute(self._channel)
195         
196
197 class ToggleMuteChannel(Actions.Action):
198
199     def __init__(self, name, mixer, channel):
200         Actions.Action.__init__(self, name)
201         self._mixer = mixer
202         self._channel = channel
203
204     def __call__(self, binding):
205         self._mixer.muteToggle(self._channel)
206
207 class ToggleMuteAll(Actions.Action):
208
209     def __init__(self, name, mixer):
210         Actions.Action.__init__(self, name)
211         self._mixer = mixer
212
213     def __call__(self, binding):
214         self._mixer.muteToggleAll()
215
216 class CycleVolume(Actions.Action):
217
218     def __init__(self, name, mixer, channel, volumes):
219         Actions.Action.__init__(self, name)
220         self._mixer = mixer
221         self._channel = channel
222         self._volumes = volumes
223
224     def __call__(self, binding):
225         self._mixer.cycleVolume(self._channel, self._volumes)
226
227 def register( viewmanager,
228               oscserver,
229               context,
230               label,
231               x, y, dx, dy,
232               channels, 
233               remote ):
234     mixer = Mixer(context, label, x, y, dx, dy, channels, oscserver, remote)
235     viewmanager.registerView( mixer )
236     return mixer