scide: LookupDialog - redo lookup on classes after partial lookup
[supercollider.git] / SCClassLibrary / QtCollider / QLevelIndicator.sc
blobf061f54986c3a445298b3739d492f8a3a9fe6257
1 QLevelIndicator : QView {
3   *qtClass {^'QcLevelIndicator'}
5   value {
6     ^this.getProperty(\value)
7   }
8   value_ { arg val;
9     this.setProperty(\value, val);
10   }
11   valueAction_ { arg val;
12     this.setProperty(\value, val);
13     this.doAction;
14   }
16   warning_ {arg val;
17     this.setProperty(\warning, val);
18   }
20   critical_ {arg val;
21     this.setProperty(\critical, val);
22   }
24   // NOT IMPLEMENTED
25   style_ {arg val;
26     this.nonimpl("style");
27   }
29   background { ^this.getProperty(\grooveColor) }
30   background_ { arg color; this.setProperty(\grooveColor, color) }
32   numSteps_ {arg val;
33     this.nonimpl("numSteps");
34   }
36   image_ {arg image;
37     this.nonimpl("image");
38   }
40   numTicks_ {arg number;
41     this.setProperty(\ticks, number);
42   }
44   numMajorTicks_ {arg number;
45     this.setProperty(\majorTicks, number);
46   }
48   drawsPeak_ {arg bool;
49     this.setProperty(\drawPeak, bool);
50   }
52   peakLevel_ { arg val;
53     this.setProperty(\peak, val);
54   }
56   *meterServer { arg server;
57     var window, inmeters, outmeters, inresp, outresp, insynth, outsynth, func;
58     var numIns, numOuts;
59     var view, viewWidth, meterWidth = 15, gapWidth = 4;
60     var updateFreq = 10, dBLow = -80;
61     var numRMSSamps, numRMSSampsRecip;
64     numIns = server.options.numInputBusChannels;
65     numOuts = server.options.numOutputBusChannels;
66     viewWidth = (numIns + numOuts + 2) * (meterWidth + gapWidth);
67     window = Window.new(server.name ++ " levels (dBFS)", Rect(5, 305, viewWidth + 20, 230));
68     window.view.background = Color.grey(0.4);
70     view = CompositeView(window, Rect(10,25, viewWidth, 180) );
71     view.addFlowLayout(0@0, gapWidth@gapWidth);
73     // dB scale
74     UserView(view, Rect(0,0,meterWidth,195)).drawFunc_({
75       Pen.color = Color.white;
76       Pen.font = Font("Helvetica", 10, true);
77       Pen.stringCenteredIn("0", Rect(0, 0, meterWidth, 12));
78       Pen.stringCenteredIn("-80", Rect(0, 170, meterWidth, 12));
79     });
81     (numIns > 0).if({
82       // ins
83       StaticText(window, Rect(10, 5, 100, 15))
84         .font_(Font("Helvetica", 10, true))
85         .stringColor_(Color.white)
86         .string_("Inputs");
87       inmeters = Array.fill( numIns, { arg i;
88         var comp;
89         comp = CompositeView(view, Rect(0,0,meterWidth,195)).resize_(5);
90         StaticText(comp, Rect(0, 180, meterWidth, 15))
91           .font_(Font("Helvetica", 9, true))
92           .stringColor_(Color.white)
93           .string_(i.asString);
94         LevelIndicator( comp, Rect(0,0,meterWidth,180) ).warning_(0.9).critical_(1.0)
95           .drawsPeak_(true)
96           .numTicks_(9)
97           .numMajorTicks_(3);
98       });
100       // divider
101       UserView(view, Rect(0,0,meterWidth,180)).drawFunc_({
102         Pen.color = Color.white;
103         Pen.line(((meterWidth + gapWidth) * 0.5)@0, ((meterWidth + gapWidth) * 0.5)@180);
104         Pen.stroke;
105       });
106     });
108     // outs
109     StaticText(window, Rect(10 + if(numIns > 0 , ((numIns + 2) * (meterWidth + gapWidth)), 0), 5, 100, 15))
110       .font_(Font("Helvetica", 10, true))
111       .stringColor_(Color.white)
112       .string_("Outputs");
113     outmeters = Array.fill( numOuts, { arg i;
114       var comp;
115       comp = CompositeView(view, Rect(0,0,meterWidth,195));
116       StaticText(comp, Rect(0, 180, meterWidth, 15))
117         .font_(Font("Helvetica", 9, true))
118         .stringColor_(Color.white)
119         .string_(i.asString);
120       LevelIndicator( comp, Rect(0,0,meterWidth,180) ).warning_(0.9).critical_(1.0)
121         .drawsPeak_(true)
122         .numTicks_(9)
123         .numMajorTicks_(3);
124     });
126     window.front;
128     func = {
129       numRMSSamps = server.sampleRate / updateFreq;
130       numRMSSampsRecip = 1 / numRMSSamps;
131       (numIns > 0).if({
132         inresp = OSCProxy({ |msg, t|      {try {
133           msg.copyToEnd(3).pairsDo({|val, peak, i|
134             var meter;
135             i = i * 0.5;
136             meter = inmeters[i];
137             meter.value = (val.max(0.0) * numRMSSampsRecip).sqrt.ampdb.linlin(dBLow, 0, 0, 1);
138             meter.peakLevel = peak.ampdb.linlin(dBLow, 0, 0, 1);
139           }) }}.defer;
140         }, ("/" ++ server.name ++ "InLevels").asSymbol, server.addr).fix;
141       });
142       outresp = OSCProxy({ |msg, t|      {try {
143         msg.copyToEnd(3).pairsDo({|val, peak, i|
144           var meter;
145           i = i * 0.5;
146           meter = outmeters[i];
147           meter.value = (val.max(0.0) * numRMSSampsRecip).sqrt.ampdb.linlin(dBLow, 0, 0, 1);
148           meter.peakLevel = peak.ampdb.linlin(dBLow, 0, 0, 1);
149         }) }}.defer;
150       }, ("/" ++ server.name ++ "OutLevels").asSymbol, server.addr).fix;
151       server.bind({
152         (numIns > 0).if({
153           insynth = SynthDef(server.name ++ "InputLevels", {
154             var in, imp;
155             in = In.ar(NumOutputBuses.ir, numIns);
156             imp = Impulse.ar(updateFreq);
157             SendReply.ar(imp, "/" ++ server.name ++ "InLevels",
158               // do the mean and sqrt clientside to save CPU
159               [
160                 RunningSum.ar(in.squared, numRMSSamps),
161                 Peak.ar(in, Delay1.ar(imp)).lag(0, 3)]
162               .flop.flat
163             );
164           }).play(RootNode(server), nil, \addToHead);
165         });
167         outsynth = SynthDef(server.name ++ "OutputLevels", {
168           var in, imp;
169           in = In.ar(0, numOuts);
170           imp = Impulse.ar(updateFreq);
171           SendReply.ar(imp, "/" ++ server.name ++ "OutLevels",
172             // do the mean and sqrt clientside to save CPU
173             [
174               RunningSum.ar(in.squared, numRMSSamps),
175               Peak.ar(in, Delay1.ar(imp)).lag(0, 3)
176             ].flop.flat
177           );
178         }).play(RootNode(server), nil, \addToTail);
179       });
180     };
182     window.onClose_({
183       (server.options.numInputBusChannels > 0).if({ inresp.clear;});
184       outresp.clear;
185       insynth.free;
186       outsynth.free;
187       ServerTree.remove(func);
188     });
190     ServerTree.add(func);
191     if(server.serverRunning, func); // otherwise starts when booted
192   }