1 /*
2 * Copyright (C) 2020 Hermann Meyer, Andreas Degert
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 * --------------------------------------------------------------------------
18 */
19
20 /*---------------------------------------------------------------------
21 -----------------------------------------------------------------------
22 define PortIndex and plugin uri
23 -----------------------------------------------------------------------
24 ----------------------------------------------------------------------*/
25
26 #include "gx_mbcompressor.h"
27
28 /*---------------------------------------------------------------------
29 -----------------------------------------------------------------------
30 define controller numbers
31 -----------------------------------------------------------------------
32 ----------------------------------------------------------------------*/
33
34 #define CONTROLS 26
35
36 /*---------------------------------------------------------------------
37 -----------------------------------------------------------------------
38 include the LV2 interface
39 -----------------------------------------------------------------------
40 ----------------------------------------------------------------------*/
41
42 #include "lv2_plugin.cc"
43
44 /*---------------------------------------------------------------------
45 -----------------------------------------------------------------------
46 define the plugin settings
47 -----------------------------------------------------------------------
48 ----------------------------------------------------------------------*/
49
50 typedef struct {
51 Widget_t *meter_widget[10];
52 Widget_t *combo_widget[5];
53 Adjustment_t *adj[3];
54 float db_zero;
55 } X11_UI_Private_t;
56
57 // setup a color theme
set_my_theme(Xputty * main)58 static void set_my_theme(Xputty *main) {
59 main->color_scheme->normal = (Colors) {
60 /* cairo / r / g / b / a / */
61 .fg = { 0.45, 0.45, 0.45, 1.0},
62 .bg = { 0.07, 0.05, 0.14, 1.00},
63 .base = { 0.0, 0.0, 0.0, 1.00},
64 .text = { 0.45, 0.45, 0.45, 1.0},
65 .shadow = { 0.28, 0.34, 0.62, 0.43},
66 .frame = { 0.0, 0.0, 0.0, 1.0},
67 .light = { 0.1, 0.1, 0.1, 1.0}
68 };
69
70 main->color_scheme->prelight = (Colors) {
71 .fg = { 1.0, 1.0, 1.0, 1.0},
72 .bg = { 0.14, 0.14, 0.22, 1.00},
73 .base = { 0.0, 0.0, 0.0, 1.00},
74 .text = { 0.7, 0.7, 0.7, 1.0},
75 .shadow = { 0.28, 0.34, 0.62, 0.63},
76 .frame = { 0.3, 0.3, 0.3, 1.0},
77 .light = { 0.3, 0.3, 0.3, 1.0}
78 };
79
80 main->color_scheme->selected = (Colors) {
81 .fg = { 0.9, 0.9, 0.9, 1.0},
82 .bg = { 0.14, 0.14, 0.22, 1.00},
83 .base = { 0.0, 0.0, 0.18, 1.00},
84 .text = { 1.0, 1.0, 1.0, 1.0},
85 .shadow = { 0.28, 0.34, 0.62, 0.93},
86 .frame = { 0.18, 0.18, 0.18, 1.0},
87 .light = { 0.18, 0.18, 0.28, 1.0}
88 };
89 }
90
91 // draw the slider handle
rounded_rectangle(cairo_t * cr,float x,float y,float w,float h)92 static void rounded_rectangle(cairo_t *cr,float x, float y, float w, float h) {
93 float r = h*0.55;
94
95 cairo_move_to(cr,x+r,y);
96 cairo_line_to(cr,x+w-r,y);
97 cairo_curve_to(cr,x+w,y,x+w,y,x+w,y+r);
98 cairo_line_to(cr,x+w,y+h-r);
99 cairo_curve_to(cr,x+w,y+h,x+w,y+h,x+w-r,y+h);
100 cairo_line_to(cr,x+r,y+h);
101 cairo_curve_to(cr,x,y+h,x,y+h,x,y+h-r);
102 cairo_line_to(cr,x,y+r);
103 cairo_curve_to(cr,x,y,x,y,x+r,y);
104 }
105
106 // draw the slider
draw_my_hslider(void * w_,void * user_data)107 static void draw_my_hslider(void *w_, void* user_data) {
108 Widget_t *w = (Widget_t*)w_;
109 X11_UI* ui = (X11_UI*)w->parent_struct;
110 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
111
112 int width = w->width-2;
113 int height = w->height-2;
114 float center = (float)height/2;
115
116 float sliderstate1 = adj_get_state(w->adj);
117 float sliderstate2 = adj_get_state(ps->adj[0]);
118 float sliderstate3 = adj_get_state(ps->adj[1]);
119 float sliderstate4 = adj_get_state(ps->adj[2]);
120 float sliderstate = 0.0;
121 Color_state s1 = NORMAL_;
122 Color_state s2 = NORMAL_;
123 Color_state s3 = NORMAL_;
124 Color_state s4 = NORMAL_;
125
126 if (w->state>0.0 && w->state<4.0 && w->adj_x) {
127 if (w->adj_x == w->adj) {
128 sliderstate = sliderstate1;
129 s1 = PRELIGHT_;
130 } else if (w->adj_x == ps->adj[0]) {
131 sliderstate = sliderstate2;
132 s2 = PRELIGHT_;
133 } else if (w->adj_x == ps->adj[1]) {
134 sliderstate = sliderstate3;
135 s3 = PRELIGHT_;
136 } else if (w->adj_x == ps->adj[2]) {
137 sliderstate = sliderstate4;
138 s4 = PRELIGHT_;
139 }
140 }
141 cairo_pattern_t* pat;
142
143 pat = cairo_pattern_create_linear (0, 0, 0, height);
144 cairo_pattern_add_color_stop_rgba (pat, 1, 0.25, 0.25, 0.25, 1.0);
145 cairo_pattern_add_color_stop_rgba (pat, 0.75, 0.2, 0.2, 0.2, 1.0);
146 cairo_pattern_add_color_stop_rgba (pat, 0.5, 0.15, 0.15, 0.15, 1.0);
147 cairo_pattern_add_color_stop_rgba (pat, 0.25, 0.1, 0.1, 0.1, 1.0);
148 cairo_pattern_add_color_stop_rgba (pat, 0, 0.05, 0.05, 0.05, 1.0);
149
150
151 cairo_set_source (w->crb, pat);
152 rounded_rectangle(w->crb, 0.0, 0.0,width,height);
153 cairo_set_line_width(w->crb,2);
154 cairo_stroke(w->crb);
155 cairo_pattern_destroy (pat);
156 pat = NULL;
157
158 use_text_color_scheme(w, get_color_state(w));
159 cairo_move_to (w->crb, center, center);
160 cairo_line_to(w->crb,width-center,center);
161 cairo_set_line_width(w->crb,center/10);
162 cairo_stroke(w->crb);
163
164 pat = cairo_pattern_create_linear (0, 0, 0, height);
165 cairo_pattern_add_color_stop_rgba (pat, 0, 0.25, 0.25, 0.25, 1.0);
166 cairo_pattern_add_color_stop_rgba (pat, 0.25, 0.2, 0.2, 0.2, 1.0);
167 cairo_pattern_add_color_stop_rgba (pat, 0.5, 0.15, 0.15, 0.15, 1.0);
168 cairo_pattern_add_color_stop_rgba (pat, 0.75, 0.1, 0.1, 0.1, 1.0);
169 cairo_pattern_add_color_stop_rgba (pat, 1, 0.05, 0.05, 0.05, 1.0);
170
171 cairo_set_source (w->crb, pat);
172 rounded_rectangle(w->crb, (width-height)*sliderstate1,0,height, height);
173 cairo_fill_preserve (w->crb);
174 cairo_set_source_rgb (w->crb, 0.1, 0.1, 0.1);
175 cairo_set_line_width(w->crb,2);
176 cairo_stroke(w->crb);
177 cairo_new_path (w->crb);
178 cairo_set_source (w->crb, pat);
179 rounded_rectangle(w->crb, (width-height)*sliderstate2,0,height, height);
180 cairo_fill_preserve (w->crb);
181 cairo_set_source_rgb (w->crb, 0.1, 0.1, 0.1);
182 cairo_stroke(w->crb);
183 cairo_new_path (w->crb);
184 cairo_set_source (w->crb, pat);
185 rounded_rectangle(w->crb, (width-height)*sliderstate3,0,height, height);
186 cairo_fill_preserve (w->crb);
187 cairo_set_source_rgb (w->crb, 0.1, 0.1, 0.1);
188 cairo_stroke(w->crb);
189 cairo_new_path (w->crb);
190 cairo_set_source (w->crb, pat);
191 rounded_rectangle(w->crb, (width-height)*sliderstate4,0,height, height);
192 cairo_fill_preserve (w->crb);
193 cairo_set_source_rgb (w->crb, 0.1, 0.1, 0.1);
194 cairo_stroke(w->crb);
195 cairo_new_path (w->crb);
196 cairo_pattern_destroy (pat);
197 pat = NULL;
198
199 use_text_color_scheme(w, s1);
200 cairo_set_line_width(w->crb,2);
201 cairo_move_to (w->crb,((width-height)*sliderstate1)+center, 2.0);
202 cairo_line_to(w->crb,((width-height)*sliderstate1)+center,height-4.0);
203 cairo_stroke(w->crb);
204 use_text_color_scheme(w, s2);
205 cairo_move_to (w->crb,((width-height)*sliderstate2)+center, 2.0);
206 cairo_line_to(w->crb,((width-height)*sliderstate2)+center,height-4.0);
207 cairo_stroke(w->crb);
208 use_text_color_scheme(w, s3);
209 cairo_move_to (w->crb,((width-height)*sliderstate3)+center, 2.0);
210 cairo_line_to(w->crb,((width-height)*sliderstate3)+center,height-4.0);
211 cairo_stroke(w->crb);
212 use_text_color_scheme(w, s4);
213 cairo_move_to (w->crb,((width-height)*sliderstate4)+center, 2.0);
214 cairo_line_to(w->crb,((width-height)*sliderstate4)+center,height-4.0);
215 cairo_stroke(w->crb);
216
217 /** show value on the slider**/
218 if (w->state>0.0 && w->state<4.0 && w->adj_x) {
219 use_fg_color_scheme(w, PRELIGHT_);
220 cairo_text_extents_t extents;
221 char s[64];
222 char l[64];
223 snprintf(l,63,"%s ", w->label);
224 const char* format[] = {"%.1f", "%.2f", "%.3f"};
225 snprintf(s, 63, format[2-1], pow(10.0,w->adj_x->value));
226 strcat(l,s);
227 cairo_set_font_size (w->crb, min(11.0,height));
228 cairo_text_extents(w->crb, l, &extents);
229 cairo_move_to (w->crb, min(width-extents.width ,(width-height)*sliderstate), height);
230 cairo_show_text(w->crb, l);
231 cairo_new_path (w->crb);
232 }
233 }
234
plugin_value_changed(X11_UI * ui,Widget_t * w,PortIndex index)235 void plugin_value_changed(X11_UI *ui, Widget_t *w, PortIndex index) {
236 if (ui->block_event != w->data) {
237 if (index >= MODE1 && index <= MODE5) {
238 float value = adj_get_value(w->adj)+1.0;
239 ui->write_function(ui->controller,w->data,sizeof(float),0,&value);
240 ui->block_event = -1;
241 }
242 }
243 }
244
245 // check that bands didn't overlap
check_multi_controller(X11_UI * ui,uint32_t port_index,float value)246 static void check_multi_controller(X11_UI* ui, uint32_t port_index, float value) {
247 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
248 float v = log10f(value);
249 switch ((PortIndex)port_index)
250 {
251 case CROSSOVER_B1_B2:
252 check_value_changed(ui->widget[25]->adj, &v);
253 adj_set_value(ps->adj[0], max(adj_get_value(ps->adj[0]), v+0.1));
254 break;
255 case CROSSOVER_B2_B3:
256 adj_set_value(ui->widget[25]->adj, min(adj_get_value(ui->widget[25]->adj), v-0.1));
257 check_value_changed(ps->adj[0], &v);
258 adj_set_value(ps->adj[1], max(adj_get_value(ps->adj[1]), v+0.1));
259 break;
260 case CROSSOVER_B3_B4:
261 adj_set_value(ps->adj[0], min(adj_get_value(ps->adj[0]), v-0.1));
262 check_value_changed(ps->adj[1], &v);
263 adj_set_value(ps->adj[2], max(adj_get_value(ps->adj[2]), v+0.1));
264 break;
265 case CROSSOVER_B4_B5:
266 adj_set_value(ps->adj[1], min(adj_get_value(ps->adj[1]), v-0.1));
267 check_value_changed(ps->adj[2], &v);
268 break;
269 default:
270 break;
271 }
272 }
273
274 // if adjustment value changed send notify to host
slider_value_changed(void * w_,void * user_data)275 static void slider_value_changed(void *w_, void* user_data) {
276 Widget_t *w = (Widget_t*)w_;
277 X11_UI* ui = (X11_UI*)w->parent_struct;
278 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
279 uint32_t port_index = 0;
280 float value = 0.0;
281 if (w->adj_x == w->adj) {
282 port_index = CROSSOVER_B1_B2;
283 value = adj_get_value(w->adj);
284 } else if (w->adj_x == ps->adj[0]) {
285 port_index = CROSSOVER_B2_B3;
286 value = adj_get_value(ps->adj[0]);
287 } else if (w->adj_x == ps->adj[1]) {
288 port_index = CROSSOVER_B3_B4;
289 value = adj_get_value(ps->adj[1]);
290 } else if (w->adj_x == ps->adj[2]) {
291 port_index = CROSSOVER_B4_B5;
292 value = adj_get_value(ps->adj[2]);
293 }
294 if (port_index) {
295 float v = pow(10,value);
296 check_multi_controller(ui,port_index, v);
297 if (ui->block_event != (int)port_index)
298 ui->write_function(ui->controller,port_index,sizeof(float),0,&v);
299 ui->block_event = -1;
300 }
301 }
302
303 // redraw slider when mouse button released
my_slider_released(void * w_,void * button_,void * user_data)304 static void my_slider_released(void *w_, void* button_, void* user_data) {
305 Widget_t *w = (Widget_t*)w_;
306 expose_widget(w);
307 }
308
309 // set active adjustment based on mouse position
my_slider_pressed(void * w_,void * button_,void * user_data)310 static void my_slider_pressed(void *w_, void* button_, void* user_data) {
311 Widget_t *w = (Widget_t*)w_;
312 X11_UI* ui = (X11_UI*)w->parent_struct;
313 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
314 float x = float(w->pos_x)/float(w->width-w->height);
315
316 float sliderstate1 = adj_get_state(w->adj);
317 float sliderstate2 = adj_get_state(ps->adj[0]);
318 float sliderstate3 = adj_get_state(ps->adj[1]);
319 float sliderstate4 = adj_get_state(ps->adj[2]);
320
321 if (x < sliderstate1+0.04 && x >sliderstate1) {
322 w->adj_x = w->adj;
323 w->label = "Band 1<|>2 ";
324 }
325 else if (x < sliderstate2+0.04 && x >sliderstate2) {
326 w->adj_x = ps->adj[0];
327 w->label = "Band 2<|>3 ";
328 }
329 else if (x < sliderstate3+0.04 && x >sliderstate3) {
330 w->adj_x = ps->adj[1];
331 w->label = "Band 3<|>4 ";
332 }
333 else if (x < sliderstate4+0.04 && x >sliderstate4) {
334 w->adj_x = ps->adj[2];
335 w->label = "Band 4<|>5 ";
336 } else {
337 w->adj_x = NULL;
338 w->label = " ";
339 }
340 adj_set_start_value(w);
341
342 expose_widget(w);
343 }
344
345 // shortcut to create multi adjustment slider with portindex binding
add_my_slider(Widget_t * w,PortIndex index,const char * label,X11_UI * ui,int x,int y,int width,int height)346 Widget_t* add_my_slider(Widget_t *w, PortIndex index, const char * label,
347 X11_UI* ui, int x, int y, int width, int height) {
348 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
349 w = create_widget(ui->win->app, ui->win, x, y, width, height);
350 w->label = label;
351 w->adj = add_adjustment(w,1.3, 1.3, 1.3, 4.3, 0.001, CL_CONTINUOS);
352 adj_set_scale(w->adj, 2.0);
353 ps->adj[0] = add_adjustment(w,1.3, 1.3, 1.3, 4.3, 0.001, CL_CONTINUOS);
354 adj_set_scale(ps->adj[0], 2.0);
355 ps->adj[1] = add_adjustment(w,1.3, 1.3, 1.3, 4.3, 0.001, CL_CONTINUOS);
356 adj_set_scale(ps->adj[1], 2.0);
357 ps->adj[2] = add_adjustment(w,1.3, 1.3, 1.3, 4.3, 0.001, CL_CONTINUOS);
358 adj_set_scale(ps->adj[2], 2.0);
359 w->scale.gravity = ASPECT;
360 w->func.expose_callback = draw_my_hslider;
361 w->func.enter_callback = transparent_draw;
362 w->func.leave_callback = transparent_draw;
363 w->func.button_press_callback = my_slider_pressed;
364 w->func.button_release_callback = my_slider_released;
365 w->parent_struct = ui;
366 w->data = index;
367 w->func.value_changed_callback = slider_value_changed;
368 return w;
369 }
370
plugin_set_window_size(int * w,int * h,const char * plugin_uri)371 void plugin_set_window_size(int *w,int *h,const char * plugin_uri) {
372 (*w) = 780; //initial width of main window
373 (*h) = 520; //initial height of main window
374 }
375
plugin_set_name()376 const char* plugin_set_name() {
377 return "GxMultiBandCompressor"; //plugin name to display on UI
378 }
379
plugin_create_controller_widgets(X11_UI * ui,const char * plugin_uri)380 void plugin_create_controller_widgets(X11_UI *ui, const char * plugin_uri) {
381 X11_UI_Private_t *ps =(X11_UI_Private_t*)malloc(sizeof(X11_UI_Private_t));;
382 ui->private_ptr = (void*)ps;
383 ps->db_zero = 20.*log10(0.0000003); // -130db
384 set_my_theme(&ui->main);
385
386 int iw=0;
387 int w_pos = 620;
388 int port = (PortIndex) V1;
389 for (;iw<10;iw++) {
390 ps->meter_widget[iw] = add_vmeter(ui->win, "Meter", false, w_pos, 60, 20, 340);
391 ps->meter_widget[iw]->parent_struct = ui;
392 ps->meter_widget[iw]->scale.gravity = CENTER;
393 ps->meter_widget[iw]->data = port;
394 port +=1;
395 w_pos +=20;
396 if(iw == 4) w_pos = 60;
397 }
398
399
400 iw=0;
401 w_pos = 200;
402 port = (PortIndex) MAKEUP1;
403 for (;iw<5;iw++) {
404 ui->widget[iw] = add_my_knob(ui->widget[iw], (PortIndex)port,"Makeup", ui,w_pos, 0, 60, 85);
405 set_adjustment(ui->widget[iw]->adj,13.0, 13.0, -50.0, 50.0, 0.1, CL_CONTINUOS);
406 //adj_set_scale(ui->widget[iw]->adj, 2.0);
407 port +=1;
408 w_pos +=80;
409 }
410
411 w_pos = 200;
412 port = (PortIndex) MAKEUPTHRESHOLD1;
413 for (;iw<10;iw++) {
414 ui->widget[iw] = add_my_knob(ui->widget[iw], (PortIndex)port,"Threshold", ui,w_pos, 85, 60, 85);
415 set_adjustment(ui->widget[iw]->adj,2.0, 2.0, 0.0, 10.0, 0.01, CL_CONTINUOS);
416 //adj_set_scale(ui->widget[iw]->adj, 2.0);
417 port +=1;
418 w_pos +=80;
419 }
420
421 w_pos = 200;
422 port = (PortIndex) RATIO1;
423 for (;iw<15;iw++) {
424 ui->widget[iw] = add_my_knob(ui->widget[iw], (PortIndex)port,"Ratio", ui,w_pos, 170, 60, 85);
425 set_adjustment(ui->widget[iw]->adj,4.0, 4.0, 1.0, 100.0, 0.1, CL_CONTINUOS);
426 //adj_set_scale(ui->widget[iw]->adj, 2.0);
427 port +=1;
428 w_pos +=80;
429 }
430
431 w_pos = 200;
432 port = (PortIndex) ATTACK1;
433 for (;iw<20;iw++) {
434 ui->widget[iw] = add_my_knob(ui->widget[iw], (PortIndex)port,"Attack", ui,w_pos, 255, 60, 85);
435 set_adjustment(ui->widget[iw]->adj,0.012, 0.012, 0.001, 1.0, 0.001, CL_CONTINUOS);
436 //adj_set_scale(ui->widget[iw]->adj, 2.0);
437 port +=1;
438 w_pos +=80;
439 }
440
441 w_pos = 200;
442 port = (PortIndex) RELEASE1;
443 for (;iw<25;iw++) {
444 ui->widget[iw] = add_my_knob(ui->widget[iw], (PortIndex)port,"Release", ui,w_pos, 340, 60, 85);
445 set_adjustment(ui->widget[iw]->adj,1.25, 1.25, 0.01, 10.0, 0.01, CL_CONTINUOS);
446 //adj_set_scale(ui->widget[iw]->adj, 2.0);
447 port +=1;
448 w_pos +=80;
449 }
450
451 w_pos = 185;
452 port = (PortIndex) MODE1;
453 const char* model[] = {"Compress","Bypass","Mute"};
454 size_t len = sizeof(model) / sizeof(model[0]);
455 iw=0;
456 for (;iw<5;iw++) {
457 ps->combo_widget[iw] = add_my_combobox(ps->combo_widget[iw], (PortIndex)port,"Mode", model, len, 0, ui, w_pos, 425, 80, 25);
458 //adj_set_scale(ui->widget[iw]->adj, 2.0);
459 port +=1;
460 w_pos +=80;
461 }
462
463 ui->widget[25] = add_my_slider(ui->widget[25], CROSSOVER_B1_B2,"Crossover ",ui, 160,460, 480, 20);
464 }
465
466 // map power to db for meter widgets
set_meter_value(X11_UI * ui,Widget_t * w,float value)467 static void set_meter_value(X11_UI* ui, Widget_t*w, float value) {
468 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
469 float new_val = power2db(w,20.*log10(max(ps->db_zero,value)));
470 check_value_changed(w->adj,&new_val);
471 }
472
plugin_cleanup(X11_UI * ui)473 void plugin_cleanup(X11_UI *ui) {
474 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
475 int i = 0;
476 for(;i<10;i++)
477 destroy_widget(ps->meter_widget[i],&ui->main);
478 i = 0;
479 for(;i<5;i++)
480 destroy_widget(ps->combo_widget[i],&ui->main);
481 delete_adjustment(ps->adj[0]);
482 delete_adjustment(ps->adj[1]);
483 delete_adjustment(ps->adj[2]);
484 ui->widget[25]->adj_x = NULL;
485 free(ps);
486 ui->private_ptr = NULL;
487 }
488
plugin_port_event(LV2UI_Handle handle,uint32_t port_index,uint32_t buffer_size,uint32_t format,const void * buffer)489 void plugin_port_event(LV2UI_Handle handle, uint32_t port_index,
490 uint32_t buffer_size, uint32_t format,
491 const void * buffer) {
492 X11_UI* ui = (X11_UI*)handle;
493 X11_UI_Private_t *ps = (X11_UI_Private_t*)ui->private_ptr;
494 float value = *(float*)buffer;
495 if (port_index == V1) set_meter_value(ui,ps->meter_widget[0],value);
496 else if (port_index == V2) set_meter_value(ui,ps->meter_widget[1],value);
497 else if (port_index == V3) set_meter_value(ui,ps->meter_widget[2],value);
498 else if (port_index == V4) set_meter_value(ui,ps->meter_widget[3],value);
499 else if (port_index == V5) set_meter_value(ui,ps->meter_widget[4],value);
500 else if (port_index == V6) set_meter_value(ui,ps->meter_widget[5],value);
501 else if (port_index == V7) set_meter_value(ui,ps->meter_widget[6],value);
502 else if (port_index == V8) set_meter_value(ui,ps->meter_widget[7],value);
503 else if (port_index == V9) set_meter_value(ui,ps->meter_widget[8],value);
504 else if (port_index == V10) set_meter_value(ui,ps->meter_widget[9],value);
505 if (port_index >= CROSSOVER_B1_B2 && port_index <= CROSSOVER_B4_B5) {
506 check_multi_controller(ui, port_index, value);
507 ui->block_event = (int)port_index;
508 }
509 if (port_index >= MODE1 && port_index <= MODE5) {
510 value -=1.0;
511 check_value_changed(ps->combo_widget[port_index]->adj, &value);
512 ui->block_event = (int)port_index;
513 }
514 }
515